Chromium Code Reviews| Index: Source/core/css/resolver/MatchResult.h |
| diff --git a/Source/core/css/resolver/MatchResult.h b/Source/core/css/resolver/MatchResult.h |
| index 8170d451d5f000a2093d6543a17758d4515bea2c..f87836c7874fa7a401c975d953dbeadf47a1b2fd 100644 |
| --- a/Source/core/css/resolver/MatchResult.h |
| +++ b/Source/core/css/resolver/MatchResult.h |
| @@ -59,21 +59,94 @@ WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::MatchedProperties); |
| namespace blink { |
| +using MatchedPropertiesVector = WillBeHeapVector<MatchedProperties, 64>; |
| + |
| +// 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; } |
| + |
| +private: |
| + MatchedPropertiesVector::const_iterator m_begin; |
| + MatchedPropertiesVector::const_iterator m_end; |
| +}; |
| + |
| class MatchResult { |
| STACK_ALLOCATED(); |
| public: |
| void addMatchedProperties(const StylePropertySet* properties, unsigned linkMatchType = CSSSelector::MatchAll, PropertyWhitelistType = PropertyWhitelistNone); |
| + bool hasMatchedProperties() const { return m_matchedProperties.size(); } |
| + |
| + void uaRulesFinished(); |
|
kochi
2015/08/11 11:07:35
It sounds a bit strange to have "Finished" suffix
rune
2015/08/12 01:13:26
Done.
|
| + void authorScopeFinished(); |
|
kochi
2015/08/11 11:07:35
Ditto, and why "Scope", not "Rules"?
What about f
rune
2015/08/12 01:13:26
Done.
|
| + |
| + 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_authorRangeEnd; |
|
kochi
2015/08/11 11:07:35
At first I was confused why m_uaRangeEnd is a scal
rune
2015/08/12 01:13:26
Done.
|
| + 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_authorRangeEnd[m_endIndex]; |
| + unsigned rangeBegin = m_endIndex ? m_result.m_authorRangeEnd[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; } |
| + |
| +private: |
| + const MatchResult& m_result; |
| + unsigned m_endIndex; |
| +}; |
| + |
| +class ImportantAuthorRanges { |
| +public: |
| + explicit ImportantAuthorRanges(const MatchResult& result) : m_result(result) { } |
| - unsigned begin() const { return 0; } |
| - 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(); } |
| + ImportantAuthorRangeIterator begin() const { return ImportantAuthorRangeIterator(m_result, m_result.m_authorRangeEnd.size() - 1); } |
| + ImportantAuthorRangeIterator end() const { return ImportantAuthorRangeIterator(m_result, -1); } |
| - WillBeHeapVector<MatchedProperties, 64> matchedProperties; |
| - unsigned uaEnd = 0; |
| - bool isCacheable = true; |
| +private: |
| + const MatchResult& m_result; |
| }; |
| inline bool operator==(const MatchedProperties& a, const MatchedProperties& b) |