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(
&context_.GetElement(), SelectorChecker::kVisitedMatchEnabled);
context.scope = match_request.scope;
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 fast_rejected = 0;
......
......@@ -42,12 +42,12 @@ class MatchRequest {
const ContainerNode* scope = nullptr,
const CSSStyleSheet* css_sheet = nullptr,
unsigned style_sheet_index = 0,
bool is_from_vtt = false)
Element* vtt_originating_element = nullptr)
: rule_set(rule_set),
scope(scope),
style_sheet(css_sheet),
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
// rules to the set and we should make sure it's compacted.
rule_set->CompactRulesIfNeeded();
......@@ -57,7 +57,10 @@ class MatchRequest {
const ContainerNode* scope;
const CSSStyleSheet* style_sheet;
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
......
......@@ -409,12 +409,12 @@ static void MatchVTTRules(const Element& element,
int style_sheet_index = 0;
collector.ClearMatchedRules();
for (CSSStyleSheet* style : styles) {
RuleSet* rule_set =
element.GetDocument().GetStyleEngine().RuleSetForSheet(*style);
StyleEngine& style_engine = element.GetDocument().GetStyleEngine();
RuleSet* rule_set = style_engine.RuleSetForSheet(*style);
if (rule_set) {
collector.CollectMatchingRules(
MatchRequest(rule_set, nullptr /* scope */, style,
style_sheet_index, true /* is_from_webvtt */));
collector.CollectMatchingRules(MatchRequest(
rule_set, nullptr /* scope */, style, style_sheet_index,
style_engine.EnsureVTTOriginatingElement()));
style_sheet_index++;
}
}
......
......@@ -125,7 +125,7 @@ class SelectorChecker {
bool has_scrollbar_pseudo = false;
bool has_selection_pseudo = 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;
};
......@@ -155,7 +155,6 @@ class SelectorChecker {
// to by the context are a match. Delegates most of the work to the Check*
// methods below.
bool CheckOne(const SelectorCheckingContext&, MatchResult&) const;
bool CheckOneForVTT(const SelectorCheckingContext&, MatchResult&) const;
enum MatchStatus {
kSelectorMatches,
......@@ -182,35 +181,22 @@ class SelectorChecker {
// to try (e.g. same element, parent, sibling) depends on the combinators in
// the selectors.
MatchStatus MatchSelector(const SelectorCheckingContext&, MatchResult&) const;
MatchStatus MatchSelectorForVTT(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForSubSelector(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForSubSelectorForVTT(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForRelation(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForRelationForVTT(const SelectorCheckingContext&,
MatchResult&) const;
MatchStatus MatchForPseudoContent(const SelectorCheckingContext&,
const Element&,
MatchResult&) const;
MatchStatus MatchForPseudoShadow(const SelectorCheckingContext&,
const ContainerNode*,
MatchResult&) const;
bool MatchVTTBlockSelector(const SelectorCheckingContext& context,
MatchResult& result) const;
bool CheckPseudoClass(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoClassForVTT(const SelectorCheckingContext&,
MatchResult&) const;
bool CheckPseudoElement(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoElementForVTT(const SelectorCheckingContext&,
MatchResult&) const;
bool CheckScrollbarPseudoClass(const SelectorCheckingContext&,
MatchResult&) const;
bool CheckPseudoHost(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoNot(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoNotForVTT(const SelectorCheckingContext&, MatchResult&) const;
ComputedStyle* element_style_;
CustomScrollbar* scrollbar_;
......
......@@ -470,6 +470,14 @@ void StyleEngine::RemoveTextTrack(TextTrack* 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(
HeapHashSet<Member<TextTrack>>& text_tracks,
MediaValueChange change) {
......@@ -2344,6 +2352,7 @@ void StyleEngine::Trace(Visitor* visitor) const {
visitor->Trace(tracker_);
visitor->Trace(meta_color_scheme_);
visitor->Trace(text_tracks_);
visitor->Trace(vtt_originating_element_);
FontSelectorClient::Trace(visitor);
}
......
......@@ -133,6 +133,14 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void AddTextTrack(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();
bool NeedsActiveStyleUpdate() const;
......@@ -661,6 +669,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
friend class WhitespaceAttacherTest;
HeapHashSet<Member<TextTrack>> text_tracks_;
Member<Element> vtt_originating_element_;
};
} // 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