1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // David Hyatt & Eric Vaughan
8 // Netscape Communications
10 // See documentation in associated header file
13 #include "nsProgressMeterFrame.h"
14 #include "nsCSSRendering.h"
15 #include "nsIContent.h"
16 #include "nsPresContext.h"
17 #include "nsGkAtoms.h"
18 #include "nsNameSpaceManager.h"
20 #include "nsBoxLayoutState.h"
21 #include "nsIReflowCallback.h"
22 #include "nsContentUtils.h"
23 #include "mozilla/Attributes.h"
25 class nsReflowFrameRunnable
: public nsRunnable
28 nsReflowFrameRunnable(nsIFrame
* aFrame
,
29 nsIPresShell::IntrinsicDirty aIntrinsicDirty
,
30 nsFrameState aBitToAdd
);
34 nsWeakFrame mWeakFrame
;
35 nsIPresShell::IntrinsicDirty mIntrinsicDirty
;
36 nsFrameState mBitToAdd
;
39 nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame
* aFrame
,
40 nsIPresShell::IntrinsicDirty aIntrinsicDirty
,
41 nsFrameState aBitToAdd
)
43 mIntrinsicDirty(aIntrinsicDirty
),
49 nsReflowFrameRunnable::Run()
51 if (mWeakFrame
.IsAlive()) {
52 mWeakFrame
->PresContext()->PresShell()->
53 FrameNeedsReflow(mWeakFrame
, mIntrinsicDirty
, mBitToAdd
);
61 // Creates a new Toolbar frame and returns it
64 NS_NewProgressMeterFrame (nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
66 return new (aPresShell
) nsProgressMeterFrame(aPresShell
, aContext
);
69 NS_IMPL_FRAMEARENA_HELPERS(nsProgressMeterFrame
)
72 // nsProgressMeterFrame dstr
74 // Cleanup, if necessary
76 nsProgressMeterFrame :: ~nsProgressMeterFrame ( )
80 class nsAsyncProgressMeterInit MOZ_FINAL
: public nsIReflowCallback
83 explicit nsAsyncProgressMeterInit(nsIFrame
* aFrame
) : mWeakFrame(aFrame
) {}
85 virtual bool ReflowFinished() MOZ_OVERRIDE
87 bool shouldFlush
= false;
88 nsIFrame
* frame
= mWeakFrame
.GetFrame();
90 nsAutoScriptBlocker scriptBlocker
;
91 frame
->AttributeChanged(kNameSpaceID_None
, nsGkAtoms::mode
, 0);
98 virtual void ReflowCallbackCanceled() MOZ_OVERRIDE
103 nsWeakFrame mWeakFrame
;
107 nsProgressMeterFrame::DoLayout(nsBoxLayoutState
& aState
)
109 if (mNeedsReflowCallback
) {
110 nsIReflowCallback
* cb
= new nsAsyncProgressMeterInit(this);
112 PresContext()->PresShell()->PostReflowCallback(cb
);
114 mNeedsReflowCallback
= false;
116 return nsBoxFrame::DoLayout(aState
);
120 nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID
,
124 NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
125 "Scripts not blocked in nsProgressMeterFrame::AttributeChanged!");
126 nsresult rv
= nsBoxFrame::AttributeChanged(aNameSpaceID
, aAttribute
,
132 // did the progress change?
133 bool undetermined
= mContent
->AttrValueIs(kNameSpaceID_None
, nsGkAtoms::mode
,
134 nsGkAtoms::undetermined
, eCaseMatters
);
135 if (nsGkAtoms::mode
== aAttribute
||
137 (nsGkAtoms::value
== aAttribute
|| nsGkAtoms::max
== aAttribute
))) {
138 nsIFrame
* barChild
= GetFirstPrincipalChild();
139 if (!barChild
) return NS_OK
;
140 nsIFrame
* remainderChild
= barChild
->GetNextSibling();
141 if (!remainderChild
) return NS_OK
;
142 nsCOMPtr
<nsIContent
> remainderContent
= remainderChild
->GetContent();
143 if (!remainderContent
) return NS_OK
;
145 int32_t flex
= 1, maxFlex
= 1;
147 nsAutoString value
, maxValue
;
148 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::value
, value
);
149 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::max
, maxValue
);
152 flex
= value
.ToInteger(&error
);
153 maxFlex
= maxValue
.ToInteger(&error
);
154 if (NS_FAILED(error
) || maxValue
.IsEmpty()) {
163 if (flex
> maxFlex
) {
168 nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
169 barChild
->GetContent(), nsGkAtoms::flex
, flex
));
170 nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
171 remainderContent
, nsGkAtoms::flex
, maxFlex
- flex
));
172 nsContentUtils::AddScriptRunner(new nsReflowFrameRunnable(
173 this, nsIPresShell::eTreeChange
, NS_FRAME_IS_DIRTY
));
178 #ifdef DEBUG_FRAME_DUMP
180 nsProgressMeterFrame::GetFrameName(nsAString
& aResult
) const
182 return MakeFrameName(NS_LITERAL_STRING("ProgressMeter"), aResult
);