#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/css/element_rule_collector.h"
#include "base/containers/span.h"
#include "base/substring_set_matcher/substring_set_matcher.h"
#include "base/trace_event/common/trace_event_common.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-shared.h"
#include "third_party/blink/renderer/core/css/cascade_layer_map.h"
#include "third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.h"
#include "third_party/blink/renderer/core/css/container_query_evaluator.h"
#include "third_party/blink/renderer/core/css/css_import_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
#include "third_party/blink/renderer/core/css/css_media_rule.h"
#include "third_party/blink/renderer/core/css/css_nested_declarations_rule.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
#include "third_party/blink/renderer/core/css/css_selector.h"
#include "third_party/blink/renderer/core/css/css_style_rule.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/css_supports_rule.h"
#include "third_party/blink/renderer/core/css/resolver/element_resolve_context.h"
#include "third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_stats.h"
#include "third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h"
#include "third_party/blink/renderer/core/css/seeker.h"
#include "third_party/blink/renderer/core/css/selector_checker-inl.h"
#include "third_party/blink/renderer/core/css/selector_statistics.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/css/style_rule_nested_declarations.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
#include "third_party/blink/renderer/core/page/scrolling/fragment_anchor.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
namespace blink {
namespace {
struct CumulativeRulePerfKey { … };
struct ContextWithStyleScopeFrame { … };
}
}
namespace WTF {
template <>
struct HashTraits<blink::CumulativeRulePerfKey>
: TwoFieldsHashTraits<blink::CumulativeRulePerfKey,
&blink::CumulativeRulePerfKey::selector,
&blink::CumulativeRulePerfKey::style_sheet_id> { … };
}
namespace blink {
template <class CSSRuleCollection>
static CSSRule* FindStyleRule(CSSRuleCollection* css_rules,
const StyleRule* style_rule);
namespace {
const CSSStyleSheet* FindStyleSheet(const TreeScope* tree_scope_containing_rule,
const StyleEngine& style_engine,
const StyleRule* rule) { … }
unsigned AdjustLinkMatchType(EInsideLink inside_link,
unsigned link_match_type) { … }
unsigned LinkMatchTypeFromInsideLink(EInsideLink inside_link) { … }
bool EvaluateAndAddContainerQueries(
Element* style_container_candidate,
const ContainerQuery& container_query,
const StyleRecalcContext& style_recalc_context,
ContainerSelectorCache& container_selector_cache,
MatchResult& result) { … }
bool AffectsAnimations(const RuleData& rule_data) { … }
class CascadeLayerSeeker { … };
struct CumulativeRulePerfData { … };
SelectorStatisticsRuleMap;
SelectorStatisticsRuleMap& GetSelectorStatisticsRuleMap() { … }
void AggregateRulePerfData(
const TreeScope* tree_scope_containing_rule,
const StyleEngine& style_engine,
const Vector<RulePerfDataPerRequest>& rules_statistics) { … }
static const unsigned char* g_selector_stats_tracing_enabled = …;
}
ElementRuleCollector::ElementRuleCollector(
const ElementResolveContext& context,
const StyleRecalcContext& style_recalc_context,
const SelectorFilter& filter,
MatchResult& result,
EInsideLink inside_link)
: … { … }
ElementRuleCollector::~ElementRuleCollector() = default;
const MatchResult& ElementRuleCollector::MatchedResult() const { … }
StyleRuleList* ElementRuleCollector::MatchedStyleRuleList() { … }
RuleIndexList* ElementRuleCollector::MatchedCSSRuleList() { … }
void ElementRuleCollector::ClearMatchedRules() { … }
inline StyleRuleList* ElementRuleCollector::EnsureStyleRuleList() { … }
inline RuleIndexList* ElementRuleCollector::EnsureRuleList() { … }
void ElementRuleCollector::AddElementStyleProperties(
const CSSPropertyValueSet* property_set,
CascadeOrigin origin,
bool is_cacheable,
bool is_inline_style) { … }
void ElementRuleCollector::AddTryStyleProperties() { … }
void ElementRuleCollector::AddTryTacticsStyleProperties() { … }
static bool RulesApplicableInCurrentTreeScope(
const Element* element,
const ContainerNode* scoping_node) { … }
bool SlowMatchWithNoResultFlags(
const SelectorChecker& checker,
SelectorChecker::SelectorCheckingContext& context,
const CSSSelector& selector,
const RuleData& rule_data,
bool suppress_visited,
unsigned expected_proximity = std::numeric_limits<unsigned>::max()) { … }
template <bool stop_at_first_match, bool perf_trace_enabled>
bool ElementRuleCollector::CollectMatchingRulesForListInternal(
base::span<const RuleData> rules,
const MatchRequest& match_request,
const RuleSet* rule_set,
int style_sheet_index,
const SelectorChecker& checker,
SelectorChecker::SelectorCheckingContext& context,
PartRequest* part_request) { … }
template <bool stop_at_first_match>
bool ElementRuleCollector::CollectMatchingRulesForList(
base::span<const RuleData> rules,
const MatchRequest& match_request,
const RuleSet* rule_set,
int style_sheet_index,
const SelectorChecker& checker,
SelectorChecker::SelectorCheckingContext& context,
PartRequest* part_request) { … }
namespace {
base::span<const Attribute> GetAttributes(const Element& element,
bool need_style_synchronized) { … }
}
void ElementRuleCollector::CollectMatchingRules(
const MatchRequest& match_request) { … }
DISABLE_CFI_PERF
bool ElementRuleCollector::CheckIfAnyRuleMatches(
const MatchRequest& match_request) { … }
bool ElementRuleCollector::CanRejectScope(const StyleScope& style_scope) { … }
template <bool stop_at_first_match>
DISABLE_CFI_PERF bool ElementRuleCollector::CollectMatchingRulesInternal(
const MatchRequest& match_request) { … }
void ElementRuleCollector::CollectMatchingShadowHostRules(
const MatchRequest& match_request) { … }
bool ElementRuleCollector::CheckIfAnyShadowHostRuleMatches(
const MatchRequest& match_request) { … }
void ElementRuleCollector::CollectMatchingSlottedRules(
const MatchRequest& match_request) { … }
void ElementRuleCollector::CollectMatchingPartPseudoRules(
const MatchRequest& match_request,
PartNames* part_names,
bool for_shadow_pseudo) { … }
template <class CSSRuleCollection>
static CSSRule* FindStyleRule(CSSRuleCollection* css_rules,
const StyleRule* style_rule) { … }
void ElementRuleCollector::AppendCSSOMWrapperForRule(
const TreeScope* tree_scope_containing_rule,
const RuleData* rule_data,
wtf_size_t position) { … }
void ElementRuleCollector::SortAndTransferMatchedRules(
CascadeOrigin origin,
bool is_vtt_embedded_style,
StyleRuleUsageTracker* tracker) { … }
void ElementRuleCollector::DidMatchRule(
const RuleData* rule_data,
unsigned layer_order,
const ContainerQuery* container_query,
unsigned proximity,
const SelectorChecker::MatchResult& result,
int style_sheet_index) { … }
void ElementRuleCollector::DumpAndClearRulesPerfMap() { … }
inline bool ElementRuleCollector::CompareRules(
const MatchedRule& matched_rule1,
const MatchedRule& matched_rule2) { … }
void ElementRuleCollector::SortMatchedRules() { … }
void ElementRuleCollector::AddMatchedRulesToTracker(
StyleRuleUsageTracker* tracker) const { … }
}