diff options
Diffstat (limited to 'Source/WebCore/css/StyleResolver.h')
-rw-r--r-- | Source/WebCore/css/StyleResolver.h | 495 |
1 files changed, 217 insertions, 278 deletions
diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h index eaa2d98f5..acb119b73 100644 --- a/Source/WebCore/css/StyleResolver.h +++ b/Source/WebCore/css/StyleResolver.h @@ -19,25 +19,21 @@ * */ -#ifndef StyleResolver_h -#define StyleResolver_h +#pragma once +#include "CSSSelector.h" +#include "CSSToLengthConversionData.h" #include "CSSToStyleMap.h" -#include "CSSValueList.h" #include "DocumentRuleSets.h" #include "InspectorCSSOMWrappers.h" -#include "LinkHash.h" -#include "MediaQueryExp.h" +#include "MediaQueryEvaluator.h" #include "RenderStyle.h" #include "RuleFeature.h" #include "RuleSet.h" -#include "RuntimeEnabledFeatures.h" -#include "ScrollTypes.h" #include "SelectorChecker.h" -#include "SelectorFilter.h" -#include "StyleInheritedData.h" -#include "StyleScopeResolver.h" -#include "ViewportStyleResolver.h" +#include "StylePendingResources.h" +#include "StyleScope.h" +#include <bitset> #include <memory> #include <wtf/HashMap.h> #include <wtf/HashSet.h> @@ -49,21 +45,19 @@ namespace WebCore { class CSSCursorImageValue; -class CSSFontSelector; class CSSFontFace; class CSSFontFaceRule; +class CSSFontValue; class CSSImageGeneratorValue; class CSSImageSetValue; class CSSImageValue; class CSSPageRule; class CSSPrimitiveValue; class CSSProperty; -class CSSSelector; class CSSStyleSheet; class CSSValue; class ContainerNode; class Document; -class DeprecatedStyleBuilder; class Element; class Frame; class FrameView; @@ -76,42 +70,23 @@ class RenderRegion; class RenderScrollbar; class RuleData; class RuleSet; +class SelectorFilter; class Settings; -class StyleScopeResolver; +class StyleCachedImage; +class StyleGeneratedImage; class StyleImage; -class StyleKeyframe; -class StylePendingImage; +class StyleRuleKeyframe; class StyleProperties; class StyleRule; -#if ENABLE(SHADOW_DOM) -class StyleRuleHost; -#endif class StyleRuleKeyframes; class StyleRulePage; class StyleRuleRegion; class StyleSheet; class StyleSheetList; class StyledElement; +class SVGSVGElement; class ViewportStyleResolver; -class WebKitCSSFilterValue; - -class MediaQueryResult { - WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED; -public: - MediaQueryResult(const MediaQueryExp& expr, bool result) - : m_expression(expr) - , m_result(result) - { - } - - MediaQueryExp m_expression; - bool m_result; -}; - -enum StyleSharingBehavior { - AllowStyleSharing, - DisallowStyleSharing, -}; +struct ResourceLoaderOptions; // MatchOnlyUserAgentRules is used in media queries, where relative units // are interpreted according to the document root element style, and styled only @@ -123,9 +98,15 @@ enum RuleMatchingBehavior { MatchOnlyUserAgentRules, }; +enum CascadeLevel { + UserAgentLevel, + AuthorLevel, + UserLevel +}; + class PseudoStyleRequest { public: - PseudoStyleRequest(PseudoId pseudoId, RenderScrollbar* scrollbar = 0, ScrollbarPart scrollbarPart = NoPart) + PseudoStyleRequest(PseudoId pseudoId, RenderScrollbar* scrollbar = nullptr, ScrollbarPart scrollbarPart = NoPart) : pseudoId(pseudoId) , scrollbarPart(scrollbarPart) , scrollbar(scrollbar) @@ -137,68 +118,51 @@ public: RenderScrollbar* scrollbar; }; +struct ElementStyle { + ElementStyle(std::unique_ptr<RenderStyle> renderStyle, std::unique_ptr<Style::Relations> relations = { }) + : renderStyle(WTFMove(renderStyle)) + , relations(WTFMove(relations)) + { } + + std::unique_ptr<RenderStyle> renderStyle; + std::unique_ptr<Style::Relations> relations; +}; + // This class selects a RenderStyle for a given element based on a collection of stylesheets. class StyleResolver { WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED; public: - StyleResolver(Document&, bool matchAuthorAndUserStyles); + StyleResolver(Document&); ~StyleResolver(); - // Using these during tree walk will allow style selector to optimize child and descendant selector lookups. - void pushParentElement(Element*); - void popParentElement(Element*); - void pushParentShadowRoot(const ShadowRoot*); - void popParentShadowRoot(const ShadowRoot*); -#if ENABLE(SHADOW_DOM) - void addHostRule(StyleRuleHost* rule, bool hasDocumentSecurityOrigin, const ContainerNode* scope) { ensureScopeResolver()->addHostRule(rule, hasDocumentSecurityOrigin, scope); } -#endif - - PassRef<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing, - RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0); + ElementStyle styleForElement(const Element&, const RenderStyle* parentStyle, const RenderStyle* parentBoxStyle = nullptr, RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr); - void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&); + void keyframeStylesForAnimation(const Element&, const RenderStyle*, KeyframeList&); - PassRefPtr<RenderStyle> pseudoStyleForElement(Element*, const PseudoStyleRequest&, RenderStyle* parentStyle); + std::unique_ptr<RenderStyle> pseudoStyleForElement(const Element&, const PseudoStyleRequest&, const RenderStyle& parentStyle); - PassRef<RenderStyle> styleForPage(int pageIndex); - PassRef<RenderStyle> defaultStyleForElement(); + std::unique_ptr<RenderStyle> styleForPage(int pageIndex); + std::unique_ptr<RenderStyle> defaultStyleForElement(); RenderStyle* style() const { return m_state.style(); } - RenderStyle* parentStyle() const { return m_state.parentStyle(); } - RenderStyle* rootElementStyle() const { return m_state.rootElementStyle(); } - Element* element() { return m_state.element(); } + const RenderStyle* parentStyle() const { return m_state.parentStyle(); } + const RenderStyle* rootElementStyle() const { return m_state.rootElementStyle(); } + const Element* element() { return m_state.element(); } Document& document() { return m_document; } - StyleScopeResolver* scopeResolver() const { return m_scopeResolver.get(); } - bool hasParentNode() const { return m_state.parentNode(); } + const Document& document() const { return m_document; } + const Settings& settings() const { return m_document.settings(); } - // FIXME: It could be better to call m_ruleSets.appendAuthorStyleSheets() directly after we factor StyleRsolver further. - // https://bugs.webkit.org/show_bug.cgi?id=108890 - void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet>>&); + void appendAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet>>&); DocumentRuleSets& ruleSets() { return m_ruleSets; } const DocumentRuleSets& ruleSets() const { return m_ruleSets; } - SelectorFilter& selectorFilter() { return m_selectorFilter; } -#if ENABLE(SHADOW_DOM) - StyleScopeResolver* ensureScopeResolver() - { - ASSERT(RuntimeEnabledFeatures::sharedFeatures().shadowDOMEnabled()); - if (!m_scopeResolver) - m_scopeResolver = std::make_unique<StyleScopeResolver>(); - return m_scopeResolver.get(); - } -#endif + const MediaQueryEvaluator& mediaQueryEvaluator() const { return m_mediaQueryEvaluator; } -private: - void initElement(Element*); - RenderStyle* locateSharedStyle(); - bool styleSharingCandidateMatchesRuleSet(RuleSet*); - bool styleSharingCandidateMatchesHostRules(); - Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const; - StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const; - bool canShareStyleWithElement(StyledElement*) const; + void setOverrideDocumentElementStyle(RenderStyle* style) { m_overrideDocumentElementStyle = style; } - PassRef<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&); +private: + std::unique_ptr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleRuleKeyframe*, KeyframeValue&); public: // These methods will give back the set of rules that matched for a given element (or a pseudo-element). @@ -210,58 +174,55 @@ public: AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules, AllCSSRules = AllButEmptyCSSRules | EmptyCSSRules, }; - Vector<RefPtr<StyleRuleBase>> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules); - Vector<RefPtr<StyleRuleBase>> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules); + Vector<RefPtr<StyleRule>> styleRulesForElement(const Element*, unsigned rulesToInclude = AllButEmptyCSSRules); + Vector<RefPtr<StyleRule>> pseudoStyleRulesForElement(const Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules); public: - void applyPropertyToStyle(CSSPropertyID, CSSValue*, RenderStyle*); + struct MatchResult; + void applyPropertyToStyle(CSSPropertyID, CSSValue*, std::unique_ptr<RenderStyle>); void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*); void updateFont(); - void initializeFontStyle(Settings*); + void initializeFontStyle(); - void setFontSize(FontDescription&, float size); + void setFontSize(FontCascadeDescription&, float size); public: bool useSVGZoomRules(); + bool useSVGZoomRulesForLength(); - static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*); - Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const; + static bool colorFromPrimitiveValueIsDerivedFromElement(const CSSPrimitiveValue&); + Color colorFromPrimitiveValue(const CSSPrimitiveValue&, bool forVisitedLink = false) const; bool hasSelectorForId(const AtomicString&) const; bool hasSelectorForClass(const AtomicString&) const; - bool hasSelectorForAttribute(const AtomicString&) const; + bool hasSelectorForAttribute(const Element&, const AtomicString&) const; - CSSFontSelector* fontSelector() const { return m_fontSelector.get(); } #if ENABLE(CSS_DEVICE_ADAPTATION) ViewportStyleResolver* viewportStyleResolver() { return m_viewportStyleResolver.get(); } #endif - void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result); + void addViewportDependentMediaQueryResult(const MediaQueryExpression&, bool result); bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); } - bool affectedByViewportChange() const; + bool hasMediaQueriesAffectedByViewportChange() const; - void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>); + void addAccessibilitySettingsDependentMediaQueryResult(const MediaQueryExpression&, bool result); + bool hasAccessibilitySettingsDependentMediaQueries() const { return !m_accessibilitySettingsDependentMediaQueryResults.isEmpty(); } + bool hasMediaQueriesAffectedByAccessibilitySettingsChange() const; - bool checkRegionStyle(Element* regionElement); + void addKeyframeStyle(Ref<StyleRuleKeyframes>&&); + + bool checkRegionStyle(const Element* regionElement); - bool usesSiblingRules() const { return !m_ruleSets.features().siblingRules.isEmpty(); } bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; } - bool usesBeforeAfterRules() const { return m_ruleSets.features().usesBeforeAfterRules; } + bool usesFirstLetterRules() const { return m_ruleSets.features().usesFirstLetterRules; } void invalidateMatchedPropertiesCache(); -#if ENABLE(CSS_FILTERS) - bool createFilterOperations(CSSValue* inValue, FilterOperations& outOperations); -#if ENABLE(SVG) - void loadPendingSVGDocuments(); -#endif -#endif // ENABLE(CSS_FILTERS) - - void loadPendingResources(); + void clearCachedPropertiesAffectedByViewportUnits(); - int viewportPercentageValue(CSSPrimitiveValue& unit, int percentage); + bool createFilterOperations(const CSSValue& inValue, FilterOperations& outOperations); struct RuleRange { RuleRange(int& firstRuleIndex, int& lastRuleIndex): firstRuleIndex(firstRuleIndex), lastRuleIndex(lastRuleIndex) { } @@ -287,45 +248,85 @@ public: ~MatchedProperties(); RefPtr<StyleProperties> properties; - union { - struct { - unsigned linkMatchType : 2; - unsigned whitelistType : 2; - }; - // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object. - void* possiblyPaddedMember; - }; + uint16_t linkMatchType; + uint16_t whitelistType; + Style::ScopeOrdinal styleScopeOrdinal; }; struct MatchResult { MatchResult() : isCacheable(true) { } - Vector<MatchedProperties, 64> matchedProperties; Vector<StyleRule*, 64> matchedRules; MatchRanges ranges; bool isCacheable; - void addMatchedProperties(const StyleProperties&, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone); + const Vector<MatchedProperties, 64>& matchedProperties() const { return m_matchedProperties; } + + void addMatchedProperties(const StyleProperties&, StyleRule* = nullptr, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone, Style::ScopeOrdinal = Style::ScopeOrdinal::Element); + private: + Vector<MatchedProperties, 64> m_matchedProperties; + }; + + class CascadedProperties { + WTF_MAKE_FAST_ALLOCATED; + public: + CascadedProperties(TextDirection, WritingMode); + + struct Property { + void apply(StyleResolver&, const MatchResult*); + + CSSPropertyID id; + CascadeLevel level; + Style::ScopeOrdinal styleScopeOrdinal; + CSSValue* cssValue[3]; + }; + + bool hasProperty(CSSPropertyID) const; + Property& property(CSSPropertyID); + + void addNormalMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false); + void addImportantMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false); + + void applyDeferredProperties(StyleResolver&, const MatchResult*); + + HashMap<AtomicString, Property>& customProperties() { return m_customProperties; } + bool hasCustomProperty(const String&) const; + Property customProperty(const String&) const; + + private: + void addMatch(const MatchResult&, unsigned index, bool isImportant, bool inheritedOnly); + void set(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal); + void setDeferred(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal); + static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, Style::ScopeOrdinal); + + Property m_properties[numCSSProperties + 2]; + std::bitset<numCSSProperties + 2> m_propertyIsPresent; + + Vector<Property, 8> m_deferredProperties; + HashMap<AtomicString, Property> m_customProperties; + + TextDirection m_direction; + WritingMode m_writingMode; }; private: // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh - void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle); - void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle); -#if ENABLE(IOS_TEXT_AUTOSIZING) + void checkForGenericFamilyChange(RenderStyle*, const RenderStyle* parentStyle); + void checkForZoomChange(RenderStyle*, const RenderStyle* parentStyle); +#if ENABLE(TEXT_AUTOSIZING) void checkForTextSizeAdjust(RenderStyle*); #endif - void adjustRenderStyle(RenderStyle& styleToAdjust, const RenderStyle& parentStyle, Element*); - void adjustGridItemPosition(RenderStyle& styleToAdjust, const RenderStyle& parentStyle) const; - + void adjustRenderStyle(RenderStyle&, const RenderStyle& parentStyle, const RenderStyle* parentBoxStyle, const Element*); + std::unique_ptr<GridPosition> adjustNamedGridItemPosition(const NamedGridAreaMap&, const NamedGridLinesMap&, const GridPosition&, GridPositionSide) const; + + void adjustStyleForInterCharacterRuby(); + bool fastRejectSelector(const RuleData&) const; enum ShouldUseMatchedPropertiesCache { DoNotUseMatchedPropertiesCache = 0, UseMatchedPropertiesCache }; - void applyMatchedProperties(const MatchResult&, const Element*, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache); + void applyMatchedProperties(const MatchResult&, const Element&, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache); - class CascadedProperties; - - void applyCascadedProperties(CascadedProperties&, int firstProperty, int lastProperty); + void applyCascadedProperties(CascadedProperties&, int firstProperty, int lastProperty, const MatchResult*); void cascadeMatches(CascadedProperties&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly); static bool isValidRegionStyleProperty(CSSPropertyID); @@ -334,7 +335,6 @@ private: #endif void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName); void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName); - Settings* documentSettings() { return m_document.settings(); } bool isLeftPage(int pageIndex) const; bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); } @@ -350,69 +350,46 @@ public: typedef HashMap<CSSPropertyID, RefPtr<CSSValue>> PendingImagePropertyMap; class State { - WTF_MAKE_NONCOPYABLE(State); public: - State() - : m_element(0) - , m_styledElement(0) - , m_parentNode(0) - , m_parentStyle(0) - , m_rootElementStyle(0) - , m_regionForStyling(0) - , m_elementLinkState(NotInsideLink) - , m_elementAffectedByClassRules(false) - , m_applyPropertyToRegularStyle(true) - , m_applyPropertyToVisitedLinkStyle(false) - , m_lineHeightValue(0) - , m_fontDirty(false) - , m_hasUAAppearance(false) - , m_backgroundData(BackgroundFillLayer) { } + State() { } + State(const Element&, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle = nullptr, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr); public: - void initElement(Element*); - void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle = 0, RenderRegion* regionForStyling = 0); void clear(); Document& document() const { return m_element->document(); } - Element* element() const { return m_element; } - StyledElement* styledElement() const { return m_styledElement; } - void setStyle(PassRef<RenderStyle> style) { m_style = std::move(style); } + const Element* element() const { return m_element; } + + void setStyle(std::unique_ptr<RenderStyle>); RenderStyle* style() const { return m_style.get(); } - PassRef<RenderStyle> takeStyle() { return m_style.releaseNonNull(); } + std::unique_ptr<RenderStyle> takeStyle() { return WTFMove(m_style); } - const ContainerNode* parentNode() const { return m_parentNode; } - void setParentStyle(PassRef<RenderStyle> parentStyle) { m_parentStyle = std::move(parentStyle); } - RenderStyle* parentStyle() const { return m_parentStyle.get(); } - RenderStyle* rootElementStyle() const { return m_rootElementStyle; } + void setParentStyle(std::unique_ptr<RenderStyle>); + const RenderStyle* parentStyle() const { return m_parentStyle; } + const RenderStyle* rootElementStyle() const { return m_rootElementStyle; } const RenderRegion* regionForStyling() const { return m_regionForStyling; } EInsideLink elementLinkState() const { return m_elementLinkState; } - void setElementAffectedByClassRules(bool isAffected) { m_elementAffectedByClassRules = isAffected; } - bool elementAffectedByClassRules() const { return m_elementAffectedByClassRules; } void setApplyPropertyToRegularStyle(bool isApply) { m_applyPropertyToRegularStyle = isApply; } void setApplyPropertyToVisitedLinkStyle(bool isApply) { m_applyPropertyToVisitedLinkStyle = isApply; } bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; } bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; } - PendingImagePropertyMap& pendingImageProperties() { return m_pendingImageProperties; } -#if ENABLE(CSS_FILTERS) && ENABLE(SVG) - Vector<RefPtr<ReferenceFilterOperation>>& filtersWithPendingSVGDocuments() { return m_filtersWithPendingSVGDocuments; } -#endif - void setLineHeightValue(CSSValue* value) { m_lineHeightValue = value; } - CSSValue* lineHeightValue() { return m_lineHeightValue; } void setFontDirty(bool isDirty) { m_fontDirty = isDirty; } bool fontDirty() const { return m_fontDirty; } + void setFontSizeHasViewportUnits(bool hasViewportUnits) { m_fontSizeHasViewportUnits = hasViewportUnits; } + bool fontSizeHasViewportUnits() const { return m_fontSizeHasViewportUnits; } void cacheBorderAndBackground(); bool hasUAAppearance() const { return m_hasUAAppearance; } BorderData borderData() const { return m_borderData; } FillLayer backgroundData() const { return m_backgroundData; } - Color backgroundColor() const { return m_backgroundColor; } + const Color& backgroundColor() const { return m_backgroundColor; } - const FontDescription& fontDescription() { return m_style->fontDescription(); } - const FontDescription& parentFontDescription() { return m_parentStyle->fontDescription(); } - void setFontDescription(const FontDescription& fontDescription) { m_fontDirty |= m_style->setFontDescription(fontDescription); } + const FontCascadeDescription& fontDescription() { return m_style->fontDescription(); } + const FontCascadeDescription& parentFontDescription() { return m_parentStyle->fontDescription(); } + void setFontDescription(const FontCascadeDescription& fontDescription) { m_fontDirty |= m_style->setFontDescription(fontDescription); } void setZoom(float f) { m_fontDirty |= m_style->setZoom(f); } void setEffectiveZoom(float f) { m_fontDirty |= m_style->setEffectiveZoom(f); } void setWritingMode(WritingMode writingMode) { m_fontDirty |= m_style->setWritingMode(writingMode); } @@ -420,207 +397,169 @@ public: bool useSVGZoomRules() const { return m_element && m_element->isSVGElement(); } - private: - // FIXME(bug 108563): to make it easier to review, these member - // variables are public. However we should add methods to access - // these variables. - Element* m_element; - RefPtr<RenderStyle> m_style; - StyledElement* m_styledElement; - ContainerNode* m_parentNode; - RefPtr<RenderStyle> m_parentStyle; - RenderStyle* m_rootElementStyle; - - // Required to ASSERT in applyProperties. - RenderRegion* m_regionForStyling; + const CSSToLengthConversionData& cssToLengthConversionData() const { return m_cssToLengthConversionData; } + + CascadeLevel cascadeLevel() const { return m_cascadeLevel; } + void setCascadeLevel(CascadeLevel level) { m_cascadeLevel = level; } + Style::ScopeOrdinal styleScopeOrdinal() const { return m_styleScopeOrdinal; } + void setStyleScopeOrdinal(Style::ScopeOrdinal styleScopeOrdinal) { m_styleScopeOrdinal = styleScopeOrdinal; } + + CascadedProperties* authorRollback() const { return m_authorRollback.get(); } + CascadedProperties* userRollback() const { return m_userRollback.get(); } - EInsideLink m_elementLinkState; + void setAuthorRollback(std::unique_ptr<CascadedProperties>& rollback) { m_authorRollback = WTFMove(rollback); } + void setUserRollback(std::unique_ptr<CascadedProperties>& rollback) { m_userRollback = WTFMove(rollback); } - bool m_elementAffectedByClassRules; + const SelectorFilter* selectorFilter() const { return m_selectorFilter; } + + private: + void updateConversionData(); - bool m_applyPropertyToRegularStyle; - bool m_applyPropertyToVisitedLinkStyle; + const Element* m_element { nullptr }; + std::unique_ptr<RenderStyle> m_style; + const RenderStyle* m_parentStyle { nullptr }; + std::unique_ptr<RenderStyle> m_ownedParentStyle; + const RenderStyle* m_rootElementStyle { nullptr }; - PendingImagePropertyMap m_pendingImageProperties; -#if ENABLE(CSS_FILTERS) && ENABLE(SVG) - Vector<RefPtr<ReferenceFilterOperation>> m_filtersWithPendingSVGDocuments; -#endif - CSSValue* m_lineHeightValue; - bool m_fontDirty; + const RenderRegion* m_regionForStyling { nullptr }; + + EInsideLink m_elementLinkState { NotInsideLink }; + + bool m_applyPropertyToRegularStyle { true }; + bool m_applyPropertyToVisitedLinkStyle { false }; + bool m_fontDirty { false }; + bool m_fontSizeHasViewportUnits { false }; + bool m_hasUAAppearance { false }; - bool m_hasUAAppearance; BorderData m_borderData; - FillLayer m_backgroundData; + FillLayer m_backgroundData { BackgroundFillLayer }; Color m_backgroundColor; + + CSSToLengthConversionData m_cssToLengthConversionData; + + CascadeLevel m_cascadeLevel { UserAgentLevel }; + Style::ScopeOrdinal m_styleScopeOrdinal { Style::ScopeOrdinal::Element }; + std::unique_ptr<CascadedProperties> m_authorRollback; + std::unique_ptr<CascadedProperties> m_userRollback; + + const SelectorFilter* m_selectorFilter { nullptr }; }; State& state() { return m_state; } + const State& state() const { return m_state; } - static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; } - - PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*); - PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*); - PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue&); -#if ENABLE(CSS_IMAGE_SET) - PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*); -#endif - PassRefPtr<StyleImage> cursorOrPendingFromValue(CSSPropertyID, CSSCursorImageValue*); + RefPtr<StyleImage> styleImage(CSSValue&); bool applyPropertyToRegularStyle() const { return m_state.applyPropertyToRegularStyle(); } bool applyPropertyToVisitedLinkStyle() const { return m_state.applyPropertyToVisitedLinkStyle(); } - static Length convertToIntLength(const CSSPrimitiveValue*, const RenderStyle*, const RenderStyle* rootStyle, double multiplier = 1); - static Length convertToFloatLength(const CSSPrimitiveValue*, const RenderStyle*, const RenderStyle* rootStyle, double multiplier = 1); + CascadeLevel cascadeLevel() const { return m_state.cascadeLevel(); } + void setCascadeLevel(CascadeLevel level) { m_state.setCascadeLevel(level); } + + CascadedProperties* cascadedPropertiesForRollback(const MatchResult&); CSSToStyleMap* styleMap() { return &m_styleMap; } InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; } - const FontDescription& fontDescription() { return m_state.fontDescription(); } - const FontDescription& parentFontDescription() { return m_state.parentFontDescription(); } - void setFontDescription(const FontDescription& fontDescription) { m_state.setFontDescription(fontDescription); } + const FontCascadeDescription& fontDescription() { return m_state.fontDescription(); } + const FontCascadeDescription& parentFontDescription() { return m_state.parentFontDescription(); } + void setFontDescription(const FontCascadeDescription& fontDescription) { m_state.setFontDescription(fontDescription); } void setZoom(float f) { m_state.setZoom(f); } void setEffectiveZoom(float f) { m_state.setEffectiveZoom(f); } void setWritingMode(WritingMode writingMode) { m_state.setWritingMode(writingMode); } void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); } private: - static RenderStyle* s_styleNotYetAvailable; - void cacheBorderAndBackground(); -private: - bool canShareStyleWithControl(StyledElement*) const; - - void applyProperty(CSSPropertyID, CSSValue*); + void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr); + RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&); -#if ENABLE(SVG) void applySVGProperty(CSSPropertyID, CSSValue*); -#endif - - PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*, const ResourceLoaderOptions&); - PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*); - void loadPendingImages(); -#if ENABLE(CSS_SHAPES) - void loadPendingShapeImage(ShapeValue*); -#endif static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size); struct MatchedPropertiesCacheItem { Vector<MatchedProperties> matchedProperties; MatchRanges ranges; - RefPtr<RenderStyle> renderStyle; - RefPtr<RenderStyle> parentRenderStyle; + std::unique_ptr<RenderStyle> renderStyle; + std::unique_ptr<RenderStyle> parentRenderStyle; }; const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&); void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&); // Every N additions to the matched declaration cache trigger a sweep where entries holding // the last reference to a style declaration are garbage collected. - void sweepMatchedPropertiesCache(Timer<StyleResolver>*); - - bool classNamesAffectedByRules(const SpaceSplitString&) const; - bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement*) const; - + void sweepMatchedPropertiesCache(); unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep; typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache; MatchedPropertiesCache m_matchedPropertiesCache; - Timer<StyleResolver> m_matchedPropertiesCacheSweepTimer; + Timer m_matchedPropertiesCacheSweepTimer; - std::unique_ptr<MediaQueryEvaluator> m_medium; - RefPtr<RenderStyle> m_rootDefaultStyle; + MediaQueryEvaluator m_mediaQueryEvaluator; + std::unique_ptr<RenderStyle> m_rootDefaultStyle; Document& m_document; - SelectorFilter m_selectorFilter; bool m_matchAuthorAndUserStyles; - RefPtr<CSSFontSelector> m_fontSelector; - Vector<std::unique_ptr<MediaQueryResult>> m_viewportDependentMediaQueryResults; + RenderStyle* m_overrideDocumentElementStyle { nullptr }; + + Vector<MediaQueryResult> m_viewportDependentMediaQueryResults; + Vector<MediaQueryResult> m_accessibilitySettingsDependentMediaQueryResults; #if ENABLE(CSS_DEVICE_ADAPTATION) RefPtr<ViewportStyleResolver> m_viewportStyleResolver; #endif - const DeprecatedStyleBuilder& m_deprecatedStyleBuilder; - - std::unique_ptr<StyleScopeResolver> m_scopeResolver; CSSToStyleMap m_styleMap; InspectorCSSOMWrappers m_inspectorCSSOMWrappers; State m_state; - friend class DeprecatedStyleBuilder; + // See if we still have crashes where StyleResolver gets deleted early. + bool m_isDeleted { false }; + friend bool operator==(const MatchedProperties&, const MatchedProperties&); friend bool operator!=(const MatchedProperties&, const MatchedProperties&); friend bool operator==(const MatchRanges&, const MatchRanges&); friend bool operator!=(const MatchRanges&, const MatchRanges&); }; -inline bool StyleResolver::hasSelectorForAttribute(const AtomicString &attributeName) const +inline bool StyleResolver::hasSelectorForAttribute(const Element& element, const AtomicString &attributeName) const { ASSERT(!attributeName.isEmpty()); - return m_ruleSets.features().attrsInRules.contains(attributeName.impl()); + if (element.isHTMLElement()) + return m_ruleSets.features().attributeCanonicalLocalNamesInRules.contains(attributeName); + return m_ruleSets.features().attributeLocalNamesInRules.contains(attributeName); } inline bool StyleResolver::hasSelectorForClass(const AtomicString& classValue) const { ASSERT(!classValue.isEmpty()); - return m_ruleSets.features().classesInRules.contains(classValue.impl()); + return m_ruleSets.features().classesInRules.contains(classValue); } inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const { ASSERT(!idValue.isEmpty()); - return m_ruleSets.features().idsInRules.contains(idValue.impl()); + return m_ruleSets.features().idsInRules.contains(idValue); } -inline bool checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement) +inline bool checkRegionSelector(const CSSSelector* regionSelector, const Element* regionElement) { if (!regionSelector || !regionElement) return false; - SelectorChecker selectorChecker(regionElement->document(), SelectorChecker::QueryingRules); + SelectorChecker selectorChecker(regionElement->document()); for (const CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s)) { - SelectorChecker::SelectorCheckingContext selectorCheckingContext(s, regionElement, SelectorChecker::VisitedMatchDisabled); - PseudoId ignoreDynamicPseudo = NOPSEUDO; - if (selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo)) + SelectorChecker::CheckingContext selectorCheckingContext(SelectorChecker::Mode::QueryingRules); + unsigned ignoredSpecificity; + if (selectorChecker.match(*s, *regionElement, selectorCheckingContext, ignoredSpecificity)) return true; } return false; } -class StyleResolverParentPusher { -public: - StyleResolverParentPusher(Element* parent) - : m_parent(parent) - , m_pushedStyleResolver(0) - { } - void push() - { - if (m_pushedStyleResolver) - return; - m_pushedStyleResolver = &m_parent->document().ensureStyleResolver(); - m_pushedStyleResolver->pushParentElement(m_parent); - } - ~StyleResolverParentPusher() - { - if (!m_pushedStyleResolver) - return; - // This tells us that our pushed style selector is in a bad state, - // so we should just bail out in that scenario. - ASSERT(m_pushedStyleResolver == &m_parent->document().ensureStyleResolver()); - if (m_pushedStyleResolver != &m_parent->document().ensureStyleResolver()) - return; - m_pushedStyleResolver->popParentElement(m_parent); - } - -private: - Element* m_parent; - StyleResolver* m_pushedStyleResolver; -}; - } // namespace WebCore - -#endif // StyleResolver_h |