Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / layout / xul / nsProgressMeterFrame.cpp
blob5095465026584de3055292c01035383551375d9c
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/. */
6 //
7 // David Hyatt & Eric Vaughan
8 // Netscape Communications
9 //
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"
19 #include "nsCOMPtr.h"
20 #include "nsBoxLayoutState.h"
21 #include "nsIReflowCallback.h"
22 #include "nsContentUtils.h"
23 #include "mozilla/Attributes.h"
25 class nsReflowFrameRunnable : public nsRunnable
27 public:
28 nsReflowFrameRunnable(nsIFrame* aFrame,
29 nsIPresShell::IntrinsicDirty aIntrinsicDirty,
30 nsFrameState aBitToAdd);
32 NS_DECL_NSIRUNNABLE
34 nsWeakFrame mWeakFrame;
35 nsIPresShell::IntrinsicDirty mIntrinsicDirty;
36 nsFrameState mBitToAdd;
39 nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame,
40 nsIPresShell::IntrinsicDirty aIntrinsicDirty,
41 nsFrameState aBitToAdd)
42 : mWeakFrame(aFrame),
43 mIntrinsicDirty(aIntrinsicDirty),
44 mBitToAdd(aBitToAdd)
48 NS_IMETHODIMP
49 nsReflowFrameRunnable::Run()
51 if (mWeakFrame.IsAlive()) {
52 mWeakFrame->PresContext()->PresShell()->
53 FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
55 return NS_OK;
59 // NS_NewToolbarFrame
61 // Creates a new Toolbar frame and returns it
63 nsIFrame*
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
82 public:
83 explicit nsAsyncProgressMeterInit(nsIFrame* aFrame) : mWeakFrame(aFrame) {}
85 virtual bool ReflowFinished() MOZ_OVERRIDE
87 bool shouldFlush = false;
88 nsIFrame* frame = mWeakFrame.GetFrame();
89 if (frame) {
90 nsAutoScriptBlocker scriptBlocker;
91 frame->AttributeChanged(kNameSpaceID_None, nsGkAtoms::mode, 0);
92 shouldFlush = true;
94 delete this;
95 return shouldFlush;
98 virtual void ReflowCallbackCanceled() MOZ_OVERRIDE
100 delete this;
103 nsWeakFrame mWeakFrame;
106 NS_IMETHODIMP
107 nsProgressMeterFrame::DoLayout(nsBoxLayoutState& aState)
109 if (mNeedsReflowCallback) {
110 nsIReflowCallback* cb = new nsAsyncProgressMeterInit(this);
111 if (cb) {
112 PresContext()->PresShell()->PostReflowCallback(cb);
114 mNeedsReflowCallback = false;
116 return nsBoxFrame::DoLayout(aState);
119 nsresult
120 nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID,
121 nsIAtom* aAttribute,
122 int32_t aModType)
124 NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
125 "Scripts not blocked in nsProgressMeterFrame::AttributeChanged!");
126 nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
127 aModType);
128 if (NS_OK != rv) {
129 return rv;
132 // did the progress change?
133 bool undetermined = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mode,
134 nsGkAtoms::undetermined, eCaseMatters);
135 if (nsGkAtoms::mode == aAttribute ||
136 (!undetermined &&
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;
146 if (!undetermined) {
147 nsAutoString value, maxValue;
148 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, value);
149 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxValue);
151 nsresult error;
152 flex = value.ToInteger(&error);
153 maxFlex = maxValue.ToInteger(&error);
154 if (NS_FAILED(error) || maxValue.IsEmpty()) {
155 maxFlex = 100;
157 if (maxFlex < 1) {
158 maxFlex = 1;
160 if (flex < 0) {
161 flex = 0;
163 if (flex > maxFlex) {
164 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));
175 return NS_OK;
178 #ifdef DEBUG_FRAME_DUMP
179 nsresult
180 nsProgressMeterFrame::GetFrameName(nsAString& aResult) const
182 return MakeFrameName(NS_LITERAL_STRING("ProgressMeter"), aResult);
184 #endif