Changeset 153641 in webkit


Ignore:
Timestamp:
Aug 2, 2013 2:15:43 AM (11 years ago)
Author:
akling@apple.com
Message:

Removing an empty style sheet shouldn't trigger style recalc.
<http://webkit.org/b/119248>
<rdar://problem/14629045>

Reviewed by Antti Koivisto.

Teach DocumentStyleSheetCollection to filter out empty style sheets when deciding whether
or not to trigger a style recalc. We can then be clever when an empty style sheet is removed
from the document, and avoid causing extra work.

Some pages use this pattern:

(1) Create a <style> element.
(2) Add it to the document's <head> element.
(3) Insert some CSS as a text child of the <style> element.

Since the <style> element is already inside the document at (3), we had to treat this as an
old style sheet being removed, even though it was just an empty sheet of nothing.

With this patch, Document gains enough smarts to know that removing/adding an empty sheet
won't affect layout/rendering in any meaningful way, thus a style recalc can be avoided.

  • dom/Document.h:
  • dom/Document.cpp:

(WebCore::Document::styleResolverChanged):

Add a DeferRecalcStyleIfNeeded mode to styleResolverChanged().

  • css/CSSStyleSheet.h:
  • css/CSSStyleSheet.cpp:

(WebCore::CSSStyleSheet::clearOwnerNode):

Use DeferRecalcStyleIfNeeded when saying bye from a CSSStyleSheet and let Document decide
if removing the sheet should trigger style recalc instead of always assuming it should.

  • dom/DocumentStyleSheetCollection.cpp:

(WebCore::filterEnabledNonemptyCSSStyleSheets):
(WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):

Exclude empty sheets from the activeAuthorStyleSheets() collection. They are still
visible through CSSOM's document.styleSheets.

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r153640 r153641  
     12013-08-01  Andreas Kling  <akling@apple.com>
     2
     3        Removing an empty style sheet shouldn't trigger style recalc.
     4        <http://webkit.org/b/119248>
     5        <rdar://problem/14629045>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Teach DocumentStyleSheetCollection to filter out empty style sheets when deciding whether
     10        or not to trigger a style recalc. We can then be clever when an empty style sheet is removed
     11        from the document, and avoid causing extra work.
     12
     13        Some pages use this pattern:
     14
     15            (1) Create a <style> element.
     16            (2) Add it to the document's <head> element.
     17            (3) Insert some CSS as a text child of the <style> element.
     18
     19        Since the <style> element is already inside the document at (3), we had to treat this as an
     20        old style sheet being removed, even though it was just an empty sheet of nothing.
     21
     22        With this patch, Document gains enough smarts to know that removing/adding an empty sheet
     23        won't affect layout/rendering in any meaningful way, thus a style recalc can be avoided.
     24
     25        * dom/Document.h:
     26        * dom/Document.cpp:
     27        (WebCore::Document::styleResolverChanged):
     28
     29            Add a DeferRecalcStyleIfNeeded mode to styleResolverChanged().
     30
     31        * css/CSSStyleSheet.h:
     32        * css/CSSStyleSheet.cpp:
     33        (WebCore::CSSStyleSheet::clearOwnerNode):
     34
     35            Use DeferRecalcStyleIfNeeded when saying bye from a CSSStyleSheet and let Document decide
     36            if removing the sheet should trigger style recalc instead of always assuming it should.
     37
     38        * dom/DocumentStyleSheetCollection.cpp:
     39        (WebCore::filterEnabledNonemptyCSSStyleSheets):
     40        (WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):
     41
     42            Exclude empty sheets from the activeAuthorStyleSheets() collection. They are still
     43            visible through CSSOM's document.styleSheets.
     44
    1452013-08-02  Zalan Bujtas  <zalan@apple.com>
    246
  • trunk/Source/WebCore/css/CSSStyleSheet.cpp

    r152353 r153641  
    164164}
    165165
     166void CSSStyleSheet::clearOwnerNode()
     167{
     168    Document* owner = ownerDocument();
     169    m_ownerNode = 0;
     170    if (!owner)
     171        return;
     172    owner->styleResolverChanged(DeferRecalcStyleIfNeeded);
     173}
     174
    166175void CSSStyleSheet::reattachChildRuleCSSOMWrappers()
    167176{
  • trunk/Source/WebCore/css/CSSStyleSheet.h

    r153566 r153641  
    7575    CSSRule* item(unsigned index);
    7676
    77     virtual void clearOwnerNode() OVERRIDE { didMutate(); m_ownerNode = 0; }
     77    virtual void clearOwnerNode() OVERRIDE;
    7878    virtual CSSImportRule* ownerRule() const OVERRIDE { return m_ownerRule; }
    7979    virtual KURL baseURL() const OVERRIDE;
  • trunk/Source/WebCore/dom/Document.cpp

    r153407 r153641  
    31563156#endif
    31573157
    3158     DocumentStyleSheetCollection::UpdateFlag styleSheetUpdate = (updateFlag == RecalcStyleIfNeeded)
     3158    DocumentStyleSheetCollection::UpdateFlag styleSheetUpdate = (updateFlag == RecalcStyleIfNeeded || updateFlag == DeferRecalcStyleIfNeeded)
    31593159        ? DocumentStyleSheetCollection::OptimizedUpdate
    31603160        : DocumentStyleSheetCollection::FullUpdate;
     
    31633163    if (updateFlag == DeferRecalcStyle) {
    31643164        scheduleForcedStyleRecalc();
     3165        return;
     3166    }
     3167
     3168    if (updateFlag == DeferRecalcStyleIfNeeded) {
     3169        if (stylesheetChangeRequiresStyleRecalc)
     3170            scheduleForcedStyleRecalc();
    31653171        return;
    31663172    }
  • trunk/Source/WebCore/dom/Document.h

    r151980 r153641  
    198198};
    199199
    200 enum StyleResolverUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle, RecalcStyleIfNeeded };
     200enum StyleResolverUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle, RecalcStyleIfNeeded, DeferRecalcStyleIfNeeded };
    201201
    202202enum NodeListInvalidationType {
  • trunk/Source/WebCore/dom/DocumentStyleSheetCollection.cpp

    r152290 r153641  
    428428}
    429429
    430 static void filterEnabledCSSStyleSheets(Vector<RefPtr<CSSStyleSheet> >& result, const Vector<RefPtr<StyleSheet> >& sheets)
     430static void filterEnabledNonemptyCSSStyleSheets(Vector<RefPtr<CSSStyleSheet> >& result, const Vector<RefPtr<StyleSheet> >& sheets)
    431431{
    432432    for (unsigned i = 0; i < sheets.size(); ++i) {
     
    435435        if (sheets[i]->disabled())
    436436            continue;
    437         result.append(static_cast<CSSStyleSheet*>(sheets[i].get()));
     437        CSSStyleSheet* sheet = static_cast<CSSStyleSheet*>(sheets[i].get());
     438        if (!sheet->length())
     439            continue;
     440        result.append(sheet);
    438441    }
    439442}
     
    468471    activeCSSStyleSheets.appendVector(documentAuthorStyleSheets());
    469472    collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, m_document);
    470     filterEnabledCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
     473    filterEnabledNonemptyCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
    471474
    472475    StyleResolverUpdateType styleResolverUpdateType;
Note: See TracChangeset for help on using the changeset viewer.