Commit 600e1412 authored by rune@opera.com's avatar rune@opera.com

Implement proposed shadow tree cascade order.

This CL implements the shadow tree cascade order proposed in [1].

Previously, in Blink, specificity would win over scope origin, even if the
scopes had an inner/outer scope relationship, and the order-of-appearance
was governed by the CascadeOrder type. Also, !important rules did not
apply in the reverse scope order, as the current spec says for inner/outer
scopes, and the proposal in [1] says apply between all shadow scopes.

What has been done is:

1. CascadeOrder is not used, as it represents order-of-appearance
   (Removal of CascadeOrder is not done here to make the CL smaller. Will
   be removed in a follow-up CL).

2. When collecting rules, sort after each scope instead of just after UA
   and Author since we had:

   UA important
   Author important
   Author
   UA

   and now we have (with A(n) appearing before A(n+1) in the tree-of-trees
   order):

   UA important
   Author scope A(n) important
   ...
   Author scope A(1) important
   Author scope A(1)
   ...
   Author scope A(n)
   UA

   The applyProperties code is hot, and I have made performance runs for
   the micro-benchmarks in Layout and CSS without consistent regressions.

3. Since the cascading order between scopes are just the inner/outer
   relationship in the composed tree (direction decided by !important),
   which is the same as the tree-of-trees order of the shadow trees,
   we can just traverse the DocumentOrderedList of scopes in the reverse
   order instead of doing calculation tricks for CascadeOrder values.

   Because of this, TreeBoundaryCrossingRules is now reduced to a
   DocumentOrderedList of scoping nodes, so the TreeBoundaryCrossingRules
   class is removed.

[1] https://lists.w3.org/Archives/Public/www-style/2015Jun/0303.html

BUG=452542, 455148, 487125

NOTRY=true

Review URL: https://codereview.chromium.org/1298173004

