diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /layout/xul/nsProgressMeterFrame.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'layout/xul/nsProgressMeterFrame.cpp')
-rw-r--r-- | layout/xul/nsProgressMeterFrame.cpp | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/layout/xul/nsProgressMeterFrame.cpp b/layout/xul/nsProgressMeterFrame.cpp new file mode 100644 index 000000000..a798d5717 --- /dev/null +++ b/layout/xul/nsProgressMeterFrame.cpp @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// +// David Hyatt & Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsProgressMeterFrame.h" +#include "nsCSSRendering.h" +#include "nsIContent.h" +#include "nsPresContext.h" +#include "nsGkAtoms.h" +#include "nsNameSpaceManager.h" +#include "nsCOMPtr.h" +#include "nsBoxLayoutState.h" +#include "nsIReflowCallback.h" +#include "nsContentUtils.h" +#include "mozilla/Attributes.h" + +class nsReflowFrameRunnable : public mozilla::Runnable +{ +public: + nsReflowFrameRunnable(nsIFrame* aFrame, + nsIPresShell::IntrinsicDirty aIntrinsicDirty, + nsFrameState aBitToAdd); + + NS_DECL_NSIRUNNABLE + + nsWeakFrame mWeakFrame; + nsIPresShell::IntrinsicDirty mIntrinsicDirty; + nsFrameState mBitToAdd; +}; + +nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame, + nsIPresShell::IntrinsicDirty aIntrinsicDirty, + nsFrameState aBitToAdd) + : mWeakFrame(aFrame), + mIntrinsicDirty(aIntrinsicDirty), + mBitToAdd(aBitToAdd) +{ +} + +NS_IMETHODIMP +nsReflowFrameRunnable::Run() +{ + if (mWeakFrame.IsAlive()) { + mWeakFrame->PresContext()->PresShell()-> + FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd); + } + return NS_OK; +} + +// +// NS_NewToolbarFrame +// +// Creates a new Toolbar frame and returns it +// +nsIFrame* +NS_NewProgressMeterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) +{ + return new (aPresShell) nsProgressMeterFrame(aContext); +} + +NS_IMPL_FRAMEARENA_HELPERS(nsProgressMeterFrame) + +// +// nsProgressMeterFrame dstr +// +// Cleanup, if necessary +// +nsProgressMeterFrame :: ~nsProgressMeterFrame ( ) +{ +} + +class nsAsyncProgressMeterInit final : public nsIReflowCallback +{ +public: + explicit nsAsyncProgressMeterInit(nsIFrame* aFrame) : mWeakFrame(aFrame) {} + + virtual bool ReflowFinished() override + { + bool shouldFlush = false; + nsIFrame* frame = mWeakFrame.GetFrame(); + if (frame) { + nsAutoScriptBlocker scriptBlocker; + frame->AttributeChanged(kNameSpaceID_None, nsGkAtoms::mode, 0); + shouldFlush = true; + } + delete this; + return shouldFlush; + } + + virtual void ReflowCallbackCanceled() override + { + delete this; + } + + nsWeakFrame mWeakFrame; +}; + +NS_IMETHODIMP +nsProgressMeterFrame::DoXULLayout(nsBoxLayoutState& aState) +{ + if (mNeedsReflowCallback) { + nsIReflowCallback* cb = new nsAsyncProgressMeterInit(this); + if (cb) { + PresContext()->PresShell()->PostReflowCallback(cb); + } + mNeedsReflowCallback = false; + } + return nsBoxFrame::DoXULLayout(aState); +} + +nsresult +nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) +{ + NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), + "Scripts not blocked in nsProgressMeterFrame::AttributeChanged!"); + nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, + aModType); + if (NS_OK != rv) { + return rv; + } + + // did the progress change? + bool undetermined = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mode, + nsGkAtoms::undetermined, eCaseMatters); + if (nsGkAtoms::mode == aAttribute || + (!undetermined && + (nsGkAtoms::value == aAttribute || nsGkAtoms::max == aAttribute))) { + nsIFrame* barChild = PrincipalChildList().FirstChild(); + if (!barChild) return NS_OK; + nsIFrame* remainderChild = barChild->GetNextSibling(); + if (!remainderChild) return NS_OK; + nsCOMPtr<nsIContent> remainderContent = remainderChild->GetContent(); + if (!remainderContent) return NS_OK; + + int32_t flex = 1, maxFlex = 1; + if (!undetermined) { + nsAutoString value, maxValue; + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, value); + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxValue); + + nsresult error; + flex = value.ToInteger(&error); + maxFlex = maxValue.ToInteger(&error); + if (NS_FAILED(error) || maxValue.IsEmpty()) { + maxFlex = 100; + } + if (maxFlex < 1) { + maxFlex = 1; + } + if (flex < 0) { + flex = 0; + } + if (flex > maxFlex) { + flex = maxFlex; + } + } + + nsContentUtils::AddScriptRunner(new nsSetAttrRunnable( + barChild->GetContent(), nsGkAtoms::flex, flex)); + nsContentUtils::AddScriptRunner(new nsSetAttrRunnable( + remainderContent, nsGkAtoms::flex, maxFlex - flex)); + nsContentUtils::AddScriptRunner(new nsReflowFrameRunnable( + this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY)); + } + return NS_OK; +} + +#ifdef DEBUG_FRAME_DUMP +nsresult +nsProgressMeterFrame::GetFrameName(nsAString& aResult) const +{ + return MakeFrameName(NS_LITERAL_STRING("ProgressMeter"), aResult); +} +#endif |