Changeset 137708 in webkit


Ignore:
Timestamp:
Dec 13, 2012 8:40:47 PM (11 years ago)
Author:
tasak@google.com
Message:

[Shadow DOM]: scoped styles are not applied in the cascade order.
https://bugs.webkit.org/show_bug.cgi?id=103239

Reviewed by Dimitri Glazkov.

Source/WebCore:

If the scoping elements of two declarations have an ancestor/
descendant relationship, the declaration whose scoping element is
the descendant should win.
c.f. http://dev.w3.org/csswg/css3-cascade/#cascade

Test: fast/css/style-scoped/style-scoped-nested.html

fast/css/style-scoped/style-scoped-with-important-rule.html

  • css/RuleSet.cpp:

(WebCore::RuleSet::addRule):
Removed specificity for @host @-rules. Now @host @-rules use the
cascading order instead.

  • css/RuleSet.h:

Removed increaseSpecificity. The method is used by only @host @-rules.

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::matchScopedAuthorRules):
(WebCore::StyleResolver::matchHostRules):
(WebCore::StyleResolver::matchAuthorRules):
Modified to invoke sortAndTransferMatchedRules per scoping element.
The order of "matchXXXRules" must be the same as the cascading order.
So matchHostRules was invoked after collecting all scoped author rules.

  • css/StyleScopeResolver.cpp:

(WebCore::StyleScopeResolver::addHostRule):
Removed RuleIsHostRule. We don't need the flag.

  • html/HTMLStyleElement.cpp:

(WebCore::HTMLStyleElement::registerWithScopingNode):
Needs to pass the last test case of style-scoped-nested.html.
When appending some style element to a shadow root, we should recalc
styles of all elements in the shadow dom tree. And if the style
element has @host @-rules, we have to update the host's style.

LayoutTests:

  • fast/css/style-scoped/style-scoped-nested-expected.txt: Added.
  • fast/css/style-scoped/style-scoped-nested.html: Added.
  • fast/css/style-scoped/style-scoped-with-important-rule-expected.txt: Added.
  • fast/css/style-scoped/style-scoped-with-important-rule.html: Added.
  • fast/regions/style-scoped-in-flow-override-region-styling-expected.html:
  • fast/regions/style-scoped-in-flow-override-region-styling.html:

Changed the test's expectation.
Since @region's scoping element is :root but scoped styles' scoping
element is a descendant element of :root, scoped styles should win.