git-svn-id: svn://svn.chromium.org/blink/trunk@200994 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent a60ae27a
...@@ -3,9 +3,9 @@ Checking if styles in the nested shadow roots apply properly to distributed elem ...@@ -3,9 +3,9 @@ Checking if styles in the nested shadow roots apply properly to distributed elem
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS getComputedStyle(span).color is "rgb(255, 0, 0)" PASS getComputedStyle(span).color is "rgb(0, 128, 0)"
PASS getComputedStyle(span).backgroundColor is "rgb(0, 128, 0)" PASS getComputedStyle(span).backgroundColor is "rgb(0, 128, 0)"
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
red? There should be no red
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<script src="../../resources/js-test.js"></script> <script src="../../resources/js-test.js"></script>
<div id="host"> <div id="host">
<div> <div>
<span class="red" id="span">red?</span> <span class="red" id="span">There should be no red</span>
</div> </div>
</div> </div>
<script> <script>
...@@ -12,6 +12,6 @@ root.innerHTML = '<div><content></content></div><style>::content .red { color: g ...@@ -12,6 +12,6 @@ root.innerHTML = '<div><content></content></div><style>::content .red { color: g
var root2 = root.firstChild.createShadowRoot(); var root2 = root.firstChild.createShadowRoot();
root2.innerHTML = '<style>::content .red { background-color: green; color: red; }</style><content></content>'; root2.innerHTML = '<style>::content .red { background-color: green; color: red; }</style><content></content>';
var span = document.querySelector('#span'); var span = document.querySelector('#span');
shouldBeEqualToString('getComputedStyle(span).color', 'rgb(255, 0, 0)'); shouldBeEqualToString('getComputedStyle(span).color', 'rgb(0, 128, 0)');
shouldBeEqualToString('getComputedStyle(span).backgroundColor', 'rgb(0, 128, 0)'); shouldBeEqualToString('getComputedStyle(span).backgroundColor', 'rgb(0, 128, 0)');
</script> </script>
CONSOLE WARNING: /deep/ combinator is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more details.
Cascade order for inner/outer tree rules with /deep/.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS getComputedStyle(root1.querySelector('div')).color is green
TODO(rune@opera.com): Currently fails because style attributes are added to the end, not in its element's scope's cascade order
FAIL getComputedStyle(root1.querySelector('div + div')).color should be rgb(0, 128, 0). Was rgb(255, 0, 0).
PASS getComputedStyle(root2.querySelector('div')).color is green
TODO(rune@opera.com): Currently fails because style attributes are added to the end, not in its element's scope's cascade order
FAIL getComputedStyle(root2.querySelector('div + div')).color should be rgb(0, 128, 0). Was rgb(255, 0, 0).
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../resources/js-test.js"></script>
<style>
.host1 /deep/ div { color: green }
#host2 /deep/ div { color: red !important }
</style>
<div id="host1" class="host1"></div>
<div id="host2" class="host2"></div>
<script>
description("Cascade order for inner/outer tree rules with /deep/.");
var root1 = host1.createShadowRoot();
root1.innerHTML = '<style>#d1 {color:red}</style><div id="d1">Should be green</div><div style="color: red">Should be green</div>';
var root2 = host2.createShadowRoot();
root2.innerHTML = '<style>.d1 {color:green !important}</style><div class="d1">Should be green</div><div style="color: green !important">Should be green</div>';
var green = "rgb(0, 128, 0)";
shouldBe("getComputedStyle(root1.querySelector('div')).color", "green");
debug("TODO(rune@opera.com): Currently fails because style attributes are added to the end, not in its element's scope's cascade order");
shouldBe("getComputedStyle(root1.querySelector('div + div')).color", "green");
shouldBe("getComputedStyle(root2.querySelector('div')).color", "green");
debug("TODO(rune@opera.com): Currently fails because style attributes are added to the end, not in its element's scope's cascade order");
shouldBe("getComputedStyle(root2.querySelector('div + div')).color", "green");
</script>
<!DOCTYPE html> <!DOCTYPE html>
<script src="../../../resources/js-test.js"></script> <script src="../../../resources/js-test.js"></script>
<style> <style>
.d1, .d2 { color: red } custom-element { color: red }
</style> </style>
<custom-element> <custom-element>
<div class="d1">A</div> <div class="d1">A</div>
......
...@@ -7,6 +7,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE ...@@ -7,6 +7,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS borderColorOf(getNodeInTreeOfTrees("target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/host2/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/host2/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
...@@ -36,18 +36,18 @@ function cleanUp() ...@@ -36,18 +36,18 @@ function cleanUp()
description('Test for casacde of treeboundary crossing rules.'); description('Test for casacde of treeboundary crossing rules.');
// Rules declared in inner treescope should win. // Rules declared in outer treescope should win.
sandbox.appendChild( sandbox.appendChild(
createDOM('div', {'id': 'host'}, createDOM('div', {'id': 'host'},
createDOM('style', {}, createDOM('style', {},
document.createTextNode('p:empty { border: 1px solid blue; }')), document.createTextNode('p:empty { border: 1px solid green; }')),
createShadowRoot( createShadowRoot(
createDOM('style', {}, createDOM('style', {},
document.createTextNode('::content > p { border: 1px solid red; }')), document.createTextNode('::content > p { border: 1px solid red; }')),
createDOM('div', {}, createDOM('div', {},
createShadowRoot( createShadowRoot(
createDOM('style', {}, createDOM('style', {},
document.createTextNode('::content > p { border: 1px solid green; }')), document.createTextNode('::content > p { border: 1px solid blue; }')),
createDOM('content', {})), createDOM('content', {})),
createDOM('content', {}))), createDOM('content', {}))),
createDOM('p', {'id': 'target'}))); createDOM('p', {'id': 'target'})));
...@@ -103,6 +103,22 @@ borderColorShouldBe('host/target', 'rgb(0, 128, 0)'); ...@@ -103,6 +103,22 @@ borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
cleanUp(); cleanUp();
// Comparing important rules declared in outer treescope with important rules declared in inner treescope.
// Inner's should win.
sandbox.appendChild(
createDOM('div', {},
createDOM('style', {},
document.createTextNode('div { border: 1px solid red !important; }')),
createDOM('div', {'id': 'host'},
createShadowRoot(
createDOM('style', {},
document.createTextNode('#target { border: 1px solid green !important; }')),
createDOM('p', {'id': 'target'})))));
borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
cleanUp();
</script> </script>
</html> </html>
Inner scope !important rules wins, even with lower specificity.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS getComputedStyle(target).color is "rgb(0, 128, 0)"
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<script src="resources/shadow-dom.js"></script>
<div id="sandbox"></div>
<script>
description("Inner scope !important rules wins, even with lower specificity.");
sandbox.appendChild(
createDOM('div', {'id': 'host'},
createShadowRoot(
createDOM('style', {},
document.createTextNode(
'::content span { color: green !important; }')),
createDOM('content', {})),
createDOM('style', {},
document.createTextNode(
'#target { color: red !important; }')),
createDOM('span', {'id': 'target'})));
shouldBeEqualToString("getComputedStyle(target).color", "rgb(0, 128, 0)");
</script>
Outer scope rules wins, even with lower specificity.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS getComputedStyle(target).color is "rgb(0, 128, 0)"
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<script src="resources/shadow-dom.js"></script>
<div id="sandbox"></div>
<script>
description("Outer scope rules wins, even with lower specificity.");
sandbox.appendChild(
createDOM('div', {'id': 'host'},
createShadowRoot(
createDOM('style', {},
document.createTextNode(
'::content #target { color: red; }')),
createDOM('content', {})),
createDOM('style', {},
document.createTextNode(
'span { color: green; }')),
createDOM('span', {'id': 'target'})));
shouldBeEqualToString("getComputedStyle(target).color", "rgb(0, 128, 0)");
</script>
<!DOCTYPE html>
<style>.t { color: green }</style>
<div id="host">
<span id="t" class="t">This text should be green.</span>
</div>
<script>
if (window.testRunner)
testRunner.dumpAsText();
var root = host.createShadowRoot();
root.innerHTML = '<style>::content > * { color: red }</style><content></content>';
document.write(getComputedStyle(t).color == "rgb(0, 128, 0)" ? "PASS" : "FAIL");
</script>
...@@ -15,7 +15,7 @@ PASS borderColorOf(getNodeInTreeOfTrees("host/host1/host2/span3")) is "rgb(0, 12 ...@@ -15,7 +15,7 @@ PASS borderColorOf(getNodeInTreeOfTrees("host/host1/host2/span3")) is "rgb(0, 12
PASS borderColorOf(getNodeInTreeOfTrees("host/host1/host2/host3/span4")) is not "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/host1/host2/host3/span4")) is not "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(255, 0, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)" PASS borderColorOf(getNodeInTreeOfTrees("host/target")) is "rgb(0, 128, 0)"
......
...@@ -88,7 +88,7 @@ sandbox.appendChild( ...@@ -88,7 +88,7 @@ sandbox.appendChild(
createDOM('div', {'id': 'host'}, createDOM('div', {'id': 'host'},
createShadowRoot( createShadowRoot(
createDOM('span', {'id': 'target'}, createDOM('span', {'id': 'target'},
document.createTextNode('green border, because of hat.')))))); document.createTextNode('green border, because of ::shadow.'))))));
borderColorShouldBe('host/target', 'rgb(0, 128, 0)'); borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
...@@ -104,7 +104,7 @@ sandbox.appendChild( ...@@ -104,7 +104,7 @@ sandbox.appendChild(
createDOM('style', {}, createDOM('style', {},
document.createTextNode('span { border: 1px solid red; }')), document.createTextNode('span { border: 1px solid red; }')),
createDOM('span', {'id': 'target'}, createDOM('span', {'id': 'target'},
document.createTextNode('green border, because of hat.')))))); document.createTextNode('green border, because of ::shadow.'))))));
borderColorShouldBe('host/target', 'rgb(0, 128, 0)'); borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
...@@ -119,10 +119,9 @@ sandbox.appendChild( ...@@ -119,10 +119,9 @@ sandbox.appendChild(
createDOM('style', {}, createDOM('style', {},
document.createTextNode('span#target { border: 1px solid red; }')), document.createTextNode('span#target { border: 1px solid red; }')),
createDOM('span', {'id': 'target'}, createDOM('span', {'id': 'target'},
document.createTextNode('green border, because of hat.')))))); document.createTextNode('green border, because of ::shadow.'))))));
// Need to clarify the spec, i.e. using specificity? Currently rgb(255,0,0). borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
borderColorShouldBe('host/target', 'rgb(255, 0, 0)');
cleanUp(); cleanUp();
...@@ -133,7 +132,7 @@ sandbox.appendChild( ...@@ -133,7 +132,7 @@ sandbox.appendChild(
createDOM('div', {'id': 'host'}, createDOM('div', {'id': 'host'},
createShadowRoot( createShadowRoot(
createDOM('span', {'id': 'target'}, createDOM('span', {'id': 'target'},
document.createTextNode('green border, because of hat.')))))); document.createTextNode('green border, because of ::shadow.'))))));
borderColorShouldBe('host/target', 'rgb(0, 128, 0)'); borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
...@@ -149,7 +148,7 @@ sandbox.appendChild( ...@@ -149,7 +148,7 @@ sandbox.appendChild(
document.createTextNode('div > span { border: 1px solid red; }')), document.createTextNode('div > span { border: 1px solid red; }')),
createDOM('div', {}, createDOM('div', {},
createDOM('span', {'id': 'target'}, createDOM('span', {'id': 'target'},
document.createTextNode('green border, because parent hat wins.'))))))); document.createTextNode('green border, because parent ::shadow wins.')))))));
borderColorShouldBe('host/target', 'rgb(0, 128, 0)'); borderColorShouldBe('host/target', 'rgb(0, 128, 0)');
......
...@@ -1202,8 +1202,6 @@ ...@@ -1202,8 +1202,6 @@
'css/StyleSheetContents.h', 'css/StyleSheetContents.h',
'css/StyleSheetList.cpp', 'css/StyleSheetList.cpp',
'css/StyleSheetList.h', 'css/StyleSheetList.h',
'css/TreeBoundaryCrossingRules.cpp',
'css/TreeBoundaryCrossingRules.h',
'css/invalidation/DescendantInvalidationSet.cpp', 'css/invalidation/DescendantInvalidationSet.cpp',
'css/invalidation/DescendantInvalidationSet.h', 'css/invalidation/DescendantInvalidationSet.h',
'css/invalidation/StyleInvalidator.cpp', 'css/invalidation/StyleInvalidator.cpp',
......
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
* Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* Copyright (C) Research In Motion Limited 2011. All rights reserved.
* Copyright (C) 2013 Google 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.
*/
#include "config.h"
#include "core/css/TreeBoundaryCrossingRules.h"
#include "core/css/ElementRuleCollector.h"
#include "core/css/StylePropertySet.h"
#include "core/css/resolver/ScopedStyleResolver.h"
namespace blink {
void TreeBoundaryCrossingRules::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
{
if (m_scopingNodes.isEmpty())
return;
// When comparing rules declared in outer treescopes, outer's rules win.
CascadeOrder outerCascadeOrder = size() + size();
// When comparing rules declared in inner treescopes, inner's rules win.
CascadeOrder innerCascadeOrder = size();
ASSERT(!collector.scopeContainsLastMatchedElement());
collector.setScopeContainsLastMatchedElement(true);
for (const auto& scope : m_scopingNodes) {
bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scope->treeScope());
CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder;
scope->treeScope().scopedStyleResolver()->collectMatchingTreeBoundaryCrossingRules(collector, includeEmptyRules, cascadeOrder);
++innerCascadeOrder;
--outerCascadeOrder;
}
collector.setScopeContainsLastMatchedElement(false);
}
void TreeBoundaryCrossingRules::addScope(ContainerNode& scopingNode)
{
m_scopingNodes.add(&scopingNode);
}
void TreeBoundaryCrossingRules::removeScope(const ContainerNode& scopingNode)
{
m_scopingNodes.remove(&scopingNode);
}
DEFINE_TRACE(TreeBoundaryCrossingRules)
{
#if ENABLE(OILPAN)
visitor->trace(m_scopingNodes);
#endif
}
} // namespace blink
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google 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 TreeBoundaryCrossingRules_h
#define TreeBoundaryCrossingRules_h
#include "core/dom/DocumentOrderedList.h"
#include "wtf/OwnPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
namespace blink {
class ContainerNode;
class Element;
class ElementRuleCollector;
class TreeBoundaryCrossingRules final {
DISALLOW_ALLOCATION();
public:
void addScope(ContainerNode&);
void removeScope(const ContainerNode&);
void collectTreeBoundaryCrossingRules(Element*, ElementRuleCollector&, bool includeEmptyRules);
DECLARE_TRACE();
private:
size_t size() const { return m_scopingNodes.size(); }
DocumentOrderedList m_scopingNodes;
};
} // namespace blink
#endif // TreeBoundaryCrossingRules_h
...@@ -169,10 +169,18 @@ void ScopedStyleResolver::collectMatchingShadowHostRules(ElementRuleCollector& c ...@@ -169,10 +169,18 @@ void ScopedStyleResolver::collectMatchingShadowHostRules(ElementRuleCollector& c
void ScopedStyleResolver::collectMatchingTreeBoundaryCrossingRules(ElementRuleCollector& collector, bool includeEmptyRules, CascadeOrder cascadeOrder) void ScopedStyleResolver::collectMatchingTreeBoundaryCrossingRules(ElementRuleCollector& collector, bool includeEmptyRules, CascadeOrder cascadeOrder)
{ {
if (!m_treeBoundaryCrossingRuleSet)
return;
ASSERT(!collector.scopeContainsLastMatchedElement());
collector.setScopeContainsLastMatchedElement(true);
for (const auto& rules : *m_treeBoundaryCrossingRuleSet) { for (const auto& rules : *m_treeBoundaryCrossingRuleSet) {
MatchRequest request(rules->m_ruleSet.get(), includeEmptyRules, &treeScope().rootNode(), rules->m_parentStyleSheet, rules->m_parentIndex); MatchRequest request(rules->m_ruleSet.get(), includeEmptyRules, &treeScope().rootNode(), rules->m_parentStyleSheet, rules->m_parentIndex);
collector.collectMatchingRules(request, cascadeOrder, true); collector.collectMatchingRules(request, cascadeOrder, true);
} }
collector.setScopeContainsLastMatchedElement(false);
} }
void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector) void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector)
......
...@@ -59,7 +59,7 @@ public: ...@@ -59,7 +59,7 @@ public:
void appendCSSStyleSheet(CSSStyleSheet&, const MediaQueryEvaluator&); void appendCSSStyleSheet(CSSStyleSheet&, const MediaQueryEvaluator&);
void collectMatchingAuthorRules(ElementRuleCollector&, bool includeEmptyRules, CascadeOrder = ignoreCascadeOrder); void collectMatchingAuthorRules(ElementRuleCollector&, bool includeEmptyRules, CascadeOrder = ignoreCascadeOrder);
void collectMatchingShadowHostRules(ElementRuleCollector&, bool includeEmptyRules, CascadeOrder = ignoreCascadeOrder); void collectMatchingShadowHostRules(ElementRuleCollector&, bool includeEmptyRules, CascadeOrder = ignoreCascadeOrder);
void collectMatchingTreeBoundaryCrossingRules(ElementRuleCollector&, bool includeEmptyRules, CascadeOrder); void collectMatchingTreeBoundaryCrossingRules(ElementRuleCollector&, bool includeEmptyRules, CascadeOrder = ignoreCascadeOrder);
void matchPageRules(PageRuleCollector&); void matchPageRules(PageRuleCollector&);
void collectFeaturesTo(RuleFeatureSet&, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents) const; void collectFeaturesTo(RuleFeatureSet&, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents) const;
void resetAuthorStyle(); void resetAuthorStyle();
......
...@@ -30,12 +30,12 @@ ...@@ -30,12 +30,12 @@
#include "core/css/RuleSet.h" #include "core/css/RuleSet.h"
#include "core/css/SelectorChecker.h" #include "core/css/SelectorChecker.h"
#include "core/css/SelectorFilter.h" #include "core/css/SelectorFilter.h"
#include "core/css/TreeBoundaryCrossingRules.h"
#include "core/css/resolver/CSSPropertyPriority.h" #include "core/css/resolver/CSSPropertyPriority.h"
#include "core/css/resolver/MatchedPropertiesCache.h" #include "core/css/resolver/MatchedPropertiesCache.h"
#include "core/css/resolver/StyleBuilder.h" #include "core/css/resolver/StyleBuilder.h"
#include "core/css/resolver/StyleResolverStats.h" #include "core/css/resolver/StyleResolverStats.h"
#include "core/css/resolver/StyleResourceLoader.h" #include "core/css/resolver/StyleResourceLoader.h"
#include "core/dom/DocumentOrderedList.h"
#include "core/style/AuthorStyleInfo.h" #include "core/style/AuthorStyleInfo.h"
#include "core/style/CachedUAStyle.h" #include "core/style/CachedUAStyle.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
...@@ -201,7 +201,10 @@ private: ...@@ -201,7 +201,10 @@ private:
void collectPseudoRulesForElement(Element*, ElementRuleCollector&, PseudoId, unsigned rulesToInclude); void collectPseudoRulesForElement(Element*, ElementRuleCollector&, PseudoId, unsigned rulesToInclude);
void matchRuleSet(ElementRuleCollector&, RuleSet*); void matchRuleSet(ElementRuleCollector&, RuleSet*);
void matchUARules(ElementRuleCollector&); void matchUARules(ElementRuleCollector&);
void matchAuthorRules(Element*, ElementRuleCollector&, bool includeEmptyRules); void matchAuthorRules(const Element&, ElementRuleCollector&, bool includeEmptyRules);
void matchHostRules(const Element&, ElementRuleCollector&, bool includeEmptyRules);
void matchElementScopeRules(ScopedStyleResolver&, ElementRuleCollector&, bool includeEmptyRules);
void matchScopedRules(const Element&, ElementRuleCollector&, bool includeEmptyRules);
void matchAllRules(StyleResolverState&, ElementRuleCollector&, bool includeSMILProperties); void matchAllRules(StyleResolverState&, ElementRuleCollector&, bool includeSMILProperties);
void collectFeatures(); void collectFeatures();
void resetRuleFeatures(); void resetRuleFeatures();
...@@ -245,7 +248,7 @@ private: ...@@ -245,7 +248,7 @@ private:
OwnPtrWillBeMember<RuleSet> m_siblingRuleSet; OwnPtrWillBeMember<RuleSet> m_siblingRuleSet;
OwnPtrWillBeMember<RuleSet> m_uncommonAttributeRuleSet; OwnPtrWillBeMember<RuleSet> m_uncommonAttributeRuleSet;
OwnPtrWillBeMember<RuleSet> m_watchedSelectorsRules; OwnPtrWillBeMember<RuleSet> m_watchedSelectorsRules;
TreeBoundaryCrossingRules m_treeBoundaryCrossingRules; DocumentOrderedList m_treeBoundaryCrossingScopes;
bool m_needCollectFeatures; bool m_needCollectFeatures;
bool m_printMediaType; bool m_printMediaType;
......
...@@ -50,10 +50,14 @@ public: ...@@ -50,10 +50,14 @@ public:
size_t size() const { return m_nodes.size(); } size_t size() const { return m_nodes.size(); }
using iterator = WillBeHeapListHashSet<RawPtrWillBeMember<Node>, 32>::iterator; using iterator = WillBeHeapListHashSet<RawPtrWillBeMember<Node>, 32>::iterator;
using const_reverse_iterator = WillBeHeapListHashSet<RawPtrWillBeMember<Node>, 32>::const_reverse_iterator;
iterator begin() { return m_nodes.begin(); } iterator begin() { return m_nodes.begin(); }
iterator end() { return m_nodes.end(); } iterator end() { return m_nodes.end(); }
const_reverse_iterator rbegin() const { return m_nodes.rbegin(); }
const_reverse_iterator rend() const { return m_nodes.rend(); }
DECLARE_TRACE(); DECLARE_TRACE();
private: private:
......
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