Select attribute of HTMLContentElement should be able be changed dynamically.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Feb 2012 03:22:22 +0000 (03:22 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Feb 2012 03:22:22 +0000 (03:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76261

Patch by Shinya Kawanaka <shinyak@google.com> on 2012-02-01
Reviewed by Hajime Morita.

Source/WebCore:

When select attribute is changed, the flag to recalc style is set.

Test: fast/dom/shadow/content-element-select-dynamic.html

* html/shadow/HTMLContentElement.cpp:
(WebCore::HTMLContentElement::parseMappedAttribute):
  Sets recalc style when select is changed.
* html/shadow/HTMLContentElement.h:
(HTMLContentElement):

LayoutTests:

Test cases for changing select attribute dynamically.

* fast/dom/shadow/content-element-select-dynamic-expected.txt: Added.
* fast/dom/shadow/content-element-select-dynamic.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/dom/shadow/content-element-select-dynamic-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/shadow/content-element-select-dynamic.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/shadow/HTMLContentElement.cpp
Source/WebCore/html/shadow/HTMLContentElement.h

index 66df37b..caf31e3 100644 (file)
@@ -1,3 +1,15 @@
+2012-02-01  Shinya Kawanaka  <shinyak@google.com>
+
+        Select attribute of HTMLContentElement should be able be changed dynamically.
+        https://bugs.webkit.org/show_bug.cgi?id=76261
+
+        Reviewed by Hajime Morita.
+
+        Test cases for changing select attribute dynamically.
+
+        * fast/dom/shadow/content-element-select-dynamic-expected.txt: Added.
+        * fast/dom/shadow/content-element-select-dynamic.html: Added.
+
 2012-02-01  Michael Saboff  <msaboff@apple.com>
 
         Yarr crash with regexp replace
diff --git a/LayoutTests/fast/dom/shadow/content-element-select-dynamic-expected.txt b/LayoutTests/fast/dom/shadow/content-element-select-dynamic-expected.txt
new file mode 100644 (file)
index 0000000..9e7b7b3
--- /dev/null
@@ -0,0 +1,12 @@
+testChangeSelect1
+PASS
+testChangeSelect2
+PASS
+testChangeSelectToEmpty
+PASS
+testChangeSelectToFallback
+PASS
+testChangeSelectFromFallback
+PASS
+TEST COMPLETED
+
diff --git a/LayoutTests/fast/dom/shadow/content-element-select-dynamic.html b/LayoutTests/fast/dom/shadow/content-element-select-dynamic.html
new file mode 100644 (file)
index 0000000..75d724b
--- /dev/null
@@ -0,0 +1,299 @@
+ <!DOCTYPE html>
+<html>
+<head>
+<style>
+/* relative positioning ensures underlying RenderLayer */
+.container {
+    position: relative;
+}
+
+.span {
+    display: boxed-inline;
+    margin: 2px;
+    border: solid;
+}
+</style>
+<script>
+function log(message) {
+    document.getElementById('console').innerHTML += (message + "\n");
+}
+
+function removeAllChildren(elem) {
+    while (elem.firstChild)
+        elem.removeChild(elem.firstChild);
+}
+
+function cleanUp() {
+    removeAllChildren(document.getElementById('actual-container'));
+    removeAllChildren(document.getElementById('expect-container'));
+}
+
+function removeContainerLines(text) {
+    var lines = text.split('\n');
+    lines.splice(0, 2);
+    return lines.join('\n');
+}
+
+function check() {
+    var refContainerRenderTree = internals.elementRenderTreeAsText(document.getElementById('expect-container'));
+    var refRenderTree = removeContainerLines(refContainerRenderTree);
+
+    var targetContainerRenderTree = internals.elementRenderTreeAsText(document.getElementById('actual-container'));
+    var targetRenderTree = removeContainerLines(targetContainerRenderTree);
+
+    if (targetRenderTree == refRenderTree)
+        log("PASS");
+    else {
+        log("FAIL");
+        log("Expected: ");
+        log(refRenderTree);
+        log("Actual: ");
+        log(targetRenderTree);
+    }
+}
+
+function createSpanWithText(text) {
+    var span = document.createElement('span');
+    span.appendChild(document.createTextNode(text));
+    return span;
+}
+
+function createContentWithSelect(select, fallback) {
+    var content = internals.createContentElement(document);
+    content.setAttribute('select', select);
+    if (!fallback)
+        content.appendChild(createSpanWithText("FALLBACK"));
+
+    return content;
+}
+
+function appendShadow(target, select) {
+    var root = internals.ensureShadowRoot(target);
+
+    var content = internals.createContentElement(document);
+    content.setAttribute('select', select);
+    content.appendChild(createSpanWithText("FALLBACK"));
+
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content);
+    root.appendChild(document.createTextNode("}"));
+}
+
+function appendShadowDeep(target, select) {
+    var root = internals.ensureShadowRoot(target);
+
+    var child = document.createElement("span");
+    {
+        var content = internals.createContentElement(document);
+        content.setAttribute('select', select);
+        content.appendChild(createSpanWithText("FALLBACK"));
+
+        child.appendChild(document.createTextNode("{INNER: "));
+        child.appendChild(content);
+        child.appendChild(document.createTextNode("}"));
+    }
+
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(child);
+    root.appendChild(document.createTextNode("}"));
+}
+
+// ----------------------------------------------------------------------
+// Test Functions.
+
+function testChangeSelect1(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>BEFORE</span><span>LIGHT 2</span><span>AFTER</span></div>";
+
+    var root = document.createElement('div');
+
+    // Create light tree.
+    root.innerHTML = "<span class='c1'>LIGHT 1</span><span class='c2'>LIGHT 2</span>";
+
+    // Create shadow tree.
+    var content = createContentWithSelect('.c1');
+    var sr = internals.ensureShadowRoot(root);
+    sr.appendChild(createSpanWithText("BEFORE"));
+    sr.appendChild(content);
+    sr.appendChild(createSpanWithText("AFTER"));
+
+    document.getElementById('actual-container').appendChild(root);
+
+    var f = (function(root, content, callIfDone) {
+        return function() {
+            content.setAttribute('select', '.c2');
+            callIfDone();
+        };
+    })(root, content, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+function testChangeSelect2(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>BEFORE</span><span>LIGHT 1</span><span>LIGHT 2</span><span>AFTER</span></div>";
+
+    var root = document.createElement('div');
+
+    // Create light tree.
+    root.innerHTML = "<span class='c1'>LIGHT 1</span><span class='c2'>LIGHT 2</span>";
+
+    // Create shadow tree.
+    var content = createContentWithSelect('.c1');
+    var sr = internals.ensureShadowRoot(root);
+    sr.appendChild(createSpanWithText("BEFORE"));
+    sr.appendChild(content);
+    sr.appendChild(createSpanWithText("AFTER"));
+
+    document.getElementById('actual-container').appendChild(root);
+
+    var f = (function(root, content, callIfDone) {
+        return function() {
+            content.setAttribute('select', 'span');
+            callIfDone();
+        };
+    })(root, content, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+function testChangeSelectToEmpty(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>BEFORE</span><span>LIGHT 1</span><span>LIGHT 2</span><span>AFTER</span></div>";
+
+    var root = document.createElement('div');
+
+    // Create light tree.
+    root.innerHTML = "<span class='c1'>LIGHT 1</span><span class='c2'>LIGHT 2</span>";
+
+    // Create shadow tree.
+    var content = createContentWithSelect('.c1');
+    var sr = internals.ensureShadowRoot(root);
+    sr.appendChild(createSpanWithText("BEFORE"));
+    sr.appendChild(content);
+    sr.appendChild(createSpanWithText("AFTER"));
+
+    document.getElementById('actual-container').appendChild(root);
+
+    var f = (function(root, content, callIfDone) {
+        return function() {
+            content.removeAttribute('select');
+            callIfDone();
+        };
+    })(root, content, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+function testChangeSelectToFallback(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>BEFORE</span><span>FALLBACK</span><span>AFTER</span></div>";
+
+    var root = document.createElement('div');
+
+    // Create light tree.
+    root.innerHTML = "<span class='c1'>LIGHT 1</span><span class='c2'>LIGHT 2</span>";
+
+    // Create shadow tree.
+    var content = createContentWithSelect('.c1');
+    content.innerHTML = "<span>FALLBACK</span>"
+
+    var sr = internals.ensureShadowRoot(root);
+    sr.appendChild(createSpanWithText("BEFORE"));
+    sr.appendChild(content);
+    sr.appendChild(createSpanWithText("AFTER"));
+
+    document.getElementById('actual-container').appendChild(root);
+
+    var f = (function(root, content, callIfDone) {
+        return function() {
+            content.setAttribute('select', 'div')
+            callIfDone();
+        };
+    })(root, content, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+function testChangeSelectFromFallback(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>BEFORE</span><span>LIGHT 1</span><span>LIGHT 2</span><span>AFTER</span></div>";
+
+    var root = document.createElement('div');
+
+    // Create light tree.
+    root.innerHTML = "<span class='c1'>LIGHT 1</span><span class='c2'>LIGHT 2</span>";
+
+    // Create shadow tree.
+    var content = createContentWithSelect('div');
+    content.innerHTML = "<span>FALLBACK</span>"
+
+    var sr = internals.ensureShadowRoot(root);
+    sr.appendChild(createSpanWithText("BEFORE"));
+    sr.appendChild(content);
+    sr.appendChild(createSpanWithText("AFTER"));
+
+    document.getElementById('actual-container').appendChild(root);
+
+    var f = (function(root, content, callIfDone) {
+        return function() {
+            content.setAttribute('select', 'span')
+            callIfDone();
+        };
+    })(root, content, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+// ----------------------------------------------------------------------
+// Test Drivers.
+
+var testFuncs = [
+    testChangeSelect1,
+    testChangeSelect2,
+    testChangeSelectToEmpty,
+    testChangeSelectToFallback,
+    testChangeSelectFromFallback,
+];
+
+function doTestIfLeft() {
+    var test = testFuncs.shift();
+    if (test == null)
+        return doneTest();
+
+    var callIfDone = function() {
+        setTimeout(function() {
+            check();
+            cleanUp();
+            doTestIfLeft();
+        }, 0);
+    };
+
+    log(test.name);
+    test(callIfDone);
+}
+
+function doneTest() {
+    log("TEST COMPLETED");
+    layoutTestController.notifyDone();
+}
+
+function doTest() {
+    if (window.layoutTestController) {
+        layoutTestController.waitUntilDone();
+        layoutTestController.dumpAsText();
+    }
+
+    cleanUp();
+    doTestIfLeft();
+}
+</script>
+</head>
+<body onload="doTest()">
+
+<div id="actual-container" class="container"></div>
+<div id="expect-container" class="container"></div>
+<pre id="console"></pre>
+
+</body>
+</html>
index a8f370b..2e7df05 100644 (file)
@@ -1,3 +1,20 @@
+2012-02-01  Shinya Kawanaka  <shinyak@google.com>
+
+        Select attribute of HTMLContentElement should be able be changed dynamically.
+        https://bugs.webkit.org/show_bug.cgi?id=76261
+
+        Reviewed by Hajime Morita.
+
+        When select attribute is changed, the flag to recalc style is set.
+
+        Test: fast/dom/shadow/content-element-select-dynamic.html
+
+        * html/shadow/HTMLContentElement.cpp:
+        (WebCore::HTMLContentElement::parseMappedAttribute):
+          Sets recalc style when select is changed.
+        * html/shadow/HTMLContentElement.h:
+        (HTMLContentElement):
+
 2012-02-01  Kentaro Hara  <haraken@chromium.org>
 
         Remove [ImplementationUUID] and [InterfaceUUID] from html/canvas/*.idl
index 4af45b2..c1a1ef0 100644 (file)
@@ -118,4 +118,13 @@ void HTMLContentElement::setSelect(const AtomicString& selectValue)
     setAttribute(selectAttr, selectValue);
 }
 
+void HTMLContentElement::parseMappedAttribute(Attribute* attr)
+{
+    if (attr->name() == selectAttr) {
+        if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode()))
+            root->setNeedsReattachHostChildrenAndShadow();
+    } else
+        HTMLElement::parseMappedAttribute(attr);
+}
+
 }
index 75b7d47..7845e09 100644 (file)
@@ -73,6 +73,8 @@ private:
     virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) { return 0; }
 
+    virtual void parseMappedAttribute(Attribute*);
+
     OwnPtr<ShadowInclusionList> m_inclusions;
 };