Location:
trunk
Files:
4 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r137702 r137708  
     12012-12-13  Takashi Sakamoto  <tasak@google.com>
     2
     3        [Shadow DOM]: scoped styles are not applied in the cascade order.
     4        https://bugs.webkit.org/show_bug.cgi?id=103239
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        * fast/css/style-scoped/style-scoped-nested-expected.txt: Added.
     9        * fast/css/style-scoped/style-scoped-nested.html: Added.
     10        * fast/css/style-scoped/style-scoped-with-important-rule-expected.txt: Added.
     11        * fast/css/style-scoped/style-scoped-with-important-rule.html: Added.
     12        * fast/regions/style-scoped-in-flow-override-region-styling-expected.html:
     13        * fast/regions/style-scoped-in-flow-override-region-styling.html:
     14        Changed the test's expectation.
     15        Since @region's scoping element is :root but scoped styles' scoping
     16        element is a descendant element of :root, scoped styles should win.
     17
    1182012-12-13  Kentaro Hara  <haraken@chromium.org>
    219
  • trunk/LayoutTests/fast/regions/style-scoped-in-flow-override-region-styling-expected.html

    r112398 r137708  
    3333        <div class='container' id='r1'>
    3434                <p class='light'>Styled line of text</p>
    35                 <p class='lime'>Styled line of text</p>
    36                 <p class='green'>Styled line of text</p>
     35                <p class='light'>Styled line of text</p>
     36                <p class='light'>Styled line of text</p>
    3737        </div>
    3838        Partial overlap, &lt;style scoped&gt; more specific than @region (@region style has rule for &lt;p&gt;, scoped style has rules for class and id)
  • trunk/LayoutTests/fast/regions/style-scoped-in-flow-override-region-styling.html

    r112398 r137708  
    5151        @-webkit-region #r3 {
    5252                p {
    53                         background-color: lightgreen;
     53                        background-color: yellow;
    5454                }
    5555                .c3 {
    56                         background-color: lime;
     56                        background-color: orange;
    5757                }
    5858                #p3 {
    59                         background-color: green;
     59                        background-color: red;
    6060                }
    6161        }
     
    8888        <div id='f3'>
    8989                <style scoped='true'>
    90                         p {
    91                                 background-color: yellow;
    92                         }
    93                         .c3 {
    94                                 background-color: orange;
    95                         }
    96                         #p3 {
    97                                 background-color: red;
    98                         }
     90                        p {
     91                                background-color: lightgreen;
     92                        }
     93                        .c3 {
     94                                background-color: lime;
     95                        }
     96                        #p3 {
     97                                background-color: green;
     98                        }
    9999                </style>
    100100                <p>Styled line of text</p>
  • trunk/Source/WebCore/ChangeLog

    r137707 r137708  
     12012-12-13  Takashi Sakamoto  <tasak@google.com>
     2
     3        [Shadow DOM]: scoped styles are not applied in the cascade order.
     4        https://bugs.webkit.org/show_bug.cgi?id=103239
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        If the scoping elements of two declarations have an ancestor/
     9        descendant relationship, the declaration whose scoping element is
     10        the descendant should win.
     11        c.f. http://dev.w3.org/csswg/css3-cascade/#cascade
     12
     13        Test: fast/css/style-scoped/style-scoped-nested.html
     14              fast/css/style-scoped/style-scoped-with-important-rule.html
     15
     16        * css/RuleSet.cpp:
     17        (WebCore::RuleSet::addRule):
     18        Removed specificity for @host @-rules. Now @host @-rules use the
     19        cascading order instead.
     20        * css/RuleSet.h:
     21        Removed increaseSpecificity. The method is used by only @host @-rules.
     22        * css/StyleResolver.cpp:
     23        (WebCore::StyleResolver::matchScopedAuthorRules):
     24        (WebCore::StyleResolver::matchHostRules):
     25        (WebCore::StyleResolver::matchAuthorRules):
     26        Modified to invoke sortAndTransferMatchedRules per scoping element.
     27        The order of "matchXXXRules" must be the same as the cascading order.
     28        So matchHostRules was invoked after collecting all scoped author rules.
     29        * css/StyleScopeResolver.cpp:
     30        (WebCore::StyleScopeResolver::addHostRule):
     31        Removed RuleIsHostRule. We don't need the flag.
     32        * html/HTMLStyleElement.cpp:
     33        (WebCore::HTMLStyleElement::registerWithScopingNode):
     34        Needs to pass the last test case of style-scoped-nested.html.
     35        When appending some style element to a shadow root, we should recalc
     36        styles of all elements in the shadow dom tree. And if the style
     37        element has @host @-rules, we have to update the host's style.
     38
    1392012-12-13  Filip Pizlo  <fpizlo@apple.com>
    240
  • trunk/Source/WebCore/css/RuleSet.cpp

    r135163 r137708  
    192192{
    193193    RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags);
    194     static const unsigned athostRuleSpecificity = 0x100000;
    195 
    196     if (addRuleFlags & RuleIsHostRule)
    197         ruleData.increaseSpecificity(athostRuleSpecificity);
    198194
    199195    collectFeaturesFromRuleData(m_features, ruleData);
  • trunk/Source/WebCore/css/RuleSet.h

    r132618 r137708  
    3737    RuleCanUseFastCheckSelector   = 1 << 1,
    3838    RuleIsInRegionRule            = 1 << 2,
    39     RuleIsHostRule                = 1 << 3,
    4039};
    4140
     
    6463    bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; }
    6564    bool isInRegionRule() const { return m_isInRegionRule; }
    66     void increaseSpecificity(unsigned value) { m_specificity += value; }
    6765
    6866    // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance.
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r137478 r137708  
    727727        return;
    728728
     729    // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent).
     730    if (m_scopeResolver->hasScopedStyles() && m_scopeResolver->ensureStackConsistency(m_element)) {
     731        bool applyAuthorStyles = m_element->treeScope()->applyAuthorStyles();
     732        bool documentScope = true;
     733        unsigned scopeSize = m_scopeResolver->stackSize();
     734        for (unsigned i = 0; i < scopeSize; ++i) {
     735            m_matchedRules.clear();
     736            result.ranges.lastAuthorRule = result.matchedProperties.size() - 1;
     737
     738            const StyleScopeResolver::StackFrame& frame = m_scopeResolver->stackFrameAt(i);
     739            documentScope = documentScope && !frame.m_scope->isInShadowTree();
     740            if (documentScope) {
     741                if (!applyAuthorStyles)
     742                    continue;
     743            } else {
     744                if (!m_scopeResolver->matchesStyleBounds(frame))
     745                    continue;
     746            }
     747
     748            MatchOptions options(includeEmptyRules, frame.m_scope);
     749            collectMatchingRules(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
     750            collectMatchingRulesForRegion(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
     751            sortAndTransferMatchedRules(result);
     752        }
     753    }
     754
    729755    matchHostRules(result, includeEmptyRules);
    730 
    731     if (!m_scopeResolver->hasScopedStyles())
    732         return;
    733 
    734     // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent).
    735     if (!m_scopeResolver->ensureStackConsistency(m_element))
    736         return;
    737 
    738     bool applyAuthorStyles = m_element->treeScope()->applyAuthorStyles();
    739     bool documentScope = true;
    740     unsigned scopeSize = m_scopeResolver->stackSize();
    741     for (unsigned i = 0; i < scopeSize; ++i) {
    742         const StyleScopeResolver::StackFrame& frame = m_scopeResolver->stackFrameAt(i);
    743         documentScope = documentScope && !frame.m_scope->isInShadowTree();
    744         if (documentScope) {
    745             if (!applyAuthorStyles)
    746                 continue;
    747         } else {
    748             if (!m_scopeResolver->matchesStyleBounds(frame))
    749                 continue;
    750         }
    751            
    752         MatchOptions options(includeEmptyRules, frame.m_scope);
    753         collectMatchingRules(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
    754         collectMatchingRulesForRegion(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
    755     }
    756 
    757756#else
    758757    UNUSED_PARAM(result);
     
    775774    ASSERT(m_scopeResolver);
    776775
     776    m_matchedRules.clear();
     777    result.ranges.lastAuthorRule = result.matchedProperties.size() - 1;
     778
    777779    Vector<RuleSet*> matchedRules;
    778780    m_scopeResolver->matchHostRules(m_element, matchedRules);
     
    780782        return;
    781783
    782     MatchOptions options(includeEmptyRules);
    783     options.scope = m_element;
     784    MatchOptions options(includeEmptyRules, m_element);
    784785    for (unsigned i = matchedRules.size(); i > 0; --i)
    785786        collectMatchingRules(matchedRules.at(i-1), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
     787    sortAndTransferMatchedRules(result);
    786788#else
    787789    UNUSED_PARAM(result);
     
    802804    collectMatchingRules(m_authorStyle.get(), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
    803805    collectMatchingRulesForRegion(m_authorStyle.get(), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
     806    sortAndTransferMatchedRules(result);
    804807
    805808    matchScopedAuthorRules(result, includeEmptyRules);
    806 
    807     sortAndTransferMatchedRules(result);
    808809}
    809810
  • trunk/Source/WebCore/css/StyleScopeResolver.cpp

    r136924 r137708  
    184184    const Vector<RefPtr<StyleRuleBase> >& childRules = hostRule->childRules();
    185185    AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
    186     addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector | RuleIsHostRule);
     186    addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector);
    187187    for (unsigned i = 0; i < childRules.size(); ++i) {
    188188        StyleRuleBase* hostStylingRule = childRules[i].get();
  • trunk/Source/WebCore/html/HTMLStyleElement.cpp

    r136924 r137708  
    141141        return;
    142142    }
    143 
    144143    scope->registerScopedHTMLStyleChild();
    145     scope->setNeedsStyleRecalc();
     144    if (scope->isShadowRoot())
     145        scope->shadowHost()->setNeedsStyleRecalc();
     146    else
     147        scope->setNeedsStyleRecalc();
    146148    if (inDocument() && !document()->parsing() && document()->renderer())
    147149        document()->styleResolverChanged(DeferRecalcStyle);
Note: See TracChangeset for help on using the changeset viewer.