Changeset 207669 in webkit


Ignore:
Timestamp:
Oct 21, 2016 6:36:45 AM (8 years ago)
Author:
Antti Koivisto
Message:

Style resolver should be updated lazily
https://bugs.webkit.org/show_bug.cgi?id=163721

Reviewed by Andreas Kling.

Currently when stylesheets change in some way we generally update style resolvers and
invalidate style immediately. We should do this lazily to avoid unnecessary work.

Also improve naming of the stylesheet invalidation functions and use more optimal functions in some places.

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::updateStyleIfNeededForNode):

  • css/CSSStyleSheet.cpp:

(WebCore::CSSStyleSheet::didMutateRules):
(WebCore::CSSStyleSheet::didMutate):
(WebCore::CSSStyleSheet::setDisabled):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::StyleResolver):

Initialize root style font with null font selector.
This avoids hitting a CSSFontSelector assert in fast/media/mq-relative-constraints-08.html where
media query evaluation requires font information before it is ready.
Exposed by increased laziness in this patch.

  • dom/Document.cpp:

(WebCore::Document::setContentLanguage):
(WebCore::Document::updateLayoutIgnorePendingStylesheets):
(WebCore::Document::isPageBoxVisible):
(WebCore::Document::pageSizeAndMarginsInPixels):
(WebCore::Document::processHttpEquiv):
(WebCore::Document::setSelectedStylesheetSet):
(WebCore::Document::didInsertInDocumentShadowRoot):
(WebCore::Document::didRemoveInDocumentShadowRoot):

  • dom/Document.h:

(WebCore::Document::inDocumentShadowRoots):

Track all shadow roots in the document. This allows us to find and flush style scopes cheaply.

  • dom/Element.cpp:

(WebCore::Element::computedStyle):

  • dom/ExtensionStyleSheets.cpp:

(WebCore::ExtensionStyleSheets::ExtensionStyleSheets):
(WebCore::ExtensionStyleSheets::clearPageUserSheet):
(WebCore::ExtensionStyleSheets::updatePageUserSheet):
(WebCore::ExtensionStyleSheets::invalidateInjectedStyleSheetCache):
(WebCore::ExtensionStyleSheets::addUserStyleSheet):
(WebCore::ExtensionStyleSheets::addAuthorStyleSheetForTesting):
(WebCore::ExtensionStyleSheets::addDisplayNoneSelector):
(WebCore::ExtensionStyleSheets::maybeAddContentExtensionSheet):
(WebCore::ExtensionStyleSheets::styleResolverChangedTimerFired): Deleted.

Since updates are now done lazily we don't need a special timer for extension stylesheets.

  • dom/ExtensionStyleSheets.h:
  • dom/ProcessingInstruction.cpp:

(WebCore::ProcessingInstruction::checkStyleSheet):
(WebCore::ProcessingInstruction::sheetLoaded):
(WebCore::ProcessingInstruction::removedFrom):

  • dom/ShadowRoot.cpp:

(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::insertedInto):
(WebCore::ShadowRoot::removedFrom):
(WebCore::ShadowRoot::styleScope):

  • dom/ShadowRoot.h:
  • html/HTMLLinkElement.cpp:

(WebCore::HTMLLinkElement::setDisabledState):
(WebCore::HTMLLinkElement::parseAttribute):
(WebCore::HTMLLinkElement::process):
(WebCore::HTMLLinkElement::removePendingSheet):

  • html/HTMLStyleElement.cpp:

(WebCore::HTMLStyleElement::parseAttribute):

  • inspector/InspectorCSSAgent.cpp:

(WebCore::InspectorCSSAgent::createInspectorStyleSheetForDocument):
(WebCore::InspectorCSSAgent::forcePseudoState):
(WebCore::InspectorCSSAgent::resetPseudoStates):

  • inspector/InspectorPageAgent.cpp:

(WebCore::InspectorPageAgent::setEmulatedMedia):

  • page/Frame.cpp:

(WebCore::Frame::setPrinting):

  • page/FrameView.cpp:

(WebCore::FrameView::layout):
(WebCore::FrameView::setPagination):
(WebCore::FrameView::setViewportSizeForCSSViewportUnits):

  • page/Page.cpp:

(WebCore::Page::setViewMode):
(WebCore::Page::setNeedsRecalcStyleInAllFrames):
(WebCore::Page::invalidateInjectedStyleSheetCacheInAllFrames):

  • style/StyleScope.cpp:

(WebCore::Style::Scope::setPreferredStylesheetSetName):
(WebCore::Style::Scope::setSelectedStylesheetSetName):
(WebCore::Style::Scope::removePendingSheet):
(WebCore::Style::Scope::removeStyleSheetCandidateNode):
(WebCore::Style::Scope::activeStyleSheetsForInspector):
(WebCore::Style::Scope::flushPendingUpdate):

Also flush descendant shadow roots.

(WebCore::Style::Scope::scheduleUpdate):
(WebCore::Style::Scope::didChangeActiveStyleSheetCandidates):

Make lazy.

(WebCore::Style::Scope::didChangeStyleSheetContents):

Make lazy.

(WebCore::Style::Scope::didChangeStyleSheetEnvironment):

Environment changes also affect author shadow roots.

(WebCore::Style::Scope::styleSheetsForStyleSheetList):
(WebCore::Style::Scope::scheduleActiveSetUpdate): Deleted.
(WebCore::Style::Scope::didChangeCandidatesForActiveSet): Deleted.
(WebCore::Style::Scope::didChangeContentsOrInterpretation): Deleted.

Improved naming of these and split didChangeContentsOrInterpretation into two separate functions.

  • style/StyleScope.h:

