| <!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); |
| } |
| |
| root:not(.style5) target { |
| color: rgb(5, 5, 5); |
| } |
| |
| root.dynamicStyle notTarget { |
| color: rgb(99, 99, 99); |
| } |
| |
| </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"); |
| } |
| |
| addClass('style5'); |
| |
| 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); |
| |
| removeClass('style5'); |
| testStyleInvalidation("InlineStyleChange"); |
| checkStyle(5); |
| |
| addClass('style5'); |
| testStyleInvalidation("InlineStyleChange"); |
| checkStyle(0); |
| |
| addClass('dynamicStyle'); |
| testStyleInvalidation("NoStyleChange"); |
| checkStyle(0); |
| |
| removeClass('dynamicStyle'); |
| testStyleInvalidation("NoStyleChange"); |
| checkStyle(0); |
| |
| var dynamicSheet = document.createElement("style"); |
| dynamicSheet.innerHTML = "root.dynamicStyle target { color:rgb(6, 6, 6); }" |
| debug("Inserting stylesheet '" + dynamicSheet.innerHTML + "'"); |
| document.head.appendChild(dynamicSheet); |
| |
| testStyleInvalidation("NoStyleChange"); |
| checkStyle(0); |
| |
| addClass('dynamicStyle'); |
| testStyleInvalidation("InlineStyleChange"); |
| checkStyle(6); |
| |
| removeClass('dynamicStyle'); |
| testStyleInvalidation("InlineStyleChange"); |
| checkStyle(0) |
| |
| </script> |
| <script src="../../resources/js-test-post.js"></script> |
| </html> |