Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /*
7 * style sheet and style rule processor representing style attributes
8 */
10 #include "nsHTMLCSSStyleSheet.h"
11 #include "mozilla/MemoryReporting.h"
12 #include "mozilla/css/StyleRule.h"
13 #include "nsIStyleRuleProcessor.h"
14 #include "nsPresContext.h"
15 #include "nsRuleWalker.h"
16 #include "nsRuleProcessorData.h"
17 #include "mozilla/dom/Element.h"
18 #include "nsAttrValue.h"
19 #include "nsAttrValueInlines.h"
21 using namespace mozilla;
22 using namespace mozilla::dom;
24 namespace {
26 PLDHashOperator
27 ClearAttrCache(const nsAString& aKey, MiscContainer*& aValue, void*)
28 {
29 // Ideally we'd just call MiscContainer::Evict, but we can't do that since
30 // we're iterating the hashtable.
31 MOZ_ASSERT(aValue->mType == nsAttrValue::eCSSStyleRule);
33 aValue->mValue.mCSSStyleRule->SetHTMLCSSStyleSheet(nullptr);
34 aValue->mValue.mCached = 0;
36 return PL_DHASH_REMOVE;
37 }
39 } // anonymous namespace
41 nsHTMLCSSStyleSheet::nsHTMLCSSStyleSheet()
42 {
43 }
45 nsHTMLCSSStyleSheet::~nsHTMLCSSStyleSheet()
46 {
47 // We may go away before all of our cached style attributes do,
48 // so clean up any that are left.
49 mCachedStyleAttrs.Enumerate(ClearAttrCache, nullptr);
50 }
52 NS_IMPL_ISUPPORTS(nsHTMLCSSStyleSheet, nsIStyleRuleProcessor)
54 /* virtual */ void
55 nsHTMLCSSStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
56 {
57 Element* element = aData->mElement;
59 // just get the one and only style rule from the content's STYLE attribute
60 css::StyleRule* rule = element->GetInlineStyleRule();
61 if (rule) {
62 rule->RuleMatched();
63 aData->mRuleWalker->Forward(rule);
64 }
66 rule = element->GetSMILOverrideStyleRule();
67 if (rule) {
68 if (aData->mPresContext->IsProcessingRestyles() &&
69 !aData->mPresContext->IsProcessingAnimationStyleChange()) {
70 // Non-animation restyle -- don't process SMIL override style, because we
71 // don't want SMIL animation to trigger new CSS transitions. Instead,
72 // request an Animation restyle, so we still get noticed.
73 aData->mPresContext->PresShell()->RestyleForAnimation(element,
74 eRestyle_Self);
75 } else {
76 // Animation restyle (or non-restyle traversal of rules)
77 // Now we can walk SMIL overrride style, without triggering transitions.
78 rule->RuleMatched();
79 aData->mRuleWalker->Forward(rule);
80 }
81 }
82 }
84 /* virtual */ void
85 nsHTMLCSSStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
86 {
87 if (nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(aData->mPseudoType)) {
88 MOZ_ASSERT(aData->mPseudoElement,
89 "If pseudo element is supposed to support style attribute, it must "
90 "have a pseudo element set");
92 // just get the one and only style rule from the content's STYLE attribute
93 css::StyleRule* rule = aData->mPseudoElement->GetInlineStyleRule();
94 if (rule) {
95 rule->RuleMatched();
96 aData->mRuleWalker->Forward(rule);
97 }
98 }
99 }
101 /* virtual */ void
102 nsHTMLCSSStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData)
103 {
104 }
106 #ifdef MOZ_XUL
107 /* virtual */ void
108 nsHTMLCSSStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData)
109 {
110 }
111 #endif
113 // Test if style is dependent on content state
114 /* virtual */ nsRestyleHint
115 nsHTMLCSSStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData)
116 {
117 return nsRestyleHint(0);
118 }
120 /* virtual */ nsRestyleHint
121 nsHTMLCSSStyleSheet::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
122 {
123 return nsRestyleHint(0);
124 }
126 /* virtual */ bool
127 nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
128 {
129 return false;
130 }
132 // Test if style is dependent on attribute
133 /* virtual */ nsRestyleHint
134 nsHTMLCSSStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
135 {
136 // Perhaps should check that it's XUL, SVG, (or HTML) namespace, but
137 // it doesn't really matter.
138 if (aData->mAttrHasChanged && aData->mAttribute == nsGkAtoms::style) {
139 return eRestyle_Self;
140 }
142 return nsRestyleHint(0);
143 }
145 /* virtual */ bool
146 nsHTMLCSSStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext)
147 {
148 return false;
149 }
151 /* virtual */ size_t
152 nsHTMLCSSStyleSheet::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
153 {
154 return 0;
155 }
157 /* virtual */ size_t
158 nsHTMLCSSStyleSheet::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
159 {
160 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
161 }
163 void
164 nsHTMLCSSStyleSheet::CacheStyleAttr(const nsAString& aSerialized,
165 MiscContainer* aValue)
166 {
167 mCachedStyleAttrs.Put(aSerialized, aValue);
168 }
170 void
171 nsHTMLCSSStyleSheet::EvictStyleAttr(const nsAString& aSerialized,
172 MiscContainer* aValue)
173 {
174 #ifdef DEBUG
175 {
176 NS_ASSERTION(aValue = mCachedStyleAttrs.Get(aSerialized),
177 "Cached value does not match?!");
178 }
179 #endif
180 mCachedStyleAttrs.Remove(aSerialized);
181 }
183 MiscContainer*
184 nsHTMLCSSStyleSheet::LookupStyleAttr(const nsAString& aSerialized)
185 {
186 return mCachedStyleAttrs.Get(aSerialized);
187 }