no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / layout / style / ServoStyleSet.h
blob92c0fe7e4e848b16cf07966b782bd6312b610985
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/. */
7 #ifndef mozilla_ServoStyleSet_h
8 #define mozilla_ServoStyleSet_h
10 #include "mozilla/AlreadyAddRefed.h"
11 #include "mozilla/AnonymousContentKey.h"
12 #include "mozilla/AtomArray.h"
13 #include "mozilla/EnumeratedArray.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/PostTraversalTask.h"
16 #include "mozilla/ServoBindingTypes.h"
17 #include "mozilla/ServoUtils.h"
18 #include "mozilla/dom/RustTypes.h"
19 #include "mozilla/UniquePtr.h"
20 #include "MainThreadUtils.h"
21 #include "nsCSSPseudoElements.h"
22 #include "nsCSSAnonBoxes.h"
23 #include "nsChangeHint.h"
24 #include "nsCoord.h"
25 #include "nsAtom.h"
26 #include "nsIMemoryReporter.h"
27 #include "nsTArray.h"
28 #include "nsSize.h"
30 namespace mozilla {
31 enum class MediaFeatureChangeReason : uint8_t;
32 enum class StylePageSizeOrientation : uint8_t;
33 enum class StyleRuleChangeKind : uint32_t;
35 class ErrorResult;
37 template <typename Integer, typename Number, typename LinearStops>
38 struct StyleTimingFunction;
39 struct StylePagePseudoClassFlags;
40 struct StylePiecewiseLinearFunction;
41 using StyleComputedTimingFunction =
42 StyleTimingFunction<int32_t, float, StylePiecewiseLinearFunction>;
44 namespace css {
45 class Rule;
46 } // namespace css
47 namespace dom {
48 class CSSImportRule;
49 class Element;
50 class ShadowRoot;
51 struct PropertyDefinition;
52 } // namespace dom
53 namespace gfx {
54 class FontPaletteValueSet;
55 } // namespace gfx
56 class StyleSheet;
57 struct Keyframe;
58 class ServoElementSnapshotTable;
59 class ComputedStyle;
60 class ServoStyleRuleMap;
61 class StyleSheet;
62 } // namespace mozilla
63 class gfxFontFeatureValueSet;
64 class nsIContent;
66 class nsPresContext;
67 class nsWindowSizes;
68 struct TreeMatchContext;
70 namespace mozilla {
72 // A few flags used to track which kind of stylist state we may need to
73 // update.
74 enum class StylistState : uint8_t {
75 // The stylist is not dirty, we should do nothing.
76 NotDirty = 0,
78 // The style sheets have changed, so we need to update the style data.
79 StyleSheetsDirty = 1 << 0,
81 // Some of the style sheets of the shadow trees in the document have
82 // changed.
83 ShadowDOMStyleSheetsDirty = 1 << 1,
86 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StylistState)
88 enum class StyleOrigin : uint8_t;
90 // Bitfield type to represent Servo stylesheet origins.
91 enum class OriginFlags : uint8_t {
92 UserAgent = 0x01,
93 User = 0x02,
94 Author = 0x04,
95 All = 0x07,
98 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(OriginFlags)
101 * The set of style sheets that apply to a document, backed by a Servo
102 * Stylist. A ServoStyleSet contains StyleSheets.
104 class ServoStyleSet {
105 friend class RestyleManager;
106 using SnapshotTable = ServoElementSnapshotTable;
107 using Origin = StyleOrigin;
109 // We assert that these match the Servo ones in the definition of this array.
110 static constexpr Origin kOrigins[] = {
111 Origin(static_cast<uint8_t>(OriginFlags::UserAgent)),
112 Origin(static_cast<uint8_t>(OriginFlags::User)),
113 Origin(static_cast<uint8_t>(OriginFlags::Author)),
116 public:
117 static bool IsInServoTraversal() { return mozilla::IsInServoTraversal(); }
119 #ifdef DEBUG
120 // Used for debug assertions. We make this debug-only to prevent callers from
121 // accidentally using it instead of IsInServoTraversal, which is cheaper. We
122 // can change this if a use-case arises.
123 static bool IsCurrentThreadInServoTraversal();
124 #endif
126 static ServoStyleSet* Current() { return sInServoTraversal; }
128 explicit ServoStyleSet(dom::Document&);
129 ~ServoStyleSet();
131 void ShellDetachedFromDocument();
133 // Called when a rules in a stylesheet in this set, or a child sheet of that,
134 // are mutated from CSSOM.
135 void RuleAdded(StyleSheet&, css::Rule&);
136 void RuleRemoved(StyleSheet&, css::Rule&);
137 void RuleChanged(StyleSheet&, css::Rule*, StyleRuleChangeKind);
138 void SheetCloned(StyleSheet&);
139 void ImportRuleLoaded(dom::CSSImportRule&, StyleSheet&);
141 // Runs style invalidation due to document state changes.
142 void InvalidateStyleForDocumentStateChanges(
143 dom::DocumentState aStatesChanged);
145 void RecordShadowStyleChange(dom::ShadowRoot&);
147 bool StyleSheetsHaveChanged() const { return StylistNeedsUpdate(); }
149 RestyleHint MediumFeaturesChanged(MediaFeatureChangeReason);
151 // Evaluates a given SourceSizeList, returning the optimal viewport width in
152 // app units.
154 // The SourceSizeList parameter can be null, in which case it will return
155 // 100vw.
156 inline nscoord EvaluateSourceSizeList(
157 const StyleSourceSizeList* aSourceSizeList) const;
159 void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
160 const StylePerDocumentStyleData* RawData() const { return mRawData.get(); }
162 bool GetAuthorStyleDisabled() const { return mAuthorStyleDisabled; }
164 bool UsesFontMetrics() const;
166 void SetAuthorStyleDisabled(bool aStyleDisabled);
168 // Get a CopmutedStyle for a text node (which no rules will match).
170 // The returned ComputedStyle will have nsCSSAnonBoxes::mozText() as its
171 // pseudo.
173 // (Perhaps mozText should go away and we shouldn't even create style
174 // contexts for such content nodes, when text-combine-upright is not
175 // present. However, not doing any rule matching for them is a first step.)
176 already_AddRefed<ComputedStyle> ResolveStyleForText(
177 nsIContent* aTextNode, ComputedStyle* aParentStyle);
179 // Get a ComputedStyle for a first-letter continuation (which no rules will
180 // match).
182 // The returned ComputedStyle will have
183 // nsCSSAnonBoxes::firstLetterContinuation() as its pseudo.
185 // (Perhaps nsCSSAnonBoxes::firstLetterContinuation() should go away and we
186 // shouldn't even create ComputedStyles for such frames. However, not doing
187 // any rule matching for them is a first step. And right now we do use this
188 // ComputedStyle for some things)
189 already_AddRefed<ComputedStyle> ResolveStyleForFirstLetterContinuation(
190 ComputedStyle* aParentStyle);
192 // Get a ComputedStyle for a placeholder frame (which no rules will match).
194 // The returned ComputedStyle will have nsCSSAnonBoxes::oofPlaceholder() as
195 // its pseudo.
197 // (Perhaps nsCSSAnonBoxes::oofPaceholder() should go away and we shouldn't
198 // even create ComputedStyle for placeholders. However, not doing any rule
199 // matching for them is a first step.)
200 already_AddRefed<ComputedStyle> ResolveStyleForPlaceholder();
202 // Returns whether a given pseudo-element should exist or not.
203 static bool GeneratedContentPseudoExists(const ComputedStyle& aParentStyle,
204 const ComputedStyle& aPseudoStyle);
206 enum class IsProbe {
208 Yes,
211 // Get a style for a pseudo-element.
213 // If IsProbe is Yes, then no style is returned if there are no rules matching
214 // for the pseudo-element, or GeneratedContentPseudoExists returns false.
216 // If IsProbe is No, then the style is guaranteed to be non-null.
217 already_AddRefed<ComputedStyle> ResolvePseudoElementStyle(
218 const dom::Element& aOriginatingElement, PseudoStyleType,
219 nsAtom* aFunctionalPseudoParameter, ComputedStyle* aParentStyle,
220 IsProbe = IsProbe::No);
222 already_AddRefed<ComputedStyle> ProbePseudoElementStyle(
223 const dom::Element& aOriginatingElement, PseudoStyleType aType,
224 nsAtom* aFunctionalPseudoParameter, ComputedStyle* aParentStyle) {
225 return ResolvePseudoElementStyle(aOriginatingElement, aType,
226 aFunctionalPseudoParameter, aParentStyle,
227 IsProbe::Yes);
230 // Resolves style for a (possibly-pseudo) Element without assuming that the
231 // style has been resolved. If the element was unstyled and a new style
232 // was resolved, it is not stored in the DOM. (That is, the element remains
233 // unstyled.)
234 already_AddRefed<ComputedStyle> ResolveStyleLazily(
235 const dom::Element&, PseudoStyleType = PseudoStyleType::NotPseudo,
236 nsAtom* aFunctionalPseudoParameter = nullptr,
237 StyleRuleInclusion = StyleRuleInclusion::All);
239 // Get a ComputedStyle for an anonymous box. The pseudo type must be an
240 // inheriting anon box.
241 already_AddRefed<ComputedStyle> ResolveInheritingAnonymousBoxStyle(
242 PseudoStyleType, ComputedStyle* aParentStyle);
244 // Get a ComputedStyle for an anonymous box. The pseudo type must be
245 // a non-inheriting anon box, and must not be page-content.
246 // See ResolvePageContentStyle for resolving page-content style.
247 already_AddRefed<ComputedStyle> ResolveNonInheritingAnonymousBoxStyle(
248 PseudoStyleType aType);
250 // Get a ComputedStyle for a pageContent box with the specified page-name.
251 // A page name that is null or the empty atom and has no pseudo classes gets
252 // the global page style.
253 already_AddRefed<ComputedStyle> ResolvePageContentStyle(
254 const nsAtom* aPageName, const StylePagePseudoClassFlags& aPseudo);
256 already_AddRefed<ComputedStyle> ResolveXULTreePseudoStyle(
257 dom::Element* aParentElement, nsCSSAnonBoxPseudoStaticAtom* aPseudoTag,
258 ComputedStyle* aParentStyle, const AtomArray& aInputWord);
260 size_t SheetCount(Origin) const;
261 StyleSheet* SheetAt(Origin, size_t aIndex) const;
263 struct PageSizeAndOrientation {
264 Maybe<StylePageSizeOrientation> orientation;
265 Maybe<nsSize> size;
267 // Gets the default page size and orientation (the size/orientation specified
268 // by @page rules without a selector list), if any.
270 // If the specified size is just an orientation, then the size will be set to
271 // nothing and the orientation will be set accordingly.
272 // If the specified size is auto or square, then the orientation will be set
273 // to nothing.
274 // Otherwise, the size will and orientation is determined by the specified
275 // page size.
276 PageSizeAndOrientation GetDefaultPageSizeAndOrientation();
278 void AppendAllNonDocumentAuthorSheets(nsTArray<StyleSheet*>& aArray) const;
280 // Manage the set of style sheets in the style set
281 void AppendStyleSheet(StyleSheet&);
282 void InsertStyleSheetBefore(StyleSheet&, StyleSheet& aReferenceSheet);
283 void RemoveStyleSheet(StyleSheet&);
284 void AddDocStyleSheet(StyleSheet&);
287 * Performs a Servo traversal to compute style for all dirty nodes in the
288 * document.
290 * This will traverse all of the document's style roots (that is, its document
291 * element, and the roots of the document-level native anonymous content).
293 * We specify |ForCSSRuleChanges| to try to update all CSS animations
294 * when we call this function due to CSS rule changes since @keyframes rules
295 * may have changed.
297 * Returns true if a post-traversal is required.
299 bool StyleDocument(ServoTraversalFlags aFlags);
302 * Eagerly styles a subtree of unstyled nodes that was just appended to the
303 * tree. This is used in situations where we need the style immediately and
304 * cannot wait for a future batch restyle.
306 void StyleNewSubtree(dom::Element* aRoot);
309 * Helper for correctly calling UpdateStylist without paying the cost of an
310 * extra function call in the common no-rebuild-needed case.
312 void UpdateStylistIfNeeded() {
313 if (StylistNeedsUpdate()) {
314 UpdateStylist();
319 * Checks whether the rule tree has crossed its threshold for unused nodes,
320 * and if so, frees them.
322 void MaybeGCRuleTree();
325 * Returns true if the given element may be used as the root of a style
326 * traversal. Reasons for false include having an unstyled parent, or having
327 * a parent that is display:none.
329 * Most traversal callsites don't need to check this, but some do.
331 static bool MayTraverseFrom(const dom::Element* aElement);
333 #ifdef DEBUG
334 void AssertTreeIsClean();
335 #else
336 void AssertTreeIsClean() {}
337 #endif
340 * Clears any cached style data that may depend on all sorts of computed
341 * values.
343 * Right now this clears the non-inheriting ComputedStyle cache, resets the
344 * default computed values, and clears cached anonymous content style.
346 * This does _not_, however, clear the stylist.
348 void ClearCachedStyleData();
351 * Notifies the Servo stylesheet that the document's compatibility mode has
352 * changed.
354 void CompatibilityModeChanged();
356 template <typename T>
357 void EnumerateStyleSheets(T aCb) {
358 for (auto origin : kOrigins) {
359 for (size_t i = 0, count = SheetCount(origin); i < count; ++i) {
360 aCb(*SheetAt(origin, i));
366 * Resolve style for the given element, and return it as a
367 * ComputedStyle.
369 * FIXME(emilio): Is there a point in this after bug 1367904?
371 static inline already_AddRefed<ComputedStyle> ResolveServoStyle(
372 const dom::Element&);
374 bool GetKeyframesForName(const dom::Element&, const ComputedStyle&,
375 nsAtom* aName,
376 const StyleComputedTimingFunction& aTimingFunction,
377 nsTArray<Keyframe>& aKeyframes);
379 nsTArray<ComputedKeyframeValues> GetComputedKeyframeValuesFor(
380 const nsTArray<Keyframe>& aKeyframes, dom::Element* aElement,
381 PseudoStyleType aPseudoType, const ComputedStyle* aStyle);
383 void GetAnimationValues(
384 StyleLockedDeclarationBlock* aDeclarations, dom::Element* aElement,
385 const mozilla::ComputedStyle* aStyle,
386 nsTArray<RefPtr<StyleAnimationValue>>& aAnimationValues);
388 void AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
390 const StyleLockedCounterStyleRule* CounterStyleRuleForName(nsAtom* aName);
392 // Get all the currently-active font feature values set.
393 already_AddRefed<gfxFontFeatureValueSet> BuildFontFeatureValueSet();
395 // Get the set of all currently-active font-palette-values.
396 already_AddRefed<gfx::FontPaletteValueSet> BuildFontPaletteValueSet();
398 already_AddRefed<ComputedStyle> GetBaseContextForElement(
399 dom::Element* aElement, const ComputedStyle* aStyle);
402 * Resolve style for a given declaration block with/without the parent style.
403 * If the parent style is not specified, the document default computed values
404 * is used.
406 already_AddRefed<ComputedStyle> ResolveForDeclarations(
407 const ComputedStyle* aParentOrNull,
408 const StyleLockedDeclarationBlock* aDeclarations);
410 already_AddRefed<StyleAnimationValue> ComputeAnimationValue(
411 dom::Element* aElement, StyleLockedDeclarationBlock* aDeclaration,
412 const mozilla::ComputedStyle* aStyle);
414 void AppendTask(PostTraversalTask aTask) {
415 MOZ_ASSERT(IsInServoTraversal());
417 // We currently only use PostTraversalTasks while the Servo font metrics
418 // mutex is locked. If we need to use them in other situations during
419 // a traversal, we should assert that we've taken appropriate
420 // synchronization measures.
421 AssertIsMainThreadOrServoFontMetricsLocked();
423 mPostTraversalTasks.AppendElement(aTask);
426 // Returns true if a restyle of the document is needed due to cloning
427 // sheet inners.
428 bool EnsureUniqueInnerOnCSSSheets();
430 // Returns the style rule map.
431 ServoStyleRuleMap* StyleRuleMap();
434 * Returns true if a modification to an an attribute with the specified
435 * local name might require us to restyle the element.
437 * This function allows us to skip taking a an attribute snapshot when
438 * the modified attribute doesn't appear in an attribute selector in
439 * a style sheet.
441 bool MightHaveAttributeDependency(const dom::Element&,
442 nsAtom* aAttribute) const;
445 * Returns true if a modification to an attribute with the specified local
446 * name might require us to restyle the element's siblings.
448 bool MightHaveNthOfAttributeDependency(const dom::Element&,
449 nsAtom* aAttribute) const;
452 * Returns true if a modification to a class might require us to restyle the
453 * element's siblings.
455 bool MightHaveNthOfClassDependency(const dom::Element&);
458 * Returns true if a modification to an ID might require us to restyle the
459 * element's siblings.
461 bool MightHaveNthOfIDDependency(const dom::Element&, nsAtom* aOldID,
462 nsAtom* aNewID) const;
465 * Maybe invalidate if a modification to an ID might require us to restyle
466 * the relative selector it refers to.
468 void MaybeInvalidateRelativeSelectorIDDependency(
469 const dom::Element&, nsAtom* aOldID, nsAtom* aNewID,
470 const ServoElementSnapshotTable& aSnapshots);
473 * Maybe invalidate if a modification to an attribute with the specified local
474 * name might require us to restyle the relative selector it refers to.
476 void MaybeInvalidateRelativeSelectorClassDependency(
477 const dom::Element&, const ServoElementSnapshotTable& aSnapshots);
480 * Maybe invalidate if a modification to a Custom State might require us to
481 * restyle the relative selector it refers to.
483 void MaybeInvalidateRelativeSelectorCustomStateDependency(
484 const dom::Element&, nsAtom* state,
485 const ServoElementSnapshotTable& aSnapshots);
488 * Maybe invalidate if a modification to an ID might require us to restyle
489 * the relative selector it refers to.
491 void MaybeInvalidateRelativeSelectorAttributeDependency(
492 const dom::Element&, nsAtom* aAttribute,
493 const ServoElementSnapshotTable& aSnapshots);
496 * Maybe invalidate if a change in event state on an element might require us
497 * to restyle the relative selector it refers to.
499 void MaybeInvalidateRelativeSelectorStateDependency(
500 const dom::Element&, dom::ElementState,
501 const ServoElementSnapshotTable& aSnapshots);
504 * Maybe invalidate if a change on an element that might be selected by :empty
505 * that might require us to restyle the relative selector it refers to.
507 void MaybeInvalidateRelativeSelectorForEmptyDependency(const dom::Element&);
510 * Maybe invalidate if a state change on an element that might be selected
511 * by a selector that can only selector first/last child, that
512 * might require us to restyle the relative selector it refers to.
514 void MaybeInvalidateRelativeSelectorForNthEdgeDependency(const dom::Element&);
517 * Maybe invalidate if a state change on an element that might be selected by
518 * :nth-* (Or :nth-like) selectors that might require us to restyle the
519 * relative selector it refers to.
521 void MaybeInvalidateRelativeSelectorForNthDependencyFromSibling(
522 const dom::Element*);
525 * Maybe invalidate if a DOM element insertion might require us to restyle
526 * the relative selector to ancestors/previous siblings.
528 void MaybeInvalidateForElementInsertion(const dom::Element&);
531 * Maybe invalidate if a series of nodes is appended, among which may
532 * be element(s) that might require us to restyle the relative selector
533 * to ancestors/previous siblings.
535 void MaybeInvalidateForElementAppend(const nsIContent&);
538 * Maybe invalidate if a DOM element removal might require us to restyle
539 * the relative selector to ancestors/previous siblings.
541 void MaybeInvalidateForElementRemove(const dom::Element& aElement,
542 const nsIContent* aFollowingSibling);
545 * Returns true if a change in event state on an element might require
546 * us to restyle the element.
548 * This function allows us to skip taking a state snapshot when
549 * the changed state isn't depended upon by any pseudo-class selectors
550 * in a style sheet.
552 bool HasStateDependency(const dom::Element&, dom::ElementState) const;
555 * Returns true if a change in event state on an element might require
556 * us to restyle the element's siblings.
558 bool HasNthOfStateDependency(const dom::Element&, dom::ElementState) const;
561 * Restyle this element's siblings in order to propagate any potential change
562 * in :nth-child(of) styling.
564 void RestyleSiblingsForNthOf(const dom::Element&, uint32_t) const;
567 * Returns true if a change in document state might require us to restyle the
568 * document.
570 bool HasDocumentStateDependency(dom::DocumentState) const;
573 * Get a new ComputedStyle that uses the same rules as the given ComputedStyle
574 * but has a different parent.
576 * aElement is non-null if this is a ComputedStyle for a frame whose mContent
577 * is an element and which has no pseudo on its ComputedStyle (so it's the
578 * actual style for the element being passed).
580 already_AddRefed<ComputedStyle> ReparentComputedStyle(
581 ComputedStyle* aComputedStyle, ComputedStyle* aNewParent,
582 ComputedStyle* aNewLayoutParent, dom::Element* aElement);
585 * Invalidate styles where there's any viewport units dependent style.
587 enum class OnlyDynamic : bool { No, Yes };
588 void InvalidateForViewportUnits(OnlyDynamic);
590 private:
591 friend class AutoSetInServoTraversal;
592 friend class AutoPrepareTraversal;
593 friend class PostTraversalTask;
595 bool ShouldTraverseInParallel() const;
597 void RuleChangedInternal(StyleSheet&, css::Rule&, StyleRuleChangeKind);
600 * Forces all the ShadowRoot styles to be dirty.
602 * Only to be used for:
604 * * Devtools (dealing with sheet cloning).
605 * * Compatibility-mode changes.
607 * Try to do something more incremental for other callers that are exposed to
608 * the web.
610 void ForceDirtyAllShadowStyles();
613 * Gets the pending snapshots to handle from the restyle manager.
615 const SnapshotTable& Snapshots();
618 * Clear our cached mNonInheritingComputedStyles.
620 * We do this when we want to make sure those ComputedStyles won't live too
621 * long (e.g. when rebuilding all style data or when shutting down the style
622 * set).
624 void ClearNonInheritingComputedStyles();
627 * Perform processes that we should do before traversing.
629 * When aRoot is null, the entire document is pre-traversed. Otherwise,
630 * only the subtree rooted at aRoot is pre-traversed.
632 void PreTraverse(ServoTraversalFlags aFlags, dom::Element* aRoot = nullptr);
634 // Subset of the pre-traverse steps that involve syncing up data
635 void PreTraverseSync();
638 * Records that the contents of style sheets at the specified origin have
639 * changed since the last. Calling this will ensure that the Stylist
640 * rebuilds its selector maps.
642 void MarkOriginsDirty(OriginFlags aChangedOrigins);
645 * Note that the stylist needs a style flush due to style sheet changes.
647 void SetStylistStyleSheetsDirty();
649 void SetStylistShadowDOMStyleSheetsDirty();
651 bool StylistNeedsUpdate() const {
652 return mStylistState != StylistState::NotDirty;
656 * Update the stylist as needed to ensure style data is up-to-date.
658 * This should only be called if StylistNeedsUpdate returns true.
660 void UpdateStylist();
662 void RunPostTraversalTasks();
664 void PrependSheetOfType(Origin, StyleSheet*);
665 void AppendSheetOfType(Origin, StyleSheet*);
666 void InsertSheetOfType(Origin, StyleSheet*, StyleSheet* aBeforeSheet);
667 void RemoveSheetOfType(Origin, StyleSheet*);
669 const nsPresContext* GetPresContext() const {
670 return const_cast<ServoStyleSet*>(this)->GetPresContext();
674 * Return the associated pres context if we're the master style set and we
675 * have an associated pres shell.
677 nsPresContext* GetPresContext();
679 // The owner document of this style set. Never null, and always outlives the
680 // StyleSet.
681 dom::Document* mDocument;
682 UniquePtr<StylePerDocumentStyleData> mRawData;
684 // Map from raw Servo style rule to Gecko's wrapper object.
685 // Constructed lazily when requested by devtools.
686 UniquePtr<ServoStyleRuleMap> mStyleRuleMap;
687 uint64_t mUserFontSetUpdateGeneration = 0;
689 // Tasks to perform after a traversal, back on the main thread.
691 // These are similar to Servo's SequentialTasks, except that they are
692 // posted by C++ code running on style worker threads.
693 nsTArray<PostTraversalTask> mPostTraversalTasks;
695 // Stores pointers to our cached ComputedStyles for non-inheriting anonymous
696 // boxes.
697 EnumeratedArray<nsCSSAnonBoxes::NonInheriting, RefPtr<ComputedStyle>,
698 size_t(nsCSSAnonBoxes::NonInheriting::_Count)>
699 mNonInheritingComputedStyles;
701 public:
702 void PutCachedAnonymousContentStyles(
703 AnonymousContentKey aKey, nsTArray<RefPtr<ComputedStyle>>&& aStyles) {
704 auto index = static_cast<size_t>(aKey);
706 MOZ_ASSERT(mCachedAnonymousContentStyles.Length() + aStyles.Length() < 256,
707 "(index, length) pairs must be bigger");
708 MOZ_ASSERT(mCachedAnonymousContentStyleIndexes[index].second == 0,
709 "shouldn't need to overwrite existing cached styles");
710 MOZ_ASSERT(!aStyles.IsEmpty(), "should have some styles to cache");
712 mCachedAnonymousContentStyleIndexes[index] = std::make_pair(
713 mCachedAnonymousContentStyles.Length(), aStyles.Length());
714 mCachedAnonymousContentStyles.AppendElements(std::move(aStyles));
717 void GetCachedAnonymousContentStyles(
718 AnonymousContentKey aKey, nsTArray<RefPtr<ComputedStyle>>& aStyles) {
719 auto index = static_cast<size_t>(aKey);
720 auto loc = mCachedAnonymousContentStyleIndexes[index];
721 aStyles.AppendElements(mCachedAnonymousContentStyles.Elements() + loc.first,
722 loc.second);
725 void RegisterProperty(const dom::PropertyDefinition&, ErrorResult&);
727 private:
728 // Map of AnonymousContentKey values to an (index, length) pair pointing into
729 // mCachedAnonymousContentStyles.
731 // We assert that the index and length values fit into uint8_ts.
732 Array<std::pair<uint8_t, uint8_t>, 1 << sizeof(AnonymousContentKey) * 8>
733 mCachedAnonymousContentStyleIndexes;
735 // Stores cached ComputedStyles for certain native anonymous content.
736 nsTArray<RefPtr<ComputedStyle>> mCachedAnonymousContentStyles;
738 StylistState mStylistState = StylistState::NotDirty;
739 bool mAuthorStyleDisabled = false;
740 bool mNeedsRestyleAfterEnsureUniqueInner = false;
743 class UACacheReporter final : public nsIMemoryReporter {
744 NS_DECL_ISUPPORTS
745 NS_DECL_NSIMEMORYREPORTER
747 private:
748 ~UACacheReporter() = default;
751 } // namespace mozilla
753 #endif // mozilla_ServoStyleSet_h