Add test for class change style invalidation optimization
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Feb 2016 10:30:36 +0000 (10:30 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Feb 2016 10:30:36 +0000 (10:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154226

Reviewed by Myles Maxfield.

Test for https://trac.webkit.org/r196383

Source/WebCore:

Add internals.styleChangeType function.

Test: fast/css/style-invalidation-class-change-descendants.html

* testing/Internals.cpp:
(WebCore::Internals::nodeNeedsStyleRecalc):
(WebCore::asString):
(WebCore::Internals::styleChangeType):
(WebCore::Internals::description):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* fast/css/style-invalidation-class-change-descendants-expected.txt: Added.
* fast/css/style-invalidation-class-change-descendants.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196575 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css/style-invalidation-class-change-descendants-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/style-invalidation-class-change-descendants.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index d1d0612..59d9bb7 100644 (file)
@@ -1,3 +1,15 @@
+2016-02-14  Antti Koivisto  <antti@apple.com>
+
+        Add test for class change style invalidation optimization
+        https://bugs.webkit.org/show_bug.cgi?id=154226
+
+        Reviewed by Myles Maxfield.
+
+        Test for https://trac.webkit.org/r196383
+
+        * fast/css/style-invalidation-class-change-descendants-expected.txt: Added.
+        * fast/css/style-invalidation-class-change-descendants.html: Added.
+
 2016-02-15  Hunseop Jeong  <hs85.jeong@samsung.com>
 
         Unreviewed. EFL gardening. Mark more video tests to failure.
 2016-02-15  Hunseop Jeong  <hs85.jeong@samsung.com>
 
         Unreviewed. EFL gardening. Mark more video tests to failure.
diff --git a/LayoutTests/fast/css/style-invalidation-class-change-descendants-expected.txt b/LayoutTests/fast/css/style-invalidation-class-change-descendants-expected.txt
new file mode 100644 (file)
index 0000000..4dc860b
--- /dev/null
@@ -0,0 +1,57 @@
+Test that we invalidate the element subtree minimally on class attribute change
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS hasExpectedStyle is true
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "NoStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Adding class NotThere
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "NoStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+Adding class style1
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Adding class style2
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Removing class style2
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Adding class style3
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Removing class style3
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Adding class style4
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "NoStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Removing class NotThere
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "NoStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+Removing class style1
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/style-invalidation-class-change-descendants.html b/LayoutTests/fast/css/style-invalidation-class-change-descendants.html
new file mode 100644 (file)
index 0000000..607ef18
--- /dev/null
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+<style>
+* {
+    color: black;
+}
+root.style1 target {
+    color: rgb(1, 1, 1);
+}
+
+root.style2 > inert target {
+    color: rgb(2, 2, 2);
+}
+
+root.style3 inert + target {
+    color: rgb(3, 3, 3);
+}
+
+root.style4 > target inert {
+    color: rgb(4, 4, 4);
+}
+
+</style>
+</head>
+<body>
+    <root>
+        <!-- With renderer -->
+        <inert>
+            <inert>
+                <inert></inert>
+                <target>
+                    <inert></inert>
+                    <target></target>
+                </target>
+            </inert>
+            <target></target>
+            <inert></inert>
+        </inert>
+    </root>
+    <root style="display:none;">
+        <!-- Without renderer -->
+        <inert>
+            <inert>
+                <inert></inert>
+                <target>
+                    <inert></inert>
+                    <target></target>
+                </target>
+            </inert>
+            <target></target>
+            <inert></inert>
+        </inert>
+    </root>
+</body>
+<script>
+
+description('Test that we invalidate the element subtree minimally on class attribute change');
+
+function testStyleChangeType(tag, type)
+{
+    var elements = document.querySelectorAll(tag);
+    for (var i = 0; i < elements.length; ++i) {
+        if (window.internals.styleChangeType(elements[i]) != type)
+            return false;
+    }
+    return true;
+}
+
+function testStyleInvalidation(expectedDescendantStyleChange) {
+    // Ideally we would't invalidate the root at all.
+    shouldBeTrue('testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange")');
+
+    shouldBeTrue('testStyleChangeType("target", "' + expectedDescendantStyleChange +'")');
+
+    shouldBeTrue('testStyleChangeType("inert", "NoStyleChange")');
+}
+
+function addClass(name) {
+    debug("Adding class " + name);
+    var allRoots = document.querySelectorAll("root");
+    allRoots[0].classList.add(name);
+    allRoots[1].classList.add(name);
+}
+
+function removeClass(name) {
+    debug("Removing class " + name);
+    var allRoots = document.querySelectorAll("root");
+    allRoots[0].classList.remove(name);
+    allRoots[1].classList.remove(name);
+}
+
+function checkStyle(n) {
+    document.documentElement.offsetTop;
+
+    hasExpectedStyle = true;
+    expectedColor = 'rgb('+n+', '+n+', '+n+')';
+    var targets = document.querySelectorAll("target");
+    for (var i = 0; i < targets.length; ++i) {
+        hasExpectedStyle = getComputedStyle(targets[i]).color == expectedColor;
+        if (!hasExpectedStyle)
+            break;
+    }
+    shouldBeTrue("hasExpectedStyle");
+}
+
+checkStyle(0);
+testStyleInvalidation("NoStyleChange");
+checkStyle(0);
+
+addClass('NotThere');
+testStyleInvalidation("NoStyleChange");
+
+addClass('style1');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(1);
+
+addClass('style2');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(2);
+
+removeClass('style2');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(1);
+
+addClass('style3');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(3);
+
+removeClass('style3');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(1);
+
+addClass('style4');
+testStyleInvalidation("NoStyleChange");
+checkStyle(1);
+
+removeClass('NotThere');
+testStyleInvalidation("NoStyleChange");
+
+removeClass('style1');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(0);
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
index c63a950..042998e 100644 (file)
@@ -1,3 +1,24 @@
+2016-02-14  Antti Koivisto  <antti@apple.com>
+
+        Add test for class change style invalidation optimization
+        https://bugs.webkit.org/show_bug.cgi?id=154226
+
+        Reviewed by Myles Maxfield.
+
+        Test for https://trac.webkit.org/r196383
+
+        Add internals.styleChangeType function.
+
+        Test: fast/css/style-invalidation-class-change-descendants.html
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::nodeNeedsStyleRecalc):
+        (WebCore::asString):
+        (WebCore::Internals::styleChangeType):
+        (WebCore::Internals::description):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2016-02-14  Simon Fraser  <simon.fraser@apple.com>
 
         [CSS Filters] When applying an SVG filter on a composited image using CSS the image is rendered without the filter
 2016-02-14  Simon Fraser  <simon.fraser@apple.com>
 
         [CSS Filters] When applying an SVG filter on a composited image using CSS the image is rendered without the filter
index dc410b6..2d5ac83 100644 (file)
@@ -464,6 +464,34 @@ bool Internals::nodeNeedsStyleRecalc(Node* node, ExceptionCode& exception)
     return node->needsStyleRecalc();
 }
 
     return node->needsStyleRecalc();
 }
 
