Title: [104445] trunk
Revision
104445
Author
[email protected]
Date
2012-01-09 02:00:51 -0800 (Mon, 09 Jan 2012)

Log Message

Subtree invalidation on stylesheet change
https://bugs.webkit.org/show_bug.cgi?id=75834

Source/WebCore: 

Reviewed by Andreas Kling.
        
Currently if we add a stylesheet with scoped selectors and matching scope elements exist,
we recalculate the entire document style. It is sufficient to invalidate the subtrees 
matching the scope only.
        
This allows us to do less full style recalcs on many popular web sites (nytimes.com for example).
Subtree recalcs are typically much cheaper.
        
Test: fast/css/id-or-class-before-stylesheet.html

* dom/Document.cpp:
(WebCore::Document::testAddedStylesheetRequiresStyleRecalc):
(WebCore::Document::analyzeStylesheetChange):
(WebCore::Document::updateActiveStylesheets):
* dom/Document.h:

LayoutTests: 

Reviewed by Andreas Kling.

* fast/css/id-or-class-before-stylesheet-expected.txt: Added.
* fast/css/id-or-class-before-stylesheet.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (104444 => 104445)


--- trunk/LayoutTests/ChangeLog	2012-01-09 09:53:28 UTC (rev 104444)
+++ trunk/LayoutTests/ChangeLog	2012-01-09 10:00:51 UTC (rev 104445)
@@ -1,3 +1,13 @@
+2012-01-09  Antti Koivisto  <[email protected]>
+
+        Subtree invalidation on stylesheet change
+        https://bugs.webkit.org/show_bug.cgi?id=75834
+
+        Reviewed by Andreas Kling.
+
+        * fast/css/id-or-class-before-stylesheet-expected.txt: Added.
+        * fast/css/id-or-class-before-stylesheet.html: Added.
+
 2012-01-09  Adam Barth  <[email protected]>
 
         insertAdjacentHTML doesn't play nice with DocumentFragment

Added: trunk/LayoutTests/fast/css/id-or-class-before-stylesheet-expected.txt (0 => 104445)


--- trunk/LayoutTests/fast/css/id-or-class-before-stylesheet-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/id-or-class-before-stylesheet-expected.txt	2012-01-09 10:00:51 UTC (rev 104445)
@@ -0,0 +1,12 @@
+Test that elements before inline stylesheets get their style updated properly
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.getComputedStyle(document.getElementById("testid")).backgroundColor is "rgb(0, 128, 0)"
+PASS window.getComputedStyle(document.getElementsByClassName("testclass")[0]).backgroundColor is "rgb(0, 128, 0)"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+id test
+class test

Added: trunk/LayoutTests/fast/css/id-or-class-before-stylesheet.html (0 => 104445)


--- trunk/LayoutTests/fast/css/id-or-class-before-stylesheet.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/id-or-class-before-stylesheet.html	2012-01-09 10:00:51 UTC (rev 104445)
@@ -0,0 +1,24 @@
+<html lang=en>
+<head>
+<script src=""
+<style>
+#testid { background-color: red; }
+.testclass { background-color: red; }
+</style>
+</head>
+<body>
+<div id=testid>id test</div>
+<style>
+#testid { background-color: green }
+</style>
+<div class=testclass>class test</div>
+<style>
+.testclass { background-color: green; }
+</style>
+<script>
+description("Test that elements before inline stylesheets get their style updated properly");
+shouldBe('window.getComputedStyle(document.getElementById("testid")).backgroundColor','"rgb(0, 128, 0)"');
+shouldBe('window.getComputedStyle(document.getElementsByClassName("testclass")[0]).backgroundColor','"rgb(0, 128, 0)"');
+</script>
+<script src=""
+</body>

Modified: trunk/Source/WebCore/ChangeLog (104444 => 104445)


--- trunk/Source/WebCore/ChangeLog	2012-01-09 09:53:28 UTC (rev 104444)
+++ trunk/Source/WebCore/ChangeLog	2012-01-09 10:00:51 UTC (rev 104445)
@@ -1,3 +1,25 @@
+2012-01-09  Antti Koivisto  <[email protected]>
+
+        Subtree invalidation on stylesheet change
+        https://bugs.webkit.org/show_bug.cgi?id=75834
+
+        Reviewed by Andreas Kling.
+        
+        Currently if we add a stylesheet with scoped selectors and matching scope elements exist,
+        we recalculate the entire document style. It is sufficient to invalidate the subtrees 
+        matching the scope only.
+        
+        This allows us to do less full style recalcs on many popular web sites (nytimes.com for example).
+        Subtree recalcs are typically much cheaper.
+        
+        Test: fast/css/id-or-class-before-stylesheet.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::testAddedStylesheetRequiresStyleRecalc):
+        (WebCore::Document::analyzeStylesheetChange):
+        (WebCore::Document::updateActiveStylesheets):
+        * dom/Document.h:
+
 2012-01-09  Carlos Garcia Campos  <[email protected]>
 
         Unreviewed. Fix make distcheck issues.

