1 | /* |
2 | * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Library General Public License |
16 | * along with this library; see the file COPYING.LIB. If not, write to |
17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | * Boston, MA 02110-1301, USA. |
19 | * |
20 | */ |
21 | |
22 | #pragma once |
23 | |
24 | #include "CSSSelector.h" |
25 | #include "CSSToLengthConversionData.h" |
26 | #include "CSSToStyleMap.h" |
27 | #include "DocumentRuleSets.h" |
28 | #include "InspectorCSSOMWrappers.h" |
29 | #include "MediaQueryEvaluator.h" |
30 | #include "RenderStyle.h" |
31 | #include "RuleSet.h" |
32 | #include "SelectorChecker.h" |
33 | #include <bitset> |
34 | #include <memory> |
35 | #include <wtf/Bitmap.h> |
36 | #include <wtf/HashMap.h> |
37 | #include <wtf/RefPtr.h> |
38 | #include <wtf/Vector.h> |
39 | #include <wtf/text/AtomicStringHash.h> |
40 | #include <wtf/text/StringHash.h> |
41 | |
42 | namespace WebCore { |
43 | |
44 | class CSSCursorImageValue; |
45 | class CSSFontFace; |
46 | class CSSFontFaceRule; |
47 | class CSSFontValue; |
48 | class CSSImageGeneratorValue; |
49 | class CSSImageSetValue; |
50 | class CSSImageValue; |
51 | class ; |
52 | class CSSPrimitiveValue; |
53 | class CSSProperty; |
54 | class CSSStyleSheet; |
55 | class CSSValue; |
56 | class ContainerNode; |
57 | class Document; |
58 | class Element; |
59 | class Frame; |
60 | class FrameView; |
61 | class KeyframeList; |
62 | class KeyframeValue; |
63 | class MediaQueryEvaluator; |
64 | class Node; |
65 | class RenderScrollbar; |
66 | class RuleData; |
67 | class RuleSet; |
68 | class SelectorFilter; |
69 | class Settings; |
70 | class StyleCachedImage; |
71 | class StyleGeneratedImage; |
72 | class StyleImage; |
73 | class StyleRuleKeyframe; |
74 | class StyleProperties; |
75 | class StyleRule; |
76 | class StyleRuleKeyframes; |
77 | class StyleRulePage; |
78 | class StyleSheet; |
79 | class StyleSheetList; |
80 | class StyledElement; |
81 | class SVGSVGElement; |
82 | class ViewportStyleResolver; |
83 | struct ResourceLoaderOptions; |
84 | |
85 | // MatchOnlyUserAgentRules is used in media queries, where relative units |
86 | // are interpreted according to the document root element style, and styled only |
87 | // from the User Agent Stylesheet rules. |
88 | |
89 | enum class RuleMatchingBehavior: uint8_t { |
90 | MatchAllRules, |
91 | MatchAllRulesExcludingSMIL, |
92 | MatchOnlyUserAgentRules, |
93 | }; |
94 | |
95 | enum class CascadeLevel: uint8_t { |
96 | UserAgentLevel, |
97 | AuthorLevel, |
98 | UserLevel |
99 | }; |
100 | |
101 | class PseudoStyleRequest { |
102 | public: |
103 | PseudoStyleRequest(PseudoId pseudoId, RenderScrollbar* scrollbar = nullptr, ScrollbarPart scrollbarPart = NoPart) |
104 | : pseudoId(pseudoId) |
105 | , scrollbarPart(scrollbarPart) |
106 | , scrollbar(scrollbar) |
107 | { |
108 | } |
109 | |
110 | PseudoId pseudoId; |
111 | ScrollbarPart scrollbarPart; |
112 | RenderScrollbar* scrollbar; |
113 | }; |
114 | |
115 | struct ElementStyle { |
116 | ElementStyle(std::unique_ptr<RenderStyle> renderStyle, std::unique_ptr<Style::Relations> relations = { }) |
117 | : renderStyle(WTFMove(renderStyle)) |
118 | , relations(WTFMove(relations)) |
119 | { } |
120 | |
121 | std::unique_ptr<RenderStyle> renderStyle; |
122 | std::unique_ptr<Style::Relations> relations; |
123 | }; |
124 | |
125 | // This class selects a RenderStyle for a given element based on a collection of stylesheets. |
126 | class StyleResolver { |
127 | WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED; |
128 | public: |
129 | StyleResolver(Document&); |
130 | ~StyleResolver(); |
131 | |
132 | ElementStyle styleForElement(const Element&, const RenderStyle* parentStyle, const RenderStyle* parentBoxStyle = nullptr, RuleMatchingBehavior = RuleMatchingBehavior::MatchAllRules, const SelectorFilter* = nullptr); |
133 | |
134 | void keyframeStylesForAnimation(const Element&, const RenderStyle*, KeyframeList&); |
135 | |
136 | std::unique_ptr<RenderStyle> pseudoStyleForElement(const Element&, const PseudoStyleRequest&, const RenderStyle& parentStyle, const SelectorFilter* = nullptr); |
137 | |
138 | std::unique_ptr<RenderStyle> styleForPage(int pageIndex); |
139 | std::unique_ptr<RenderStyle> defaultStyleForElement(); |
140 | |
141 | RenderStyle* style() const { return m_state.style(); } |
142 | const RenderStyle* parentStyle() const { return m_state.parentStyle(); } |
143 | const RenderStyle* rootElementStyle() const { return m_state.rootElementStyle(); } |
144 | const Element* element() { return m_state.element(); } |
145 | Document& document() { return m_document; } |
146 | const Document& document() const { return m_document; } |
147 | const Settings& settings() const { return m_document.settings(); } |
148 | |
149 | void appendAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet>>&); |
150 | |
151 | DocumentRuleSets& ruleSets() { return m_ruleSets; } |
152 | const DocumentRuleSets& ruleSets() const { return m_ruleSets; } |
153 | |
154 | const MediaQueryEvaluator& mediaQueryEvaluator() const { return m_mediaQueryEvaluator; } |
155 | |
156 | RenderStyle* overrideDocumentElementStyle() const { return m_overrideDocumentElementStyle; } |
157 | void setOverrideDocumentElementStyle(RenderStyle* style) { m_overrideDocumentElementStyle = style; } |
158 | |
159 | void addCurrentSVGFontFaceRules(); |
160 | static void adjustSVGElementStyle(const SVGElement&, RenderStyle&); |
161 | |
162 | void setNewStateWithElement(const Element&); |
163 | std::unique_ptr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleRuleKeyframe*, KeyframeValue&); |
164 | bool isAnimationNameValid(const String&); |
165 | |
166 | public: |
167 | // These methods will give back the set of rules that matched for a given element (or a pseudo-element). |
168 | enum CSSRuleFilter { |
169 | UAAndUserCSSRules = 1 << 1, |
170 | AuthorCSSRules = 1 << 2, |
171 | EmptyCSSRules = 1 << 3, |
172 | AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules, |
173 | AllCSSRules = AllButEmptyCSSRules | EmptyCSSRules, |
174 | }; |
175 | Vector<RefPtr<StyleRule>> styleRulesForElement(const Element*, unsigned rulesToInclude = AllButEmptyCSSRules); |
176 | Vector<RefPtr<StyleRule>> pseudoStyleRulesForElement(const Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules); |
177 | |
178 | public: |
179 | struct MatchResult; |
180 | |
181 | void applyPropertyToStyle(CSSPropertyID, CSSValue*, std::unique_ptr<RenderStyle>); |
182 | void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*); |
183 | |
184 | void updateFont(); |
185 | void initializeFontStyle(); |
186 | |
187 | void setFontSize(FontCascadeDescription&, float size); |
188 | |
189 | public: |
190 | bool useSVGZoomRules() const; |
191 | bool useSVGZoomRulesForLength() const; |
192 | |
193 | static bool colorFromPrimitiveValueIsDerivedFromElement(const CSSPrimitiveValue&); |
194 | Color colorFromPrimitiveValue(const CSSPrimitiveValue&, bool forVisitedLink = false) const; |
195 | |
196 | bool hasSelectorForId(const AtomicString&) const; |
197 | bool hasSelectorForAttribute(const Element&, const AtomicString&) const; |
198 | |
199 | #if ENABLE(CSS_DEVICE_ADAPTATION) |
200 | ViewportStyleResolver* viewportStyleResolver() { return m_viewportStyleResolver.get(); } |
201 | #endif |
202 | |
203 | void addViewportDependentMediaQueryResult(const MediaQueryExpression&, bool result); |
204 | bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); } |
205 | bool hasMediaQueriesAffectedByViewportChange() const; |
206 | |
207 | void addAccessibilitySettingsDependentMediaQueryResult(const MediaQueryExpression&, bool result); |
208 | bool hasAccessibilitySettingsDependentMediaQueries() const { return !m_accessibilitySettingsDependentMediaQueryResults.isEmpty(); } |
209 | bool hasMediaQueriesAffectedByAccessibilitySettingsChange() const; |
210 | |
211 | void addAppearanceDependentMediaQueryResult(const MediaQueryExpression&, bool result); |
212 | bool hasAppearanceDependentMediaQueries() const { return !m_appearanceDependentMediaQueryResults.isEmpty(); } |
213 | bool hasMediaQueriesAffectedByAppearanceChange() const; |
214 | |
215 | void addKeyframeStyle(Ref<StyleRuleKeyframes>&&); |
216 | |
217 | bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; } |
218 | bool usesFirstLetterRules() const { return m_ruleSets.features().usesFirstLetterRules; } |
219 | |
220 | void invalidateMatchedPropertiesCache(); |
221 | |
222 | void clearCachedPropertiesAffectedByViewportUnits(); |
223 | |
224 | bool createFilterOperations(const CSSValue& inValue, FilterOperations& outOperations); |
225 | |
226 | struct RuleRange { |
227 | RuleRange(int& firstRuleIndex, int& lastRuleIndex): firstRuleIndex(firstRuleIndex), lastRuleIndex(lastRuleIndex) { } |
228 | int& firstRuleIndex; |
229 | int& lastRuleIndex; |
230 | }; |
231 | |
232 | struct MatchRanges { |
233 | MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { } |
234 | int firstUARule; |
235 | int lastUARule; |
236 | int firstAuthorRule; |
237 | int lastAuthorRule; |
238 | int firstUserRule; |
239 | int lastUserRule; |
240 | RuleRange UARuleRange() { return RuleRange(firstUARule, lastUARule); } |
241 | RuleRange authorRuleRange() { return RuleRange(firstAuthorRule, lastAuthorRule); } |
242 | RuleRange userRuleRange() { return RuleRange(firstUserRule, lastUserRule); } |
243 | }; |
244 | |
245 | struct MatchedProperties { |
246 | MatchedProperties(); |
247 | ~MatchedProperties(); |
248 | |
249 | RefPtr<StyleProperties> properties; |
250 | uint16_t linkMatchType; |
251 | uint16_t whitelistType; |
252 | Style::ScopeOrdinal styleScopeOrdinal; |
253 | }; |
254 | |
255 | struct MatchResult { |
256 | MatchResult() : isCacheable(true) { } |
257 | Vector<StyleRule*, 64> matchedRules; |
258 | MatchRanges ranges; |
259 | bool isCacheable; |
260 | |
261 | const Vector<MatchedProperties, 64>& matchedProperties() const { return m_matchedProperties; } |
262 | |
263 | void addMatchedProperties(const StyleProperties&, StyleRule* = nullptr, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone, Style::ScopeOrdinal = Style::ScopeOrdinal::Element); |
264 | private: |
265 | Vector<MatchedProperties, 64> m_matchedProperties; |
266 | }; |
267 | |
268 | class CascadedProperties { |
269 | WTF_MAKE_FAST_ALLOCATED; |
270 | public: |
271 | CascadedProperties(TextDirection, WritingMode); |
272 | |
273 | struct Property { |
274 | void apply(StyleResolver&, ApplyCascadedPropertyState&); |
275 | |
276 | CSSPropertyID id; |
277 | CascadeLevel level; |
278 | Style::ScopeOrdinal styleScopeOrdinal; |
279 | CSSValue* cssValue[3]; |
280 | }; |
281 | |
282 | bool hasProperty(CSSPropertyID) const; |
283 | Property& property(CSSPropertyID); |
284 | |
285 | void addNormalMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false); |
286 | void addImportantMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false); |
287 | |
288 | void applyDeferredProperties(StyleResolver&, ApplyCascadedPropertyState&); |
289 | |
290 | HashMap<AtomicString, Property>& customProperties() { return m_customProperties; } |
291 | bool hasCustomProperty(const String&) const; |
292 | Property customProperty(const String&) const; |
293 | |
294 | private: |
295 | void addMatch(const MatchResult&, unsigned index, bool isImportant, bool inheritedOnly); |
296 | void set(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal); |
297 | void setDeferred(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal); |
298 | static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal); |
299 | |
300 | Property m_properties[numCSSProperties + 2]; |
301 | std::bitset<numCSSProperties + 2> m_propertyIsPresent; |
302 | |
303 | Vector<Property, 8> m_deferredProperties; |
304 | HashMap<AtomicString, Property> m_customProperties; |
305 | |
306 | TextDirection m_direction; |
307 | WritingMode m_writingMode; |
308 | }; |
309 | |
310 | void applyCascadedProperties(int firstProperty, int lastProperty, ApplyCascadedPropertyState&); |
311 | void applyCascadedCustomProperty(const String& name, ApplyCascadedPropertyState&); |
312 | |
313 | private: |
314 | // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh |
315 | void checkForGenericFamilyChange(RenderStyle*, const RenderStyle* parentStyle); |
316 | void checkForZoomChange(RenderStyle*, const RenderStyle* parentStyle); |
317 | #if ENABLE(TEXT_AUTOSIZING) |
318 | void checkForTextSizeAdjust(RenderStyle*); |
319 | #endif |
320 | |
321 | void adjustRenderStyle(RenderStyle&, const RenderStyle& parentStyle, const RenderStyle* parentBoxStyle, const Element*); |
322 | void adjustRenderStyleForSiteSpecificQuirks(RenderStyle&, const Element&); |
323 | |
324 | std::unique_ptr<GridPosition> adjustNamedGridItemPosition(const NamedGridAreaMap&, const NamedGridLinesMap&, const GridPosition&, GridPositionSide) const; |
325 | |
326 | void adjustStyleForInterCharacterRuby(); |
327 | |
328 | bool fastRejectSelector(const RuleData&) const; |
329 | |
330 | enum ShouldUseMatchedPropertiesCache { DoNotUseMatchedPropertiesCache = 0, UseMatchedPropertiesCache }; |
331 | void applyMatchedProperties(const MatchResult&, const Element&, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache); |
332 | |
333 | enum CustomPropertyCycleTracking { Enabled = 0, Disabled }; |
334 | template<CustomPropertyCycleTracking> |
335 | inline void applyCascadedPropertiesImpl(int firstProperty, int lastProperty, ApplyCascadedPropertyState&); |
336 | |
337 | void cascadeMatches(CascadedProperties&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly); |
338 | |
339 | void (MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName); |
340 | void (Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName); |
341 | |
342 | bool isLeftPage(int pageIndex) const; |
343 | bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); } |
344 | bool isFirstPage(int pageIndex) const; |
345 | String pageName(int pageIndex) const; |
346 | |
347 | DocumentRuleSets m_ruleSets; |
348 | |
349 | typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes>> KeyframesRuleMap; |
350 | KeyframesRuleMap m_keyframesRuleMap; |
351 | |
352 | public: |
353 | typedef HashMap<CSSPropertyID, RefPtr<CSSValue>> PendingImagePropertyMap; |
354 | |
355 | class State { |
356 | public: |
357 | State() { } |
358 | State(const Element&, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle = nullptr, const SelectorFilter* = nullptr); |
359 | |
360 | public: |
361 | void clear(); |
362 | |
363 | const Element* element() const { return m_element; } |
364 | |
365 | void setStyle(std::unique_ptr<RenderStyle>); |
366 | RenderStyle* style() const { return m_style.get(); } |
367 | std::unique_ptr<RenderStyle> takeStyle() { return WTFMove(m_style); } |
368 | |
369 | void setParentStyle(std::unique_ptr<RenderStyle>); |
370 | const RenderStyle* parentStyle() const { return m_parentStyle; } |
371 | const RenderStyle* rootElementStyle() const { return m_rootElementStyle; } |
372 | |
373 | InsideLink elementLinkState() const { return m_elementLinkState; } |
374 | |
375 | void setApplyPropertyToRegularStyle(bool isApply) { m_applyPropertyToRegularStyle = isApply; } |
376 | void setApplyPropertyToVisitedLinkStyle(bool isApply) { m_applyPropertyToVisitedLinkStyle = isApply; } |
377 | bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; } |
378 | bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; } |
379 | |
380 | void setFontDirty(bool isDirty) { m_fontDirty = isDirty; } |
381 | bool fontDirty() const { return m_fontDirty; } |
382 | void setFontSizeHasViewportUnits(bool hasViewportUnits) { m_fontSizeHasViewportUnits = hasViewportUnits; } |
383 | bool fontSizeHasViewportUnits() const { return m_fontSizeHasViewportUnits; } |
384 | |
385 | void cacheBorderAndBackground(); |
386 | bool hasUAAppearance() const { return m_hasUAAppearance; } |
387 | BorderData borderData() const { return m_borderData; } |
388 | FillLayer backgroundData() const { return m_backgroundData; } |
389 | const Color& backgroundColor() const { return m_backgroundColor; } |
390 | |
391 | const FontCascadeDescription& fontDescription() { return m_style->fontDescription(); } |
392 | const FontCascadeDescription& parentFontDescription() { return m_parentStyle->fontDescription(); } |
393 | void setFontDescription(FontCascadeDescription&& fontDescription) { m_fontDirty |= m_style->setFontDescription(WTFMove(fontDescription)); } |
394 | void setZoom(float f) { m_fontDirty |= m_style->setZoom(f); } |
395 | void setEffectiveZoom(float f) { m_fontDirty |= m_style->setEffectiveZoom(f); } |
396 | void setWritingMode(WritingMode writingMode) { m_fontDirty |= m_style->setWritingMode(writingMode); } |
397 | void setTextOrientation(TextOrientation textOrientation) { m_fontDirty |= m_style->setTextOrientation(textOrientation); } |
398 | |
399 | bool useSVGZoomRules() const { return m_element && m_element->isSVGElement(); } |
400 | |
401 | const CSSToLengthConversionData& cssToLengthConversionData() const { return m_cssToLengthConversionData; } |
402 | |
403 | CascadeLevel cascadeLevel() const { return m_cascadeLevel; } |
404 | void setCascadeLevel(CascadeLevel level) { m_cascadeLevel = level; } |
405 | Style::ScopeOrdinal styleScopeOrdinal() const { return m_styleScopeOrdinal; } |
406 | void setStyleScopeOrdinal(Style::ScopeOrdinal styleScopeOrdinal) { m_styleScopeOrdinal = styleScopeOrdinal; } |
407 | |
408 | CascadedProperties* authorRollback() const { return m_authorRollback.get(); } |
409 | CascadedProperties* userRollback() const { return m_userRollback.get(); } |
410 | |
411 | void setAuthorRollback(std::unique_ptr<CascadedProperties>& rollback) { m_authorRollback = WTFMove(rollback); } |
412 | void setUserRollback(std::unique_ptr<CascadedProperties>& rollback) { m_userRollback = WTFMove(rollback); } |
413 | |
414 | const SelectorFilter* selectorFilter() const { return m_selectorFilter; } |
415 | |
416 | private: |
417 | void updateConversionData(); |
418 | |
419 | const Element* m_element { nullptr }; |
420 | std::unique_ptr<RenderStyle> m_style; |
421 | const RenderStyle* m_parentStyle { nullptr }; |
422 | std::unique_ptr<RenderStyle> m_ownedParentStyle; |
423 | const RenderStyle* m_rootElementStyle { nullptr }; |
424 | std::unique_ptr<CascadedProperties> m_authorRollback; |
425 | std::unique_ptr<CascadedProperties> m_userRollback; |
426 | |
427 | const SelectorFilter* m_selectorFilter { nullptr }; |
428 | |
429 | BorderData m_borderData; |
430 | FillLayer m_backgroundData { FillLayerType::Background }; |
431 | Color m_backgroundColor; |
432 | |
433 | CSSToLengthConversionData m_cssToLengthConversionData; |
434 | |
435 | Style::ScopeOrdinal m_styleScopeOrdinal { Style::ScopeOrdinal::Element }; |
436 | |
437 | InsideLink m_elementLinkState { InsideLink::NotInside }; |
438 | CascadeLevel m_cascadeLevel { CascadeLevel::UserAgentLevel }; |
439 | |
440 | bool m_applyPropertyToRegularStyle { true }; |
441 | bool m_applyPropertyToVisitedLinkStyle { false }; |
442 | bool m_fontDirty { false }; |
443 | bool m_fontSizeHasViewportUnits { false }; |
444 | bool m_hasUAAppearance { false }; |
445 | }; |
446 | |
447 | State& state() { return m_state; } |
448 | const State& state() const { return m_state; } |
449 | |
450 | RefPtr<StyleImage> styleImage(CSSValue&); |
451 | |
452 | bool applyPropertyToRegularStyle() const { return m_state.applyPropertyToRegularStyle(); } |
453 | bool applyPropertyToVisitedLinkStyle() const { return m_state.applyPropertyToVisitedLinkStyle(); } |
454 | |
455 | CascadeLevel cascadeLevel() const { return m_state.cascadeLevel(); } |
456 | void setCascadeLevel(CascadeLevel level) { m_state.setCascadeLevel(level); } |
457 | |
458 | CascadedProperties* cascadedPropertiesForRollback(const MatchResult&); |
459 | |
460 | CSSToStyleMap* styleMap() { return &m_styleMap; } |
461 | InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; } |
462 | const FontCascadeDescription& fontDescription() { return m_state.fontDescription(); } |
463 | const FontCascadeDescription& parentFontDescription() { return m_state.parentFontDescription(); } |
464 | void setFontDescription(FontCascadeDescription&& fontDescription) { m_state.setFontDescription(WTFMove(fontDescription)); } |
465 | void setZoom(float f) { m_state.setZoom(f); } |
466 | void setEffectiveZoom(float f) { m_state.setEffectiveZoom(f); } |
467 | void setWritingMode(WritingMode writingMode) { m_state.setWritingMode(writingMode); } |
468 | void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); } |
469 | |
470 | RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&, ApplyCascadedPropertyState&) const; |
471 | |
472 | private: |
473 | void cacheBorderAndBackground(); |
474 | |
475 | void applyProperty(CSSPropertyID, CSSValue*, ApplyCascadedPropertyState&, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault); |
476 | |
477 | void applySVGProperty(CSSPropertyID, CSSValue*); |
478 | |
479 | static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size); |
480 | struct MatchedPropertiesCacheItem { |
481 | Vector<MatchedProperties> matchedProperties; |
482 | MatchRanges ranges; |
483 | std::unique_ptr<RenderStyle> renderStyle; |
484 | std::unique_ptr<RenderStyle> parentRenderStyle; |
485 | |
486 | MatchedPropertiesCacheItem(const MatchResult& matchResult, const RenderStyle* style, const RenderStyle* parentStyle) |
487 | : ranges(matchResult.ranges) |
488 | , renderStyle(RenderStyle::clonePtr(*style)) |
489 | , parentRenderStyle(RenderStyle::clonePtr(*parentStyle)) |
490 | { |
491 | // Assign rather than copy-construct so we only allocate as much vector capacity as needed. |
492 | matchedProperties = matchResult.matchedProperties(); |
493 | } |
494 | MatchedPropertiesCacheItem() = default; |
495 | }; |
496 | const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&); |
497 | void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&); |
498 | |
499 | // Every N additions to the matched declaration cache trigger a sweep where entries holding |
500 | // the last reference to a style declaration are garbage collected. |
501 | void sweepMatchedPropertiesCache(); |
502 | |
503 | typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache; |
504 | MatchedPropertiesCache m_matchedPropertiesCache; |
505 | |
506 | Timer m_matchedPropertiesCacheSweepTimer; |
507 | |
508 | MediaQueryEvaluator m_mediaQueryEvaluator; |
509 | std::unique_ptr<RenderStyle> m_rootDefaultStyle; |
510 | |
511 | Document& m_document; |
512 | |
513 | RenderStyle* m_overrideDocumentElementStyle { nullptr }; |
514 | |
515 | Vector<MediaQueryResult> m_viewportDependentMediaQueryResults; |
516 | Vector<MediaQueryResult> m_accessibilitySettingsDependentMediaQueryResults; |
517 | Vector<MediaQueryResult> m_appearanceDependentMediaQueryResults; |
518 | |
519 | #if ENABLE(CSS_DEVICE_ADAPTATION) |
520 | RefPtr<ViewportStyleResolver> m_viewportStyleResolver; |
521 | #endif |
522 | |
523 | CSSToStyleMap m_styleMap; |
524 | InspectorCSSOMWrappers m_inspectorCSSOMWrappers; |
525 | |
526 | State m_state; |
527 | |
528 | unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep { 0 }; |
529 | |
530 | bool m_matchAuthorAndUserStyles { true }; |
531 | // See if we still have crashes where StyleResolver gets deleted early. |
532 | bool m_isDeleted { false }; |
533 | |
534 | friend bool operator==(const MatchedProperties&, const MatchedProperties&); |
535 | friend bool operator!=(const MatchedProperties&, const MatchedProperties&); |
536 | friend bool operator==(const MatchRanges&, const MatchRanges&); |
537 | friend bool operator!=(const MatchRanges&, const MatchRanges&); |
538 | }; |
539 | |
540 | // State to use when applying properties, to keep track of which custom and high-priority |
541 | // properties have been resolved. |
542 | struct ApplyCascadedPropertyState { |
543 | StyleResolver* styleResolver; |
544 | StyleResolver::CascadedProperties* cascade; |
545 | const StyleResolver::MatchResult* matchResult; |
546 | Bitmap<numCSSProperties> appliedProperties = { }; |
547 | HashSet<String> appliedCustomProperties = { }; |
548 | Bitmap<numCSSProperties> inProgressProperties = { }; |
549 | HashSet<String> inProgressPropertiesCustom = { }; |
550 | }; |
551 | |
552 | |
553 | inline bool StyleResolver::hasSelectorForAttribute(const Element& element, const AtomicString &attributeName) const |
554 | { |
555 | ASSERT(!attributeName.isEmpty()); |
556 | if (element.isHTMLElement()) |
557 | return m_ruleSets.features().attributeCanonicalLocalNamesInRules.contains(attributeName); |
558 | return m_ruleSets.features().attributeLocalNamesInRules.contains(attributeName); |
559 | } |
560 | |
561 | inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const |
562 | { |
563 | ASSERT(!idValue.isEmpty()); |
564 | return m_ruleSets.features().idsInRules.contains(idValue); |
565 | } |
566 | |
567 | } // namespace WebCore |
568 | |