layout/xul/nsProgressMeterFrame.cpp

changeset 0
6474c204b198
     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

mercurial