Commit fe0a5fdc authored by Anders Hartvoll Ruud's avatar Anders Hartvoll Ruud Committed by Commit Bot

Remove ForVTT codepath in SelectorMatcher

Having a separate copy-pasted codepath for selector matching is not
acceptable for maintainability reasons. Instead we can lazily create
an actual Element to represent the almost-featureless element
described by the spec [1], and use this as the originating element
during selector matching. The element has no ID, no classes, no
attributes, no tag name, no namespace, no parent, no siblings; so it
should be pretty hard to match against it.

Longer term it would be nice to make the originating element actually
featureless [2].

Bug: 1137349
TEST=external/wpt/webvtt/rendering/cues-with-video/processing-model/support/embedded_style_selectors.html

[1] https://w3c.github.io/webvtt/#obtaining-css-boxes
[2] https://github.com/w3c/webvtt/issues/477

Change-Id: I06d618546893be3942ea5406507a01bc508340d3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462274
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816299}
parent bd17fcf4
...@@ -150,7 +150,7 @@ void ElementRuleCollector::CollectMatchingRulesForList( ...@@ -150,7 +150,7 @@ void ElementRuleCollector::CollectMatchingRulesForList(
&context_.GetElement(), SelectorChecker::kVisitedMatchEnabled); &context_.GetElement(), SelectorChecker::kVisitedMatchEnabled);
context.scope = match_request.scope; context.scope = match_request.scope;
context.pseudo_id = pseudo_style_request_.pseudo_id; context.pseudo_id = pseudo_style_request_.pseudo_id;
context.is_from_vtt = match_request.is_from_vtt; context.vtt_originating_element = match_request.vtt_originating_element;
unsigned rejected = 0; unsigned rejected = 0;
unsigned fast_rejected = 0; unsigned fast_rejected = 0;
......
...@@ -42,12 +42,12 @@ class MatchRequest { ...@@ -42,12 +42,12 @@ class MatchRequest {
const ContainerNode* scope = nullptr, const ContainerNode* scope = nullptr,
const CSSStyleSheet* css_sheet = nullptr, const CSSStyleSheet* css_sheet = nullptr,
unsigned style_sheet_index = 0, unsigned style_sheet_index = 0,
bool is_from_vtt = false) Element* vtt_originating_element = nullptr)
: rule_set(rule_set), : rule_set(rule_set),
scope(scope), scope(scope),
style_sheet(css_sheet), style_sheet(css_sheet),
style_sheet_index(style_sheet_index), style_sheet_index(style_sheet_index),
is_from_vtt(is_from_vtt) { vtt_originating_element(vtt_originating_element) {
// Now that we're about to read from the RuleSet, we're done adding more // Now that we're about to read from the RuleSet, we're done adding more
// rules to the set and we should make sure it's compacted. // rules to the set and we should make sure it's compacted.
rule_set->CompactRulesIfNeeded(); rule_set->CompactRulesIfNeeded();
...@@ -57,7 +57,10 @@ class MatchRequest { ...@@ -57,7 +57,10 @@ class MatchRequest {
const ContainerNode* scope; const ContainerNode* scope;
const CSSStyleSheet* style_sheet; const CSSStyleSheet* style_sheet;
const unsigned style_sheet_index; const unsigned style_sheet_index;
bool is_from_vtt; // For WebVTT STYLE blocks, this is set to the featureless-like Element
// described by the spec:
// https://w3c.github.io/webvtt/#obtaining-css-boxes
Element* vtt_originating_element;
}; };
} // namespace blink } // namespace blink
......
...@@ -409,12 +409,12 @@ static void MatchVTTRules(const Element& element, ...@@ -409,12 +409,12 @@ static void MatchVTTRules(const Element& element,
int style_sheet_index = 0; int style_sheet_index = 0;
collector.ClearMatchedRules(); collector.ClearMatchedRules();
for (CSSStyleSheet* style : styles) { for (CSSStyleSheet* style : styles) {
RuleSet* rule_set = StyleEngine& style_engine = element.GetDocument().GetStyleEngine();
element.GetDocument().GetStyleEngine().RuleSetForSheet(*style); RuleSet* rule_set = style_engine.RuleSetForSheet(*style);
if (rule_set) { if (rule_set) {
collector.CollectMatchingRules( collector.CollectMatchingRules(MatchRequest(
MatchRequest(rule_set, nullptr /* scope */, style, rule_set, nullptr /* scope */, style, style_sheet_index,
style_sheet_index, true /* is_from_webvtt */)); style_engine.EnsureVTTOriginatingElement()));
style_sheet_index++; style_sheet_index++;
} }
} }
......
...@@ -125,7 +125,7 @@ class SelectorChecker { ...@@ -125,7 +125,7 @@ class SelectorChecker {
bool has_scrollbar_pseudo = false; bool has_scrollbar_pseudo = false;
bool has_selection_pseudo = false; bool has_selection_pseudo = false;
bool treat_shadow_host_as_normal_scope = false; bool treat_shadow_host_as_normal_scope = false;
bool is_from_vtt = false; Element* vtt_originating_element = nullptr;
bool in_nested_complex_selector = false; bool in_nested_complex_selector = false;
}; };
...@@ -155,7 +155,6 @@ class SelectorChecker { ...@@ -155,7 +155,6 @@ class SelectorChecker {
// to by the context are a match. Delegates most of the work to the Check* // to by the context are a match. Delegates most of the work to the Check*
// methods below. // methods below.
bool CheckOne(const SelectorCheckingContext&, MatchResult&) const; bool CheckOne(const SelectorCheckingContext&, MatchResult&) const;
bool CheckOneForVTT(const SelectorCheckingContext&, MatchResult&) const;
enum MatchStatus { enum MatchStatus {
kSelectorMatches, kSelectorMatches,
...@@ -182,35 +181,22 @@ class SelectorChecker { ...@@ -182,35 +181,22 @@ class SelectorChecker {
// to try (e.g. same element, parent, sibling) depends on the combinators in // to try (e.g. same element, parent, sibling) depends on the combinators in
// the selectors. // the selectors.
MatchStatus MatchSelector(const SelectorCheckingContext&, MatchResult&) const; MatchStatus MatchSelector(const SelectorCheckingContext&, MatchResult&) const;
MatchStatus MatchSelectorForVTT(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForSubSelector(const SelectorCheckingContext&, MatchStatus MatchForSubSelector(const SelectorCheckingContext&,
MatchResult&) const; MatchResult&) const;
MatchStatus MatchForSubSelectorForVTT(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForRelation(const SelectorCheckingContext&, MatchStatus MatchForRelation(const SelectorCheckingContext&,
MatchResult&) const; MatchResult&) const;
MatchStatus MatchForRelationForVTT(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForPseudoContent(const SelectorCheckingContext&, MatchStatus MatchForPseudoContent(const SelectorCheckingContext&,
const Element&, const Element&,
MatchResult&) const; MatchResult&) const;
MatchStatus MatchForPseudoShadow(const SelectorCheckingContext&, MatchStatus MatchForPseudoShadow(const SelectorCheckingContext&,
const ContainerNode*, const ContainerNode*,
MatchResult&) const; MatchResult&) const;
bool MatchVTTBlockSelector(const SelectorCheckingContext& context,
MatchResult& result) const;
bool CheckPseudoClass(const SelectorCheckingContext&, MatchResult&) const; bool CheckPseudoClass(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoClassForVTT(const SelectorCheckingContext&,
MatchResult&) const;
bool CheckPseudoElement(const SelectorCheckingContext&, MatchResult&) const; bool CheckPseudoElement(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoElementForVTT(const SelectorCheckingContext&,
MatchResult&) const;
bool CheckScrollbarPseudoClass(const SelectorCheckingContext&, bool CheckScrollbarPseudoClass(const SelectorCheckingContext&,
MatchResult&) const; MatchResult&) const;
bool CheckPseudoHost(const SelectorCheckingContext&, MatchResult&) const; bool CheckPseudoHost(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoNot(const SelectorCheckingContext&, MatchResult&) const; bool CheckPseudoNot(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoNotForVTT(const SelectorCheckingContext&, MatchResult&) const;
ComputedStyle* element_style_; ComputedStyle* element_style_;
CustomScrollbar* scrollbar_; CustomScrollbar* scrollbar_;
......
...@@ -470,6 +470,14 @@ void StyleEngine::RemoveTextTrack(TextTrack* text_track) { ...@@ -470,6 +470,14 @@ void StyleEngine::RemoveTextTrack(TextTrack* text_track) {
text_tracks_.erase(text_track); text_tracks_.erase(text_track);
} }
Element* StyleEngine::EnsureVTTOriginatingElement() {
if (!vtt_originating_element_) {
vtt_originating_element_ = MakeGarbageCollected<Element>(
QualifiedName(g_null_atom, g_empty_atom, g_empty_atom), document_);
}
return vtt_originating_element_;
}
void StyleEngine::MediaQueryAffectingValueChanged( void StyleEngine::MediaQueryAffectingValueChanged(
HeapHashSet<Member<TextTrack>>& text_tracks, HeapHashSet<Member<TextTrack>>& text_tracks,
MediaValueChange change) { MediaValueChange change) {
...@@ -2344,6 +2352,7 @@ void StyleEngine::Trace(Visitor* visitor) const { ...@@ -2344,6 +2352,7 @@ void StyleEngine::Trace(Visitor* visitor) const {
visitor->Trace(tracker_); visitor->Trace(tracker_);
visitor->Trace(meta_color_scheme_); visitor->Trace(meta_color_scheme_);
visitor->Trace(text_tracks_); visitor->Trace(text_tracks_);
visitor->Trace(vtt_originating_element_);
FontSelectorClient::Trace(visitor); FontSelectorClient::Trace(visitor);
} }
......
...@@ -133,6 +133,14 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>, ...@@ -133,6 +133,14 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void AddTextTrack(TextTrack*); void AddTextTrack(TextTrack*);
void RemoveTextTrack(TextTrack*); void RemoveTextTrack(TextTrack*);
// An Element with no tag name, IDs, classes (etc), as described by the
// WebVTT spec:
// https://w3c.github.io/webvtt/#obtaining-css-boxes
//
// TODO(https://github.com/w3c/webvtt/issues/477): Make originating element
// actually featureless.
Element* EnsureVTTOriginatingElement();
const ActiveStyleSheetVector ActiveStyleSheetsForInspector(); const ActiveStyleSheetVector ActiveStyleSheetsForInspector();
bool NeedsActiveStyleUpdate() const; bool NeedsActiveStyleUpdate() const;
...@@ -661,6 +669,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>, ...@@ -661,6 +669,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
friend class WhitespaceAttacherTest; friend class WhitespaceAttacherTest;
HeapHashSet<Member<TextTrack>> text_tracks_; HeapHashSet<Member<TextTrack>> text_tracks_;
Member<Element> vtt_originating_element_;
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment