Commit 0ee9c7a2 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Collect TreeScopes for scoped references in MatchResult.

In order to store tree-scoped names/references in ComputedStyle we need
to keep track of which TreeScope the MatchedProperties came from during
selector matching. We do this by pushing TreeScope pointers for each
scoped to MatchResult which maps to the tree_order number stored in
each MatchedProperties entry.

This mapping will be used during cascading and stored with the name to
create a tree-scoped reference on ComputedStyle.

Bug: 336876
Change-Id: I416d9b12276917cb17c368909d3d5fd1b9f4f5e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2453392Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815316}
parent 323f1a73
...@@ -103,7 +103,7 @@ using StyleRuleList = HeapVector<Member<StyleRule>>; ...@@ -103,7 +103,7 @@ using StyleRuleList = HeapVector<Member<StyleRule>>;
// Create one, ask what rules the ElementResolveContext matches // Create one, ask what rules the ElementResolveContext matches
// and then let it go out of scope. // and then let it go out of scope.
// FIXME: Currently it modifies the ComputedStyle but should not! // FIXME: Currently it modifies the ComputedStyle but should not!
class ElementRuleCollector { class CORE_EXPORT ElementRuleCollector {
STACK_ALLOCATED(); STACK_ALLOCATED();
public: public:
...@@ -148,8 +148,8 @@ class ElementRuleCollector { ...@@ -148,8 +148,8 @@ class ElementRuleCollector {
void FinishAddingUserRules() { void FinishAddingUserRules() {
result_.FinishAddingUserRules(); result_.FinishAddingUserRules();
} }
void FinishAddingAuthorRulesForTreeScope() { void FinishAddingAuthorRulesForTreeScope(const TreeScope& tree_scope) {
result_.FinishAddingAuthorRulesForTreeScope(); result_.FinishAddingAuthorRulesForTreeScope(tree_scope);
} }
void SetIncludeEmptyRules(bool include) { include_empty_rules_ = include; } void SetIncludeEmptyRules(bool include) { include_empty_rules_ = include; }
bool IncludeEmptyRules() const { return include_empty_rules_; } bool IncludeEmptyRules() const { return include_empty_rules_; }
......
...@@ -47,7 +47,7 @@ TEST_F(CascadeExpansionTest, UARules) { ...@@ -47,7 +47,7 @@ TEST_F(CascadeExpansionTest, UARules) {
result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px")); result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px"));
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -69,7 +69,7 @@ TEST_F(CascadeExpansionTest, UserRules) { ...@@ -69,7 +69,7 @@ TEST_F(CascadeExpansionTest, UserRules) {
result.AddMatchedProperties(ParseDeclarationBlock("cursor:help")); result.AddMatchedProperties(ParseDeclarationBlock("cursor:help"));
result.AddMatchedProperties(ParseDeclarationBlock("float:left")); result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(2u, result.GetMatchedProperties().size()); ASSERT_EQ(2u, result.GetMatchedProperties().size());
...@@ -98,7 +98,7 @@ TEST_F(CascadeExpansionTest, AuthorRules) { ...@@ -98,7 +98,7 @@ TEST_F(CascadeExpansionTest, AuthorRules) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px")); result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px"));
result.AddMatchedProperties(ParseDeclarationBlock("float:left")); result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(2u, result.GetMatchedProperties().size()); ASSERT_EQ(2u, result.GetMatchedProperties().size());
...@@ -133,9 +133,9 @@ TEST_F(CascadeExpansionTest, AllOriginRules) { ...@@ -133,9 +133,9 @@ TEST_F(CascadeExpansionTest, AllOriginRules) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("left:1px")); result.AddMatchedProperties(ParseDeclarationBlock("left:1px"));
result.AddMatchedProperties(ParseDeclarationBlock("float:left")); result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(ParseDeclarationBlock("bottom:2px")); result.AddMatchedProperties(ParseDeclarationBlock("bottom:2px"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(5u, result.GetMatchedProperties().size()); ASSERT_EQ(5u, result.GetMatchedProperties().size());
...@@ -195,7 +195,7 @@ TEST_F(CascadeExpansionTest, Name) { ...@@ -195,7 +195,7 @@ TEST_F(CascadeExpansionTest, Name) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("--x:1px;--y:2px")); result.AddMatchedProperties(ParseDeclarationBlock("--x:1px;--y:2px"));
result.AddMatchedProperties(ParseDeclarationBlock("float:left")); result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(2u, result.GetMatchedProperties().size()); ASSERT_EQ(2u, result.GetMatchedProperties().size());
...@@ -227,7 +227,7 @@ TEST_F(CascadeExpansionTest, Value) { ...@@ -227,7 +227,7 @@ TEST_F(CascadeExpansionTest, Value) {
result.AddMatchedProperties(ParseDeclarationBlock("background-color:red")); result.AddMatchedProperties(ParseDeclarationBlock("background-color:red"));
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -249,7 +249,7 @@ TEST_F(CascadeExpansionTest, LinkOmitted) { ...@@ -249,7 +249,7 @@ TEST_F(CascadeExpansionTest, LinkOmitted) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("color:red"), result.AddMatchedProperties(ParseDeclarationBlock("color:red"),
CSSSelector::kMatchVisited); CSSSelector::kMatchVisited);
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -265,7 +265,7 @@ TEST_F(CascadeExpansionTest, InternalVisited) { ...@@ -265,7 +265,7 @@ TEST_F(CascadeExpansionTest, InternalVisited) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("color:red")); result.AddMatchedProperties(ParseDeclarationBlock("color:red"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -285,7 +285,7 @@ TEST_F(CascadeExpansionTest, InternalVisitedOmitted) { ...@@ -285,7 +285,7 @@ TEST_F(CascadeExpansionTest, InternalVisitedOmitted) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("color:red"), result.AddMatchedProperties(ParseDeclarationBlock("color:red"),
CSSSelector::kMatchLink); CSSSelector::kMatchLink);
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -301,7 +301,7 @@ TEST_F(CascadeExpansionTest, InternalVisitedWithTrailer) { ...@@ -301,7 +301,7 @@ TEST_F(CascadeExpansionTest, InternalVisitedWithTrailer) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("color:red;left:1px")); result.AddMatchedProperties(ParseDeclarationBlock("color:red;left:1px"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -323,7 +323,7 @@ TEST_F(CascadeExpansionTest, All) { ...@@ -323,7 +323,7 @@ TEST_F(CascadeExpansionTest, All) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("all:unset")); result.AddMatchedProperties(ParseDeclarationBlock("all:unset"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -344,7 +344,7 @@ TEST_F(CascadeExpansionTest, InlineAll) { ...@@ -344,7 +344,7 @@ TEST_F(CascadeExpansionTest, InlineAll) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties( result.AddMatchedProperties(
ParseDeclarationBlock("left:1px;all:unset;right:1px")); ParseDeclarationBlock("left:1px;all:unset;right:1px"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -372,7 +372,7 @@ TEST_F(CascadeExpansionTest, FilterNormalNonInherited) { ...@@ -372,7 +372,7 @@ TEST_F(CascadeExpansionTest, FilterNormalNonInherited) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("font-size:1px;left:1px")); result.AddMatchedProperties(ParseDeclarationBlock("font-size:1px;left:1px"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -392,7 +392,7 @@ TEST_F(CascadeExpansionTest, FilterInternalVisited) { ...@@ -392,7 +392,7 @@ TEST_F(CascadeExpansionTest, FilterInternalVisited) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("color:red")); result.AddMatchedProperties(ParseDeclarationBlock("color:red"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
CascadeFilter filter(CSSProperty::kVisited, true); CascadeFilter filter(CSSProperty::kVisited, true);
...@@ -412,7 +412,7 @@ TEST_F(CascadeExpansionTest, FilterFirstLetter) { ...@@ -412,7 +412,7 @@ TEST_F(CascadeExpansionTest, FilterFirstLetter) {
result.AddMatchedProperties( result.AddMatchedProperties(
ParseDeclarationBlock("object-fit:unset;font-size:1px"), ParseDeclarationBlock("object-fit:unset;font-size:1px"),
CSSSelector::kMatchAll, ValidPropertyFilter::kFirstLetter); CSSSelector::kMatchAll, ValidPropertyFilter::kFirstLetter);
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
auto e = ExpansionAt(result, 0); auto e = ExpansionAt(result, 0);
ASSERT_FALSE(e.AtEnd()); ASSERT_FALSE(e.AtEnd());
...@@ -428,7 +428,7 @@ TEST_F(CascadeExpansionTest, FilterCue) { ...@@ -428,7 +428,7 @@ TEST_F(CascadeExpansionTest, FilterCue) {
result.AddMatchedProperties( result.AddMatchedProperties(
ParseDeclarationBlock("object-fit:unset;font-size:1px"), ParseDeclarationBlock("object-fit:unset;font-size:1px"),
CSSSelector::kMatchAll, ValidPropertyFilter::kCue); CSSSelector::kMatchAll, ValidPropertyFilter::kCue);
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
auto e = ExpansionAt(result, 0); auto e = ExpansionAt(result, 0);
ASSERT_FALSE(e.AtEnd()); ASSERT_FALSE(e.AtEnd());
...@@ -444,7 +444,7 @@ TEST_F(CascadeExpansionTest, FilterMarker) { ...@@ -444,7 +444,7 @@ TEST_F(CascadeExpansionTest, FilterMarker) {
result.AddMatchedProperties( result.AddMatchedProperties(
ParseDeclarationBlock("object-fit:unset;font-size:1px"), ParseDeclarationBlock("object-fit:unset;font-size:1px"),
CSSSelector::kMatchAll, ValidPropertyFilter::kMarker); CSSSelector::kMatchAll, ValidPropertyFilter::kMarker);
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
auto e = ExpansionAt(result, 0); auto e = ExpansionAt(result, 0);
ASSERT_FALSE(e.AtEnd()); ASSERT_FALSE(e.AtEnd());
...@@ -458,7 +458,7 @@ TEST_F(CascadeExpansionTest, FilterAllNonInherited) { ...@@ -458,7 +458,7 @@ TEST_F(CascadeExpansionTest, FilterAllNonInherited) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("all:unset")); result.AddMatchedProperties(ParseDeclarationBlock("all:unset"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -481,7 +481,7 @@ TEST_F(CascadeExpansionTest, Importance) { ...@@ -481,7 +481,7 @@ TEST_F(CascadeExpansionTest, Importance) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties( result.AddMatchedProperties(
ParseDeclarationBlock("cursor:help;display:block !important")); ParseDeclarationBlock("cursor:help;display:block !important"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -504,7 +504,7 @@ TEST_F(CascadeExpansionTest, AllImportance) { ...@@ -504,7 +504,7 @@ TEST_F(CascadeExpansionTest, AllImportance) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("all:unset !important")); result.AddMatchedProperties(ParseDeclarationBlock("all:unset !important"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -525,7 +525,7 @@ TEST_F(CascadeExpansionTest, AllNonImportance) { ...@@ -525,7 +525,7 @@ TEST_F(CascadeExpansionTest, AllNonImportance) {
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("all:unset")); result.AddMatchedProperties(ParseDeclarationBlock("all:unset"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(1u, result.GetMatchedProperties().size()); ASSERT_EQ(1u, result.GetMatchedProperties().size());
...@@ -547,7 +547,7 @@ TEST_F(CascadeExpansionTest, Position) { ...@@ -547,7 +547,7 @@ TEST_F(CascadeExpansionTest, Position) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(ParseDeclarationBlock("left:1px;top:1px")); result.AddMatchedProperties(ParseDeclarationBlock("left:1px;top:1px"));
result.AddMatchedProperties(ParseDeclarationBlock("bottom:1px;right:1px")); result.AddMatchedProperties(ParseDeclarationBlock("bottom:1px;right:1px"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(2u, result.GetMatchedProperties().size()); ASSERT_EQ(2u, result.GetMatchedProperties().size());
......
...@@ -73,8 +73,10 @@ void MatchResult::FinishAddingUserRules() { ...@@ -73,8 +73,10 @@ void MatchResult::FinishAddingUserRules() {
current_origin_ = CascadeOrigin::kAuthor; current_origin_ = CascadeOrigin::kAuthor;
} }
void MatchResult::FinishAddingAuthorRulesForTreeScope() { void MatchResult::FinishAddingAuthorRulesForTreeScope(
const TreeScope& tree_scope) {
DCHECK_EQ(current_origin_, CascadeOrigin::kAuthor); DCHECK_EQ(current_origin_, CascadeOrigin::kAuthor);
tree_scopes_.push_back(&tree_scope);
current_tree_order_ = base::ClampAdd(current_tree_order_, 1); current_tree_order_ = base::ClampAdd(current_tree_order_, 1);
} }
......
...@@ -140,7 +140,7 @@ class CORE_EXPORT MatchResult { ...@@ -140,7 +140,7 @@ class CORE_EXPORT MatchResult {
void FinishAddingUARules(); void FinishAddingUARules();
void FinishAddingUserRules(); void FinishAddingUserRules();
void FinishAddingAuthorRulesForTreeScope(); void FinishAddingAuthorRulesForTreeScope(const TreeScope&);
void SetIsCacheable(bool cacheable) { is_cacheable_ = cacheable; } void SetIsCacheable(bool cacheable) { is_cacheable_ = cacheable; }
bool IsCacheable() const { return is_cacheable_; } bool IsCacheable() const { return is_cacheable_; }
...@@ -155,11 +155,17 @@ class CORE_EXPORT MatchResult { ...@@ -155,11 +155,17 @@ class CORE_EXPORT MatchResult {
// objects were added. // objects were added.
void Reset(); void Reset();
const TreeScope& ScopeFromTreeOrder(uint16_t tree_order) const {
SECURITY_DCHECK(tree_order < tree_scopes_.size());
return *tree_scopes_[tree_order];
}
private: private:
MatchedPropertiesVector matched_properties_; MatchedPropertiesVector matched_properties_;
bool is_cacheable_ = true; HeapVector<Member<const TreeScope>, 4> tree_scopes_;
CascadeOrigin current_origin_ = CascadeOrigin::kUserAgent; bool is_cacheable_{true};
uint16_t current_tree_order_ = 0; CascadeOrigin current_origin_{CascadeOrigin::kUserAgent};
uint16_t current_tree_order_{0};
}; };
inline bool operator==(const MatchedProperties& a, const MatchedProperties& b) { inline bool operator==(const MatchedProperties& a, const MatchedProperties& b) {
......
...@@ -50,7 +50,7 @@ TEST_F(MatchResultTest, CascadeOriginUserAgent) { ...@@ -50,7 +50,7 @@ TEST_F(MatchResultTest, CascadeOriginUserAgent) {
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 2u); ASSERT_EQ(LengthOf(result), 2u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
...@@ -63,7 +63,7 @@ TEST_F(MatchResultTest, CascadeOriginUser) { ...@@ -63,7 +63,7 @@ TEST_F(MatchResultTest, CascadeOriginUser) {
result.AddMatchedProperties(PropertySet(0)); result.AddMatchedProperties(PropertySet(0));
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 2u); ASSERT_EQ(LengthOf(result), 2u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUser); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUser);
...@@ -76,7 +76,7 @@ TEST_F(MatchResultTest, CascadeOriginAuthor) { ...@@ -76,7 +76,7 @@ TEST_F(MatchResultTest, CascadeOriginAuthor) {
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(PropertySet(0)); result.AddMatchedProperties(PropertySet(0));
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 2u); ASSERT_EQ(LengthOf(result), 2u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kAuthor); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kAuthor);
...@@ -93,7 +93,7 @@ TEST_F(MatchResultTest, CascadeOriginAll) { ...@@ -93,7 +93,7 @@ TEST_F(MatchResultTest, CascadeOriginAll) {
result.AddMatchedProperties(PropertySet(3)); result.AddMatchedProperties(PropertySet(3));
result.AddMatchedProperties(PropertySet(4)); result.AddMatchedProperties(PropertySet(4));
result.AddMatchedProperties(PropertySet(5)); result.AddMatchedProperties(PropertySet(5));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 6u); ASSERT_EQ(LengthOf(result), 6u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
...@@ -113,7 +113,7 @@ TEST_F(MatchResultTest, CascadeOriginAllExceptUserAgent) { ...@@ -113,7 +113,7 @@ TEST_F(MatchResultTest, CascadeOriginAllExceptUserAgent) {
result.AddMatchedProperties(PropertySet(3)); result.AddMatchedProperties(PropertySet(3));
result.AddMatchedProperties(PropertySet(4)); result.AddMatchedProperties(PropertySet(4));
result.AddMatchedProperties(PropertySet(5)); result.AddMatchedProperties(PropertySet(5));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 5u); ASSERT_EQ(LengthOf(result), 5u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUser); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUser);
...@@ -131,7 +131,7 @@ TEST_F(MatchResultTest, CascadeOriginAllExceptUser) { ...@@ -131,7 +131,7 @@ TEST_F(MatchResultTest, CascadeOriginAllExceptUser) {
result.AddMatchedProperties(PropertySet(3)); result.AddMatchedProperties(PropertySet(3));
result.AddMatchedProperties(PropertySet(4)); result.AddMatchedProperties(PropertySet(4));
result.AddMatchedProperties(PropertySet(5)); result.AddMatchedProperties(PropertySet(5));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 4u); ASSERT_EQ(LengthOf(result), 4u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
...@@ -147,7 +147,7 @@ TEST_F(MatchResultTest, CascadeOriginAllExceptAuthor) { ...@@ -147,7 +147,7 @@ TEST_F(MatchResultTest, CascadeOriginAllExceptAuthor) {
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.AddMatchedProperties(PropertySet(2)); result.AddMatchedProperties(PropertySet(2));
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 3u); ASSERT_EQ(LengthOf(result), 3u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
...@@ -162,14 +162,14 @@ TEST_F(MatchResultTest, CascadeOriginTreeScopes) { ...@@ -162,14 +162,14 @@ TEST_F(MatchResultTest, CascadeOriginTreeScopes) {
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(PropertySet(2)); result.AddMatchedProperties(PropertySet(2));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(PropertySet(3)); result.AddMatchedProperties(PropertySet(3));
result.AddMatchedProperties(PropertySet(4)); result.AddMatchedProperties(PropertySet(4));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(PropertySet(5)); result.AddMatchedProperties(PropertySet(5));
result.AddMatchedProperties(PropertySet(6)); result.AddMatchedProperties(PropertySet(6));
result.AddMatchedProperties(PropertySet(7)); result.AddMatchedProperties(PropertySet(7));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 8u); ASSERT_EQ(LengthOf(result), 8u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
...@@ -193,7 +193,7 @@ TEST_F(MatchResultTest, ExpansionsRange) { ...@@ -193,7 +193,7 @@ TEST_F(MatchResultTest, ExpansionsRange) {
result.AddMatchedProperties(ParseDeclarationBlock("top:unset")); result.AddMatchedProperties(ParseDeclarationBlock("top:unset"));
result.AddMatchedProperties( result.AddMatchedProperties(
ParseDeclarationBlock("right:unset;bottom:unset")); ParseDeclarationBlock("right:unset;bottom:unset"));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
CascadeFilter filter; CascadeFilter filter;
...@@ -216,7 +216,7 @@ TEST_F(MatchResultTest, EmptyExpansionsRange) { ...@@ -216,7 +216,7 @@ TEST_F(MatchResultTest, EmptyExpansionsRange) {
MatchResult result; MatchResult result;
result.FinishAddingUARules(); result.FinishAddingUARules();
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
CascadeFilter filter; CascadeFilter filter;
auto range = result.Expansions(GetDocument(), filter); auto range = result.Expansions(GetDocument(), filter);
...@@ -230,11 +230,11 @@ TEST_F(MatchResultTest, Reset) { ...@@ -230,11 +230,11 @@ TEST_F(MatchResultTest, Reset) {
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(PropertySet(2)); result.AddMatchedProperties(PropertySet(2));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(PropertySet(3)); result.AddMatchedProperties(PropertySet(3));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(PropertySet(4)); result.AddMatchedProperties(PropertySet(4));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 5u); ASSERT_EQ(LengthOf(result), 5u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
...@@ -264,11 +264,11 @@ TEST_F(MatchResultTest, Reset) { ...@@ -264,11 +264,11 @@ TEST_F(MatchResultTest, Reset) {
result.AddMatchedProperties(PropertySet(1)); result.AddMatchedProperties(PropertySet(1));
result.FinishAddingUserRules(); result.FinishAddingUserRules();
result.AddMatchedProperties(PropertySet(2)); result.AddMatchedProperties(PropertySet(2));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(PropertySet(3)); result.AddMatchedProperties(PropertySet(3));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
result.AddMatchedProperties(PropertySet(4)); result.AddMatchedProperties(PropertySet(4));
result.FinishAddingAuthorRulesForTreeScope(); result.FinishAddingAuthorRulesForTreeScope(GetDocument());
ASSERT_EQ(LengthOf(result), 5u); ASSERT_EQ(LengthOf(result), 5u);
EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent); EXPECT_EQ(OriginAt(result, 0), CascadeOrigin::kUserAgent);
......
...@@ -20,19 +20,21 @@ class MatchedPropertiesCacheTestKey { ...@@ -20,19 +20,21 @@ class MatchedPropertiesCacheTestKey {
STACK_ALLOCATED(); STACK_ALLOCATED();
public: public:
explicit MatchedPropertiesCacheTestKey(String block_text, unsigned hash) explicit MatchedPropertiesCacheTestKey(String block_text,
: key_(ParseBlock(block_text), hash) { unsigned hash,
} const TreeScope& tree_scope)
: key_(ParseBlock(block_text, tree_scope), hash) {}
const MatchedPropertiesCache::Key& InnerKey() const { return key_; } const MatchedPropertiesCache::Key& InnerKey() const { return key_; }
private: private:
const MatchResult& ParseBlock(String block_text) { const MatchResult& ParseBlock(String block_text,
const TreeScope& tree_scope) {
result_.FinishAddingUARules(); result_.FinishAddingUARules();
result_.FinishAddingUserRules(); result_.FinishAddingUserRules();
auto* set = css_test_helpers::ParseDeclarationBlock(block_text); auto* set = css_test_helpers::ParseDeclarationBlock(block_text);
result_.AddMatchedProperties(set); result_.AddMatchedProperties(set);
result_.FinishAddingAuthorRulesForTreeScope(); result_.FinishAddingAuthorRulesForTreeScope(tree_scope);
return result_; return result_;
} }
...@@ -180,10 +182,11 @@ TEST_F(MatchedPropertiesCacheTest, AllowedKeyValues) { ...@@ -180,10 +182,11 @@ TEST_F(MatchedPropertiesCacheTest, AllowedKeyValues) {
ASSERT_EQ(0u, HashTraits<unsigned>::EmptyValue()); ASSERT_EQ(0u, HashTraits<unsigned>::EmptyValue());
ASSERT_TRUE(HashTraits<unsigned>::IsDeletedValue(deleted)); ASSERT_TRUE(HashTraits<unsigned>::IsDeletedValue(deleted));
EXPECT_FALSE(TestKey("left:0", empty).InnerKey().IsValid()); EXPECT_FALSE(TestKey("left:0", empty, GetDocument()).InnerKey().IsValid());
EXPECT_TRUE(TestKey("left:0", empty + 1).InnerKey().IsValid()); EXPECT_TRUE(TestKey("left:0", empty + 1, GetDocument()).InnerKey().IsValid());
EXPECT_TRUE(TestKey("left:0", deleted - 1).InnerKey().IsValid()); EXPECT_TRUE(
EXPECT_FALSE(TestKey("left:0", deleted).InnerKey().IsValid()); TestKey("left:0", deleted - 1, GetDocument()).InnerKey().IsValid());
EXPECT_FALSE(TestKey("left:0", deleted, GetDocument()).InnerKey().IsValid());
} }
TEST_F(MatchedPropertiesCacheTest, InvalidKeyForUncacheableMatchResult) { TEST_F(MatchedPropertiesCacheTest, InvalidKeyForUncacheableMatchResult) {
...@@ -194,7 +197,7 @@ TEST_F(MatchedPropertiesCacheTest, InvalidKeyForUncacheableMatchResult) { ...@@ -194,7 +197,7 @@ TEST_F(MatchedPropertiesCacheTest, InvalidKeyForUncacheableMatchResult) {
TEST_F(MatchedPropertiesCacheTest, Miss) { TEST_F(MatchedPropertiesCacheTest, Miss) {
TestCache cache(GetDocument()); TestCache cache(GetDocument());
TestKey key("color:red", 1); TestKey key("color:red", 1, GetDocument());
auto style = CreateStyle(); auto style = CreateStyle();
auto parent = CreateStyle(); auto parent = CreateStyle();
...@@ -204,7 +207,7 @@ TEST_F(MatchedPropertiesCacheTest, Miss) { ...@@ -204,7 +207,7 @@ TEST_F(MatchedPropertiesCacheTest, Miss) {
TEST_F(MatchedPropertiesCacheTest, Hit) { TEST_F(MatchedPropertiesCacheTest, Hit) {
TestCache cache(GetDocument()); TestCache cache(GetDocument());
TestKey key("color:red", 1); TestKey key("color:red", 1, GetDocument());
auto style = CreateStyle(); auto style = CreateStyle();
auto parent = CreateStyle(); auto parent = CreateStyle();
...@@ -219,8 +222,8 @@ TEST_F(MatchedPropertiesCacheTest, HitOnlyForAddedEntry) { ...@@ -219,8 +222,8 @@ TEST_F(MatchedPropertiesCacheTest, HitOnlyForAddedEntry) {
auto style = CreateStyle(); auto style = CreateStyle();
auto parent = CreateStyle(); auto parent = CreateStyle();
TestKey key1("color:red", 1); TestKey key1("color:red", 1, GetDocument());
TestKey key2("display:block", 2); TestKey key2("display:block", 2, GetDocument());
cache.Add(key1, *style, *parent); cache.Add(key1, *style, *parent);
...@@ -234,7 +237,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithStandardDependency) { ...@@ -234,7 +237,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithStandardDependency) {
auto style = CreateStyle(); auto style = CreateStyle();
auto parent = CreateStyle(); auto parent = CreateStyle();
TestKey key("top:inherit", 1); TestKey key("top:inherit", 1, GetDocument());
cache.Add(key, *style, *parent, Vector<String>{"top"}); cache.Add(key, *style, *parent, Vector<String>{"top"});
EXPECT_TRUE(cache.Find(key, *style, *parent)); EXPECT_TRUE(cache.Find(key, *style, *parent));
...@@ -251,7 +254,7 @@ TEST_F(MatchedPropertiesCacheTest, MissWithStandardDependency) { ...@@ -251,7 +254,7 @@ TEST_F(MatchedPropertiesCacheTest, MissWithStandardDependency) {
auto parent2 = CreateStyle(); auto parent2 = CreateStyle();
parent2->SetTop(Length(2, Length::kFixed)); parent2->SetTop(Length(2, Length::kFixed));
TestKey key("top:inherit", 1); TestKey key("top:inherit", 1, GetDocument());
cache.Add(key, *style, *parent1, Vector<String>{"top"}); cache.Add(key, *style, *parent1, Vector<String>{"top"});
EXPECT_TRUE(cache.Find(key, *style, *parent1)); EXPECT_TRUE(cache.Find(key, *style, *parent1));
EXPECT_FALSE(cache.Find(key, *style, *parent2)); EXPECT_FALSE(cache.Find(key, *style, *parent2));
...@@ -265,7 +268,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithCustomDependency) { ...@@ -265,7 +268,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithCustomDependency) {
auto parent = CreateStyle(); auto parent = CreateStyle();
parent->SetVariableData("--x", CreateVariableData("1px"), true); parent->SetVariableData("--x", CreateVariableData("1px"), true);
TestKey key("top:var(--x)", 1); TestKey key("top:var(--x)", 1, GetDocument());
cache.Add(key, *style, *parent, Vector<String>{"--x"}); cache.Add(key, *style, *parent, Vector<String>{"--x"});
EXPECT_TRUE(cache.Find(key, *style, *parent)); EXPECT_TRUE(cache.Find(key, *style, *parent));
...@@ -282,7 +285,7 @@ TEST_F(MatchedPropertiesCacheTest, MissWithCustomDependency) { ...@@ -282,7 +285,7 @@ TEST_F(MatchedPropertiesCacheTest, MissWithCustomDependency) {
auto parent2 = CreateStyle(); auto parent2 = CreateStyle();
parent2->SetVariableData("--x", CreateVariableData("2px"), true); parent2->SetVariableData("--x", CreateVariableData("2px"), true);
TestKey key("top:var(--x)", 1); TestKey key("top:var(--x)", 1, GetDocument());
cache.Add(key, *style, *parent1, Vector<String>{"--x"}); cache.Add(key, *style, *parent1, Vector<String>{"--x"});
EXPECT_FALSE(cache.Find(key, *style, *parent2)); EXPECT_FALSE(cache.Find(key, *style, *parent2));
...@@ -301,7 +304,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithMultipleCustomDependencies) { ...@@ -301,7 +304,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithMultipleCustomDependencies) {
auto parent2 = ComputedStyle::Clone(*parent1); auto parent2 = ComputedStyle::Clone(*parent1);
parent2->SetVariableData("--z", CreateVariableData("4px"), true); parent2->SetVariableData("--z", CreateVariableData("4px"), true);
TestKey key("top:var(--x);left:var(--y)", 1); TestKey key("top:var(--x);left:var(--y)", 1, GetDocument());
// Does not depend on --z, so doesn't matter that --z changed. // Does not depend on --z, so doesn't matter that --z changed.
cache.Add(key, *style, *parent1, Vector<String>{"--x", "--y"}); cache.Add(key, *style, *parent1, Vector<String>{"--x", "--y"});
...@@ -320,7 +323,7 @@ TEST_F(MatchedPropertiesCacheTest, MissWithMultipleCustomDependencies) { ...@@ -320,7 +323,7 @@ TEST_F(MatchedPropertiesCacheTest, MissWithMultipleCustomDependencies) {
auto parent2 = ComputedStyle::Clone(*parent1); auto parent2 = ComputedStyle::Clone(*parent1);
parent2->SetVariableData("--y", CreateVariableData("3px"), true); parent2->SetVariableData("--y", CreateVariableData("3px"), true);
TestKey key("top:var(--x);left:var(--y)", 1); TestKey key("top:var(--x);left:var(--y)", 1, GetDocument());
cache.Add(key, *style, *parent1, Vector<String>{"--x", "--y"}); cache.Add(key, *style, *parent1, Vector<String>{"--x", "--y"});
EXPECT_FALSE(cache.Find(key, *style, *parent2)); EXPECT_FALSE(cache.Find(key, *style, *parent2));
...@@ -341,7 +344,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithMixedDependencies) { ...@@ -341,7 +344,7 @@ TEST_F(MatchedPropertiesCacheTest, HitWithMixedDependencies) {
parent2->SetVariableData("--y", CreateVariableData("5px"), true); parent2->SetVariableData("--y", CreateVariableData("5px"), true);
parent2->SetRight(Length(6, Length::kFixed)); parent2->SetRight(Length(6, Length::kFixed));
TestKey key("left:inherit;top:var(--x)", 1); TestKey key("left:inherit;top:var(--x)", 1, GetDocument());
cache.Add(key, *style, *parent1, Vector<String>{"left", "--x"}); cache.Add(key, *style, *parent1, Vector<String>{"left", "--x"});
EXPECT_TRUE(cache.Find(key, *style, *parent2)); EXPECT_TRUE(cache.Find(key, *style, *parent2));
...@@ -536,7 +539,7 @@ TEST_F(MatchedPropertiesCacheTest, EnsuredInDisplayNone) { ...@@ -536,7 +539,7 @@ TEST_F(MatchedPropertiesCacheTest, EnsuredInDisplayNone) {
auto ensured_parent = CreateStyle(); auto ensured_parent = CreateStyle();
ensured_parent->SetIsEnsuredInDisplayNone(); ensured_parent->SetIsEnsuredInDisplayNone();
TestKey key1("display:block", 1); TestKey key1("display:block", 1, GetDocument());
cache.Add(key1, *style, *parent); cache.Add(key1, *style, *parent);
EXPECT_TRUE(cache.Find(key1, *style, *parent)); EXPECT_TRUE(cache.Find(key1, *style, *parent));
...@@ -555,7 +558,7 @@ TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTree) { ...@@ -555,7 +558,7 @@ TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTree) {
auto ensured_style = CreateStyle(); auto ensured_style = CreateStyle();
ensured_style->SetIsEnsuredOutsideFlatTree(); ensured_style->SetIsEnsuredOutsideFlatTree();
TestKey key1("display:block", 1); TestKey key1("display:block", 1, GetDocument());
cache.Add(key1, *style, *parent); cache.Add(key1, *style, *parent);
EXPECT_TRUE(cache.Find(key1, *style, *parent)); EXPECT_TRUE(cache.Find(key1, *style, *parent));
...@@ -576,7 +579,7 @@ TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTreeAndDisplayNone) { ...@@ -576,7 +579,7 @@ TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTreeAndDisplayNone) {
parent_none->SetIsEnsuredInDisplayNone(); parent_none->SetIsEnsuredInDisplayNone();
style_flat->SetIsEnsuredOutsideFlatTree(); style_flat->SetIsEnsuredOutsideFlatTree();
TestKey key1("display:block", 1); TestKey key1("display:block", 1, GetDocument());
cache.Add(key1, *style, *parent_none); cache.Add(key1, *style, *parent_none);
EXPECT_TRUE(cache.Find(key1, *style_flat, *parent)); EXPECT_TRUE(cache.Find(key1, *style_flat, *parent));
......
...@@ -313,7 +313,25 @@ static void MatchHostAndCustomElementRules(const Element& element, ...@@ -313,7 +313,25 @@ static void MatchHostAndCustomElementRules(const Element& element,
MatchCustomElementRules(element, collector); MatchCustomElementRules(element, collector);
MatchHostRules(element, collector); MatchHostRules(element, collector);
collector.SortAndTransferMatchedRules(); collector.SortAndTransferMatchedRules();
collector.FinishAddingAuthorRulesForTreeScope(); // TODO(futhark): If the resolver is null here, it means we are matching rules
// for custom element default styles. Since we don't have a
// ScopedStyleResolver if the custom element does not have a shadow root,
// there is no way to collect @-rules for @font-face, @keyframes, etc. We
// currently pass the element's TreeScope, which might not be what we want. It
// means that if you have:
//
// <style>@keyframes anim { ... }</style>
// <custom-element></custom-element>
//
// and the custom-element is defined with:
//
// @keyframes anim { ... }
// custom-element { animation-name: anim }
//
// it means that the custom element will pick up the @keyframes definition
// from the element's scope.
collector.FinishAddingAuthorRulesForTreeScope(
resolver ? resolver->GetTreeScope() : element.GetTreeScope());
} }
static void MatchSlottedRules(const Element&, ElementRuleCollector&); static void MatchSlottedRules(const Element&, ElementRuleCollector&);
...@@ -368,7 +386,7 @@ static void MatchSlottedRules(const Element& element, ...@@ -368,7 +386,7 @@ static void MatchSlottedRules(const Element& element,
collector.ClearMatchedRules(); collector.ClearMatchedRules();
(*it)->CollectMatchingSlottedRules(collector); (*it)->CollectMatchingSlottedRules(collector);
collector.SortAndTransferMatchedRules(); collector.SortAndTransferMatchedRules();
collector.FinishAddingAuthorRulesForTreeScope(); collector.FinishAddingAuthorRulesForTreeScope((*it)->GetTreeScope());
} }
} }
...@@ -425,7 +443,9 @@ static void MatchElementScopeRules(const Element& element, ...@@ -425,7 +443,9 @@ static void MatchElementScopeRules(const Element& element,
is_inline_style_cacheable); is_inline_style_cacheable);
} }
collector.FinishAddingAuthorRulesForTreeScope(); collector.FinishAddingAuthorRulesForTreeScope(
element_scope_resolver ? element_scope_resolver->GetTreeScope()
: element.GetTreeScope());
} }
void StyleResolver::MatchPseudoPartRulesForUAHost( void StyleResolver::MatchPseudoPartRulesForUAHost(
...@@ -461,7 +481,7 @@ void StyleResolver::MatchPseudoPartRules(const Element& element, ...@@ -461,7 +481,7 @@ void StyleResolver::MatchPseudoPartRules(const Element& element,
collector.ClearMatchedRules(); collector.ClearMatchedRules();
resolver->CollectMatchingPartPseudoRules(collector, current_names); resolver->CollectMatchingPartPseudoRules(collector, current_names);
collector.SortAndTransferMatchedRules(); collector.SortAndTransferMatchedRules();
collector.FinishAddingAuthorRulesForTreeScope(); collector.FinishAddingAuthorRulesForTreeScope(resolver->GetTreeScope());
} }
// If the host doesn't forward any parts using partmap= then the element is // If the host doesn't forward any parts using partmap= then the element is
...@@ -555,23 +575,24 @@ void StyleResolver::MatchScopedRulesV0( ...@@ -555,23 +575,24 @@ void StyleResolver::MatchScopedRulesV0(
collector.ClearMatchedRules(); collector.ClearMatchedRules();
resolver->CollectMatchingTreeBoundaryCrossingRules(collector); resolver->CollectMatchingTreeBoundaryCrossingRules(collector);
collector.SortAndTransferMatchedRules(); collector.SortAndTransferMatchedRules();
collector.FinishAddingAuthorRulesForTreeScope(); collector.FinishAddingAuthorRulesForTreeScope(resolver->GetTreeScope());
} }
if (!match_element_scope_done) if (!match_element_scope_done)
MatchElementScopeRules(element, element_scope_resolver, collector); MatchElementScopeRules(element, element_scope_resolver, collector);
} }
void StyleResolver::MatchAuthorRules(const Element& element, void StyleResolver::MatchAuthorRules(
ElementRuleCollector& collector) { const Element& element,
ScopedStyleResolver* element_scope_resolver,
ElementRuleCollector& collector) {
if (GetDocument().GetShadowCascadeOrder() == if (GetDocument().GetShadowCascadeOrder() ==
ShadowCascadeOrder::kShadowCascadeV0) { ShadowCascadeOrder::kShadowCascadeV0) {
MatchAuthorRulesV0(element, collector); MatchAuthorRulesV0(element, element_scope_resolver, collector);
return; return;
} }
MatchHostAndCustomElementRules(element, collector); MatchHostAndCustomElementRules(element, collector);
ScopedStyleResolver* element_scope_resolver = ScopedResolverFor(element);
if (GetDocument().MayContainV0Shadow()) { if (GetDocument().MayContainV0Shadow()) {
MatchScopedRulesV0(element, collector, element_scope_resolver); MatchScopedRulesV0(element, collector, element_scope_resolver);
return; return;
...@@ -582,8 +603,10 @@ void StyleResolver::MatchAuthorRules(const Element& element, ...@@ -582,8 +603,10 @@ void StyleResolver::MatchAuthorRules(const Element& element,
MatchPseudoPartRules(element, collector); MatchPseudoPartRules(element, collector);
} }
void StyleResolver::MatchAuthorRulesV0(const Element& element, void StyleResolver::MatchAuthorRulesV0(
ElementRuleCollector& collector) { const Element& element,
ScopedStyleResolver* element_scope_resolver,
ElementRuleCollector& collector) {
collector.ClearMatchedRules(); collector.ClearMatchedRules();
ShadowV0CascadeOrder cascade_order = 0; ShadowV0CascadeOrder cascade_order = 0;
...@@ -596,8 +619,10 @@ void StyleResolver::MatchAuthorRulesV0(const Element& element, ...@@ -596,8 +619,10 @@ void StyleResolver::MatchAuthorRulesV0(const Element& element,
collector, ++cascade_order); collector, ++cascade_order);
// Apply normal rules from element scope. // Apply normal rules from element scope.
if (ScopedStyleResolver* resolver = ScopedResolverFor(element)) if (element_scope_resolver) {
resolver->CollectMatchingAuthorRules(collector, ++cascade_order); element_scope_resolver->CollectMatchingAuthorRules(collector,
++cascade_order);
}
// Apply /deep/ and ::shadow rules from outer scopes, and ::content from // Apply /deep/ and ::shadow rules from outer scopes, and ::content from
// inner. // inner.
...@@ -664,23 +689,23 @@ DISABLE_CFI_PERF ...@@ -664,23 +689,23 @@ DISABLE_CFI_PERF
void StyleResolver::MatchAllRules(StyleResolverState& state, void StyleResolver::MatchAllRules(StyleResolverState& state,
ElementRuleCollector& collector, ElementRuleCollector& collector,
bool include_smil_properties) { bool include_smil_properties) {
MatchUARules(state.GetElement(), collector); Element& element = state.GetElement();
MatchUARules(element, collector);
MatchUserRules(collector); MatchUserRules(collector);
// Now check author rules, beginning first with presentational attributes // Now check author rules, beginning first with presentational attributes
// mapped from HTML. // mapped from HTML.
if (state.GetElement().IsStyledElement()) { if (element.IsStyledElement()) {
collector.AddElementStyleProperties( collector.AddElementStyleProperties(element.PresentationAttributeStyle());
state.GetElement().PresentationAttributeStyle());
// Now we check additional mapped declarations. // Now we check additional mapped declarations.
// Tables and table cells share an additional mapped rule that must be // Tables and table cells share an additional mapped rule that must be
// applied after all attributes, since their mapped style depends on the // applied after all attributes, since their mapped style depends on the
// values of multiple attributes. // values of multiple attributes.
collector.AddElementStyleProperties( collector.AddElementStyleProperties(
state.GetElement().AdditionalPresentationAttributeStyle()); element.AdditionalPresentationAttributeStyle());
if (auto* html_element = DynamicTo<HTMLElement>(state.GetElement())) { if (auto* html_element = DynamicTo<HTMLElement>(element)) {
bool is_auto; bool is_auto;
TextDirection text_direction = TextDirection text_direction =
html_element->DirectionalityIfhasDirAutoAttribute(is_auto); html_element->DirectionalityIfhasDirAutoAttribute(is_auto);
...@@ -693,30 +718,32 @@ void StyleResolver::MatchAllRules(StyleResolverState& state, ...@@ -693,30 +718,32 @@ void StyleResolver::MatchAllRules(StyleResolverState& state,
} }
} }
MatchAuthorRules(state.GetElement(), collector); ScopedStyleResolver* element_scope_resolver = ScopedResolverFor(element);
MatchAuthorRules(element, element_scope_resolver, collector);
if (state.GetElement().IsStyledElement()) { if (element.IsStyledElement()) {
// For Shadow DOM V1, inline style is already collected in // For Shadow DOM V1, inline style is already collected in
// matchScopedRules(). // matchScopedRules().
if (GetDocument().GetShadowCascadeOrder() == if (GetDocument().GetShadowCascadeOrder() ==
ShadowCascadeOrder::kShadowCascadeV0 && ShadowCascadeOrder::kShadowCascadeV0 &&
state.GetElement().InlineStyle()) { element.InlineStyle()) {
// Inline style is immutable as long as there is no CSSOM wrapper. // Inline style is immutable as long as there is no CSSOM wrapper.
bool is_inline_style_cacheable = bool is_inline_style_cacheable = !element.InlineStyle()->IsMutable();
!state.GetElement().InlineStyle()->IsMutable(); collector.AddElementStyleProperties(element.InlineStyle(),
collector.AddElementStyleProperties(state.GetElement().InlineStyle(),
is_inline_style_cacheable); is_inline_style_cacheable);
} }
// Now check SMIL animation override style. // Now check SMIL animation override style.
auto* svg_element = DynamicTo<SVGElement>(state.GetElement()); auto* svg_element = DynamicTo<SVGElement>(element);
if (include_smil_properties && svg_element) { if (include_smil_properties && svg_element) {
collector.AddElementStyleProperties( collector.AddElementStyleProperties(
svg_element->AnimatedSMILStyleProperties(), false /* isCacheable */); svg_element->AnimatedSMILStyleProperties(), false /* isCacheable */);
} }
} }
collector.FinishAddingAuthorRulesForTreeScope(); collector.FinishAddingAuthorRulesForTreeScope(
element_scope_resolver ? element_scope_resolver->GetTreeScope()
: element.GetTreeScope());
} }
void StyleResolver::CollectTreeBoundaryCrossingRulesV0CascadeOrder( void StyleResolver::CollectTreeBoundaryCrossingRulesV0CascadeOrder(
...@@ -1116,7 +1143,7 @@ scoped_refptr<ComputedStyle> StyleResolver::PseudoStyleForElement( ...@@ -1116,7 +1143,7 @@ scoped_refptr<ComputedStyle> StyleResolver::PseudoStyleForElement(
// TODO(obrufau): support styling nested pseudo-elements // TODO(obrufau): support styling nested pseudo-elements
if (!element->IsPseudoElement()) { if (!element->IsPseudoElement()) {
MatchUserRules(collector); MatchUserRules(collector);
MatchAuthorRules(*element, collector); MatchAuthorRules(*element, ScopedResolverFor(*element), collector);
} }
if (tracker_) if (tracker_)
...@@ -1341,7 +1368,7 @@ void StyleResolver::CollectPseudoRulesForElement( ...@@ -1341,7 +1368,7 @@ void StyleResolver::CollectPseudoRulesForElement(
if (rules_to_include & kAuthorCSSRules) { if (rules_to_include & kAuthorCSSRules) {
collector.SetSameOriginOnly(!(rules_to_include & kCrossOriginCSSRules)); collector.SetSameOriginOnly(!(rules_to_include & kCrossOriginCSSRules));
collector.SetIncludeEmptyRules(rules_to_include & kEmptyCSSRules); collector.SetIncludeEmptyRules(rules_to_include & kEmptyCSSRules);
MatchAuthorRules(element, collector); MatchAuthorRules(element, ScopedResolverFor(element), collector);
} }
} }
......
...@@ -191,8 +191,12 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> { ...@@ -191,8 +191,12 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
void MatchScopedRulesV0(const Element&, void MatchScopedRulesV0(const Element&,
ElementRuleCollector&, ElementRuleCollector&,
ScopedStyleResolver*); ScopedStyleResolver*);
void MatchAuthorRules(const Element&, ElementRuleCollector&); void MatchAuthorRules(const Element&,
void MatchAuthorRulesV0(const Element&, ElementRuleCollector&); ScopedStyleResolver*,
ElementRuleCollector&);
void MatchAuthorRulesV0(const Element&,
ScopedStyleResolver*,
ElementRuleCollector&);
void MatchAllRules(StyleResolverState&, void MatchAllRules(StyleResolverState&,
ElementRuleCollector&, ElementRuleCollector&,
bool include_smil_properties); bool include_smil_properties);
...@@ -264,6 +268,7 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> { ...@@ -264,6 +268,7 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
bool was_viewport_resized_ = false; bool was_viewport_resized_ = false;
FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, ApplyInternalLightDarkColor); FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, ApplyInternalLightDarkColor);
FRIEND_TEST_ALL_PREFIXES(StyleResolverTest, TreeScopedReferences);
}; };
} // namespace blink } // namespace blink
......
...@@ -864,4 +864,89 @@ TEST_F(StyleResolverTest, ComputeValueCustomProperty) { ...@@ -864,4 +864,89 @@ TEST_F(StyleResolverTest, ComputeValueCustomProperty) {
EXPECT_EQ("blue", computed_value->CssText()); EXPECT_EQ("blue", computed_value->CssText());
} }
TEST_F(StyleResolverTest, TreeScopedReferences) {
GetDocument().body()->setInnerHTML(R"HTML(
<style>
#host { animation-name: anim }
</style>
<div id="host">
<span id="slotted"></span>
</host>
)HTML");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
ShadowRoot& root = host->AttachShadowRootInternal(ShadowRootType::kOpen);
root.setInnerHTML(R"HTML(
<style>
::slotted(span) { animation-name: anim-slotted }
:host { font-family: myfont }
</style>
<div id="inner-host">
<slot></slot>
</div>
)HTML");
Element* inner_host = root.getElementById("inner-host");
ASSERT_TRUE(inner_host);
ShadowRoot& inner_root =
inner_host->AttachShadowRootInternal(ShadowRootType::kOpen);
inner_root.setInnerHTML(R"HTML(
<style>
::slotted(span) { animation-name: anim-inner-slotted }
</style>
<slot></slot>
)HTML");
UpdateAllLifecyclePhasesForTest();
{
StyleResolverState state(GetDocument(), *host);
SelectorFilter filter;
MatchResult match_result;
ElementRuleCollector collector(state.ElementContext(), filter, match_result,
state.Style(), EInsideLink::kNotInsideLink);
GetDocument().GetStyleEngine().GetStyleResolver().MatchAllRules(
state, collector, false /* include_smil_properties */);
const auto& properties = match_result.GetMatchedProperties();
ASSERT_EQ(properties.size(), 3u);
// div { display: block }
EXPECT_EQ(properties[0].types_.origin, CascadeOrigin::kUserAgent);
// :host { font-family: myfont }
EXPECT_EQ(match_result.ScopeFromTreeOrder(properties[1].types_.tree_order),
root.GetTreeScope());
EXPECT_EQ(properties[1].types_.origin, CascadeOrigin::kAuthor);
// #host { animation-name: anim }
EXPECT_EQ(properties[2].types_.origin, CascadeOrigin::kAuthor);
EXPECT_EQ(match_result.ScopeFromTreeOrder(properties[2].types_.tree_order),
host->GetTreeScope());
}
{
auto* span = GetDocument().getElementById("slotted");
StyleResolverState state(GetDocument(), *span);
SelectorFilter filter;
MatchResult match_result;
ElementRuleCollector collector(state.ElementContext(), filter, match_result,
state.Style(), EInsideLink::kNotInsideLink);
GetDocument().GetStyleEngine().GetStyleResolver().MatchAllRules(
state, collector, false /* include_smil_properties */);
const auto& properties = match_result.GetMatchedProperties();
ASSERT_EQ(properties.size(), 2u);
// ::slotted(span) { animation-name: anim-inner-slotted }
EXPECT_EQ(properties[0].types_.origin, CascadeOrigin::kAuthor);
EXPECT_EQ(match_result.ScopeFromTreeOrder(properties[0].types_.tree_order),
inner_root.GetTreeScope());
// ::slotted(span) { animation-name: anim-slotted }
EXPECT_EQ(properties[1].types_.origin, CascadeOrigin::kAuthor);
EXPECT_EQ(match_result.ScopeFromTreeOrder(properties[1].types_.tree_order),
root.GetTreeScope());
}
}
} // 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