/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #pragma once #include "CSSSelector.h" #include "ElementRuleCollector.h" #include "InspectorCSSOMWrappers.h" #include "MatchedDeclarationsCache.h" #include "MediaQueryEvaluator.h" #include "RenderStyle.h" #include "RuleSet.h" #include "StyleBuilderState.h" #include "StyleScopeRuleSets.h" #include #include #include #include #include #include namespace WebCore { class CSSStyleSheet; class Document; class Element; class KeyframeList; class KeyframeValue; class RuleData; class RuleSet; class SelectorFilter; class Settings; class StyleRuleKeyframe; class StyleProperties; class StyleRule; class StyleRuleKeyframes; class StyleRulePage; class StyleSheet; class StyleSheetList; class ViewportStyleResolver; // MatchOnlyUserAgentRules is used in media queries, where relative units // are interpreted according to the document root element style, and styled only // from the User Agent Stylesheet rules. enum class RuleMatchingBehavior: uint8_t { MatchAllRules, MatchAllRulesExcludingSMIL, MatchOnlyUserAgentRules, }; namespace Style { struct ElementStyle { ElementStyle(std::unique_ptr renderStyle, std::unique_ptr relations = { }) : renderStyle(WTFMove(renderStyle)) , relations(WTFMove(relations)) { } std::unique_ptr renderStyle; std::unique_ptr relations; }; class Resolver : public RefCounted { WTF_MAKE_ISO_ALLOCATED(Resolver); public: static Ref create(Document&); ~Resolver(); ElementStyle styleForElement(const Element&, const RenderStyle* parentStyle, const RenderStyle* parentBoxStyle = nullptr, RuleMatchingBehavior = RuleMatchingBehavior::MatchAllRules, const SelectorFilter* = nullptr); void keyframeStylesForAnimation(const Element&, const RenderStyle* elementStyle, const RenderStyle* parentElementStyle, KeyframeList&); WEBCORE_EXPORT std::unique_ptr pseudoStyleForElement(const Element&, const PseudoElementRequest&, const RenderStyle& parentStyle, const RenderStyle* parentBoxStyle = nullptr, const SelectorFilter* = nullptr); std::unique_ptr styleForPage(int pageIndex); std::unique_ptr defaultStyleForElement(const Element*); Document& document() { return m_document; } const Document& document() const { return m_document; } const Settings& settings() const { return m_document.settings(); } void appendAuthorStyleSheets(const Vector>&); ScopeRuleSets& ruleSets() { return m_ruleSets; } const ScopeRuleSets& ruleSets() const { return m_ruleSets; } const MediaQueryEvaluator& mediaQueryEvaluator() const { return m_mediaQueryEvaluator; } const RenderStyle* overrideDocumentElementStyle() const { return m_overrideDocumentElementStyle; } void setOverrideDocumentElementStyle(const RenderStyle* style) { m_overrideDocumentElementStyle = style; } void addCurrentSVGFontFaceRules(); std::unique_ptr styleForKeyframe(const Element&, const RenderStyle* elementStyle, const RenderStyle* parentElementStyle, const StyleRuleKeyframe*, KeyframeValue&); bool isAnimationNameValid(const String&); // These methods will give back the set of rules that matched for a given element (or a pseudo-element). enum CSSRuleFilter { UAAndUserCSSRules = 1 << 1, AuthorCSSRules = 1 << 2, EmptyCSSRules = 1 << 3, AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules, AllCSSRules = AllButEmptyCSSRules | EmptyCSSRules, }; Vector> styleRulesForElement(const Element*, unsigned rulesToInclude = AllButEmptyCSSRules); Vector> pseudoStyleRulesForElement(const Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules); bool hasSelectorForId(const AtomString&) const; bool hasSelectorForAttribute(const Element&, const AtomString&) const; bool hasViewportDependentMediaQueries() const; std::optional evaluateDynamicMediaQueries(); void addKeyframeStyle(Ref&&); bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; } bool usesFirstLetterRules() const { return m_ruleSets.features().usesFirstLetterRules; } void invalidateMatchedDeclarationsCache(); void clearCachedDeclarationsAffectedByViewportUnits(); InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; } bool isSharedBetweenShadowTrees() const { return m_isSharedBetweenShadowTrees; } void setSharedBetweenShadowTrees() { m_isSharedBetweenShadowTrees = true; } private: friend class PageRuleCollector; Resolver(Document&); class State { public: State() { } State(const Element&, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle = nullptr); public: const Element* element() const { return m_element; } void setStyle(std::unique_ptr); RenderStyle* style() const { return m_style.get(); } std::unique_ptr takeStyle() { return WTFMove(m_style); } void setParentStyle(std::unique_ptr); const RenderStyle* parentStyle() const { return m_parentStyle; } const RenderStyle* rootElementStyle() const { return m_rootElementStyle; } const RenderStyle* userAgentAppearanceStyle() const { return m_userAgentAppearanceStyle.get(); } void setUserAgentAppearanceStyle(std::unique_ptr style) { m_userAgentAppearanceStyle = WTFMove(style); } private: const Element* m_element { nullptr }; std::unique_ptr m_style; const RenderStyle* m_parentStyle { nullptr }; std::unique_ptr m_ownedParentStyle; const RenderStyle* m_rootElementStyle { nullptr }; std::unique_ptr m_userAgentAppearanceStyle; }; BuilderContext builderContext(const State&); enum class UseMatchedDeclarationsCache { Yes, No }; void applyMatchedProperties(State&, const MatchResult&, UseMatchedDeclarationsCache = UseMatchedDeclarationsCache::Yes); ScopeRuleSets m_ruleSets; typedef HashMap> KeyframesRuleMap; KeyframesRuleMap m_keyframesRuleMap; MediaQueryEvaluator m_mediaQueryEvaluator; std::unique_ptr m_rootDefaultStyle; Document& m_document; const RenderStyle* m_overrideDocumentElementStyle { nullptr }; InspectorCSSOMWrappers m_inspectorCSSOMWrappers; MatchedDeclarationsCache m_matchedDeclarationsCache; bool m_matchAuthorAndUserStyles { true }; bool m_isSharedBetweenShadowTrees { false }; // See if we still have crashes where Resolver gets deleted early. bool m_isDeleted { false }; }; inline bool Resolver::hasSelectorForAttribute(const Element& element, const AtomString &attributeName) const { ASSERT(!attributeName.isEmpty()); if (element.isHTMLElement()) return m_ruleSets.features().attributeCanonicalLocalNamesInRules.contains(attributeName); return m_ruleSets.features().attributeLocalNamesInRules.contains(attributeName); } inline bool Resolver::hasSelectorForId(const AtomString& idValue) const { ASSERT(!idValue.isEmpty()); return m_ruleSets.features().idsInRules.contains(idValue); } } // namespace Style } // namespace WebCore