123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /* -*- 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
|