Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/style/ComputedStyle.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
/* the interface (to internal code) for retrieving computed style data */
8
9
#include "mozilla/ComputedStyle.h"
10
#include "mozilla/DebugOnly.h"
11
#include "mozilla/Maybe.h"
12
13
#include "nsCSSAnonBoxes.h"
14
#include "nsCSSPseudoElements.h"
15
#include "nsFontMetrics.h"
16
#include "nsStyleConsts.h"
17
#include "nsStyleStruct.h"
18
#include "nsStyleStructInlines.h"
19
#include "nsString.h"
20
#include "nsPresContext.h"
21
#include "nsWindowSizes.h"
22
23
#include "nsCOMPtr.h"
24
#include "nsIPresShell.h"
25
26
#include "GeckoProfiler.h"
27
#include "nsIDocument.h"
28
#include "nsPrintfCString.h"
29
#include "RubyUtils.h"
30
#include "mozilla/ArenaObjectID.h"
31
#include "mozilla/ComputedStyleInlines.h"
32
#include "mozilla/Preferences.h"
33
34
#include "mozilla/ReflowInput.h"
35
#include "nsLayoutUtils.h"
36
#include "nsCoord.h"
37
38
// Ensure the binding function declarations in ComputedStyle.h matches
39
// those in ServoBindings.h.
40
#include "mozilla/ServoBindings.h"
41
42
namespace mozilla {
43
44
//----------------------------------------------------------------------
45
46
ComputedStyle::ComputedStyle(nsPresContext* aPresContext,
47
                             nsAtom* aPseudoTag,
48
                             CSSPseudoElementType aPseudoType,
49
                             ServoComputedDataForgotten aComputedValues)
50
  : mPresContext(aPresContext)
51
  , mSource(aComputedValues)
52
  , mPseudoTag(aPseudoTag)
53
  , mBits(static_cast<Bit>(Servo_ComputedValues_GetStyleBits(this)))
54
  , mPseudoType(aPseudoType)
55
0
{
56
0
  MOZ_ASSERT(ComputedData());
57
0
}
58
59
nsChangeHint
60
ComputedStyle::CalcStyleDifference(ComputedStyle* aNewContext,
61
                                   uint32_t* aEqualStructs)
62
0
{
63
0
  MOZ_ASSERT(aNewContext);
64
0
  AUTO_PROFILER_LABEL("ComputedStyle::CalcStyleDifference", LAYOUT);
65
0
  static_assert(StyleStructConstants::kStyleStructCount <= 32,
66
0
                "aEqualStructs is not big enough");
67
0
68
0
  *aEqualStructs = 0;
69
0
70
0
  nsChangeHint hint = nsChangeHint(0);
71
0
  // We must always ensure that we populate the structs on the new style
72
0
  // context that are filled in on the old context, so that if we get
73
0
  // two style changes in succession, the second of which causes a real
74
0
  // style change, the PeekStyleData doesn't return null (implying that
75
0
  // nobody ever looked at that struct's data).  In other words, we
76
0
  // can't skip later structs if we get a big change up front, because
77
0
  // we could later get a small change in one of those structs that we
78
0
  // don't want to miss.
79
0
80
0
  DebugOnly<uint32_t> structsFound = 0;
81
0
82
0
  DebugOnly<int> styleStructCount = 0;
83
0
84
0
  // Servo's optimization to stop the cascade when there are no style changes
85
0
  // that children need to be recascade for relies on comparing all of the
86
0
  // structs, not just those that are returned from PeekStyleData, although
87
0
  // if PeekStyleData does return null we could avoid to accumulate any change
88
0
  // hints for those structs.
89
0
  //
90
0
  // FIXME(emilio): Reintroduce that optimization either for all kind of structs
91
0
  // after bug 1368290 with a weak parent pointer from text, or just for reset
92
0
  // structs.
93
0
#define STYLE_STRUCT_BIT(name_) \
94
0
  StyleStructConstants::BitFor(StyleStructID::name_)
95
0
#define PEEK(struct_) \
96
0
   ComputedData()->GetStyle##struct_()
97
0
98
0
#define EXPAND(...) __VA_ARGS__
99
0
#define DO_STRUCT_DIFFERENCE_WITH_ARGS(struct_, extra_args_)                  \
100
0
  PR_BEGIN_MACRO                                                              \
101
0
    const nsStyle##struct_* this##struct_ = PEEK(struct_);                    \
102
0
    if (this##struct_) {                                                      \
103
0
      structsFound |= STYLE_STRUCT_BIT(struct_);                              \
104
0
                                                                              \
105
0
      const nsStyle##struct_* other##struct_ =                                \
106
0
        aNewContext->ThreadsafeStyle##struct_();                              \
107
0
      if (this##struct_ == other##struct_) {                                  \
108
0
        /* The very same struct, so we know that there will be no */          \
109
0
        /* differences.                                           */          \
110
0
        *aEqualStructs |= STYLE_STRUCT_BIT(struct_);                          \
111
0
      } else {                                                                \
112
0
        nsChangeHint difference =                                             \
113
0
          this##struct_->CalcDifference(*other##struct_ EXPAND extra_args_);  \
114
0
        hint |= difference;                                                   \
115
0
        if (!difference) {                                                    \
116
0
          *aEqualStructs |= STYLE_STRUCT_BIT(struct_);                        \
117
0
        }                                                                     \
118
0
      }                                                                       \
119
0
    } else {                                                                  \
120
0
      *aEqualStructs |= STYLE_STRUCT_BIT(struct_);                            \
121
0
    }                                                                         \
122
0
    styleStructCount++;                                                       \
123
0
  PR_END_MACRO
124
0
#define DO_STRUCT_DIFFERENCE(struct_) \
125
0
  DO_STRUCT_DIFFERENCE_WITH_ARGS(struct_, ())
126
0
127
0
  // FIXME: The order of these DO_STRUCT_DIFFERENCE calls is no longer
128
0
  // significant.  With a small amount of effort, we could replace them with a
129
0
  // #include "nsStyleStructList.h".
130
0
  DO_STRUCT_DIFFERENCE(Display);
131
0
  DO_STRUCT_DIFFERENCE(XUL);
132
0
  DO_STRUCT_DIFFERENCE(Column);
133
0
  DO_STRUCT_DIFFERENCE(Content);
134
0
  DO_STRUCT_DIFFERENCE(UI);
135
0
  DO_STRUCT_DIFFERENCE(Visibility);
136
0
  DO_STRUCT_DIFFERENCE(Outline);
137
0
  DO_STRUCT_DIFFERENCE(TableBorder);
138
0
  DO_STRUCT_DIFFERENCE(Table);
139
0
  DO_STRUCT_DIFFERENCE(UIReset);
140
0
  DO_STRUCT_DIFFERENCE(Text);
141
0
  DO_STRUCT_DIFFERENCE_WITH_ARGS(List, (, PEEK(Display)));
142
0
  DO_STRUCT_DIFFERENCE(SVGReset);
143
0
  DO_STRUCT_DIFFERENCE(SVG);
144
0
  DO_STRUCT_DIFFERENCE_WITH_ARGS(Position, (, PEEK(Visibility)));
145
0
  DO_STRUCT_DIFFERENCE(Font);
146
0
  DO_STRUCT_DIFFERENCE(Margin);
147
0
  DO_STRUCT_DIFFERENCE(Padding);
148
0
  DO_STRUCT_DIFFERENCE(Border);
149
0
  DO_STRUCT_DIFFERENCE(TextReset);
150
0
  DO_STRUCT_DIFFERENCE(Effects);
151
0
  DO_STRUCT_DIFFERENCE(Background);
152
0
  DO_STRUCT_DIFFERENCE(Color);
153
0
154
0
#undef DO_STRUCT_DIFFERENCE
155
0
#undef DO_STRUCT_DIFFERENCE_WITH_ARGS
156
0
#undef EXPAND
157
0
158
0
  MOZ_ASSERT(styleStructCount == StyleStructConstants::kStyleStructCount,
159
0
             "missing a call to DO_STRUCT_DIFFERENCE");
160
0
161
#ifdef DEBUG
162
  #define STYLE_STRUCT(name_)                                             \
163
    MOZ_ASSERT(!!(structsFound & STYLE_STRUCT_BIT(name_)) ==              \
164
               (PEEK(name_) != nullptr),                                  \
165
               "PeekStyleData results must not change in the middle of "  \
166
               "difference calculation.");
167
  #include "nsStyleStructList.h"
168
  #undef STYLE_STRUCT
169
#endif
170
171
0
  // Note that we do not check whether this->RelevantLinkVisited() !=
172
0
  // aNewContext->RelevantLinkVisited(); we don't need to since
173
0
  // nsCSSFrameConstructor::DoContentStateChanged always adds
174
0
  // nsChangeHint_RepaintFrame for NS_EVENT_STATE_VISITED changes (and
175
0
  // needs to, since HasStateDependentStyle probably doesn't work right
176
0
  // for NS_EVENT_STATE_VISITED).  Hopefully this doesn't actually
177
0
  // expose whether links are visited to performance tests since all
178
0
  // link coloring happens asynchronously at a time when it's hard for
179
0
  // the page to measure.
180
0
  // However, we do need to compute the larger of the changes that can
181
0
  // happen depending on whether the link is visited or unvisited, since
182
0
  // doing only the one that's currently appropriate would expose which
183
0
  // links are in history to easy performance measurement.  Therefore,
184
0
  // here, we add nsChangeHint_RepaintFrame hints (the maximum for
185
0
  // things that can depend on :visited) for the properties on which we
186
0
  // call GetVisitedDependentColor.
187
0
  ComputedStyle* thisVis = GetStyleIfVisited();
188
0
  ComputedStyle* otherVis = aNewContext->GetStyleIfVisited();
189
0
  if (!thisVis != !otherVis) {
190
0
    // One style has a style-if-visited and the other doesn't.
191
0
    // Presume a difference.
192
0
#define STYLE_STRUCT(name_, fields_) \
193
0
    *aEqualStructs &= ~STYLE_STRUCT_BIT(name_);
194
0
#include "nsCSSVisitedDependentPropList.h"
195
0
#undef STYLE_STRUCT
196
0
    hint |= nsChangeHint_RepaintFrame;
197
0
  } else if (thisVis) {
198
0
    // Both styles have a style-if-visited.
199
0
    bool change = false;
200
0
201
0
    // NB: Calling Peek on |this|, not |thisVis|, since callers may look
202
0
    // at a struct on |this| without looking at the same struct on
203
0
    // |thisVis| (including this function if we skip one of these checks
204
0
    // due to change being true already or due to the old style not having a
205
0
    // style-if-visited), but not the other way around.
206
0
#define STYLE_FIELD(name_) thisVisStruct->name_ != otherVisStruct->name_
207
0
#define STYLE_STRUCT(name_, fields_)                                    \
208
0
    if (PEEK(name_)) {                                                  \
209
0
      const nsStyle##name_* thisVisStruct =                             \
210
0
        thisVis->ThreadsafeStyle##name_();                              \
211
0
      const nsStyle##name_* otherVisStruct =                            \
212
0
        otherVis->ThreadsafeStyle##name_();                             \
213
0
      if (MOZ_FOR_EACH_SEPARATED(STYLE_FIELD, (||), (), fields_)) {     \
214
0
        *aEqualStructs &= ~STYLE_STRUCT_BIT(name_);                     \
215
0
        change = true;                                                  \
216
0
      }                                                                 \
217
0
    }
218
0
#include "nsCSSVisitedDependentPropList.h"
219
0
#undef STYLE_STRUCT
220
0
#undef STYLE_FIELD
221
0
#undef STYLE_STRUCT_BIT
222
0
223
0
    if (change) {
224
0
      hint |= nsChangeHint_RepaintFrame;
225
0
    }
226
0
  }
227
0
228
0
  if (hint & nsChangeHint_UpdateContainingBlock) {
229
0
    // If a struct returned nsChangeHint_UpdateContainingBlock, that
230
0
    // means that one property's influence on whether we're a containing
231
0
    // block for abs-pos or fixed-pos elements has changed.  However, we
232
0
    // only need to return the hint if the overall computation of
233
0
    // whether we establish a containing block has changed.
234
0
235
0
    // This depends on data in nsStyleDisplay and nsStyleEffects, so we do it
236
0
    // here
237
0
238
0
    // Note that it's perhaps good for this test to be last because it
239
0
    // doesn't use Peek* functions to get the structs on the old
240
0
    // context.  But this isn't a big concern because these struct
241
0
    // getters should be called during frame construction anyway.
242
0
    const nsStyleDisplay* oldDisp = ThreadsafeStyleDisplay();
243
0
    const nsStyleDisplay* newDisp = aNewContext->ThreadsafeStyleDisplay();
244
0
    bool isFixedCB;
245
0
    if (oldDisp->IsAbsPosContainingBlockForNonSVGTextFrames() ==
246
0
        newDisp->IsAbsPosContainingBlockForNonSVGTextFrames() &&
247
0
        (isFixedCB =
248
0
           oldDisp->IsFixedPosContainingBlockForNonSVGTextFrames(*this)) ==
249
0
        newDisp->IsFixedPosContainingBlockForNonSVGTextFrames(*aNewContext) &&
250
0
        // transform-supporting frames are a subcategory of non-SVG-text
251
0
        // frames, so no need to test this if isFixedCB is true (both
252
0
        // before and after the change)
253
0
        (isFixedCB ||
254
0
         oldDisp->IsFixedPosContainingBlockForTransformSupportingFrames() ==
255
0
         newDisp->IsFixedPosContainingBlockForTransformSupportingFrames()) &&
256
0
        // contain-layout-and-paint-supporting frames are a subset of
257
0
        // non-SVG-text frames, so no need to test this if isFixedCB is true
258
0
        // (both before and after the change).
259
0
        //
260
0
        // Note, however, that neither of these last two sets is a
261
0
        // subset of the other, because table frames support contain:
262
0
        // layout/paint but not transforms (which are instead inherited
263
0
        // to the table wrapper), and quite a few frame types support
264
0
        // transforms but not contain: layout/paint (e.g., table rows
265
0
        // and row groups, many SVG frames).
266
0
        (isFixedCB ||
267
0
         oldDisp->IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() ==
268
0
         newDisp->IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames())) {
269
0
      // While some styles that cause the frame to be a containing block
270
0
      // has changed, the overall result cannot have changed (no matter
271
0
      // what the frame type is).
272
0
      hint &= ~nsChangeHint_UpdateContainingBlock;
273
0
    }
274
0
  }
275
0
276
0
  MOZ_ASSERT(NS_IsHintSubset(hint, nsChangeHint_AllHints),
277
0
             "Added a new hint without bumping AllHints?");
278
0
  return hint & ~nsChangeHint_NeutralChange;
279
0
}
280
281
#ifdef DEBUG
282
void ComputedStyle::List(FILE* out, int32_t aIndent)
283
{
284
  nsAutoCString str;
285
  // Indent
286
  int32_t ix;
287
  for (ix = aIndent; --ix >= 0; ) {
288
    str.AppendLiteral("  ");
289
  }
290
  str.Append(nsPrintfCString("%p(%d) parent=%p ",
291
                             (void*)this,
292
                             0, nullptr
293
                             ));
294
  if (mPseudoTag) {
295
    nsAutoString  buffer;
296
    mPseudoTag->ToString(buffer);
297
    AppendUTF16toUTF8(buffer, str);
298
    str.Append(' ');
299
  }
300
301
  fprintf_stderr(out, "%s{ServoComputedData}\n", str.get());
302
}
303
#endif
304
305
306
nsIPresShell*
307
ComputedStyle::Arena()
308
0
{
309
0
  return mPresContext->PresShell();
310
0
}
311
312
template<typename Func>
313
static nscolor
314
GetVisitedDependentColorInternal(ComputedStyle* aSc, Func aColorFunc)
315
0
{
316
0
  nscolor colors[2];
317
0
  colors[0] = aColorFunc(aSc);
318
0
  if (ComputedStyle* visitedStyle = aSc->GetStyleIfVisited()) {
319
0
    colors[1] = aColorFunc(visitedStyle);
320
0
    return ComputedStyle::
321
0
      CombineVisitedColors(colors, aSc->RelevantLinkVisited());
322
0
  }
323
0
  return colors[0];
324
0
}
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<unsigned int, nsStyleColor>(unsigned int nsStyleColor::*)::$_0>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<unsigned int, nsStyleColor>(unsigned int nsStyleColor::*)::$_0)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBackground>(mozilla::StyleComplexColor nsStyleBackground::*)::$_1>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBackground>(mozilla::StyleComplexColor nsStyleBackground::*)::$_1)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBorder>(mozilla::StyleComplexColor nsStyleBorder::*)::$_2>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBorder>(mozilla::StyleComplexColor nsStyleBorder::*)::$_2)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleOutline>(mozilla::StyleComplexColor nsStyleOutline::*)::$_3>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleOutline>(mozilla::StyleComplexColor nsStyleOutline::*)::$_3)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleColumn>(mozilla::StyleComplexColor nsStyleColumn::*)::$_4>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleColumn>(mozilla::StyleComplexColor nsStyleColumn::*)::$_4)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleText>(mozilla::StyleComplexColor nsStyleText::*)::$_5>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleText>(mozilla::StyleComplexColor nsStyleText::*)::$_5)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleTextReset>(mozilla::StyleComplexColor nsStyleTextReset::*)::$_6>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleTextReset>(mozilla::StyleComplexColor nsStyleTextReset::*)::$_6)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<nsStyleSVGPaint, nsStyleSVG>(nsStyleSVGPaint nsStyleSVG::*)::$_7>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<nsStyleSVGPaint, nsStyleSVG>(nsStyleSVGPaint nsStyleSVG::*)::$_7)
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::GetVisitedDependentColorInternal<unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleUI>(mozilla::StyleComplexColor nsStyleUI::*)::$_8>(mozilla::ComputedStyle*, unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleUI>(mozilla::StyleComplexColor nsStyleUI::*)::$_8)
325
326
static nscolor
327
ExtractColor(ComputedStyle* aStyle, const nscolor& aColor)
328
0
{
329
0
  return aColor;
330
0
}
331
332
static nscolor
333
ExtractColor(ComputedStyle* aStyle, const StyleComplexColor& aColor)
334
0
{
335
0
  return aColor.CalcColor(aStyle);
336
0
}
337
338
static nscolor
339
ExtractColor(ComputedStyle* aStyle, const nsStyleSVGPaint& aPaintServer)
340
0
{
341
0
  return aPaintServer.Type() == eStyleSVGPaintType_Color
342
0
    ? aPaintServer.GetColor(aStyle) : NS_RGBA(0, 0, 0, 0);
343
0
}
344
345
#define STYLE_FIELD(struct_, field_) aField == &struct_::field_ ||
346
#define STYLE_STRUCT(name_, fields_)                                          \
347
  template<> nscolor                                                          \