Modified: trunk/Source/WebCore/dom/Document.cpp (104444 => 104445)


--- trunk/Source/WebCore/dom/Document.cpp	2012-01-09 09:53:28 UTC (rev 104444)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-01-09 10:00:51 UTC (rev 104445)
@@ -3161,22 +3161,29 @@
         return true;
     HashSet<AtomicStringImpl*>::iterator end = idScopes.end();
     for (HashSet<AtomicStringImpl*>::iterator it = idScopes.begin(); it != end; ++it) {
-        if (hasElementWithId(*it))
+        AtomicStringImpl* id = *it;
+        Element* idElement = getElementById(id);
+        if (!idElement)
+            continue;
+        if (containsMultipleElementsWithId(id))
             return true;
+        idElement->setNeedsStyleRecalc();
     }
     end = classScopes.end();
     for (HashSet<AtomicStringImpl*>::iterator it = classScopes.begin(); it != end; ++it) {
         // FIXME: getElementsByClassName is not optimal for this. We should handle all classes in a single pass.
-        if (getElementsByClassName(*it)->length())
-            return true;
+        RefPtr<NodeList> classElements = getElementsByClassName(*it);
+        unsigned elementCount = classElements->length();
+        for (unsigned i = 0; i < elementCount; ++i)
+            classElements->item(i)->setNeedsStyleRecalc();
     }
     return false;
 }
     
-void Document::analyzeStylesheetChange(StyleSelectorUpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleSelectorReset, bool& requiresStyleRecalc)
+void Document::analyzeStylesheetChange(StyleSelectorUpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleSelectorReset, bool& requiresFullStyleRecalc)
 {
     requiresStyleSelectorReset = true;
-    requiresStyleRecalc = true;
+    requiresFullStyleRecalc = true;
     
     // Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
     bool hasActiveLoadingStylesheet = false;
@@ -3215,7 +3222,7 @@
         if (testAddedStylesheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(newStylesheets[i].get())))
             return;
     }
-    requiresStyleRecalc = false;
+    requiresFullStyleRecalc = false;
 }
 
 bool Document::updateActiveStylesheets(StyleSelectorUpdateFlag updateFlag)
@@ -3235,8 +3242,8 @@
     collectActiveStylesheets(newStylesheets);
 
     bool requiresStyleSelectorReset;
-    bool requiresStyleRecalc;
-    analyzeStylesheetChange(updateFlag, newStylesheets, requiresStyleSelectorReset, requiresStyleRecalc);
+    bool requiresFullStyleRecalc;
+    analyzeStylesheetChange(updateFlag, newStylesheets, requiresStyleSelectorReset, requiresFullStyleRecalc);
 
     if (requiresStyleSelectorReset)
         m_styleSelector.clear();
@@ -3249,7 +3256,7 @@
     m_didCalculateStyleSelector = true;
     m_hasDirtyStyleSelector = false;
     
-    return requiresStyleRecalc;
+    return requiresFullStyleRecalc;
 }
 
 void Document::setHoverNode(PassRefPtr<Node> newHoverNode)

Modified: trunk/Source/WebCore/dom/Document.h (104444 => 104445)


--- trunk/Source/WebCore/dom/Document.h	2012-01-09 09:53:28 UTC (rev 104444)
+++ trunk/Source/WebCore/dom/Document.h	2012-01-09 10:00:51 UTC (rev 104445)
@@ -1162,7 +1162,7 @@
     bool updateActiveStylesheets(StyleSelectorUpdateFlag);
     void collectActiveStylesheets(Vector<RefPtr<StyleSheet> >&);
     bool testAddedStylesheetRequiresStyleRecalc(CSSStyleSheet*);
-    void analyzeStylesheetChange(StyleSelectorUpdateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleSelectorReset, bool& requiresStyleRecalc);
+    void analyzeStylesheetChange(StyleSelectorUpdateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleSelectorReset, bool& requiresFullStyleRecalc);
 
     void deleteCustomFonts();
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to