+static String styleChangeTypeToString(StyleChangeType type)
+{
+    switch (type) {
+    case NoStyleChange:
+        return "NoStyleChange";
+    case InlineStyleChange:
+        return "InlineStyleChange";
+    case FullStyleChange:
+        return "FullStyleChange";
+    case SyntheticStyleChange:
+        return "SyntheticStyleChange";
+    case ReconstructRenderTree:
+        return "ReconstructRenderTree";
+    }
+    ASSERT_NOT_REACHED();
+    return "";
+}
+
+String Internals::styleChangeType(Node* node, ExceptionCode& exception)
+{
+    if (!node) {
+        exception = INVALID_ACCESS_ERR;
+        return { };
+    }
+
+    return styleChangeTypeToString(node->styleChangeType());
+}
+
 String Internals::description(Deprecated::ScriptValue value)
 {
     return toString(value.jsValue());
 String Internals::description(Deprecated::ScriptValue value)
 {
     return toString(value.jsValue());
index c643bae..3bb87c8 100644 (file)
@@ -89,6 +89,7 @@ public:
 
     String address(Node*);
     bool nodeNeedsStyleRecalc(Node*, ExceptionCode&);
 
     String address(Node*);
     bool nodeNeedsStyleRecalc(Node*, ExceptionCode&);
+    String styleChangeType(Node*, ExceptionCode&);
     String description(Deprecated::ScriptValue);
 
     bool isPreloaded(const String& url);
     String description(Deprecated::ScriptValue);
 
     bool isPreloaded(const String& url);
index a046f9d..0084b57 100644 (file)
@@ -68,6 +68,7 @@ enum AutoFillButtonType {
 ] interface Internals {
     DOMString address(Node node);
     [RaisesException] boolean nodeNeedsStyleRecalc(Node node);
 ] interface Internals {
     DOMString address(Node node);
     [RaisesException] boolean nodeNeedsStyleRecalc(Node node);
+    [RaisesException] DOMString styleChangeType(Node node);
     DOMString description(any value);
 
     // Animated image pausing testing.
     DOMString description(any value);
 
     // Animated image pausing testing.