348
  ComputedStyle::GetVisitedDependentColor(                                   \
349
    decltype(nsStyle##name_::MOZ_ARG_1 fields_) nsStyle##name_::* aField)     \
350
0
  {                                                                           \
351
0
    MOZ_ASSERT(MOZ_FOR_EACH(STYLE_FIELD, (nsStyle##name_,), fields_) false,   \
352
0
               "Getting visited-dependent color for a field in nsStyle"#name_ \
353
0
               " which is not listed in nsCSSVisitedDependentPropList.h");    \
354
0
    return GetVisitedDependentColorInternal(this,                             \
355
0
                                            [aField](ComputedStyle* sc) {    \
356
0
      return ExtractColor(sc, sc->Style##name_()->*aField);                   \
357
0
    });                                                                       \
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<unsigned int, nsStyleColor>(unsigned int nsStyleColor::*)::$_0::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBackground>(mozilla::StyleComplexColor nsStyleBackground::*)::$_1::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBorder>(mozilla::StyleComplexColor nsStyleBorder::*)::$_2::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleOutline>(mozilla::StyleComplexColor nsStyleOutline::*)::$_3::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleColumn>(mozilla::StyleComplexColor nsStyleColumn::*)::$_4::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleText>(mozilla::StyleComplexColor nsStyleText::*)::$_5::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleTextReset>(mozilla::StyleComplexColor nsStyleTextReset::*)::$_6::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<nsStyleSVGPaint, nsStyleSVG>(nsStyleSVGPaint nsStyleSVG::*)::$_7::operator()(mozilla::ComputedStyle*) const
Unexecuted instantiation: Unified_cpp_layout_style1.cpp:unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleUI>(mozilla::StyleComplexColor nsStyleUI::*)::$_8::operator()(mozilla::ComputedStyle*) const
358
0
  }
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<unsigned int, nsStyleColor>(unsigned int nsStyleColor::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBackground>(mozilla::StyleComplexColor nsStyleBackground::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleBorder>(mozilla::StyleComplexColor nsStyleBorder::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleOutline>(mozilla::StyleComplexColor nsStyleOutline::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleColumn>(mozilla::StyleComplexColor nsStyleColumn::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleText>(mozilla::StyleComplexColor nsStyleText::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleTextReset>(mozilla::StyleComplexColor nsStyleTextReset::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<nsStyleSVGPaint, nsStyleSVG>(nsStyleSVGPaint nsStyleSVG::*)
Unexecuted instantiation: unsigned int mozilla::ComputedStyle::GetVisitedDependentColor<mozilla::StyleComplexColor, nsStyleUI>(mozilla::StyleComplexColor nsStyleUI::*)
359
#include "nsCSSVisitedDependentPropList.h"
360
#undef STYLE_STRUCT
361
#undef STYLE_FIELD
362
363
struct ColorIndexSet {
364
  uint8_t colorIndex, alphaIndex;
365
};
366
367
static const ColorIndexSet gVisitedIndices[2] = { { 0, 0 }, { 1, 0 } };
368
369
/* static */ nscolor
370
ComputedStyle::CombineVisitedColors(nscolor *aColors, bool aLinkIsVisited)
371
0
{
372
0
  if (NS_GET_A(aColors[1]) == 0) {
373
0
    // If the style-if-visited is transparent, then just use the
374
0
    // unvisited style rather than using the (meaningless) color
375
0
    // components of the visited style along with a potentially
376
0
    // non-transparent alpha value.
377
0
    aLinkIsVisited = false;
378
0
  }
379
0
380
0
  // NOTE: We want this code to have as little timing dependence as
381
0
  // possible on whether this->RelevantLinkVisited() is true.
382
0
  const ColorIndexSet &set =
383
0
    gVisitedIndices[aLinkIsVisited ? 1 : 0];
384
0
385
0
  nscolor colorColor = aColors[set.colorIndex];
386
0
  nscolor alphaColor = aColors[set.alphaIndex];
387
0
  return NS_RGBA(NS_GET_R(colorColor), NS_GET_G(colorColor),
388
0
                 NS_GET_B(colorColor), NS_GET_A(alphaColor));
389
0
}
390
391
#ifdef DEBUG
392
/* static */ const char*
393
ComputedStyle::StructName(StyleStructID aSID)
394
{
395
  switch (aSID) {
396
#define STYLE_STRUCT(name_)     \
397
    case StyleStructID::name_:  \
398
      return #name_;
399
#include "nsStyleStructList.h"
400
#undef STYLE_STRUCT
401
    default:
402
      return "Unknown";
403
  }
404
}
405
406
/* static */ Maybe<StyleStructID>
407
ComputedStyle::LookupStruct(const nsACString& aName)
408
{
409
#define STYLE_STRUCT(name_)             \
410
  if (aName.EqualsLiteral(#name_)) \
411
    return Some(StyleStructID::name_);
412
#include "nsStyleStructList.h"
413
#undef STYLE_STRUCT
414
  return Nothing();
415
}
416
#endif // DEBUG
417
418
ComputedStyle*
419
ComputedStyle::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const
420
0
{
421
0
  MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo &&
422
0
             aPseudo != CSSPseudoElementType::InheritingAnonBox &&
423
0
             aPseudo != CSSPseudoElementType::NonInheritingAnonBox);
424
0
  MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "Lazy pseudos can't inherit lazy pseudos");
425
0
426
0
  if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aPseudo)) {
427
0
    return nullptr;
428
0
  }
429
0
430
0
  return mCachedInheritingStyles.Lookup(nsCSSPseudoElements::GetPseudoAtom(aPseudo));
431
0
}
432
433
MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoComputedValuesMallocEnclosingSizeOf)
434
435
void
436
ComputedStyle::AddSizeOfIncludingThis(nsWindowSizes& aSizes,
437
                                      size_t* aCVsSize) const
438
0
{
439
0
  // Note: |this| sits within a servo_arc::Arc, i.e. it is preceded by a
440
0
  // refcount. So we need to measure it with a function that can handle an
441
0
  // interior pointer. We use ServoComputedValuesMallocEnclosingSizeOf to
442
0
  // clearly identify in DMD's output the memory measured here.
443
0
  *aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
444
0
  mSource.AddSizeOfExcludingThis(aSizes);
445
0
  mCachedInheritingStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
446
0
}
447
448
} // namespace mozilla