1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/xul/nsProgressMeterFrame.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,184 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +// 1.10 +// David Hyatt & Eric Vaughan 1.11 +// Netscape Communications 1.12 +// 1.13 +// See documentation in associated header file 1.14 +// 1.15 + 1.16 +#include "nsProgressMeterFrame.h" 1.17 +#include "nsCSSRendering.h" 1.18 +#include "nsIContent.h" 1.19 +#include "nsPresContext.h" 1.20 +#include "nsGkAtoms.h" 1.21 +#include "nsNameSpaceManager.h" 1.22 +#include "nsCOMPtr.h" 1.23 +#include "nsBoxLayoutState.h" 1.24 +#include "nsIReflowCallback.h" 1.25 +#include "nsContentUtils.h" 1.26 +#include "mozilla/Attributes.h" 1.27 + 1.28 +class nsReflowFrameRunnable : public nsRunnable 1.29 +{ 1.30 +public: 1.31 + nsReflowFrameRunnable(nsIFrame* aFrame, 1.32 + nsIPresShell::IntrinsicDirty aIntrinsicDirty, 1.33 + nsFrameState aBitToAdd); 1.34 + 1.35 + NS_DECL_NSIRUNNABLE 1.36 + 1.37 + nsWeakFrame mWeakFrame; 1.38 + nsIPresShell::IntrinsicDirty mIntrinsicDirty; 1.39 + nsFrameState mBitToAdd; 1.40 +}; 1.41 + 1.42 +nsReflowFrameRunnable::nsReflowFrameRunnable(nsIFrame* aFrame, 1.43 + nsIPresShell::IntrinsicDirty aIntrinsicDirty, 1.44 + nsFrameState aBitToAdd) 1.45 + : mWeakFrame(aFrame), 1.46 + mIntrinsicDirty(aIntrinsicDirty), 1.47 + mBitToAdd(aBitToAdd) 1.48 +{ 1.49 +} 1.50 + 1.51 +NS_IMETHODIMP 1.52 +nsReflowFrameRunnable::Run() 1.53 +{ 1.54 + if (mWeakFrame.IsAlive()) { 1.55 + mWeakFrame->PresContext()->PresShell()-> 1.56 + FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd); 1.57 + } 1.58 + return NS_OK; 1.59 +} 1.60 + 1.61 +// 1.62 +// NS_NewToolbarFrame 1.63 +// 1.64 +// Creates a new Toolbar frame and returns it 1.65 +// 1.66 +nsIFrame* 1.67 +NS_NewProgressMeterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext) 1.68 +{ 1.69 + return new (aPresShell) nsProgressMeterFrame(aPresShell, aContext); 1.70 +} 1.71 + 1.72 +NS_IMPL_FRAMEARENA_HELPERS(nsProgressMeterFrame) 1.73 + 1.74 +// 1.75 +// nsProgressMeterFrame dstr 1.76 +// 1.77 +// Cleanup, if necessary 1.78 +// 1.79 +nsProgressMeterFrame :: ~nsProgressMeterFrame ( ) 1.80 +{ 1.81 +} 1.82 + 1.83 +class nsAsyncProgressMeterInit MOZ_FINAL : public nsIReflowCallback 1.84 +{ 1.85 +public: 1.86 + nsAsyncProgressMeterInit(nsIFrame* aFrame) : mWeakFrame(aFrame) {} 1.87 + 1.88 + virtual bool ReflowFinished() MOZ_OVERRIDE 1.89 + { 1.90 + bool shouldFlush = false; 1.91 + nsIFrame* frame = mWeakFrame.GetFrame(); 1.92 + if (frame) { 1.93 + nsAutoScriptBlocker scriptBlocker; 1.94 + frame->AttributeChanged(kNameSpaceID_None, nsGkAtoms::mode, 0); 1.95 + shouldFlush = true; 1.96 + } 1.97 + delete this; 1.98 + return shouldFlush; 1.99 + } 1.100 + 1.101 + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE 1.102 + { 1.103 + delete this; 1.104 + } 1.105 + 1.106 + nsWeakFrame mWeakFrame; 1.107 +}; 1.108 + 1.109 +NS_IMETHODIMP 1.110 +nsProgressMeterFrame::DoLayout(nsBoxLayoutState& aState) 1.111 +{ 1.112 + if (mNeedsReflowCallback) { 1.113 + nsIReflowCallback* cb = new nsAsyncProgressMeterInit(this); 1.114 + if (cb) { 1.115 + PresContext()->PresShell()->PostReflowCallback(cb); 1.116 + } 1.117 + mNeedsReflowCallback = false; 1.118 + } 1.119 + return nsBoxFrame::DoLayout(aState); 1.120 +} 1.121 + 1.122 +nsresult 1.123 +nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID, 1.124 + nsIAtom* aAttribute, 1.125 + int32_t aModType) 1.126 +{ 1.127 + NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), 1.128 + "Scripts not blocked in nsProgressMeterFrame::AttributeChanged!"); 1.129 + nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, 1.130 + aModType); 1.131 + if (NS_OK != rv) { 1.132 + return rv; 1.133 + } 1.134 + 1.135 + // did the progress change? 1.136 + bool undetermined = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mode, 1.137 + nsGkAtoms::undetermined, eCaseMatters); 1.138 + if (nsGkAtoms::mode == aAttribute || 1.139 + (!undetermined && 1.140 + (nsGkAtoms::value == aAttribute || nsGkAtoms::max == aAttribute))) { 1.141 + nsIFrame* barChild = GetFirstPrincipalChild(); 1.142 + if (!barChild) return NS_OK; 1.143 + nsIFrame* remainderChild = barChild->GetNextSibling(); 1.144 + if (!remainderChild) return NS_OK; 1.145 + nsCOMPtr<nsIContent> remainderContent = remainderChild->GetContent(); 1.146 + if (!remainderContent) return NS_OK; 1.147 + 1.148 + int32_t flex = 1, maxFlex = 1; 1.149 + if (!undetermined) { 1.150 + nsAutoString value, maxValue; 1.151 + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, value); 1.152 + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxValue); 1.153 + 1.154 + nsresult error; 1.155 + flex = value.ToInteger(&error); 1.156 + maxFlex = maxValue.ToInteger(&error); 1.157 + if (NS_FAILED(error) || maxValue.IsEmpty()) { 1.158 + maxFlex = 100; 1.159 + } 1.160 + if (maxFlex < 1) { 1.161 + maxFlex = 1; 1.162 + } 1.163 + if (flex < 0) { 1.164 + flex = 0; 1.165 + } 1.166 + if (flex > maxFlex) { 1.167 + flex = maxFlex; 1.168 + } 1.169 + } 1.170 + 1.171 + nsContentUtils::AddScriptRunner(new nsSetAttrRunnable( 1.172 + barChild->GetContent(), nsGkAtoms::flex, flex)); 1.173 + nsContentUtils::AddScriptRunner(new nsSetAttrRunnable( 1.174 + remainderContent, nsGkAtoms::flex, maxFlex - flex)); 1.175 + nsContentUtils::AddScriptRunner(new nsReflowFrameRunnable( 1.176 + this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY)); 1.177 + } 1.178 + return NS_OK; 1.179 +} 1.180 + 1.181 +#ifdef DEBUG_FRAME_DUMP 1.182 +nsresult 1.183 +nsProgressMeterFrame::GetFrameName(nsAString& aResult) const 1.184 +{ 1.185 + return MakeFrameName(NS_LITERAL_STRING("ProgressMeter"), aResult); 1.186 +} 1.187 +#endif