Commit fd4273ba authored by hans@chromium.org's avatar hans@chromium.org

Revert of Prepare for multiple !important author ranges. (patchset #11...

Revert of Prepare for multiple !important author ranges. (patchset #11 id:200001 of https://codereview.chromium.org/1282243002/ )

Reason for revert:
This caused oilpan plugin errors on Windows.
From http://build.chromium.org/p/chromium.fyi/builders/ClangToTWin/builds/2535/steps/compile/logs/stdio:

..\..\third_party\WebKit\Source\core/css/resolver/MatchResult.h(115,1) :  error: [blink-gc] Class 'ImportantAuthorRangeIterator' contains invalid fields.
class ImportantAuthorRangeIterator {
^
..\..\third_party\WebKit\Source\core/css/resolver/MatchResult.h(140,5) :  note: [blink-gc] Stack-allocated field 'm_result' declared here:
    const MatchResult& m_result;
    ^
..\..\third_party\WebKit\Source\core/css/resolver/MatchResult.h(144,1) :  error: [blink-gc] Class 'ImportantAuthorRanges' contains invalid fields.
class ImportantAuthorRanges {
^
..\..\third_party\WebKit\Source\core/css/resolver/MatchResult.h(152,5) :  note: [blink-gc] Stack-allocated field 'm_result' declared here:
    const MatchResult& m_result;
    ^

Original issue's description:
> Prepare for multiple !important author ranges.
> 
> This CL is split out from [1] where we support multiple author origins in
> terms of shadow dom scopes. The vector of MatchedProperties contains
> matched declarations from all origins in the order in which they should
> be applied. For !important declarations, they are applied in the same
> order within the same origin, but the order of the origins are different
> as the cascading order is:
> 
>   - UA important
>   - Author important
>   - Author
>   - UA
> 
> We used to have two ranges, one for UA and one for author to accomplish
> this. However, with the normal/!important cascading order for
> declarations from different shadow doms, we need multiple author ranges:
> 
>   - UA important
>   - Author important scope n
>   ...
>   - Author important scope 1
>   - Author scope 1
>   ...
>   - Author scope n
>   - UA
> 
> We introduce an ImportantAuthorRangeIterator to iterate through the
> author ranges and add iterator-style iteration for each range through the
> MatchedPropertiesRange class.
> 
> As the applyMatchedProperties code is hot, I've run the blink_perf.css
> tests locally. Some improved by 2-4%, some became worse by similar
> percentages.
> 
> [1] https://codereview.chromium.org/1224673002/
> 
> BUG=487125
> TEST=fast/css
> 
> Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=200697

TBR=kochi@chromium.org,timloh@chromium.org,rune@opera.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=487125

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

git-svn-id: svn://svn.chromium.org/blink/trunk@200728 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 947e42e0
...@@ -3746,7 +3746,6 @@ ...@@ -3746,7 +3746,6 @@
'css/parser/SizesAttributeParserTest.cpp', 'css/parser/SizesAttributeParserTest.cpp',
'css/parser/SizesCalcParserTest.cpp', 'css/parser/SizesCalcParserTest.cpp',
'css/resolver/FontBuilderTest.cpp', 'css/resolver/FontBuilderTest.cpp',
'css/resolver/MatchResultTest.cpp',
'dom/ActiveDOMObjectTest.cpp', 'dom/ActiveDOMObjectTest.cpp',
'dom/AttrTest.cpp', 'dom/AttrTest.cpp',
'dom/CrossThreadTaskTest.cpp', 'dom/CrossThreadTaskTest.cpp',
......
...@@ -110,7 +110,7 @@ void ElementRuleCollector::addElementStyleProperties(const StylePropertySet* pro ...@@ -110,7 +110,7 @@ void ElementRuleCollector::addElementStyleProperties(const StylePropertySet* pro
return; return;
m_result.addMatchedProperties(propertySet); m_result.addMatchedProperties(propertySet);
if (!isCacheable) if (!isCacheable)
m_result.setIsCacheable(false); m_result.isCacheable = false;
} }
static bool rulesApplicableInCurrentTreeScope(const Element* element, const ContainerNode* scopingNode, bool matchingTreeBoundaryRules) static bool rulesApplicableInCurrentTreeScope(const Element* element, const ContainerNode* scopingNode, bool matchingTreeBoundaryRules)
...@@ -293,6 +293,9 @@ void ElementRuleCollector::sortAndTransferMatchedRules() ...@@ -293,6 +293,9 @@ void ElementRuleCollector::sortAndTransferMatchedRules()
const RuleData* ruleData = m_matchedRules[i].ruleData(); const RuleData* ruleData = m_matchedRules[i].ruleData();
m_result.addMatchedProperties(&ruleData->rule()->properties(), ruleData->linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules)); m_result.addMatchedProperties(&ruleData->rule()->properties(), ruleData->linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules));
} }
if (m_matchingUARules)
m_result.uaEnd = m_result.matchedProperties.size();
} }
void ElementRuleCollector::didMatchRule(const RuleData& ruleData, const SelectorChecker::MatchResult& result, CascadeOrder cascadeOrder, const MatchRequest& matchRequest) void ElementRuleCollector::didMatchRule(const RuleData& ruleData, const SelectorChecker::MatchResult& result, CascadeOrder cascadeOrder, const MatchRequest& matchRequest)
......
...@@ -127,8 +127,6 @@ public: ...@@ -127,8 +127,6 @@ public:
void sortAndTransferMatchedRules(); void sortAndTransferMatchedRules();
void clearMatchedRules(); void clearMatchedRules();
void addElementStyleProperties(const StylePropertySet*, bool isCacheable = true); void addElementStyleProperties(const StylePropertySet*, bool isCacheable = true);
void finishAddingUARules() { m_result.finishAddingUARules(); }
void finishAddingAuthorRulesForTreeScope() { m_result.finishAddingAuthorRulesForTreeScope(); }
private: private:
template<typename RuleDataListType> template<typename RuleDataListType>
......
...@@ -50,26 +50,11 @@ DEFINE_TRACE(MatchedProperties) ...@@ -50,26 +50,11 @@ DEFINE_TRACE(MatchedProperties)
void MatchResult::addMatchedProperties(const StylePropertySet* properties, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType) void MatchResult::addMatchedProperties(const StylePropertySet* properties, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType)
{ {
m_matchedProperties.grow(m_matchedProperties.size() + 1); matchedProperties.grow(matchedProperties.size() + 1);
MatchedProperties& newProperties = m_matchedProperties.last(); MatchedProperties& newProperties = matchedProperties.last();
newProperties.properties = const_cast<StylePropertySet*>(properties); newProperties.properties = const_cast<StylePropertySet*>(properties);
newProperties.m_types.linkMatchType = linkMatchType; newProperties.m_types.linkMatchType = linkMatchType;
newProperties.m_types.whitelistType = propertyWhitelistType; newProperties.m_types.whitelistType = propertyWhitelistType;
} }
void MatchResult::finishAddingUARules()
{
m_uaRangeEnd = m_matchedProperties.size();
}
void MatchResult::finishAddingAuthorRulesForTreeScope()
{
// Don't add empty ranges.
if (m_authorRangeEnds.isEmpty() && m_uaRangeEnd == m_matchedProperties.size())
return;
if (!m_authorRangeEnds.isEmpty() && m_authorRangeEnds.last() == m_matchedProperties.size())
return;
m_authorRangeEnds.append(m_matchedProperties.size());
}
} // namespace blink } // namespace blink
...@@ -33,7 +33,7 @@ namespace blink { ...@@ -33,7 +33,7 @@ namespace blink {
class StylePropertySet; class StylePropertySet;
struct CORE_EXPORT MatchedProperties { struct MatchedProperties {
ALLOW_ONLY_INLINE_ALLOCATION(); ALLOW_ONLY_INLINE_ALLOCATION();
public: public:
MatchedProperties(); MatchedProperties();
...@@ -59,97 +59,21 @@ WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedProperties); ...@@ -59,97 +59,21 @@ WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedProperties);
namespace blink { namespace blink {
using MatchedPropertiesVector = WillBeHeapVector<MatchedProperties, 64>; class MatchResult {
// MatchedPropertiesRange is used to represent a subset of the matched properties from
// a given origin, for instance UA rules, author rules, or a shadow tree scope. This is
// needed because rules from different origins are applied in the opposite order for
// !important rules, yet in the same order as for normal rules within the same origin.
class MatchedPropertiesRange {
public:
MatchedPropertiesRange(MatchedPropertiesVector::const_iterator begin, MatchedPropertiesVector::const_iterator end)
: m_begin(begin)
, m_end(end)
{
}
MatchedPropertiesVector::const_iterator begin() const { return m_begin; }
MatchedPropertiesVector::const_iterator end() const { return m_end; }
bool isEmpty() const { return begin() == end(); }
private:
MatchedPropertiesVector::const_iterator m_begin;
MatchedPropertiesVector::const_iterator m_end;
};
class CORE_EXPORT MatchResult {
STACK_ALLOCATED(); STACK_ALLOCATED();
public: public:
void addMatchedProperties(const StylePropertySet* properties, unsigned linkMatchType = CSSSelector::MatchAll, PropertyWhitelistType = PropertyWhitelistNone); void addMatchedProperties(const StylePropertySet* properties, unsigned linkMatchType = CSSSelector::MatchAll, PropertyWhitelistType = PropertyWhitelistNone);
bool hasMatchedProperties() const { return m_matchedProperties.size(); }
void finishAddingUARules();
void finishAddingAuthorRulesForTreeScope();
void setIsCacheable(bool cacheable) { m_isCacheable = cacheable; }
bool isCacheable() const { return m_isCacheable; }
MatchedPropertiesRange allRules() const { return MatchedPropertiesRange(m_matchedProperties.begin(), m_matchedProperties.end()); }
MatchedPropertiesRange uaRules() const { return MatchedPropertiesRange(m_matchedProperties.begin(), m_matchedProperties.begin() + m_uaRangeEnd); }
MatchedPropertiesRange authorRules() const { return MatchedPropertiesRange(m_matchedProperties.begin() + m_uaRangeEnd, m_matchedProperties.end()); }
const MatchedPropertiesVector& matchedProperties() const { return m_matchedProperties; }
private:
friend class ImportantAuthorRanges;
friend class ImportantAuthorRangeIterator;
MatchedPropertiesVector m_matchedProperties;
Vector<unsigned, 16> m_authorRangeEnds;
unsigned m_uaRangeEnd = 0;
bool m_isCacheable = true;
};
class ImportantAuthorRangeIterator {
public:
ImportantAuthorRangeIterator(const MatchResult& result, int endIndex)
: m_result(result)
, m_endIndex(endIndex) { }
MatchedPropertiesRange operator*() const
{
ASSERT(m_endIndex >= 0);
unsigned rangeEnd = m_result.m_authorRangeEnds[m_endIndex];
unsigned rangeBegin = m_endIndex ? m_result.m_authorRangeEnds[m_endIndex - 1] : m_result.m_uaRangeEnd;
return MatchedPropertiesRange(m_result.matchedProperties().begin() + rangeBegin, m_result.matchedProperties().begin() + rangeEnd);
}
ImportantAuthorRangeIterator& operator++()
{
ASSERT(m_endIndex >= 0);
--m_endIndex;
return *this;
}
bool operator==(const ImportantAuthorRangeIterator& other) const { return m_endIndex == other.m_endIndex && &m_result == &other.m_result; }
bool operator!=(const ImportantAuthorRangeIterator& other) const { return !(*this == other); }
private:
const MatchResult& m_result;
unsigned m_endIndex;
};
class ImportantAuthorRanges {
public:
explicit ImportantAuthorRanges(const MatchResult& result) : m_result(result) { }
ImportantAuthorRangeIterator begin() const { return ImportantAuthorRangeIterator(m_result, m_result.m_authorRangeEnds.size() - 1); } unsigned begin() const { return 0; }
ImportantAuthorRangeIterator end() const { return ImportantAuthorRangeIterator(m_result, -1); } unsigned end() const { return matchedProperties.size(); }
unsigned beginUA() const { return 0; }
unsigned endUA() const { return uaEnd; }
unsigned beginAuthor() const { return uaEnd; }
unsigned endAuthor() const { return matchedProperties.size(); }
private: WillBeHeapVector<MatchedProperties, 64> matchedProperties;
const MatchResult& m_result; unsigned uaEnd = 0;
bool isCacheable = true;
}; };
inline bool operator==(const MatchedProperties& a, const MatchedProperties& b) inline bool operator==(const MatchedProperties& a, const MatchedProperties& b)
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/css/resolver/MatchResult.h"
#include "core/css/StylePropertySet.h"
#include <gtest/gtest.h>
namespace blink {
class MatchResultTest : public ::testing::Test {
protected:
void SetUp() override;
const StylePropertySet* propertySet(unsigned index) const
{
return propertySets[index].get();
}
private:
WillBePersistentHeapVector<RefPtrWillBeMember<MutableStylePropertySet>, 6> propertySets;
};
void MatchResultTest::SetUp()
{
for (unsigned i = 0; i < 6; i++)
propertySets.append(MutableStylePropertySet::create());
}
void testMatchedPropertiesRange(const MatchedPropertiesRange& range, int expectedLength, const StylePropertySet** expectedSets)
{
EXPECT_EQ(expectedLength, range.end() - range.begin());
for (const auto& matchedProperties : range)
EXPECT_EQ(*expectedSets++, matchedProperties.properties);
}
TEST_F(MatchResultTest, UARules)
{
const StylePropertySet* uaSets[] = { propertySet(0), propertySet(1) };
MatchResult result;
result.addMatchedProperties(uaSets[0]);
result.addMatchedProperties(uaSets[1]);
result.finishAddingUARules();
result.finishAddingAuthorRulesForTreeScope();
testMatchedPropertiesRange(result.allRules(), 2, uaSets);
testMatchedPropertiesRange(result.uaRules(), 2, uaSets);
testMatchedPropertiesRange(result.authorRules(), 0, nullptr);
ImportantAuthorRanges important(result);
EXPECT_EQ(important.end(), important.begin());
}
TEST_F(MatchResultTest, AuthorRules)
{
const StylePropertySet* authorSets[] = { propertySet(0), propertySet(1) };
MatchResult result;
result.finishAddingUARules();
result.addMatchedProperties(authorSets[0]);
result.addMatchedProperties(authorSets[1]);
result.finishAddingAuthorRulesForTreeScope();
testMatchedPropertiesRange(result.allRules(), 2, authorSets);
testMatchedPropertiesRange(result.uaRules(), 0, nullptr);
testMatchedPropertiesRange(result.authorRules(), 2, authorSets);
ImportantAuthorRanges important(result);
EXPECT_EQ(important.end(), ++important.begin());
}
TEST_F(MatchResultTest, UAAndAuthorRules)
{
const StylePropertySet* allSets[] = { propertySet(0), propertySet(1), propertySet(2), propertySet(3) };
const StylePropertySet** uaSets = &allSets[0];
const StylePropertySet** authorSets = &allSets[2];
MatchResult result;
result.addMatchedProperties(uaSets[0]);
result.addMatchedProperties(uaSets[1]);
result.finishAddingUARules();
result.addMatchedProperties(authorSets[0]);
result.addMatchedProperties(authorSets[1]);
result.finishAddingAuthorRulesForTreeScope();
testMatchedPropertiesRange(result.allRules(), 4, allSets);
testMatchedPropertiesRange(result.uaRules(), 2, uaSets);
testMatchedPropertiesRange(result.authorRules(), 2, authorSets);
ImportantAuthorRanges important(result);
EXPECT_EQ(important.end(), ++important.begin());
}
TEST_F(MatchResultTest, AuthorRulesMultipleScopes)
{
const StylePropertySet* authorSets[] = { propertySet(0), propertySet(1), propertySet(2), propertySet(3) };
MatchResult result;
result.finishAddingUARules();
result.addMatchedProperties(authorSets[0]);
result.addMatchedProperties(authorSets[1]);
result.finishAddingAuthorRulesForTreeScope();
result.addMatchedProperties(authorSets[2]);
result.addMatchedProperties(authorSets[3]);
result.finishAddingAuthorRulesForTreeScope();
testMatchedPropertiesRange(result.allRules(), 4, authorSets);
testMatchedPropertiesRange(result.uaRules(), 0, nullptr);
testMatchedPropertiesRange(result.authorRules(), 4, authorSets);
ImportantAuthorRanges important(result);
auto iter = important.begin();
EXPECT_NE(important.end(), iter);
testMatchedPropertiesRange(*iter, 2, &authorSets[2]);
++iter;
EXPECT_NE(important.end(), iter);
testMatchedPropertiesRange(*iter, 2, authorSets);
++iter;
EXPECT_EQ(important.end(), iter);
}
TEST_F(MatchResultTest, UARulesAndAuthorRulesMultipleScopes)
{
const StylePropertySet* allSets[] = { propertySet(0), propertySet(1), propertySet(2), propertySet(3), propertySet(4), propertySet(5) };
const StylePropertySet** uaSets = &allSets[0];
const StylePropertySet** authorSets = &allSets[2];
MatchResult result;
result.addMatchedProperties(uaSets[0]);
result.addMatchedProperties(uaSets[1]);
result.finishAddingUARules();
result.addMatchedProperties(authorSets[0]);
result.addMatchedProperties(authorSets[1]);
result.finishAddingAuthorRulesForTreeScope();
result.addMatchedProperties(authorSets[2]);
result.addMatchedProperties(authorSets[3]);
result.finishAddingAuthorRulesForTreeScope();
testMatchedPropertiesRange(result.allRules(), 6, allSets);
testMatchedPropertiesRange(result.uaRules(), 2, uaSets);
testMatchedPropertiesRange(result.authorRules(), 4, authorSets);
ImportantAuthorRanges important(result);
ImportantAuthorRangeIterator iter = important.begin();
EXPECT_NE(important.end(), iter);
testMatchedPropertiesRange(*iter, 2, &authorSets[2]);
++iter;
EXPECT_NE(important.end(), iter);
testMatchedPropertiesRange(*iter, 2, authorSets);
++iter;
EXPECT_EQ(important.end(), iter);
}
} // namespace blink
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
namespace blink { namespace blink {
void CachedMatchedProperties::set(const ComputedStyle& style, const ComputedStyle& parentStyle, const MatchedPropertiesVector& properties) void CachedMatchedProperties::set(const ComputedStyle& style, const ComputedStyle& parentStyle, const MatchResult& matchResult)
{ {
matchedProperties.appendVector(properties); matchedProperties.appendVector(matchResult.matchedProperties);
// Note that we don't cache the original ComputedStyle instance. It may be further modified. // Note that we don't cache the original ComputedStyle instance. It may be further modified.
// The ComputedStyle in the cache is really just a holder for the substructures and never used as-is. // The ComputedStyle in the cache is really just a holder for the substructures and never used as-is.
...@@ -60,7 +60,7 @@ MatchedPropertiesCache::MatchedPropertiesCache() ...@@ -60,7 +60,7 @@ MatchedPropertiesCache::MatchedPropertiesCache()
{ {
} }
const CachedMatchedProperties* MatchedPropertiesCache::find(unsigned hash, const StyleResolverState& styleResolverState, const MatchedPropertiesVector& properties) const CachedMatchedProperties* MatchedPropertiesCache::find(unsigned hash, const StyleResolverState& styleResolverState, const MatchResult& matchResult)
{ {
ASSERT(hash); ASSERT(hash);
...@@ -70,19 +70,19 @@ const CachedMatchedProperties* MatchedPropertiesCache::find(unsigned hash, const ...@@ -70,19 +70,19 @@ const CachedMatchedProperties* MatchedPropertiesCache::find(unsigned hash, const
CachedMatchedProperties* cacheItem = it->value.get(); CachedMatchedProperties* cacheItem = it->value.get();
ASSERT(cacheItem); ASSERT(cacheItem);
size_t size = properties.size(); size_t size = matchResult.matchedProperties.size();
if (size != cacheItem->matchedProperties.size()) if (size != cacheItem->matchedProperties.size())
return 0; return 0;
if (cacheItem->computedStyle->insideLink() != styleResolverState.style()->insideLink()) if (cacheItem->computedStyle->insideLink() != styleResolverState.style()->insideLink())
return 0; return 0;
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
if (properties[i] != cacheItem->matchedProperties[i]) if (matchResult.matchedProperties[i] != cacheItem->matchedProperties[i])
return 0; return 0;
} }
return cacheItem; return cacheItem;
} }
void MatchedPropertiesCache::add(const ComputedStyle& style, const ComputedStyle& parentStyle, unsigned hash, const MatchedPropertiesVector& properties) void MatchedPropertiesCache::add(const ComputedStyle& style, const ComputedStyle& parentStyle, unsigned hash, const MatchResult& matchResult)
{ {
#if !ENABLE(OILPAN) #if !ENABLE(OILPAN)
static const unsigned maxAdditionsBetweenSweeps = 100; static const unsigned maxAdditionsBetweenSweeps = 100;
...@@ -102,7 +102,7 @@ void MatchedPropertiesCache::add(const ComputedStyle& style, const ComputedStyle ...@@ -102,7 +102,7 @@ void MatchedPropertiesCache::add(const ComputedStyle& style, const ComputedStyle
if (!addResult.isNewEntry) if (!addResult.isNewEntry)
cacheItem->clear(); cacheItem->clear();
cacheItem->set(style, parentStyle, properties); cacheItem->set(style, parentStyle, matchResult);
} }
void MatchedPropertiesCache::clear() void MatchedPropertiesCache::clear()
......
...@@ -43,7 +43,7 @@ public: ...@@ -43,7 +43,7 @@ public:
RefPtr<ComputedStyle> computedStyle; RefPtr<ComputedStyle> computedStyle;
RefPtr<ComputedStyle> parentComputedStyle; RefPtr<ComputedStyle> parentComputedStyle;
void set(const ComputedStyle&, const ComputedStyle& parentStyle, const MatchedPropertiesVector&); void set(const ComputedStyle&, const ComputedStyle& parentStyle, const MatchResult&);
void clear(); void clear();
DEFINE_INLINE_TRACE() DEFINE_INLINE_TRACE()
{ {
...@@ -95,8 +95,8 @@ class MatchedPropertiesCache { ...@@ -95,8 +95,8 @@ class MatchedPropertiesCache {
public: public:
MatchedPropertiesCache(); MatchedPropertiesCache();
const CachedMatchedProperties* find(unsigned hash, const StyleResolverState&, const MatchedPropertiesVector&); const CachedMatchedProperties* find(unsigned hash, const StyleResolverState&, const MatchResult&);
void add(const ComputedStyle&, const ComputedStyle& parentStyle, unsigned hash, const MatchedPropertiesVector&); void add(const ComputedStyle&, const ComputedStyle& parentStyle, unsigned hash, const MatchResult&);
void clear(); void clear();
void clearViewportDependent(); void clearViewportDependent();
......
...@@ -413,7 +413,6 @@ void StyleResolver::matchUARules(ElementRuleCollector& collector) ...@@ -413,7 +413,6 @@ void StyleResolver::matchUARules(ElementRuleCollector& collector)
if (document().isViewSource()) if (document().isViewSource())
matchRuleSet(collector, defaultStyleSheets.defaultViewSourceStyle()); matchRuleSet(collector, defaultStyleSheets.defaultViewSourceStyle());
collector.finishAddingUARules();
collector.setMatchingUARules(false); collector.setMatchingUARules(false);
} }
...@@ -460,8 +459,6 @@ void StyleResolver::matchAllRules(StyleResolverState& state, ElementRuleCollecto ...@@ -460,8 +459,6 @@ void StyleResolver::matchAllRules(StyleResolverState& state, ElementRuleCollecto
if (includeSMILProperties && state.element()->isSVGElement()) if (includeSMILProperties && state.element()->isSVGElement())
collector.addElementStyleProperties(toSVGElement(state.element())->animatedSMILStyleProperties(), false /* isCacheable */); collector.addElementStyleProperties(toSVGElement(state.element())->animatedSMILStyleProperties(), false /* isCacheable */);
} }
collector.finishAddingAuthorRulesForTreeScope();
} }
PassRefPtr<ComputedStyle> StyleResolver::styleForDocument(Document& document) PassRefPtr<ComputedStyle> StyleResolver::styleForDocument(Document& document)
...@@ -759,9 +756,8 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo ...@@ -759,9 +756,8 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo
matchUARules(collector); matchUARules(collector);
matchAuthorRules(state.element(), collector, false); matchAuthorRules(state.element(), collector, false);
collector.finishAddingAuthorRulesForTreeScope();
if (!collector.matchedResult().hasMatchedProperties()) if (collector.matchedResult().matchedProperties.isEmpty())
return false; return false;
applyMatchedProperties(state, collector.matchedResult()); applyMatchedProperties(state, collector.matchedResult());
...@@ -834,12 +830,12 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex) ...@@ -834,12 +830,12 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex)
bool inheritedOnly = false; bool inheritedOnly = false;
const MatchResult& result = collector.matchedResult(); const MatchResult& result = collector.matchedResult();
applyMatchedProperties<HighPropertyPriority>(state, result.allRules(), false, inheritedOnly); applyMatchedProperties<HighPropertyPriority>(state, result, false, result.begin(), result.end(), inheritedOnly);
// If our font got dirtied, go ahead and update it now. // If our font got dirtied, go ahead and update it now.
updateFont(state); updateFont(state);
applyMatchedProperties<LowPropertyPriority>(state, result.allRules(), false, inheritedOnly); applyMatchedProperties<LowPropertyPriority>(state, result, false, result.begin(), result.end(), inheritedOnly);
loadPendingResources(state); loadPendingResources(state);
...@@ -1237,13 +1233,16 @@ void StyleResolver::applyProperties(StyleResolverState& state, const StyleProper ...@@ -1237,13 +1233,16 @@ void StyleResolver::applyProperties(StyleResolverState& state, const StyleProper
} }
template <CSSPropertyPriority priority> template <CSSPropertyPriority priority>
void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchedPropertiesRange& range, bool isImportant, bool inheritedOnly) void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchResult& matchResult, bool isImportant, unsigned startIndex, unsigned endIndex, bool inheritedOnly)
{ {
if (range.isEmpty()) if (startIndex == endIndex)
return; return;
ASSERT_WITH_SECURITY_IMPLICATION(endIndex <= matchResult.matchedProperties.size());
if (state.style()->insideLink() != NotInsideLink) { if (state.style()->insideLink() != NotInsideLink) {
for (const auto& matchedProperties : range) { for (unsigned i = startIndex; i < endIndex; ++i) {
const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
unsigned linkMatchType = matchedProperties.m_types.linkMatchType; unsigned linkMatchType = matchedProperties.m_types.linkMatchType;
// FIXME: It would be nicer to pass these as arguments but that requires changes in many places. // FIXME: It would be nicer to pass these as arguments but that requires changes in many places.
state.setApplyPropertyToRegularStyle(linkMatchType & CSSSelector::MatchLink); state.setApplyPropertyToRegularStyle(linkMatchType & CSSSelector::MatchLink);
...@@ -1255,8 +1254,10 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc ...@@ -1255,8 +1254,10 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
state.setApplyPropertyToVisitedLinkStyle(false); state.setApplyPropertyToVisitedLinkStyle(false);
return; return;
} }
for (const auto& matchedProperties : range) for (unsigned i = startIndex; i < endIndex; ++i) {
const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
applyProperties<priority>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType)); applyProperties<priority>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
}
} }
static unsigned computeMatchedPropertiesHash(const MatchedProperties* properties, unsigned size) static unsigned computeMatchedPropertiesHash(const MatchedProperties* properties, unsigned size)
...@@ -1282,9 +1283,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc ...@@ -1282,9 +1283,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply, 1); INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply, 1);
unsigned cacheHash = matchResult.isCacheable() ? computeMatchedPropertiesHash(matchResult.matchedProperties().data(), matchResult.matchedProperties().size()) : 0; unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0;
bool applyInheritedOnly = false; bool applyInheritedOnly = false;
const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_matchedPropertiesCache.find(cacheHash, state, matchResult.matchedProperties()) : 0; const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_matchedPropertiesCache.find(cacheHash, state, matchResult) : 0;
if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element, *state.style(), *state.parentStyle())) { if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element, *state.style(), *state.parentStyle())) {
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit, 1); INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit, 1);
...@@ -1315,10 +1316,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc ...@@ -1315,10 +1316,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
// high-priority properties first, i.e., those properties that other properties depend on. // high-priority properties first, i.e., those properties that other properties depend on.
// The order is (1) high-priority not important, (2) high-priority important, (3) normal not important // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
// and (4) normal important. // and (4) normal important.
applyMatchedProperties<HighPropertyPriority>(state, matchResult.allRules(), false, applyInheritedOnly); applyMatchedProperties<HighPropertyPriority>(state, matchResult, false, matchResult.begin(), matchResult.end(), applyInheritedOnly);
for (auto range : ImportantAuthorRanges(matchResult)) applyMatchedProperties<HighPropertyPriority>(state, matchResult, true, matchResult.beginAuthor(), matchResult.endAuthor(), applyInheritedOnly);
applyMatchedProperties<HighPropertyPriority>(state, range, true, applyInheritedOnly); applyMatchedProperties<HighPropertyPriority>(state, matchResult, true, matchResult.beginUA(), matchResult.endUA(), applyInheritedOnly);
applyMatchedProperties<HighPropertyPriority>(state, matchResult.uaRules(), true, applyInheritedOnly);
if (UNLIKELY(isSVGForeignObjectElement(element))) { if (UNLIKELY(isSVGForeignObjectElement(element))) {
// LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should not be scaled again. // LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should not be scaled again.
...@@ -1344,22 +1344,21 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc ...@@ -1344,22 +1344,21 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
applyInheritedOnly = false; applyInheritedOnly = false;
// Now do the normal priority UA properties. // Now do the normal priority UA properties.
applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), false, applyInheritedOnly); applyMatchedProperties<LowPropertyPriority>(state, matchResult, false, matchResult.beginUA(), matchResult.endUA(), applyInheritedOnly);
// Cache the UA properties to pass them to LayoutTheme in adjustComputedStyle. // Cache the UA properties to pass them to LayoutTheme in adjustComputedStyle.
state.cacheUserAgentBorderAndBackground(); state.cacheUserAgentBorderAndBackground();
// Now do the author and user normal priority properties and all the !important properties. // Now do the author and user normal priority properties and all the !important properties.
applyMatchedProperties<LowPropertyPriority>(state, matchResult.authorRules(), false, applyInheritedOnly); applyMatchedProperties<LowPropertyPriority>(state, matchResult, false, matchResult.beginAuthor(), matchResult.endAuthor(), applyInheritedOnly);
for (auto range : ImportantAuthorRanges(matchResult)) applyMatchedProperties<LowPropertyPriority>(state, matchResult, true, matchResult.beginAuthor(), matchResult.endAuthor(), applyInheritedOnly);
applyMatchedProperties<LowPropertyPriority>(state, range, true, applyInheritedOnly); applyMatchedProperties<LowPropertyPriority>(state, matchResult, true, matchResult.beginUA(), matchResult.endUA(), applyInheritedOnly);
applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), true, applyInheritedOnly);
loadPendingResources(state); loadPendingResources(state);
if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, *state.style(), *state.parentStyle())) { if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, *state.style(), *state.parentStyle())) {
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded, 1); INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded, 1);
m_matchedPropertiesCache.add(*state.style(), *state.parentStyle(), cacheHash, matchResult.matchedProperties()); m_matchedPropertiesCache.add(*state.style(), *state.parentStyle(), cacheHash, matchResult);
} }
ASSERT(!state.fontBuilder().fontDirty()); ASSERT(!state.fontBuilder().fontDirty());
......
...@@ -211,7 +211,7 @@ private: ...@@ -211,7 +211,7 @@ private:
void applyCallbackSelectors(StyleResolverState&); void applyCallbackSelectors(StyleResolverState&);
template <CSSPropertyPriority priority> template <CSSPropertyPriority priority>
void applyMatchedProperties(StyleResolverState&, const MatchedPropertiesRange&, bool important, bool inheritedOnly); void applyMatchedProperties(StyleResolverState&, const MatchResult&, bool important, unsigned startIndex, unsigned endIndex, bool inheritedOnly);
template <CSSPropertyPriority priority> template <CSSPropertyPriority priority>
void applyProperties(StyleResolverState&, const StylePropertySet* properties, bool isImportant, bool inheritedOnly, PropertyWhitelistType = PropertyWhitelistNone); void applyProperties(StyleResolverState&, const StylePropertySet* properties, bool isImportant, bool inheritedOnly, PropertyWhitelistType = PropertyWhitelistNone);
template <CSSPropertyPriority priority> template <CSSPropertyPriority priority>
......
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