Changeset 182130 in webkit
- Timestamp:
- Mar 29, 2015 8:10:48 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r182125 r182130 1 2015-03-29 Benjamin Poulain <benjamin@webkit.org> 2 3 `currentColor` computes to the same colour on all elements, even if 'color' is inherited differently 4 https://bugs.webkit.org/show_bug.cgi?id=133420 5 6 Reviewed by Darin Adler. 7 8 * fast/css/currentColor-on-before-after-pseudo-elements-expected.html: Added. 9 * fast/css/currentColor-on-before-after-pseudo-elements.html: Added. 10 * fast/css/currentColor-style-update-reftest-expected.html: Added. 11 * fast/css/currentColor-style-update-reftest.html: Added. 12 * fast/css/currentColor-value-style-update-expected.txt: Added. 13 * fast/css/currentColor-value-style-update.html: Added. 14 1 15 2015-03-29 Darin Adler <darin@apple.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r182129 r182130 1 2015-03-29 Benjamin Poulain <benjamin@webkit.org> 2 3 `currentColor` computes to the same colour on all elements, even if 'color' is inherited differently 4 https://bugs.webkit.org/show_bug.cgi?id=133420 5 6 Reviewed by Darin Adler. 7 8 When resolving a style with the help of the property cache, we were 9 completely ignoring currentColor. 10 11 Since you can set currentColor on properties that are not inherited, 12 those properties would just be copied from the cached style, which 13 may have a completely different inherited color. 14 15 This pacth fixes the issue by preventing any MatchResult from hitting 16 the cache if it contains any non-inherited property that would require 17 resolution by the cache: 18 -Using the inherit value. 19 -Using the currentColor value. 20 21 Tests: fast/css/currentColor-on-before-after-pseudo-elements.html 22 fast/css/currentColor-style-update-reftest.html 23 fast/css/currentColor-value-style-update.html 24 25 * css/ElementRuleCollector.cpp: 26 (WebCore::ElementRuleCollector::addElementStyleProperties): 27 (WebCore::ElementRuleCollector::matchAuthorRules): 28 (WebCore::ElementRuleCollector::matchUserRules): 29 (WebCore::ElementRuleCollector::matchUARules): 30 * css/StyleResolver.cpp: 31 (WebCore::StyleResolver::MatchResult::addMatchedProperties): 32 (WebCore::StyleResolver::styleForKeyframe): 33 (WebCore::StyleResolver::pseudoStyleForElement): 34 (WebCore::StyleResolver::styleForPage): 35 (WebCore::StyleResolver::findFromMatchedPropertiesCache): 36 (WebCore::StyleResolver::addToMatchedPropertiesCache): 37 (WebCore::extractDirectionAndWritingMode): 38 (WebCore::StyleResolver::applyMatchedProperties): 39 (WebCore::StyleResolver::CascadedProperties::addStyleProperties): 40 (WebCore::StyleResolver::CascadedProperties::addMatches): 41 * css/StyleResolver.h: 42 (WebCore::StyleResolver::MatchResult::matchedProperties): 43 1 44 2015-03-29 Benjamin Poulain <benjamin@webkit.org> 2 45 -
trunk/Source/WebCore/css/ElementRuleCollector.cpp
r179132 r182130 105 105 if (!propertySet) 106 106 return; 107 m_result.ranges.lastAuthorRule = m_result.matchedProperties .size();107 m_result.ranges.lastAuthorRule = m_result.matchedProperties().size(); 108 108 if (m_result.ranges.firstAuthorRule == -1) 109 109 m_result.ranges.firstAuthorRule = m_result.ranges.lastAuthorRule; … … 221 221 { 222 222 clearMatchedRules(); 223 m_result.ranges.lastAuthorRule = m_result.matchedProperties .size() - 1;223 m_result.ranges.lastAuthorRule = m_result.matchedProperties().size() - 1; 224 224 225 225 // Match global author rules. … … 239 239 clearMatchedRules(); 240 240 241 m_result.ranges.lastUserRule = m_result.matchedProperties .size() - 1;241 m_result.ranges.lastUserRule = m_result.matchedProperties().size() - 1; 242 242 MatchRequest matchRequest(m_ruleSets.userStyle(), includeEmptyRules); 243 243 StyleResolver::RuleRange ruleRange = m_result.ranges.userRuleRange(); … … 268 268 clearMatchedRules(); 269 269 270 m_result.ranges.lastUARule = m_result.matchedProperties .size() - 1;270 m_result.ranges.lastUARule = m_result.matchedProperties().size() - 1; 271 271 StyleResolver::RuleRange ruleRange = m_result.ranges.UARuleRange(); 272 272 collectMatchingRules(MatchRequest(rules), ruleRange); -
trunk/Source/WebCore/css/StyleResolver.cpp
r182120 r182130 185 185 bool hasProperty(CSSPropertyID id) const; 186 186 Property& property(CSSPropertyID); 187 booladdMatches(const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly = false);187 void addMatches(const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly = false); 188 188 189 189 void set(CSSPropertyID, CSSValue&, unsigned linkMatchType); … … 193 193 194 194 private: 195 booladdStyleProperties(const StyleProperties&, StyleRule&, bool isImportant, bool inheritedOnly, PropertyWhitelistType, unsigned linkMatchType);195 void addStyleProperties(const StyleProperties&, StyleRule&, bool isImportant, bool inheritedOnly, PropertyWhitelistType, unsigned linkMatchType); 196 196 static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, unsigned linkMatchType); 197 197 … … 246 246 void StyleResolver::MatchResult::addMatchedProperties(const StyleProperties& properties, StyleRule* rule, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType) 247 247 { 248 m atchedProperties.grow(matchedProperties.size() + 1);249 StyleResolver::MatchedProperties& newProperties = m atchedProperties.last();248 m_matchedProperties.grow(m_matchedProperties.size() + 1); 249 StyleResolver::MatchedProperties& newProperties = m_matchedProperties.last(); 250 250 newProperties.properties = const_cast<StyleProperties*>(&properties); 251 251 newProperties.linkMatchType = linkMatchType; 252 252 newProperties.whitelistType = propertyWhitelistType; 253 253 matchedRules.append(rule); 254 255 if (isCacheable) { 256 for (unsigned i = 0, count = properties.propertyCount(); i < count; ++i) { 257 // Currently the property cache only copy the non-inherited values and resolve 258 // the inherited ones. 259 // Here we define some exception were we have to resolve some properties that are not inherited 260 // by default. If those exceptions become too common on the web, it should be possible 261 // to build a list of exception to resolve instead of completely disabling the cache. 262 263 StyleProperties::PropertyReference current = properties.propertyAt(i); 264 if (!current.isInherited()) { 265 // If the property value is explicitly inherited, we need to apply further non-inherited properties 266 // as they might override the value inherited here. For this reason we don't allow declarations with 267 // explicitly inherited properties to be cached. 268 const CSSValue& value = *current.value(); 269 if (value.isInheritedValue()) { 270 isCacheable = false; 271 break; 272 } 273 274 // The value currentColor has implicitely the same side effect. It depends on the value of color, 275 // which is an inherited value, making the non-inherited property implicitely inherited. 276 if (is<CSSPrimitiveValue>(value) && downcast<CSSPrimitiveValue>(value).getValueID() == CSSValueCurrentcolor) { 277 isCacheable = false; 278 break; 279 } 280 } 281 } 282 } 254 283 } 255 284 … … 836 865 // decl, there's nothing to override. So just add the first properties. 837 866 CascadedProperties cascade(direction, writingMode); 838 cascade.addMatches(result, false, 0, result.matchedProperties .size() - 1);867 cascade.addMatches(result, false, 0, result.matchedProperties().size() - 1); 839 868 840 869 applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty); … … 963 992 } 964 993 965 if (collector.matchedResult().matchedProperties .isEmpty())994 if (collector.matchedResult().matchedProperties().isEmpty()) 966 995 return 0; 967 996 … … 1002 1031 1003 1032 CascadedProperties cascade(direction, writingMode); 1004 cascade.addMatches(result, false, 0, result.matchedProperties .size() - 1);1033 cascade.addMatches(result, false, 0, result.matchedProperties().size() - 1); 1005 1034 1006 1035 applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty); … … 1611 1640 MatchedPropertiesCacheItem& cacheItem = it->value; 1612 1641 1613 size_t size = matchResult.matchedProperties .size();1642 size_t size = matchResult.matchedProperties().size(); 1614 1643 if (size != cacheItem.matchedProperties.size()) 1615 1644 return 0; 1616 1645 for (size_t i = 0; i < size; ++i) { 1617 if (matchResult.matchedProperties [i] != cacheItem.matchedProperties[i])1646 if (matchResult.matchedProperties()[i] != cacheItem.matchedProperties[i]) 1618 1647 return 0; 1619 1648 } … … 1634 1663 ASSERT(hash); 1635 1664 MatchedPropertiesCacheItem cacheItem; 1636 cacheItem.matchedProperties.appendVector(matchResult.matchedProperties );1665 cacheItem.matchedProperties.appendVector(matchResult.matchedProperties()); 1637 1666 cacheItem.ranges = matchResult.ranges; 1638 1667 // Note that we don't cache the original RenderStyle instance. It may be further modified. … … 1686 1715 bool hadImportantDirection = false; 1687 1716 1688 for ( auto& matchedProperties : matchResult.matchedProperties) {1717 for (const auto& matchedProperties : matchResult.matchedProperties()) { 1689 1718 for (unsigned i = 0, count = matchedProperties.properties->propertyCount(); i < count; ++i) { 1690 1719 auto property = matchedProperties.properties->propertyAt(i); … … 1715 1744 ASSERT(element); 1716 1745 State& state = m_state; 1717 unsigned cacheHash = shouldUseMatchedPropertiesCache && matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties .data(), matchResult.matchedProperties.size()) : 0;1746 unsigned cacheHash = shouldUseMatchedPropertiesCache && matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties().data(), matchResult.matchedProperties().size()) : 0; 1718 1747 bool applyInheritedOnly = false; 1719 1748 const MatchedPropertiesCacheItem* cacheItem = 0; … … 1749 1778 // can look at them later to figure out if this is a styled form control or not. 1750 1779 CascadedProperties cascade(direction, writingMode); 1751 if (!cascade.addMatches(matchResult, false, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly) 1752 || !cascade.addMatches(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly)) 1753 return applyMatchedProperties(matchResult, element, DoNotUseMatchedPropertiesCache); 1780 cascade.addMatches(matchResult, false, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly); 1781 cascade.addMatches(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly); 1754 1782 1755 1783 applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition); … … 1766 1794 1767 1795 CascadedProperties cascade(direction, writingMode); 1768 if (!cascade.addMatches(matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly) 1769 || !cascade.addMatches(matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly) 1770 || !cascade.addMatches(matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly) 1771 || !cascade.addMatches(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly)) 1772 return applyMatchedProperties(matchResult, element, DoNotUseMatchedPropertiesCache); 1796 cascade.addMatches(matchResult, false, 0, matchResult.matchedProperties().size() - 1, applyInheritedOnly); 1797 cascade.addMatches(matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly); 1798 cascade.addMatches(matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly); 1799 cascade.addMatches(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly); 1773 1800 1774 1801 applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition); … … 2624 2651 } 2625 2652 2626 boolStyleResolver::CascadedProperties::addStyleProperties(const StyleProperties& properties, StyleRule&, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType, unsigned linkMatchType)2653 void StyleResolver::CascadedProperties::addStyleProperties(const StyleProperties& properties, StyleRule&, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType, unsigned linkMatchType) 2627 2654 { 2628 2655 for (unsigned i = 0, count = properties.propertyCount(); i < count; ++i) { … … 2631 2658 continue; 2632 2659 if (inheritedOnly && !current.isInherited()) { 2633 // If the property value is explicitly inherited, we need to apply further non-inherited properties 2634 // as they might override the value inherited here. For this reason we don't allow declarations with 2635 // explicitly inherited properties to be cached. 2636 if (current.value()->isInheritedValue()) 2637 return false; 2660 // We apply the inherited properties only when using the property cache. 2661 // A match with a value that is explicitely inherited should never have been cached. 2662 ASSERT(!current.value()->isInheritedValue()); 2638 2663 continue; 2639 2664 } … … 2652 2677 set(propertyID, *current.value(), linkMatchType); 2653 2678 } 2654 return true; 2655 } 2656 2657 bool StyleResolver::CascadedProperties::addMatches(const MatchResult& matchResult, bool important, int startIndex, int endIndex, bool inheritedOnly) 2679 } 2680 2681 void StyleResolver::CascadedProperties::addMatches(const MatchResult& matchResult, bool important, int startIndex, int endIndex, bool inheritedOnly) 2658 2682 { 2659 2683 if (startIndex == -1) 2660 return true;2684 return; 2661 2685 2662 2686 for (int i = startIndex; i <= endIndex; ++i) { 2663 const MatchedProperties& matchedProperties = matchResult.matchedProperties[i]; 2664 if (!addStyleProperties(*matchedProperties.properties, *matchResult.matchedRules[i], important, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType), matchedProperties.linkMatchType)) 2665 return false; 2666 } 2667 return true; 2687 const MatchedProperties& matchedProperties = matchResult.matchedProperties()[i]; 2688 addStyleProperties(*matchedProperties.properties, *matchResult.matchedRules[i], important, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType), matchedProperties.linkMatchType); 2689 } 2668 2690 } 2669 2691 -
trunk/Source/WebCore/css/StyleResolver.h
r180051 r182130 278 278 struct MatchResult { 279 279 MatchResult() : isCacheable(true) { } 280 Vector<MatchedProperties, 64> matchedProperties;281 280 Vector<StyleRule*, 64> matchedRules; 282 281 MatchRanges ranges; 283 282 bool isCacheable; 284 283 285 void addMatchedProperties(const StyleProperties&, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone); 284 const Vector<MatchedProperties, 64>& matchedProperties() const { return m_matchedProperties; } 285 286 void addMatchedProperties(const StyleProperties&, StyleRule* = nullptr, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone); 287 private: 288 Vector<MatchedProperties, 64> m_matchedProperties; 286 289 }; 287 290
Note: See TracChangeset
for help on using the changeset viewer.