⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278346 in webkit


Ignore:
Timestamp:
Jun 2, 2021, 2:41:43 AM (5 years ago)
Author:
Antti Koivisto
Message:

REGRESSION(r276882): Style not invalidated correctly for media queries in shadow trees that share style
https://bugs.webkit.org/show_bug.cgi?id=226369
<rdar://problem/78684562>

Reviewed by Sam Weinig.

Source/WebCore:

Style resolvers are stateful in respect to media queries. We would only invalidate in the first shadow tree
because that evaluation flipped the state and the second evaluation would see nothing changing in media query
state.

  • style/StyleScope.cpp:

(WebCore::Style::Scope::collectResolverScopes):

Add a helper to collect all scopes associated with a resolver.

(WebCore::Style::Scope::evaluateMediaQueries):

Only evaluate each resolver once, then invalidate all associated scopes if needed.

  • style/StyleScope.h:

LayoutTests:

Expand the existing test to have multiple shadow trees sharing style.

  • fast/shadow-dom/media-query-in-shadow-style-expected.html:
  • fast/shadow-dom/media-query-in-shadow-style.html:
  • fast/shadow-dom/resources/media-query-in-shadow-style-frame.html:
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r278345 r278346  
     12021-06-02  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION(r276882): Style not invalidated correctly for media queries in shadow trees that share style
     4        https://bugs.webkit.org/show_bug.cgi?id=226369
     5        <rdar://problem/78684562>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Expand the existing test to have multiple shadow trees sharing style.
     10
     11        * fast/shadow-dom/media-query-in-shadow-style-expected.html:
     12        * fast/shadow-dom/media-query-in-shadow-style.html:
     13        * fast/shadow-dom/resources/media-query-in-shadow-style-frame.html:
     14
    1152021-06-02  Youenn Fablet  <youenn@apple.com>
    216
  • trunk/LayoutTests/fast/shadow-dom/media-query-in-shadow-style-expected.html

    r224864 r278346  
    1 <iframe src="data:text/html,<div style='color:red'>Text</div>" width=150 height=50></iframe><br>
    2 <iframe src="data:text/html,<div style='color:green;background-color: lightgrey'>Text</div>" width=300 height=50></iframe><br>
    3 <iframe src="data:text/html,<div style='color:red'>Text</div>" width=150 height=50></iframe><br>
    4 <iframe src="data:text/html,<div style='color:green;background-color: lightgrey'>Text</div>" width=300 height=50></iframe><br>
     1<iframe src="data:text/html,<div style='color:red'>First</div><div style='color:red'>Second</div>" width=150 height=100></iframe><br>
     2<iframe src="data:text/html,<div style='color:green;background-color: lightgrey'>First</div><div style='color:green;background-color: lightgrey'>Second</div>" width=300 height=100></iframe><br>
     3<iframe src="data:text/html,<div style='color:red'>First</div><div style='color:red'>Second</div>" width=150 height=100></iframe><br>
     4<iframe src="data:text/html,<div style='color:green;background-color: lightgrey'>First</div><div style='color:green;background-color: lightgrey'>Second</div>" width=300 height=100></iframe><br>
  • trunk/LayoutTests/fast/shadow-dom/media-query-in-shadow-style.html

    r224535 r278346  
    1 <iframe src=resources/media-query-in-shadow-style-frame.html width=150 height=50></iframe><br>
    2 <iframe src=resources/media-query-in-shadow-style-frame.html width=300 height=50></iframe><br>
    3 <iframe src=resources/media-query-in-shadow-style-frame.html width=300 height=50 onload='resize(event.target, 150)'></iframe><br>
    4 <iframe src=resources/media-query-in-shadow-style-frame.html width=150 height=50 onload='resize(event.target, 300)'></iframe><br>
     1<iframe src=resources/media-query-in-shadow-style-frame.html width=150 height=100></iframe><br>
     2<iframe src=resources/media-query-in-shadow-style-frame.html width=300 height=100></iframe><br>
     3<iframe src=resources/media-query-in-shadow-style-frame.html width=300 height=100 onload='resize(event.target, 150)'></iframe><br>
     4<iframe src=resources/media-query-in-shadow-style-frame.html width=150 height=100 onload='resize(event.target, 300)'></iframe><br>
    55<script>
    66if (window.testRunner)
  • trunk/LayoutTests/fast/shadow-dom/resources/media-query-in-shadow-style-frame.html

    r224864 r278346  
    1 <div id=test><span>Text</span></div>
     1<div class=test><span>First</span></div>
     2<div class=test><span>Second</span></div>
    23<script>
    3 const shadow = test.attachShadow({mode: 'open'});
    4 shadow.innerHTML = `
    5     <style>
    6     @media (min-width:200px) {
    7         div { color: green }
    8         :host { background-color: lightgrey }
    9     }
    10     @media (max-width:200px) {
    11         ::slotted(*) { color: red }
    12     }
    13     </style>
    14     <div><slot></slot></div>
    15 `;
     4for (test of document.querySelectorAll('.test')) {
     5    const shadow = test.attachShadow({mode: 'open'});
     6    shadow.innerHTML = `
     7        <style>
     8        @media (min-width:200px) {
     9            div { color: green }
     10            :host { background-color: lightgrey }
     11        }
     12        @media (max-width:200px) {
     13            ::slotted(*) { color: red }
     14        }
     15        </style>
     16        <div><slot></slot></div>
     17    `;
     18}
    1619</script>
  • trunk/Source/WebCore/ChangeLog

    r278343 r278346  
     12021-06-02  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION(r276882): Style not invalidated correctly for media queries in shadow trees that share style
     4        https://bugs.webkit.org/show_bug.cgi?id=226369
     5        <rdar://problem/78684562>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Style resolvers are stateful in respect to media queries. We would only invalidate in the first shadow tree
     10        because that evaluation flipped the state and the second evaluation would see nothing changing in media query
     11        state.
     12
     13        * style/StyleScope.cpp:
     14        (WebCore::Style::Scope::collectResolverScopes):
     15
     16        Add a helper to collect all scopes associated with a resolver.
     17
     18        (WebCore::Style::Scope::evaluateMediaQueries):
     19
     20        Only evaluate each resolver once, then invalidate all associated scopes if needed.
     21
     22        * style/StyleScope.h:
     23
    1242021-05-28  Antoine Quint  <graouts@webkit.org>
    225
  • trunk/Source/WebCore/style/StyleScope.cpp

    r276882 r278346  
    653653}
    654654
     655auto Scope::collectResolverScopes() -> ResolverScopes
     656{
     657    ASSERT(!m_shadowRoot);
     658
     659    if (!resolverIfExists())
     660        return { };
     661
     662    ResolverScopes resolverScopes;
     663
     664    resolverScopes.add(makeRef(*resolverIfExists()), Vector<WeakPtr<Scope>> { makeWeakPtr(*this) });
     665
     666    for (auto* shadowRoot : m_document.inDocumentShadowRoots()) {
     667        auto& scope = shadowRoot->styleScope();
     668        auto* resolver = scope.resolverIfExists();
     669        if (!resolver)
     670            continue;
     671        resolverScopes.add(makeRef(*resolver), Vector<WeakPtr<Scope>> { }).iterator->value.append(makeWeakPtr(scope));
     672    }
     673    return resolverScopes;
     674}
     675
    655676template <typename TestFunction>
    656677void Scope::evaluateMediaQueries(TestFunction&& testFunction)
    657678{
    658     auto* resolver = resolverIfExists();
    659     if (!resolver)
    660         return;
    661 
    662     auto evaluationChanges = testFunction(*resolver);
    663     if (evaluationChanges) {
    664         switch (evaluationChanges->type) {
    665         case DynamicMediaQueryEvaluationChanges::Type::InvalidateStyle: {
    666             Invalidator invalidator(evaluationChanges->invalidationRuleSets);
    667             invalidator.invalidateStyle(*this);
    668             break;
     679    bool hadChanges = false;
     680
     681    auto resolverScopes = collectResolverScopes();
     682    for (auto& [resolver, scopes] : resolverScopes) {
     683        auto evaluationChanges = testFunction(resolver.get());
     684        if (!evaluationChanges)
     685            continue;
     686        hadChanges = true;
     687
     688        for (auto& scope : scopes) {
     689            switch (evaluationChanges->type) {
     690            case DynamicMediaQueryEvaluationChanges::Type::InvalidateStyle: {
     691                Invalidator invalidator(evaluationChanges->invalidationRuleSets);
     692                invalidator.invalidateStyle(*scope);
     693                break;
     694            }
     695            case DynamicMediaQueryEvaluationChanges::Type::ResetStyle:
     696                scope->scheduleUpdate(UpdateType::ContentsOrInterpretation);
     697                break;
     698            }
    669699        }
    670         case DynamicMediaQueryEvaluationChanges::Type::ResetStyle:
    671             scheduleUpdate(UpdateType::ContentsOrInterpretation);
    672             break;
    673         }
    674 
     700    }
     701
     702    if (hadChanges)
    675703        InspectorInstrumentation::mediaQueryResultChanged(m_document);
    676     }
    677 
    678     if (!m_shadowRoot) {
    679         for (auto* descendantShadowRoot : m_document.inDocumentShadowRoots())
    680             descendantShadowRoot->styleScope().evaluateMediaQueries(testFunction);
    681     }
    682704}
    683705
  • trunk/Source/WebCore/style/StyleScope.h

    r278253 r278346  
    3636#include <wtf/RefPtr.h>
    3737#include <wtf/Vector.h>
     38#include <wtf/WeakPtr.h>
    3839#include <wtf/text/WTFString.h>
    3940
     
    5556class Resolver;
    5657
    57 class Scope {
     58class Scope : public CanMakeWeakPtr<Scope> {
    5859    WTF_MAKE_FAST_ALLOCATED;
    5960public:
     
    134135    void scheduleUpdate(UpdateType);
    135136
     137    using ResolverScopes = HashMap<Ref<Resolver>, Vector<WeakPtr<Scope>>>;
     138    ResolverScopes collectResolverScopes();
    136139    template <typename TestFunction> void evaluateMediaQueries(TestFunction&&);
    137140
Note: See TracChangeset for help on using the changeset viewer.