(WebCore::Style::Scope::styleSheetsForStyleSheetList): Deleted.
(WebCore::Style::Scope::setPreferredStylesheetSetName): Deleted.
(WebCore::Style::Scope::setSelectedStylesheetSetName): Deleted.

  • svg/SVGFontFaceElement.cpp:

(WebCore::SVGFontFaceElement::rebuildFontFace):
(WebCore::SVGFontFaceElement::removedFrom):

  • testing/Internals.cpp:

(WebCore::Internals::resetToConsistentState):

Ensure that cationsStyleSheetOverride really becomes empty. Some tests rely on not having suprise
inserted stylesheets. Previously this was racy and the patch affected order of things.

(WebCore::Internals::styleChangeType):

  • xml/XMLTreeViewer.cpp:

(WebCore::XMLTreeViewer::transformDocumentToTreeView):

  • xml/parser/XMLDocumentParser.cpp:

(WebCore::XMLDocumentParser::end):

  • xml/parser/XMLDocumentParserLibxml2.cpp:

(WebCore::XMLDocumentParser::doEnd):

Location:
trunk/Source
Files:
29 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207667 r207669  
     12016-10-21  Antti Koivisto  <antti@apple.com>
     2
     3        Style resolver should be updated lazily
     4        https://bugs.webkit.org/show_bug.cgi?id=163721
     5
     6        Reviewed by Andreas Kling.
     7
     8        Currently when stylesheets change in some way we generally update style resolvers and
     9        invalidate style immediately. We should do this lazily to avoid unnecessary work.
     10
     11        Also improve naming of the stylesheet invalidation functions and use more optimal functions in some places.
     12
     13        * css/CSSComputedStyleDeclaration.cpp:
     14        (WebCore::updateStyleIfNeededForNode):
     15        * css/CSSStyleSheet.cpp:
     16        (WebCore::CSSStyleSheet::didMutateRules):
     17        (WebCore::CSSStyleSheet::didMutate):
     18        (WebCore::CSSStyleSheet::setDisabled):
     19        * css/StyleResolver.cpp:
     20        (WebCore::StyleResolver::StyleResolver):
     21
     22            Initialize root style font with null font selector.
     23            This avoids hitting a CSSFontSelector assert in fast/media/mq-relative-constraints-08.html where
     24            media query evaluation requires font information before it is ready.
     25            Exposed by increased laziness in this patch.
     26
     27        * dom/Document.cpp:
     28        (WebCore::Document::setContentLanguage):
     29        (WebCore::Document::updateLayoutIgnorePendingStylesheets):
     30        (WebCore::Document::isPageBoxVisible):
     31        (WebCore::Document::pageSizeAndMarginsInPixels):
     32        (WebCore::Document::processHttpEquiv):
     33        (WebCore::Document::setSelectedStylesheetSet):
     34        (WebCore::Document::didInsertInDocumentShadowRoot):
     35        (WebCore::Document::didRemoveInDocumentShadowRoot):
     36        * dom/Document.h:
     37        (WebCore::Document::inDocumentShadowRoots):
     38
     39            Track all shadow roots in the document. This allows us to find and flush style scopes cheaply.
     40
     41        * dom/Element.cpp:
     42        (WebCore::Element::computedStyle):
     43        * dom/ExtensionStyleSheets.cpp:
     44        (WebCore::ExtensionStyleSheets::ExtensionStyleSheets):
     45        (WebCore::ExtensionStyleSheets::clearPageUserSheet):
     46        (WebCore::ExtensionStyleSheets::updatePageUserSheet):
     47        (WebCore::ExtensionStyleSheets::invalidateInjectedStyleSheetCache):
     48        (WebCore::ExtensionStyleSheets::addUserStyleSheet):
     49        (WebCore::ExtensionStyleSheets::addAuthorStyleSheetForTesting):
     50        (WebCore::ExtensionStyleSheets::addDisplayNoneSelector):
     51        (WebCore::ExtensionStyleSheets::maybeAddContentExtensionSheet):
     52        (WebCore::ExtensionStyleSheets::styleResolverChangedTimerFired): Deleted.
     53
     54            Since updates are now done lazily we don't need a special timer for extension stylesheets.
     55
     56        * dom/ExtensionStyleSheets.h:
     57        * dom/ProcessingInstruction.cpp:
     58        (WebCore::ProcessingInstruction::checkStyleSheet):
     59        (WebCore::ProcessingInstruction::sheetLoaded):
     60        (WebCore::ProcessingInstruction::removedFrom):
     61        * dom/ShadowRoot.cpp:
     62        (WebCore::ShadowRoot::ShadowRoot):
     63        (WebCore::ShadowRoot::insertedInto):
     64        (WebCore::ShadowRoot::removedFrom):
     65        (WebCore::ShadowRoot::styleScope):
     66        * dom/ShadowRoot.h:
     67        * html/HTMLLinkElement.cpp:
     68        (WebCore::HTMLLinkElement::setDisabledState):
     69        (WebCore::HTMLLinkElement::parseAttribute):
     70        (WebCore::HTMLLinkElement::process):
     71        (WebCore::HTMLLinkElement::removePendingSheet):
     72        * html/HTMLStyleElement.cpp:
     73        (WebCore::HTMLStyleElement::parseAttribute):
     74        * inspector/InspectorCSSAgent.cpp:
     75        (WebCore::InspectorCSSAgent::createInspectorStyleSheetForDocument):
     76        (WebCore::InspectorCSSAgent::forcePseudoState):
     77        (WebCore::InspectorCSSAgent::resetPseudoStates):
     78        * inspector/InspectorPageAgent.cpp:
     79        (WebCore::InspectorPageAgent::setEmulatedMedia):
     80        * page/Frame.cpp:
     81        (WebCore::Frame::setPrinting):
     82        * page/FrameView.cpp:
     83        (WebCore::FrameView::layout):
     84        (WebCore::FrameView::setPagination):
     85        (WebCore::FrameView::setViewportSizeForCSSViewportUnits):
     86        * page/Page.cpp:
     87        (WebCore::Page::setViewMode):
     88        (WebCore::Page::setNeedsRecalcStyleInAllFrames):
     89        (WebCore::Page::invalidateInjectedStyleSheetCacheInAllFrames):
     90        * style/StyleScope.cpp:
     91        (WebCore::Style::Scope::setPreferredStylesheetSetName):
     92        (WebCore::Style::Scope::setSelectedStylesheetSetName):
     93        (WebCore::Style::Scope::removePendingSheet):
     94        (WebCore::Style::Scope::removeStyleSheetCandidateNode):
     95        (WebCore::Style::Scope::activeStyleSheetsForInspector):
     96        (WebCore::Style::Scope::flushPendingUpdate):
     97
     98            Also flush descendant shadow roots.
     99
     100        (WebCore::Style::Scope::scheduleUpdate):
     101        (WebCore::Style::Scope::didChangeActiveStyleSheetCandidates):
     102
     103            Make lazy.
     104
     105        (WebCore::Style::Scope::didChangeStyleSheetContents):
     106
     107            Make lazy.
     108
     109        (WebCore::Style::Scope::didChangeStyleSheetEnvironment):
     110
     111            Environment changes also affect author shadow roots.
     112
     113        (WebCore::Style::Scope::styleSheetsForStyleSheetList):
     114        (WebCore::Style::Scope::scheduleActiveSetUpdate): Deleted.
     115        (WebCore::Style::Scope::didChangeCandidatesForActiveSet): Deleted.
     116        (WebCore::Style::Scope::didChangeContentsOrInterpretation): Deleted.
     117
     118            Improved naming of these and split didChangeContentsOrInterpretation into two separate functions.
     119
     120        * style/StyleScope.h:
     121        (WebCore::Style::Scope::styleSheetsForStyleSheetList): Deleted.
     122        (WebCore::Style::Scope::setPreferredStylesheetSetName): Deleted.
     123        (WebCore::Style::Scope::setSelectedStylesheetSetName): Deleted.
     124        * svg/SVGFontFaceElement.cpp:
     125        (WebCore::SVGFontFaceElement::rebuildFontFace):
     126        (WebCore::SVGFontFaceElement::removedFrom):
     127        * testing/Internals.cpp:
     128        (WebCore::Internals::resetToConsistentState):
     129
     130            Ensure that cationsStyleSheetOverride really becomes empty. Some tests rely on not having suprise
     131            inserted stylesheets. Previously this was racy and the patch affected order of things.
     132
     133        (WebCore::Internals::styleChangeType):
     134        * xml/XMLTreeViewer.cpp:
     135        (WebCore::XMLTreeViewer::transformDocumentToTreeView):
     136        * xml/parser/XMLDocumentParser.cpp:
     137        (WebCore::XMLDocumentParser::end):
     138        * xml/parser/XMLDocumentParserLibxml2.cpp:
     139        (WebCore::XMLDocumentParser::doEnd):
     140
    11412016-10-21  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Adam Bergkvist  <adam.bergkvist@ericsson.com>
    2142
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r207630 r207669  
    23552355}
    23562356
    2357 static inline bool updateStyleIfNeededForNode(const Node& node)
     2357static bool updateStyleIfNeededForNode(const Node& node)
    23582358{
    23592359    Document& document = node.document();
     2360
     2361    document.styleScope().flushPendingUpdate();
     2362
    23602363    if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
    23612364        return false;
  • trunk/Source/WebCore/css/CSSFontSelector.cpp

    r207396 r207669  
    281281FontRanges CSSFontSelector::fontRangesForFamily(const FontDescription& fontDescription, const AtomicString& familyName)
    282282{
    283     ASSERT(!m_buildIsUnderway); // If this ASSERT() fires, it usually means you forgot a document.updateStyleIfNeeded() somewhere.
     283    // If this ASSERT() fires, it usually means you forgot a document.updateStyleIfNeeded() somewhere.
     284    ASSERT(!m_buildIsUnderway || m_isComputingRootStyleFont);
    284285
    285286    // FIXME: The spec (and Firefox) says user specified generic families (sans-serif etc.) should be resolved before the @font-face lookup too.
  • trunk/Source/WebCore/css/CSSFontSelector.h

    r205093 r207669  
    8484    FontFaceSet& fontFaceSet();
    8585
     86    void setIsComputingRootStyleFont(bool value) { m_isComputingRootStyleFont = value; }
     87
    8688private:
    8789    explicit CSSFontSelector(Document&);
     
    113115    bool m_creatingFont { false };
    114116    bool m_buildIsUnderway { false };
     117    bool m_isComputingRootStyleFont { false };
    115118};
    116119
  • trunk/Source/WebCore/css/CSSStyleSheet.cpp

    r207396 r207669  
    181181            return;
    182182        }
    183         scope->scheduleActiveSetUpdate();
     183        scope->didChangeActiveStyleSheetCandidates();
    184184        return;
    185185    }
    186186
    187     scope->didChangeContentsOrInterpretation();
     187    scope->didChangeStyleSheetContents();
    188188
    189189    m_mutatedRules = true;
     
    195195    if (!scope)
    196196        return;
    197     scope->didChangeContentsOrInterpretation();
     197    scope->didChangeStyleSheetContents();
    198198}
    199199
     
    218218    m_isDisabled = disabled;
    219219
    220     didMutate();
     220    if (auto* scope = styleScope())
     221        scope->didChangeActiveStyleSheetCandidates();
    221222}
    222223
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r207539 r207669  
    269269        m_mediaQueryEvaluator = MediaQueryEvaluator { "all" };
    270270
    271     if (root)
     271    if (root) {
    272272        m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), MatchOnlyUserAgentRules).renderStyle;
     273        // Turn off assertion against font lookups during style resolver initialization. We may need root style font for media queries.
     274        m_document.fontSelector().setIsComputingRootStyleFont(true);
     275        m_rootDefaultStyle->fontCascade().update(&m_document.fontSelector());
     276        m_rootDefaultStyle->fontCascade().primaryFont();
     277        m_document.fontSelector().setIsComputingRootStyleFont(false);
     278    }
    273279
    274280    if (m_rootDefaultStyle && view)
  • trunk/Source/WebCore/dom/Document.cpp

    r207620 r207669  
    13571357
    13581358    // Recalculate style so language is used when selecting the initial font.
    1359     m_styleScope->didChangeContentsOrInterpretation();
     1359    m_styleScope->didChangeStyleSheetEnvironment();
    13601360}
    13611361
     
    19661966        if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
    19671967            m_pendingSheetLayout = DidLayoutWithPendingSheets;
    1968             styleScope().didChangeContentsOrInterpretation();
     1968            styleScope().didChangeActiveStyleSheetCandidates();
    19691969            recalcStyle(Style::Force);
    19701970        } else if (m_hasNodesWithPlaceholderStyle)
     
    21032103bool Document::isPageBoxVisible(int pageIndex)
    21042104{
     2105    updateStyleIfNeeded();
    21052106    std::unique_ptr<RenderStyle> pageStyle(styleScope().resolver().styleForPage(pageIndex));
    21062107    return pageStyle->visibility() != HIDDEN; // display property doesn't apply to @page.
     
    21092110void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
    21102111{
     2112    updateStyleIfNeeded();
    21112113    std::unique_ptr<RenderStyle> style = styleScope().resolver().styleForPage(pageIndex);
    21122114
     
    31623164        styleScope().setSelectedStylesheetSetName(content);
    31633165        styleScope().setPreferredStylesheetSetName(content);
    3164         styleScope().didChangeContentsOrInterpretation();
    31653166        break;
    31663167
     
    34723473{
    34733474    styleScope().setSelectedStylesheetSetName(aString);
    3474     styleScope().didChangeContentsOrInterpretation();
    34753475}
    34763476
     
    70447044}
    70457045
     7046void Document::didInsertInDocumentShadowRoot(ShadowRoot& shadowRoot)
     7047{
     7048    ASSERT(shadowRoot.inDocument());
     7049    m_inDocumentShadowRoots.add(&shadowRoot);
     7050}
     7051
     7052void Document::didRemoveInDocumentShadowRoot(ShadowRoot& shadowRoot)
     7053{
     7054    ASSERT(m_inDocumentShadowRoots.contains(&shadowRoot));
     7055    m_inDocumentShadowRoots.remove(&shadowRoot);
     7056}
     7057
    70467058} // namespace WebCore
  • trunk/Source/WebCore/dom/Document.h

    r207541 r207669  
    12971297    DOMSelection* getSelection();
    12981298
     1299    void didInsertInDocumentShadowRoot(ShadowRoot&);
     1300    void didRemoveInDocumentShadowRoot(ShadowRoot&);
     1301    const HashSet<ShadowRoot*>& inDocumentShadowRoots() const { return m_inDocumentShadowRoots; }
     1302
    12991303protected:
    13001304    enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     
    17381742    MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
    17391743
     1744    HashSet<ShadowRoot*> m_inDocumentShadowRoots;
     1745
    17401746#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    17411747    typedef HashMap<uint64_t, WebCore::MediaPlaybackTargetClient*> TargetIdToClientMap;
  • trunk/Source/WebCore/dom/Element.cpp

    r207544 r207669  
    27032703const RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
    27042704{
     2705    if (!inDocument())
     2706        return nullptr;
     2707
    27052708    if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(*this, pseudoElementSpecifier))
    27062709        return pseudoElement->computedStyle();
    27072710
    27082711    auto* style = existingComputedStyle();
    2709     if (!style) {
    2710         if (!inDocument())
    2711             return nullptr;
     2712    if (!style)
    27122713        style = &resolveComputedStyle();
    2713     }
    27142714
    27152715    if (pseudoElementSpecifier) {
  • trunk/Source/WebCore/dom/ExtensionStyleSheets.cpp

    r207339 r207669  
    5656ExtensionStyleSheets::ExtensionStyleSheets(Document& document)
    5757    : m_document(document)
    58     , m_styleResolverChangedTimer(*this, &ExtensionStyleSheets::styleResolverChangedTimerFired)
    5958{
    6059}
     
    9392    if (m_pageUserSheet) {
    9493        m_pageUserSheet = nullptr;
    95         m_document.styleScope().didChangeContentsOrInterpretation();
     94        m_document.styleScope().didChangeStyleSheetEnvironment();
    9695    }
    9796}
     
    101100    clearPageUserSheet();
    102101    if (pageUserSheet())
    103         m_document.styleScope().didChangeContentsOrInterpretation();
     102        m_document.styleScope().didChangeStyleSheetEnvironment();
    104103}
    105104
     
    155154void ExtensionStyleSheets::invalidateInjectedStyleSheetCache()
    156155{
    157     if (!m_injectedStyleSheetCacheValid)
    158         return;
    159156    m_injectedStyleSheetCacheValid = false;
    160     if (m_injectedUserStyleSheets.isEmpty() && m_injectedAuthorStyleSheets.isEmpty())
    161         return;
    162     m_document.styleScope().didChangeContentsOrInterpretation();
     157    m_document.styleScope().didChangeStyleSheetEnvironment();
    163158}
    164159
     
    167162    ASSERT(userSheet.get().isUserStyleSheet());
    168163    m_userStyleSheets.append(CSSStyleSheet::create(WTFMove(userSheet), m_document));
    169     m_document.styleScope().didChangeContentsOrInterpretation();
     164    m_document.styleScope().didChangeStyleSheetEnvironment();
    170165}
    171166
     
    174169    ASSERT(!authorSheet.get().isUserStyleSheet());
    175170    m_authorStyleSheetsForTesting.append(CSSStyleSheet::create(WTFMove(authorSheet), m_document));
    176     m_document.styleScope().didChangeContentsOrInterpretation();
     171    m_document.styleScope().didChangeStyleSheetEnvironment();
    177172}
    178173
     
    187182
    188183    if (result.iterator->value->addDisplayNoneSelector(selector, selectorID))
    189         m_styleResolverChangedTimer.startOneShot(0);
     184        m_document.styleScope().didChangeStyleSheetEnvironment();
    190185}
    191186
     
    200195    m_contentExtensionSheets.set(identifier, &cssSheet.get());
    201196    m_userStyleSheets.append(adoptRef(cssSheet.leakRef()));
    202     m_styleResolverChangedTimer.startOneShot(0);
     197    m_document.styleScope().didChangeStyleSheetEnvironment();
     198
    203199}
    204200#endif // ENABLE(CONTENT_EXTENSIONS)
    205 
    206 void ExtensionStyleSheets::styleResolverChangedTimerFired()
    207 {
    208     m_document.styleScope().didChangeContentsOrInterpretation();
    209 }
    210201
    211202void ExtensionStyleSheets::detachFromDocument()
  • trunk/Source/WebCore/dom/ExtensionStyleSheets.h

    r204466 r207669  
    7878
    7979private:
    80     void styleResolverChangedTimerFired();
    81 
    8280    Document& m_document;
    8381
     
    9593    HashMap<String, RefPtr<ContentExtensions::ContentExtensionStyleSheet>> m_contentExtensionSelectorSheets;
    9694#endif
    97 
    98     Timer m_styleResolverChangedTimer;
    9995};
    10096
  • trunk/Source/WebCore/dom/ProcessingInstruction.cpp

    r207053 r207669  
    157157                m_loading = false;
    158158                document().styleScope().removePendingSheet();
     159#if ENABLE(XSLT)
     160                if (m_isXSL)
     161                    document().styleScope().flushPendingUpdate();
     162#endif
    159163            }
    160164        }
     
    175179    if (!isLoading()) {
    176180        document().styleScope().removePendingSheet();
     181#if ENABLE(XSLT)
     182        if (m_isXSL)
     183            document().styleScope().flushPendingUpdate();
     184#endif
    177185        return true;
    178186    }
     
    273281    }
    274282
    275     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
    276     if (document().hasLivingRenderTree())
    277         document().styleScope().didChangeContentsOrInterpretation();
     283    document().styleScope().didChangeActiveStyleSheetCandidates();
    278284}
    279285
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r207458 r207669  
    5353    , TreeScope(*this, document)
    5454    , m_type(type)
     55    , m_styleScope(std::make_unique<Style::Scope>(*this))
    5556{
    5657}
     
    6162    , TreeScope(*this, document)
    6263    , m_type(Mode::UserAgent)
     64    , m_styleScope(std::make_unique<Style::Scope>(*this))
    6365    , m_slotAssignment(WTFMove(slotAssignment))
    6466{
     
    8082}
    8183
     84Node::InsertionNotificationRequest ShadowRoot::insertedInto(ContainerNode& insertionPoint)
     85{
     86    auto result = DocumentFragment::insertedInto(insertionPoint);
     87    if (inDocument())
     88        document().didInsertInDocumentShadowRoot(*this);
     89    return result;
     90}
     91
     92void ShadowRoot::removedFrom(ContainerNode& insertionPoint)
     93{
     94    if (inDocument())
     95        document().didRemoveInDocumentShadowRoot(*this);
     96    DocumentFragment::removedFrom(insertionPoint);
     97}
     98
    8299Style::Scope& ShadowRoot::styleScope()
    83100{
    84     if (!m_styleScope)
    85         m_styleScope = std::make_unique<Style::Scope>(*this);
    86101    return *m_styleScope;
    87102}
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r206951 r207669  
    105105    Ref<Node> cloneNodeInternal(Document&, CloningOperation) override;
    106106
     107    Node::InsertionNotificationRequest insertedInto(ContainerNode& insertionPoint) override;
     108    void removedFrom(ContainerNode& insertionPoint) override;
     109
    107110    bool m_resetStyleInheritance { false };
    108111    Mode m_type { Mode::UserAgent };
  • trunk/Source/WebCore/html/HTMLLinkElement.cpp

    r207458 r207669  
    141141            process();
    142142        else
    143             document().styleScope().didChangeContentsOrInterpretation();
     143            document().styleScope().didChangeActiveStyleSheetCandidates();
    144144    }
    145145}
     
    177177        process();
    178178        if (m_sheet && !isDisabled())
    179             document().styleScope().didChangeContentsOrInterpretation();
     179            document().styleScope().didChangeActiveStyleSheetCandidates();
    180180        return;
    181181    }
     
    284284        // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
    285285        clearSheet();
    286         document().styleScope().didChangeContentsOrInterpretation();
     286        document().styleScope().didChangeActiveStyleSheetCandidates();
    287287    }
    288288}
     
    558558    if (type == InactiveSheet) {
    559559        // Document just needs to know about the sheet for exposure through document.styleSheets
    560         document().styleScope().didChangeCandidatesForActiveSet();
     560        document().styleScope().didChangeActiveStyleSheetCandidates();
    561561        return;
    562562    }
  • trunk/Source/WebCore/html/HTMLStyleElement.cpp

    r206917 r207669  
    7878            sheet()->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(value));
    7979            if (auto* scope = m_styleSheetOwner.styleScope())
    80                 scope->didChangeContentsOrInterpretation();
     80                scope->didChangeStyleSheetContents();
    8181        } else
    8282            m_styleSheetOwner.childrenChanged(*this);
  • trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp

    r206917 r207669  
    798798    ExceptionCode ec = 0;
    799799    targetNode->appendChild(styleElement, ec);
     800    document.styleScope().flushPendingUpdate();
    800801    m_creatingViaInspectorStyleSheet = false;
    801802    if (ec)
     
    890891    else
    891892        m_nodeIdToForcedPseudoState.remove(nodeId);
    892     element->document().styleScope().didChangeContentsOrInterpretation();
     893    element->document().styleScope().didChangeStyleSheetEnvironment();
    893894}
    894895
     
    11901191    m_nodeIdToForcedPseudoState.clear();
    11911192    for (auto& document : documentsToChange)
    1192         document->styleScope().didChangeContentsOrInterpretation();
     1193        document->styleScope().didChangeStyleSheetEnvironment();
    11931194}
    11941195
  • trunk/Source/WebCore/inspector/InspectorPageAgent.cpp

    r206917 r207669  
    10031003    Document* document = m_page.mainFrame().document();
    10041004    if (document) {
    1005         document->styleScope().didChangeContentsOrInterpretation();
     1005        document->styleScope().didChangeStyleSheetEnvironment();
    10061006        document->updateLayout();
    10071007    }
  • trunk/Source/WebCore/page/Frame.cpp

    r207620 r207669  
    645645    view()->adjustMediaTypeForPrinting(printing);
    646646
    647     m_doc->styleScope().didChangeContentsOrInterpretation();
     647    m_doc->styleScope().didChangeStyleSheetEnvironment();
    648648    if (shouldUsePrintingLayout()) {
    649649        view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
  • trunk/Source/WebCore/page/FrameView.cpp

    r206951 r207669  
    13361336        if (!styleResolver || styleResolver->hasMediaQueriesAffectedByViewportChange()) {
    13371337            LOG(Layout, "  hasMediaQueriesAffectedByViewportChange, enqueueing style recalc");
    1338             document.styleScope().didChangeContentsOrInterpretation();
     1338            document.styleScope().didChangeStyleSheetEnvironment();
    13391339            // FIXME: This instrumentation event is not strictly accurate since cached media query results do not persist across StyleResolver rebuilds.
    13401340            InspectorInstrumentation::mediaQueryResultChanged(document);
     
    35333533    m_pagination = pagination;
    35343534
    3535     frame().document()->styleScope().didChangeContentsOrInterpretation();
     3535    frame().document()->styleScope().didChangeStyleSheetEnvironment();
    35363536}
    35373537
     
    49994999    m_hasOverrideViewportSize = true;
    50005000   
    5001     if (Document* document = frame().document()) {
    5002         // FIXME: this should probably be updateViewportUnitsOnResize(), but synchronously
    5003         // dirtying style here causes assertions on iOS (rdar://problem/19998166).
    5004         document->styleScope().didChangeContentsOrInterpretation();
    5005     }
     5001    if (Document* document = frame().document())
     5002        document->styleScope().didChangeStyleSheetEnvironment();
    50065003}
    50075004   
  • trunk/Source/WebCore/page/Page.cpp

    r207620 r207669  
    425425
    426426    if (m_mainFrame->document())
    427         m_mainFrame->document()->styleScope().didChangeContentsOrInterpretation();
     427        m_mainFrame->document()->styleScope().didChangeStyleSheetEnvironment();
    428428}
    429429#endif // ENABLE(VIEW_MODE_CSS_MEDIA)
     
    501501void Page::setNeedsRecalcStyleInAllFrames()
    502502{
     503    // FIXME: Figure out what this function is actually trying to add in different call sites.
    503504    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
    504505        if (Document* document = frame->document())
    505             document->styleScope().didChangeContentsOrInterpretation();
     506            document->styleScope().didChangeStyleSheetEnvironment();
    506507    }
    507508}
     
    11601161            continue;
    11611162        document->extensionStyleSheets().invalidateInjectedStyleSheetCache();
    1162         document->styleScope().didChangeContentsOrInterpretation();
    11631163    }
    11641164}
  • trunk/Source/WebCore/style/StyleScope.cpp

    r207458 r207669  
    7272}
    7373
     74Scope::~Scope()
     75{
     76}
     77
    7478bool Scope::shouldUseSharedUserAgentShadowTreeStyleResolver() const
    7579{
     
    121125}
    122126
     127void Scope::setPreferredStylesheetSetName(const String& name)
     128{
     129    if (m_preferredStylesheetSetName == name)
     130        return;
     131    m_preferredStylesheetSetName = name;
     132    didChangeActiveStyleSheetCandidates();
     133}
     134
     135void Scope::setSelectedStylesheetSetName(const String& name)
     136{
     137    if (m_selectedStylesheetSetName == name)
     138        return;
     139    m_selectedStylesheetSetName = name;
     140    didChangeActiveStyleSheetCandidates();
     141}
     142
    123143// This method is called whenever a top-level stylesheet has finished loading.
    124144void Scope::removePendingSheet(RemovePendingSheetNotificationType notification)
     
    142162    }
    143163
    144     didChangeCandidatesForActiveSet();
     164    didChangeActiveStyleSheetCandidates();
    145165
    146166    if (!m_shadowRoot)
     
    184204{
    185205    if (m_styleSheetCandidateNodes.remove(&node))
    186         scheduleActiveSetUpdate();
     206        didChangeActiveStyleSheetCandidates();
    187207}
    188208
     
    339359void Scope::updateActiveStyleSheets(UpdateType updateType)
    340360{
    341     ASSERT(!m_pendingUpdateType);
     361    ASSERT(!m_pendingUpdate);
     362
     363    if (!m_document.hasLivingRenderTree())
     364        return;
    342365
    343366    if (m_document.inStyleRecalc() || m_document.inRenderTreeUpdate()) {
     
    345368        // Crash stacks indicate we can get here when a resource load fails synchronously (for example due to content blocking).
    346369        // FIXME: These kind of cases should be eliminated and this path replaced by an assert.
    347         m_pendingUpdateType = UpdateType::ContentsOrInterpretation;
     370        m_pendingUpdate = UpdateType::ContentsOrInterpretation;
    348371        m_document.scheduleForcedStyleRecalc();
    349         return;
    350     }
    351 
    352     if (!m_document.hasLivingRenderTree()) {
    353         clearResolver();
    354372        return;
    355373    }
     
    419437}
    420438
    421 const Vector<RefPtr<CSSStyleSheet>> Scope::activeStyleSheetsForInspector() const
     439const Vector<RefPtr<CSSStyleSheet>> Scope::activeStyleSheetsForInspector()
    422440{
    423441    Vector<RefPtr<CSSStyleSheet>> result;
     
    452470void Scope::flushPendingUpdate()
    453471{
    454     if (!m_pendingUpdateType)
    455         return;
    456     auto updateType = *m_pendingUpdateType;
     472    if (!m_shadowRoot) {
     473        for (auto* descendantShadowRoot : m_document.inDocumentShadowRoots())
     474            descendantShadowRoot->styleScope().flushPendingUpdate();
     475    }
     476    if (!m_pendingUpdate)
     477        return;
     478    auto updateType = *m_pendingUpdate;
    457479
    458480    clearPendingUpdate();
     
    464486{
    465487    m_pendingUpdateTimer.stop();
    466     m_pendingUpdateType = { };
    467 }
    468 
    469 void Scope::scheduleActiveSetUpdate()
    470 {
    471     if (m_shadowRoot) {
    472         // FIXME: We need to flush updates recursively to support asynchronous updates in shadow trees.
    473         didChangeCandidatesForActiveSet();
    474         return;
    475     }
     488    m_pendingUpdate = { };
     489}
     490
     491void Scope::scheduleUpdate(UpdateType update)
     492{
     493    if (!m_pendingUpdate || *m_pendingUpdate < update)
     494        m_pendingUpdate = update;
     495
    476496    if (m_pendingUpdateTimer.isActive())
    477497        return;
    478     if (!m_pendingUpdateType)
    479         m_pendingUpdateType = UpdateType::ActiveSet;
    480498    m_pendingUpdateTimer.startOneShot(0);
    481499}
    482500
    483 void Scope::didChangeCandidatesForActiveSet()
    484 {
    485     auto updateType = m_pendingUpdateType.valueOr(UpdateType::ActiveSet);
    486     clearPendingUpdate();
    487     updateActiveStyleSheets(updateType);
    488 }
    489 
    490 void Scope::didChangeContentsOrInterpretation()
    491 {
    492     clearPendingUpdate();
    493     updateActiveStyleSheets(UpdateType::ContentsOrInterpretation);
     501void Scope::didChangeActiveStyleSheetCandidates()
     502{
     503    scheduleUpdate(UpdateType::ActiveSet);
     504}
     505
     506void Scope::didChangeStyleSheetContents()
     507{
     508    scheduleUpdate(UpdateType::ContentsOrInterpretation);
     509}
     510
     511void Scope::didChangeStyleSheetEnvironment()
     512{
     513    if (!m_shadowRoot) {
     514        for (auto* descendantShadowRoot : m_document.inDocumentShadowRoots()) {
     515            // Stylesheets is author shadow roots are are potentially affected.
     516            if (descendantShadowRoot->mode() != ShadowRoot::Mode::UserAgent)
     517                descendantShadowRoot->styleScope().scheduleUpdate(UpdateType::ContentsOrInterpretation);
     518        }
     519    }
     520    scheduleUpdate(UpdateType::ContentsOrInterpretation);
    494521}
    495522
     
    499526}
    500527
    501 }
    502 }
     528const Vector<RefPtr<StyleSheet>>& Scope::styleSheetsForStyleSheetList()
     529{
     530    // FIXME: StyleSheetList content should be updated separately from style resolver updates.
     531    flushPendingUpdate();
     532    return m_styleSheetsForStyleSheetList;
     533}
     534
     535}
     536}
  • trunk/Source/WebCore/style/StyleScope.h

    r207280 r207669  
    5757    explicit Scope(ShadowRoot&);
    5858
     59    ~Scope();
     60
    5961    const Vector<RefPtr<CSSStyleSheet>>& activeStyleSheets() const { return m_activeStyleSheets; }
    6062
    61     const Vector<RefPtr<StyleSheet>>& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
    62     const Vector<RefPtr<CSSStyleSheet>> activeStyleSheetsForInspector() const;
     63    const Vector<RefPtr<StyleSheet>>& styleSheetsForStyleSheetList();
     64    const Vector<RefPtr<CSSStyleSheet>> activeStyleSheetsForInspector();
    6365
    6466    void addStyleSheetCandidateNode(Node&, bool createdByParser);
     
    6769    String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
    6870    String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
    69     void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
    70     void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
     71    void setPreferredStylesheetSetName(const String&);
     72    void setSelectedStylesheetSetName(const String&);
    7173
    7274    void addPendingSheet() { m_pendingStyleSheetCount++; }
     
    8385    bool activeStyleSheetsContains(const CSSStyleSheet*) const;
    8486
    85     void didChangeCandidatesForActiveSet();
    86     void scheduleActiveSetUpdate();
    87     WEBCORE_EXPORT void didChangeContentsOrInterpretation();
     87    // This is called when some stylesheet becomes newly enabled or disabled.
     88    void didChangeActiveStyleSheetCandidates();
     89    // This is called when contents of a stylesheet is mutated.
     90    void didChangeStyleSheetContents();
     91    // This is called when the environment where we intrepret the stylesheets changes (for example switching to printing).
     92    // The change is assumed to potentially affect all author and user stylesheets including shadow roots.
     93    WEBCORE_EXPORT void didChangeStyleSheetEnvironment();
    8894
    89     bool hasPendingUpdate() const { return !!m_pendingUpdateType; }
    90     void flushPendingUpdate();
     95    bool hasPendingUpdate() const { return !!m_pendingUpdate; }
     96    WEBCORE_EXPORT void flushPendingUpdate();
    9197
    9298    StyleResolver& resolver();
     
    101107    enum class UpdateType { ActiveSet, ContentsOrInterpretation };
    102108    void updateActiveStyleSheets(UpdateType);
     109    void scheduleUpdate(UpdateType);
    103110
    104111    void collectActiveStyleSheets(Vector<RefPtr<StyleSheet>>&);
     
    134141    bool m_didUpdateActiveStyleSheets { false };
    135142
    136     Optional<UpdateType> m_pendingUpdateType;
     143    Optional<UpdateType> m_pendingUpdate;
    137144
    138145    ListHashSet<Node*> m_styleSheetCandidateNodes;
  • trunk/Source/WebCore/svg/SVGFontFaceElement.cpp

    r206917 r207669  
    268268    }
    269269
    270     document().styleScope().didChangeContentsOrInterpretation();
     270    document().styleScope().didChangeStyleSheetEnvironment();
    271271}
    272272
     
    293293        m_fontFaceRule->mutableProperties().clear();
    294294
    295         document().styleScope().didChangeContentsOrInterpretation();
     295        document().styleScope().didChangeStyleSheetEnvironment();
    296296    } else
    297297        ASSERT(!m_fontElement);
  • trunk/Source/WebCore/testing/Internals.cpp

    r207521 r207669  
    119119#include "SpellChecker.h"
    120120#include "StaticNodeList.h"
     121#include "StyleScope.h"
    121122#include "StyleSheetContents.h"
    122123#include "TextIterator.h"
     
    382383    WebCore::Settings::setUsesMockScrollAnimator(false);
    383384#if ENABLE(VIDEO_TRACK)
     385    page.group().captionPreferences().setTestingMode(true);
    384386    page.group().captionPreferences().setCaptionsStyleSheetOverride(emptyString());
    385387    page.group().captionPreferences().setTestingMode(false);
     
    502504String Internals::styleChangeType(Node& node)
    503505{
     506    node.document().styleScope().flushPendingUpdate();
     507
    504508    return styleValidityToToString(node.styleValidity());
    505509}
  • trunk/Source/WebCore/xml/XMLTreeViewer.cpp

    r206917 r207669  
    6565    auto text = m_document.createTextNode(cssString);
    6666    m_document.getElementById(String(ASCIILiteral("xml-viewer-style")))->appendChild(text, IGNORE_EXCEPTION);
    67     m_document.styleScope().didChangeContentsOrInterpretation();
     67    m_document.styleScope().didChangeActiveStyleSheetCandidates();
    6868}
    6969
  • trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp

    r206917 r207669  
    201201    else {
    202202        updateLeafTextNode();
    203         document()->styleScope().didChangeContentsOrInterpretation();
     203        document()->styleScope().didChangeActiveStyleSheetCandidates();
    204204    }
    205205
  • trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp

    r206917 r207669  
    13881388
    13891389        document()->setParsing(false); // Make the document think it's done, so it will apply XSL stylesheets.
    1390         document()->styleScope().didChangeContentsOrInterpretation();
     1390        document()->styleScope().didChangeActiveStyleSheetCandidates();
    13911391
    13921392        // styleResolverChanged() call can detach the parser and null out its document.
  • trunk/Source/WebKit/mac/WebView/WebHTMLView.mm

    r207483 r207669  
    36133613
    36143614    if (Frame* coreFrame = core([self _frame])) {
    3615         coreFrame->document()->styleScope().didChangeContentsOrInterpretation();
     3615        coreFrame->document()->styleScope().didChangeStyleSheetEnvironment();
    36163616        coreFrame->document()->updateStyleIfNeeded();
    36173617    }
     
    50255025            document->setPaginatedForScreen(_private->paginateScreenContent);
    50265026            document->setPrinting(_private->printing);
    5027             document->styleScope().didChangeContentsOrInterpretation();
     5027            document->styleScope().didChangeStyleSheetEnvironment();
    50285028        }
    50295029    }
Note: See TracChangeset for help on using the changeset viewer.