| /* |
| * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. |
| * |
| */ |
| |
| #ifndef RuleFeature_h |
| #define RuleFeature_h |
| |
| #include "core/CoreExport.h" |
| #include "core/css/CSSSelector.h" |
| #include "core/css/MediaQueryEvaluator.h" |
| #include "core/css/invalidation/InvalidationSet.h" |
| #include "platform/heap/Handle.h" |
| #include "platform/wtf/Forward.h" |
| #include "platform/wtf/HashSet.h" |
| #include "platform/wtf/text/AtomicStringHash.h" |
| |
| namespace blink { |
| |
| class ContainerNode; |
| struct InvalidationLists; |
| class QualifiedName; |
| class RuleData; |
| class StyleRule; |
| |
| struct RuleFeature { |
| DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
| |
| public: |
| RuleFeature(StyleRule*, |
| unsigned selector_index, |
| bool has_document_security_origin); |
| |
| DECLARE_TRACE(); |
| |
| Member<StyleRule> rule; |
| unsigned selector_index; |
| bool has_document_security_origin; |
| }; |
| |
| } // namespace blink |
| |
| // Declare the VectorTraits specialization before RuleFeatureSet |
| // declares its vector members below. |
| WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::RuleFeature); |
| |
| namespace blink { |
| |
| class CORE_EXPORT RuleFeatureSet { |
| DISALLOW_NEW(); |
| WTF_MAKE_NONCOPYABLE(RuleFeatureSet); |
| |
| public: |
| RuleFeatureSet(); |
| ~RuleFeatureSet(); |
| |
| void Add(const RuleFeatureSet&); |
| void Clear(); |
| |
| enum SelectorPreMatch { kSelectorNeverMatches, kSelectorMayMatch }; |
| |
| SelectorPreMatch CollectFeaturesFromRuleData(const RuleData&); |
| |
| bool UsesSiblingRules() const { return !sibling_rules_.IsEmpty(); } |
| bool UsesFirstLineRules() const { return metadata_.uses_first_line_rules; } |
| bool UsesWindowInactiveSelector() const { |
| return metadata_.uses_window_inactive_selector; |
| } |
| bool NeedsFullRecalcForRuleSetInvalidation() const { |
| return metadata_.needs_full_recalc_for_rule_set_invalidation; |
| } |
| |
| unsigned MaxDirectAdjacentSelectors() const { |
| return metadata_.max_direct_adjacent_selectors; |
| } |
| |
| bool HasSelectorForAttribute(const AtomicString& attribute_name) const { |
| DCHECK(!attribute_name.IsEmpty()); |
| return attribute_invalidation_sets_.Contains(attribute_name); |
| } |
| |
| bool HasSelectorForClass(const AtomicString& class_value) const { |
| DCHECK(!class_value.IsEmpty()); |
| return class_invalidation_sets_.Contains(class_value); |
| } |
| |
| bool HasSelectorForId(const AtomicString& id_value) const { |
| return id_invalidation_sets_.Contains(id_value); |
| } |
| |
| const HeapVector<RuleFeature>& SiblingRules() const { return sibling_rules_; } |
| const HeapVector<RuleFeature>& UncommonAttributeRules() const { |
| return uncommon_attribute_rules_; |
| } |
| |
| const MediaQueryResultList& ViewportDependentMediaQueryResults() const { |
| return viewport_dependent_media_query_results_; |
| } |
| const MediaQueryResultList& DeviceDependentMediaQueryResults() const { |
| return device_dependent_media_query_results_; |
| } |
| MediaQueryResultList& ViewportDependentMediaQueryResults() { |
| return viewport_dependent_media_query_results_; |
| } |
| MediaQueryResultList& DeviceDependentMediaQueryResults() { |
| return device_dependent_media_query_results_; |
| } |
| |
| // Collect descendant and sibling invalidation sets. |
| void CollectInvalidationSetsForClass(InvalidationLists&, |
| Element&, |
| const AtomicString& class_name) const; |
| void CollectInvalidationSetsForId(InvalidationLists&, |
| Element&, |
| const AtomicString& id) const; |
| void CollectInvalidationSetsForAttribute( |
| InvalidationLists&, |
| Element&, |
| const QualifiedName& attribute_name) const; |
| void CollectInvalidationSetsForPseudoClass(InvalidationLists&, |
| Element&, |
| CSSSelector::PseudoType) const; |
| |
| void CollectSiblingInvalidationSetForClass( |
| InvalidationLists&, |
| Element&, |
| const AtomicString& class_name, |
| unsigned min_direct_adjacent) const; |
| void CollectSiblingInvalidationSetForId(InvalidationLists&, |
| Element&, |
| const AtomicString& id, |
| unsigned min_direct_adjacent) const; |
| void CollectSiblingInvalidationSetForAttribute( |
| InvalidationLists&, |
| Element&, |
| const QualifiedName& attribute_name, |
| unsigned min_direct_adjacent) const; |
| void CollectUniversalSiblingInvalidationSet( |
| InvalidationLists&, |
| unsigned min_direct_adjacent) const; |
| void CollectNthInvalidationSet(InvalidationLists&) const; |
| void CollectTypeRuleInvalidationSet(InvalidationLists&, ContainerNode&) const; |
| |
| bool HasIdsInSelectors() const { return id_invalidation_sets_.size() > 0; } |
| |
| DECLARE_TRACE(); |
| |
| bool IsAlive() const { return is_alive_; } |
| |
| protected: |
| InvalidationSet* InvalidationSetForSimpleSelector(const CSSSelector&, |
| InvalidationType); |
| |
| private: |
| // Each map entry is either a DescendantInvalidationSet or |
| // SiblingInvalidationSet. |
| // When both are needed, we store the SiblingInvalidationSet, and use it to |
| // hold the DescendantInvalidationSet. |
| using InvalidationSetMap = HashMap<AtomicString, RefPtr<InvalidationSet>>; |
| using PseudoTypeInvalidationSetMap = |
| HashMap<CSSSelector::PseudoType, |
| RefPtr<InvalidationSet>, |
| WTF::IntHash<unsigned>, |
| WTF::UnsignedWithZeroKeyHashTraits<unsigned>>; |
| |
| struct FeatureMetadata { |
| DISALLOW_NEW(); |
| void Add(const FeatureMetadata& other); |
| void Clear(); |
| |
| bool uses_first_line_rules = false; |
| bool uses_window_inactive_selector = false; |
| bool found_sibling_selector = false; |
| bool found_insertion_point_crossing = false; |
| bool needs_full_recalc_for_rule_set_invalidation = false; |
| unsigned max_direct_adjacent_selectors = 0; |
| }; |
| |
| SelectorPreMatch CollectFeaturesFromSelector(const CSSSelector&, |
| FeatureMetadata&); |
| |
| InvalidationSet& EnsureClassInvalidationSet(const AtomicString& class_name, |
| InvalidationType); |
| InvalidationSet& EnsureAttributeInvalidationSet( |
| const AtomicString& attribute_name, |
| InvalidationType); |
| InvalidationSet& EnsureIdInvalidationSet(const AtomicString& id, |
| InvalidationType); |
| InvalidationSet& EnsurePseudoInvalidationSet(CSSSelector::PseudoType, |
| InvalidationType); |
| SiblingInvalidationSet& EnsureUniversalSiblingInvalidationSet(); |
| DescendantInvalidationSet& EnsureNthInvalidationSet(); |
| DescendantInvalidationSet& EnsureTypeRuleInvalidationSet(); |
| |
| void UpdateInvalidationSets(const RuleData&); |
| void UpdateInvalidationSetsForContentAttribute(const RuleData&); |
| |
| struct InvalidationSetFeatures { |
| DISALLOW_NEW(); |
| |
| void Add(const InvalidationSetFeatures& other); |
| bool HasFeatures() const; |
| bool HasIdClassOrAttribute() const; |
| |
| Vector<AtomicString> classes; |
| Vector<AtomicString> attributes; |
| Vector<AtomicString> ids; |
| Vector<AtomicString> tag_names; |
| unsigned max_direct_adjacent_selectors = 0; |
| bool custom_pseudo_element = false; |
| bool has_before_or_after = false; |
| bool tree_boundary_crossing = false; |
| bool insertion_point_crossing = false; |
| bool force_subtree = false; |
| bool content_pseudo_crossing = false; |
| bool invalidates_slotted = false; |
| bool has_nth_pseudo = false; |
| bool has_features_for_rule_set_invalidation = false; |
| }; |
| |
| static void ExtractInvalidationSetFeature(const CSSSelector&, |
| InvalidationSetFeatures&); |
| |
| enum PositionType { kSubject, kAncestor }; |
| enum FeatureInvalidationType { |
| kNormalInvalidation, |
| kRequiresSubtreeInvalidation |
| }; |
| |
| void ExtractInvalidationSetFeaturesFromSimpleSelector( |
| const CSSSelector&, |
| InvalidationSetFeatures&); |
| const CSSSelector* ExtractInvalidationSetFeaturesFromCompound( |
| const CSSSelector&, |
| InvalidationSetFeatures&, |
| PositionType, |
| CSSSelector::PseudoType = CSSSelector::kPseudoUnknown); |
| FeatureInvalidationType ExtractInvalidationSetFeaturesFromSelectorList( |
| const CSSSelector&, |
| InvalidationSetFeatures&, |
| PositionType); |
| void UpdateFeaturesFromCombinator( |
| const CSSSelector&, |
| const CSSSelector* last_compound_selector_in_adjacent_chain, |
| InvalidationSetFeatures& last_compound_in_adjacent_chain_features, |
| InvalidationSetFeatures*& sibling_features, |
| InvalidationSetFeatures& descendant_features); |
| |
| void AddFeaturesToInvalidationSet(InvalidationSet&, |
| const InvalidationSetFeatures&); |
| void AddFeaturesToInvalidationSets( |
| const CSSSelector&, |
| InvalidationSetFeatures* sibling_features, |
| InvalidationSetFeatures& descendant_features); |
| const CSSSelector* AddFeaturesToInvalidationSetsForCompoundSelector( |
| const CSSSelector&, |
| InvalidationSetFeatures* sibling_features, |
| InvalidationSetFeatures& descendant_features); |
| void AddFeaturesToInvalidationSetsForSimpleSelector( |
| const CSSSelector&, |
| InvalidationSetFeatures* sibling_features, |
| InvalidationSetFeatures& descendant_features); |
| void AddFeaturesToInvalidationSetsForSelectorList( |
| const CSSSelector&, |
| InvalidationSetFeatures* sibling_features, |
| InvalidationSetFeatures& descendant_features); |
| void AddFeaturesToUniversalSiblingInvalidationSet( |
| const InvalidationSetFeatures& sibling_features, |
| const InvalidationSetFeatures& descendant_features); |
| |
| void UpdateRuleSetInvalidation(const InvalidationSetFeatures&); |
| |
| FeatureMetadata metadata_; |
| InvalidationSetMap class_invalidation_sets_; |
| InvalidationSetMap attribute_invalidation_sets_; |
| InvalidationSetMap id_invalidation_sets_; |
| PseudoTypeInvalidationSetMap pseudo_invalidation_sets_; |
| RefPtr<SiblingInvalidationSet> universal_sibling_invalidation_set_; |
| RefPtr<DescendantInvalidationSet> nth_invalidation_set_; |
| RefPtr<DescendantInvalidationSet> type_rule_invalidation_set_; |
| HeapVector<RuleFeature> sibling_rules_; |
| HeapVector<RuleFeature> uncommon_attribute_rules_; |
| MediaQueryResultList viewport_dependent_media_query_results_; |
| MediaQueryResultList device_dependent_media_query_results_; |
| |
| // If true, the RuleFeatureSet is alive and can be used. |
| unsigned is_alive_ : 1; |
| |
| friend class RuleFeatureSetTest; |
| }; |
| |
| } // namespace blink |
| |
| #endif // RuleFeature_h |