Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/xul/nsProgressMeterFrame.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
//
8
// David Hyatt & Eric Vaughan
9
// Netscape Communications
10
//
11
// See documentation in associated header file
12
//
13
14
#include "nsProgressMeterFrame.h"
15
#include "nsCSSRendering.h"
16
#include "nsIContent.h"
17
#include "nsPresContext.h"
18
#include "nsGkAtoms.h"
19
#include "nsNameSpaceManager.h"
20
#include "nsCOMPtr.h"
21
#include "nsBoxLayoutState.h"
22
#include "nsIReflowCallback.h"
23
#include "nsContentUtils.h"
24
#include "mozilla/Attributes.h"
25
26
class nsReflowFrameRunnable : public mozilla::Runnable
27
{
28
public:
29
  nsReflowFrameRunnable(nsIFrame* aFrame,
30
                        nsIPresShell::IntrinsicDirty aIntrinsicDirty,
31
                        nsFrameState aBitToAdd);
32
33
  NS_DECL_NSIRUNNABLE
34
35
  WeakFrame mWeakFrame;
36
  nsIPresShell::IntrinsicDirty mIntrinsicDirty;
37
  nsFrameState mBitToAdd;
38
};
39
40
nsReflowFrameRunnable::nsReflowFrameRunnable(
41
  nsIFrame* aFrame,
42
  nsIPresShell::IntrinsicDirty aIntrinsicDirty,
43
  nsFrameState aBitToAdd)
44
  : mozilla::Runnable("nsReflowFrameRunnable")
45
  , mWeakFrame(aFrame)
46
  , mIntrinsicDirty(aIntrinsicDirty)
47
  , mBitToAdd(aBitToAdd)
48
0
{
49
0
}
50
51
NS_IMETHODIMP
52
nsReflowFrameRunnable::Run()
53
0
{
54
0
  if (mWeakFrame.IsAlive()) {
55
0
    mWeakFrame->PresShell()->
56
0
      FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
57
0
  }
58
0
  return NS_OK;
59
0
}
60
61
//
62
// NS_NewToolbarFrame
63
//
64
// Creates a new Toolbar frame and returns it
65
//
66
nsIFrame*
67
NS_NewProgressMeterFrame (nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle)
68
0
{
69
0
  return new (aPresShell) nsProgressMeterFrame(aStyle);
70
0
}
71
72
NS_IMPL_FRAMEARENA_HELPERS(nsProgressMeterFrame)
73
74
//
75
// nsProgressMeterFrame dstr
76
//
77
// Cleanup, if necessary
78
//
79
nsProgressMeterFrame :: ~nsProgressMeterFrame ( )
80
0
{
81
0
}
82
83
class nsAsyncProgressMeterInit final : public nsIReflowCallback
84
{
85
public:
86
0
  explicit nsAsyncProgressMeterInit(nsIFrame* aFrame) : mWeakFrame(aFrame) {}
87
88
  virtual bool ReflowFinished() override
89
0
  {
90
0
    bool shouldFlush = false;
91
0
    nsIFrame* frame = mWeakFrame.GetFrame();
92
0
    if (frame) {
93
0
      nsAutoScriptBlocker scriptBlocker;
94
0
      frame->AttributeChanged(kNameSpaceID_None, nsGkAtoms::mode, 0);
95
0
      shouldFlush = true;
96
0
    }
97
0
    delete this;
98
0
    return shouldFlush;
99
0
  }
100
101
  virtual void ReflowCallbackCanceled() override
102
0
  {
103
0
    delete this;
104
0
  }
105
106
  WeakFrame mWeakFrame;
107
};
108
109
NS_IMETHODIMP
110
nsProgressMeterFrame::DoXULLayout(nsBoxLayoutState& aState)
111
0
{
112
0
  if (mNeedsReflowCallback) {
113
0
    nsIReflowCallback* cb = new nsAsyncProgressMeterInit(this);
114
0
    if (cb) {
115
0
      PresShell()->PostReflowCallback(cb);
116
0
    }
117
0
    mNeedsReflowCallback = false;
118
0
  }
119
0
  return nsBoxFrame::DoXULLayout(aState);
120
0
}
121
122
nsresult
123
nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID,
124
                                       nsAtom* aAttribute,
125
                                       int32_t aModType)
126
0
{
127
0
  NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
128
0
      "Scripts not blocked in nsProgressMeterFrame::AttributeChanged!");
129
0
  nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
130
0
                                             aModType);
131
0
  if (NS_OK != rv) {
132
0
    return rv;
133
0
  }
134
0
135
0
  // did the progress change?
136
0
  bool undetermined =
137
0
    mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mode,
138
0
                                       nsGkAtoms::undetermined, eCaseMatters);
139
0
  if (nsGkAtoms::mode == aAttribute ||
140
0
      (!undetermined &&
141
0
       (nsGkAtoms::value == aAttribute || nsGkAtoms::max == aAttribute))) {
142
0
    nsIFrame* barChild = PrincipalChildList().FirstChild();
143
0
    if (!barChild || !barChild->GetContent()->IsElement()) return NS_OK;
144
0
    nsIFrame* remainderChild = barChild->GetNextSibling();
145
0
    if (!remainderChild) return NS_OK;
146
0
    nsCOMPtr<nsIContent> remainderContent = remainderChild->GetContent();
147
0
    if (!remainderContent->IsElement()) return NS_OK;
148
0
149
0
    int32_t flex = 1, maxFlex = 1;
150
0
    if (!undetermined) {
151
0
      nsAutoString value, maxValue;
152
0
      mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, value);
153
0
      mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxValue);
154
0
155
0
      nsresult error;
156
0
      flex = value.ToInteger(&error);
157
0
      maxFlex = maxValue.ToInteger(&error);
158
0
      if (NS_FAILED(error) || maxValue.IsEmpty()) {
159
0
        maxFlex = 100;
160
0
      }
161
0
      if (maxFlex < 1) {
162
0
        maxFlex = 1;
163
0
      }
164
0
      if (flex < 0) {
165
0
        flex = 0;
166
0
      }
167
0
      if (flex > maxFlex) {
168
0
        flex = maxFlex;
169
0
      }
170
0
    }
171
0
172
0
    nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
173
0
      barChild->GetContent()->AsElement(), nsGkAtoms::flex, flex));
174
0
    nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
175
0
      remainderContent->AsElement(), nsGkAtoms::flex, maxFlex - flex));
176
0
    nsContentUtils::AddScriptRunner(new nsReflowFrameRunnable(
177
0
      this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY));
178
0
  }
179
0
  return NS_OK;
180
0
}
181
182
#ifdef DEBUG_FRAME_DUMP
183
nsresult
184
nsProgressMeterFrame::GetFrameName(nsAString& aResult) const
185
{
186
  return MakeFrameName(NS_LITERAL_STRING("ProgressMeter"), aResult);
187
}
188
#endif