Line data Source code
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 : * style sheet and style rule processor representing style attributes
9 : */
10 :
11 : #include "nsHTMLCSSStyleSheet.h"
12 : #include "mozilla/MemoryReporting.h"
13 : #include "mozilla/css/StyleRule.h"
14 : #include "mozilla/DeclarationBlockInlines.h"
15 : #include "nsIStyleRuleProcessor.h"
16 : #include "nsPresContext.h"
17 : #include "nsRuleWalker.h"
18 : #include "nsRuleProcessorData.h"
19 : #include "mozilla/dom/Element.h"
20 : #include "nsAttrValue.h"
21 : #include "nsAttrValueInlines.h"
22 : #include "nsCSSPseudoElements.h"
23 : #include "mozilla/RestyleManager.h"
24 : #include "mozilla/RestyleManagerInlines.h"
25 :
26 : using namespace mozilla;
27 : using namespace mozilla::dom;
28 :
29 30 : nsHTMLCSSStyleSheet::nsHTMLCSSStyleSheet()
30 : {
31 30 : }
32 :
33 0 : nsHTMLCSSStyleSheet::~nsHTMLCSSStyleSheet()
34 : {
35 : // We may go away before all of our cached style attributes do,
36 : // so clean up any that are left.
37 0 : for (auto iter = mCachedStyleAttrs.Iter(); !iter.Done(); iter.Next()) {
38 0 : MiscContainer*& value = iter.Data();
39 :
40 : // Ideally we'd just call MiscContainer::Evict, but we can't do that since
41 : // we're iterating the hashtable.
42 0 : if (value->mType == nsAttrValue::eCSSDeclaration) {
43 0 : DeclarationBlock* declaration = value->mValue.mCSSDeclaration;
44 0 : declaration->SetHTMLCSSStyleSheet(nullptr);
45 : } else {
46 0 : MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
47 : }
48 :
49 0 : value->mValue.mCached = 0;
50 0 : iter.Remove();
51 : }
52 0 : }
53 :
54 146 : NS_IMPL_ISUPPORTS(nsHTMLCSSStyleSheet, nsIStyleRuleProcessor)
55 :
56 : /* virtual */ void
57 2501 : nsHTMLCSSStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
58 : {
59 2501 : ElementRulesMatching(aData->mPresContext, aData->mElement,
60 5002 : aData->mRuleWalker);
61 2501 : }
62 :
63 : void
64 2504 : nsHTMLCSSStyleSheet::ElementRulesMatching(nsPresContext* aPresContext,
65 : Element* aElement,
66 : nsRuleWalker* aRuleWalker)
67 : {
68 : // just get the one and only style rule from the content's STYLE attribute
69 2504 : DeclarationBlock* declaration = aElement->GetInlineStyleDeclaration();
70 2504 : if (declaration) {
71 30 : declaration->SetImmutable();
72 30 : aRuleWalker->Forward(declaration->AsGecko());
73 : }
74 :
75 2504 : declaration = aElement->GetSMILOverrideStyleDeclaration();
76 2504 : if (declaration) {
77 0 : MOZ_ASSERT(aPresContext->RestyleManager()->IsGecko(),
78 : "stylo: ElementRulesMatching must not be called when we have "
79 : "a Servo-backed style system");
80 : GeckoRestyleManager* restyleManager =
81 0 : aPresContext->RestyleManager()->AsGecko();
82 0 : if (!restyleManager->SkipAnimationRules()) {
83 : // Animation restyle (or non-restyle traversal of rules)
84 : // Now we can walk SMIL overrride style, without triggering transitions.
85 0 : declaration->SetImmutable();
86 0 : aRuleWalker->Forward(declaration->AsGecko());
87 : }
88 : }
89 2504 : }
90 :
91 : void
92 0 : nsHTMLCSSStyleSheet::PseudoElementRulesMatching(Element* aPseudoElement,
93 : CSSPseudoElementType
94 : aPseudoType,
95 : nsRuleWalker* aRuleWalker)
96 : {
97 0 : MOZ_ASSERT(nsCSSPseudoElements::
98 : PseudoElementSupportsStyleAttribute(aPseudoType));
99 0 : MOZ_ASSERT(aPseudoElement);
100 :
101 : // just get the one and only style rule from the content's STYLE attribute
102 0 : DeclarationBlock* declaration = aPseudoElement->GetInlineStyleDeclaration();
103 0 : if (declaration) {
104 0 : declaration->SetImmutable();
105 0 : aRuleWalker->Forward(declaration->AsGecko());
106 : }
107 0 : }
108 :
109 : /* virtual */ void
110 1288 : nsHTMLCSSStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
111 : {
112 1288 : if (nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(aData->mPseudoType) &&
113 0 : aData->mPseudoElement) {
114 0 : PseudoElementRulesMatching(aData->mPseudoElement, aData->mPseudoType,
115 0 : aData->mRuleWalker);
116 : }
117 1288 : }
118 :
119 : /* virtual */ void
120 210 : nsHTMLCSSStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData)
121 : {
122 210 : }
123 :
124 : #ifdef MOZ_XUL
125 : /* virtual */ void
126 0 : nsHTMLCSSStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData)
127 : {
128 0 : }
129 : #endif
130 :
131 : // Test if style is dependent on content state
132 : /* virtual */ nsRestyleHint
133 51 : nsHTMLCSSStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData)
134 : {
135 51 : return nsRestyleHint(0);
136 : }
137 :
138 : /* virtual */ nsRestyleHint
139 0 : nsHTMLCSSStyleSheet::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
140 : {
141 0 : return nsRestyleHint(0);
142 : }
143 :
144 : /* virtual */ bool
145 2 : nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
146 : {
147 2 : return false;
148 : }
149 :
150 : // Test if style is dependent on attribute
151 : /* virtual */ nsRestyleHint
152 648 : nsHTMLCSSStyleSheet::HasAttributeDependentStyle(
153 : AttributeRuleProcessorData* aData,
154 : RestyleHintData& aRestyleHintDataResult)
155 : {
156 : // Perhaps should check that it's XUL, SVG, (or HTML) namespace, but
157 : // it doesn't really matter.
158 648 : if (aData->mAttrHasChanged && aData->mAttribute == nsGkAtoms::style) {
159 5 : return eRestyle_StyleAttribute;
160 : }
161 :
162 643 : return nsRestyleHint(0);
163 : }
164 :
165 : /* virtual */ bool
166 21 : nsHTMLCSSStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext)
167 : {
168 21 : return false;
169 : }
170 :
171 : /* virtual */ size_t
172 21 : nsHTMLCSSStyleSheet::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
173 : {
174 : // The size of mCachedStyleAttrs's mTable member (a PLDHashTable) is
175 : // significant in itself, but more significant is the size of the nsString
176 : // members of the nsStringHashKeys.
177 21 : size_t n = 0;
178 21 : n += mCachedStyleAttrs.ShallowSizeOfExcludingThis(aMallocSizeOf);
179 21 : for (auto iter = mCachedStyleAttrs.ConstIter(); !iter.Done(); iter.Next()) {
180 : // We don't own the MiscContainers (the hash table values) so we don't
181 : // count them. We do care about the size of the nsString members in the
182 : // keys though.
183 0 : n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
184 : }
185 21 : return n;
186 : }
187 :
188 : /* virtual */ size_t
189 21 : nsHTMLCSSStyleSheet::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
190 : {
191 21 : return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
192 : }
193 :
194 : void
195 0 : nsHTMLCSSStyleSheet::CacheStyleAttr(const nsAString& aSerialized,
196 : MiscContainer* aValue)
197 : {
198 0 : mCachedStyleAttrs.Put(aSerialized, aValue);
199 0 : }
200 :
201 : void
202 0 : nsHTMLCSSStyleSheet::EvictStyleAttr(const nsAString& aSerialized,
203 : MiscContainer* aValue)
204 : {
205 : #ifdef DEBUG
206 : {
207 0 : NS_ASSERTION(aValue == mCachedStyleAttrs.Get(aSerialized),
208 : "Cached value does not match?!");
209 : }
210 : #endif
211 0 : mCachedStyleAttrs.Remove(aSerialized);
212 0 : }
213 :
214 : MiscContainer*
215 0 : nsHTMLCSSStyleSheet::LookupStyleAttr(const nsAString& aSerialized)
216 : {
217 0 : return mCachedStyleAttrs.Get(aSerialized);
218 : }
|