Title: [90536] trunk
Revision
90536
Author
[email protected]
Date
2011-07-06 21:22:17 -0700 (Wed, 06 Jul 2011)

Log Message

2011-07-06  MORITA Hajime  <[email protected]>

        [ShadowContentElement] Redundant RenderText objects are created on the content boundaries.
        https://bugs.webkit.org/show_bug.cgi?id=63977

        Reviewed by Dimitri Glazkov.

        This test have two set of fixture DOM tree:
        One is for shadow tree which has one content element,
        another is for light DOM tree, whose root is to have a shadow DOM.

        Then the test makes 2 complete DOM trees (DOM tree with shadow and
        flattened dom) for each combination of the fixture items. And
        compare their layout result.

        * fast/dom/shadow/content-element-renderers-expected.txt: Added.
        * fast/dom/shadow/content-element-renderers.html: Added.
2011-07-06  MORITA Hajime  <[email protected]>

        [ShadowContentElement] Redundant RenderText objects are created on the content boundaries.
        https://bugs.webkit.org/show_bug.cgi?id=63977

        Reviewed by Dimitri Glazkov.

        NodeRenderingContext::nextRenderer() and previousRenderer() didn't work well
        when it crosses content elements:
        - It doesn't step into forwarded children of ShadowContentElement.
        - It doesn't step out from traversing forwarded children to
          neighbors of the content element of that forwarded chidren.

        This change makes it to step into and out from content element.

        Test: fast/dom/shadow/content-element-renderers.html

        * dom/NodeRenderingContext.cpp:
        (WebCore::firstRendererOf): Added
        (WebCore::lastRendererOf): Added
        (WebCore::NodeRenderingContext::nextRenderer):
        (WebCore::NodeRenderingContext::previousRenderer):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (90535 => 90536)


--- trunk/LayoutTests/ChangeLog	2011-07-07 04:20:06 UTC (rev 90535)
+++ trunk/LayoutTests/ChangeLog	2011-07-07 04:22:17 UTC (rev 90536)
@@ -1,3 +1,21 @@
+2011-07-06  MORITA Hajime  <[email protected]>
+
+        [ShadowContentElement] Redundant RenderText objects are created on the content boundaries.
+        https://bugs.webkit.org/show_bug.cgi?id=63977
+
+        Reviewed by Dimitri Glazkov.
+
+        This test have two set of fixture DOM tree: 
+        One is for shadow tree which has one content element,
+        another is for light DOM tree, whose root is to have a shadow DOM.
+        
+        Then the test makes 2 complete DOM trees (DOM tree with shadow and
+        flattened dom) for each combination of the fixture items. And
+        compare their layout result.
+        
+        * fast/dom/shadow/content-element-renderers-expected.txt: Added.
+        * fast/dom/shadow/content-element-renderers.html: Added.
+
 2011-07-06  Juan C. Montemayor  <[email protected]>
 
         ASSERT_NOT_REACHED running test 262

Added: trunk/LayoutTests/fast/dom/shadow/content-element-renderers-expected.txt (0 => 90536)


--- trunk/LayoutTests/fast/dom/shadow/content-element-renderers-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/content-element-renderers-expected.txt	2011-07-07 04:22:17 UTC (rev 90536)
@@ -0,0 +1,182 @@
+This test compares a shadow-based render tree with one for a reference DOM tree.
+Note that this test only runs on DRT.
+PASS[0,0]: content=<div/> shadow=<content/>
+PASS[0,1]: content=<div/> shadow=<div/><content/><div/>
+PASS[0,2]: content=<div/> shadow=<div/><content/><span/>
+PASS[0,3]: content=<div/> shadow=<span/><content/><span/>
+PASS[0,4]: content=<div/> shadow=<span/><content/><div/>
+PASS[0,5]: content=<div/> shadow=<div/><content/><div/>
+PASS[0,6]: content=<div/> shadow=<div/><content/><span/>
+PASS[0,7]: content=<div/> shadow=<span/><content/><span/>
+PASS[0,8]: content=<div/> shadow=<span/><content/><div/>
+PASS[0,9]: content=<div/> shadow=<div/>#text<content/>#text<div/>
+PASS[0,10]: content=<div/> shadow=<div/>#text<content/>#text<span/>
+PASS[0,11]: content=<div/> shadow=<span/>#text<content/>#text<span/>
+PASS[0,12]: content=<div/> shadow=<span/>#text<content/>#text<div/>
+PASS[0,13]: content=<div/> shadow=<div><content/></div>
+PASS[0,14]: content=<div/> shadow=<span><content/></span>
+PASS[1,0]: content=#text<div/> shadow=<content/>
+PASS[1,1]: content=#text<div/> shadow=<div/><content/><div/>
+PASS[1,2]: content=#text<div/> shadow=<div/><content/><span/>
+PASS[1,3]: content=#text<div/> shadow=<span/><content/><span/>
+PASS[1,4]: content=#text<div/> shadow=<span/><content/><div/>
+PASS[1,5]: content=#text<div/> shadow=<div/><content/><div/>
+PASS[1,6]: content=#text<div/> shadow=<div/><content/><span/>
+PASS[1,7]: content=#text<div/> shadow=<span/><content/><span/>
+PASS[1,8]: content=#text<div/> shadow=<span/><content/><div/>
+PASS[1,9]: content=#text<div/> shadow=<div/>#text<content/>#text<div/>
+PASS[1,10]: content=#text<div/> shadow=<div/>#text<content/>#text<span/>
+PASS[1,11]: content=#text<div/> shadow=<span/>#text<content/>#text<span/>
+PASS[1,12]: content=#text<div/> shadow=<span/>#text<content/>#text<div/>
+PASS[1,13]: content=#text<div/> shadow=<div><content/></div>
+PASS[1,14]: content=#text<div/> shadow=<span><content/></span>
+PASS[2,0]: content=<div/>#text shadow=<content/>
+PASS[2,1]: content=<div/>#text shadow=<div/><content/><div/>
+PASS[2,2]: content=<div/>#text shadow=<div/><content/><span/>
+PASS[2,3]: content=<div/>#text shadow=<span/><content/><span/>
+PASS[2,4]: content=<div/>#text shadow=<span/><content/><div/>
+PASS[2,5]: content=<div/>#text shadow=<div/><content/><div/>
+PASS[2,6]: content=<div/>#text shadow=<div/><content/><span/>
+PASS[2,7]: content=<div/>#text shadow=<span/><content/><span/>
+PASS[2,8]: content=<div/>#text shadow=<span/><content/><div/>
+PASS[2,9]: content=<div/>#text shadow=<div/>#text<content/>#text<div/>
+PASS[2,10]: content=<div/>#text shadow=<div/>#text<content/>#text<span/>
+PASS[2,11]: content=<div/>#text shadow=<span/>#text<content/>#text<span/>
+PASS[2,12]: content=<div/>#text shadow=<span/>#text<content/>#text<div/>
+PASS[2,13]: content=<div/>#text shadow=<div><content/></div>
+PASS[2,14]: content=<div/>#text shadow=<span><content/></span>
+PASS[3,0]: content=#text<div/>#text shadow=<content/>
+PASS[3,1]: content=#text<div/>#text shadow=<div/><content/><div/>
+PASS[3,2]: content=#text<div/>#text shadow=<div/><content/><span/>
+PASS[3,3]: content=#text<div/>#text shadow=<span/><content/><span/>
+PASS[3,4]: content=#text<div/>#text shadow=<span/><content/><div/>
+PASS[3,5]: content=#text<div/>#text shadow=<div/><content/><div/>
+PASS[3,6]: content=#text<div/>#text shadow=<div/><content/><span/>
+PASS[3,7]: content=#text<div/>#text shadow=<span/><content/><span/>
+PASS[3,8]: content=#text<div/>#text shadow=<span/><content/><div/>
+PASS[3,9]: content=#text<div/>#text shadow=<div/>#text<content/>#text<div/>
+PASS[3,10]: content=#text<div/>#text shadow=<div/>#text<content/>#text<span/>
+PASS[3,11]: content=#text<div/>#text shadow=<span/>#text<content/>#text<span/>
+PASS[3,12]: content=#text<div/>#text shadow=<span/>#text<content/>#text<div/>
+PASS[3,13]: content=#text<div/>#text shadow=<div><content/></div>
+PASS[3,14]: content=#text<div/>#text shadow=<span><content/></span>
+PASS[4,0]: content=<span/> shadow=<content/>
+PASS[4,1]: content=<span/> shadow=<div/><content/><div/>
+PASS[4,2]: content=<span/> shadow=<div/><content/><span/>
+PASS[4,3]: content=<span/> shadow=<span/><content/><span/>
+PASS[4,4]: content=<span/> shadow=<span/><content/><div/>
+PASS[4,5]: content=<span/> shadow=<div/><content/><div/>
+PASS[4,6]: content=<span/> shadow=<div/><content/><span/>
+PASS[4,7]: content=<span/> shadow=<span/><content/><span/>
+PASS[4,8]: content=<span/> shadow=<span/><content/><div/>
+PASS[4,9]: content=<span/> shadow=<div/>#text<content/>#text<div/>
+PASS[4,10]: content=<span/> shadow=<div/>#text<content/>#text<span/>
+PASS[4,11]: content=<span/> shadow=<span/>#text<content/>#text<span/>
+PASS[4,12]: content=<span/> shadow=<span/>#text<content/>#text<div/>
+PASS[4,13]: content=<span/> shadow=<div><content/></div>
+PASS[4,14]: content=<span/> shadow=<span><content/></span>
+PASS[5,0]: content=#text<span/> shadow=<content/>
+PASS[5,1]: content=#text<span/> shadow=<div/><content/><div/>
+PASS[5,2]: content=#text<span/> shadow=<div/><content/><span/>
+PASS[5,3]: content=#text<span/> shadow=<span/><content/><span/>
+PASS[5,4]: content=#text<span/> shadow=<span/><content/><div/>
+PASS[5,5]: content=#text<span/> shadow=<div/><content/><div/>
+PASS[5,6]: content=#text<span/> shadow=<div/><content/><span/>
+PASS[5,7]: content=#text<span/> shadow=<span/><content/><span/>
+PASS[5,8]: content=#text<span/> shadow=<span/><content/><div/>
+PASS[5,9]: content=#text<span/> shadow=<div/>#text<content/>#text<div/>
+PASS[5,10]: content=#text<span/> shadow=<div/>#text<content/>#text<span/>
+PASS[5,11]: content=#text<span/> shadow=<span/>#text<content/>#text<span/>
+PASS[5,12]: content=#text<span/> shadow=<span/>#text<content/>#text<div/>
+PASS[5,13]: content=#text<span/> shadow=<div><content/></div>
+PASS[5,14]: content=#text<span/> shadow=<span><content/></span>
+PASS[6,0]: content=<span/>#text shadow=<content/>
+PASS[6,1]: content=<span/>#text shadow=<div/><content/><div/>
+PASS[6,2]: content=<span/>#text shadow=<div/><content/><span/>
+PASS[6,3]: content=<span/>#text shadow=<span/><content/><span/>
+PASS[6,4]: content=<span/>#text shadow=<span/><content/><div/>
+PASS[6,5]: content=<span/>#text shadow=<div/><content/><div/>
+PASS[6,6]: content=<span/>#text shadow=<div/><content/><span/>
+PASS[6,7]: content=<span/>#text shadow=<span/><content/><span/>
+PASS[6,8]: content=<span/>#text shadow=<span/><content/><div/>
+PASS[6,9]: content=<span/>#text shadow=<div/>#text<content/>#text<div/>
+PASS[6,10]: content=<span/>#text shadow=<div/>#text<content/>#text<span/>
+PASS[6,11]: content=<span/>#text shadow=<span/>#text<content/>#text<span/>
+PASS[6,12]: content=<span/>#text shadow=<span/>#text<content/>#text<div/>
+PASS[6,13]: content=<span/>#text shadow=<div><content/></div>
+PASS[6,14]: content=<span/>#text shadow=<span><content/></span>
+PASS[7,0]: content=#text<span/>#text shadow=<content/>
+PASS[7,1]: content=#text<span/>#text shadow=<div/><content/><div/>
+PASS[7,2]: content=#text<span/>#text shadow=<div/><content/><span/>
+PASS[7,3]: content=#text<span/>#text shadow=<span/><content/><span/>
+PASS[7,4]: content=#text<span/>#text shadow=<span/><content/><div/>
+PASS[7,5]: content=#text<span/>#text shadow=<div/><content/><div/>
+PASS[7,6]: content=#text<span/>#text shadow=<div/><content/><span/>
+PASS[7,7]: content=#text<span/>#text shadow=<span/><content/><span/>
+PASS[7,8]: content=#text<span/>#text shadow=<span/><content/><div/>
+PASS[7,9]: content=#text<span/>#text shadow=<div/>#text<content/>#text<div/>
+PASS[7,10]: content=#text<span/>#text shadow=<div/>#text<content/>#text<span/>
+PASS[7,11]: content=#text<span/>#text shadow=<span/>#text<content/>#text<span/>
+PASS[7,12]: content=#text<span/>#text shadow=<span/>#text<content/>#text<div/>
+PASS[7,13]: content=#text<span/>#text shadow=<div><content/></div>
+PASS[7,14]: content=#text<span/>#text shadow=<span><content/></span>
+PASS[8,0]: content=<span/>#text<div/> shadow=<content/>
+PASS[8,1]: content=<span/>#text<div/> shadow=<div/><content/><div/>
+PASS[8,2]: content=<span/>#text<div/> shadow=<div/><content/><span/>
+PASS[8,3]: content=<span/>#text<div/> shadow=<span/><content/><span/>
+PASS[8,4]: content=<span/>#text<div/> shadow=<span/><content/><div/>
+PASS[8,5]: content=<span/>#text<div/> shadow=<div/><content/><div/>
+PASS[8,6]: content=<span/>#text<div/> shadow=<div/><content/><span/>
+PASS[8,7]: content=<span/>#text<div/> shadow=<span/><content/><span/>
+PASS[8,8]: content=<span/>#text<div/> shadow=<span/><content/><div/>
+PASS[8,9]: content=<span/>#text<div/> shadow=<div/>#text<content/>#text<div/>
+PASS[8,10]: content=<span/>#text<div/> shadow=<div/>#text<content/>#text<span/>
+PASS[8,11]: content=<span/>#text<div/> shadow=<span/>#text<content/>#text<span/>
+PASS[8,12]: content=<span/>#text<div/> shadow=<span/>#text<content/>#text<div/>
+PASS[8,13]: content=<span/>#text<div/> shadow=<div><content/></div>
+PASS[8,14]: content=<span/>#text<div/> shadow=<span><content/></span>
+PASS[9,0]: content=<div/>#text<span/> shadow=<content/>
+PASS[9,1]: content=<div/>#text<span/> shadow=<div/><content/><div/>
+PASS[9,2]: content=<div/>#text<span/> shadow=<div/><content/><span/>
+PASS[9,3]: content=<div/>#text<span/> shadow=<span/><content/><span/>
+PASS[9,4]: content=<div/>#text<span/> shadow=<span/><content/><div/>
+PASS[9,5]: content=<div/>#text<span/> shadow=<div/><content/><div/>
+PASS[9,6]: content=<div/>#text<span/> shadow=<div/><content/><span/>
+PASS[9,7]: content=<div/>#text<span/> shadow=<span/><content/><span/>
+PASS[9,8]: content=<div/>#text<span/> shadow=<span/><content/><div/>
+PASS[9,9]: content=<div/>#text<span/> shadow=<div/>#text<content/>#text<div/>
+PASS[9,10]: content=<div/>#text<span/> shadow=<div/>#text<content/>#text<span/>
+PASS[9,11]: content=<div/>#text<span/> shadow=<span/>#text<content/>#text<span/>
+PASS[9,12]: content=<div/>#text<span/> shadow=<span/>#text<content/>#text<div/>
+PASS[9,13]: content=<div/>#text<span/> shadow=<div><content/></div>
+PASS[9,14]: content=<div/>#text<span/> shadow=<span><content/></span>
+PASS[10,0]: content=<div/><span/> shadow=<content/>
+PASS[10,1]: content=<div/><span/> shadow=<div/><content/><div/>
+PASS[10,2]: content=<div/><span/> shadow=<div/><content/><span/>
+PASS[10,3]: content=<div/><span/> shadow=<span/><content/><span/>
+PASS[10,4]: content=<div/><span/> shadow=<span/><content/><div/>
+PASS[10,5]: content=<div/><span/> shadow=<div/><content/><div/>
+PASS[10,6]: content=<div/><span/> shadow=<div/><content/><span/>
+PASS[10,7]: content=<div/><span/> shadow=<span/><content/><span/>
+PASS[10,8]: content=<div/><span/> shadow=<span/><content/><div/>
+PASS[10,9]: content=<div/><span/> shadow=<div/>#text<content/>#text<div/>
+PASS[10,10]: content=<div/><span/> shadow=<div/>#text<content/>#text<span/>
+PASS[10,11]: content=<div/><span/> shadow=<span/>#text<content/>#text<span/>
+PASS[10,12]: content=<div/><span/> shadow=<span/>#text<content/>#text<div/>
+PASS[10,13]: content=<div/><span/> shadow=<div><content/></div>
+PASS[10,14]: content=<div/><span/> shadow=<span><content/></span>
+PASS[11,0]: content=<span/><div/> shadow=<content/>
+PASS[11,1]: content=<span/><div/> shadow=<div/><content/><div/>
+PASS[11,2]: content=<span/><div/> shadow=<div/><content/><span/>
+PASS[11,3]: content=<span/><div/> shadow=<span/><content/><span/>
+PASS[11,4]: content=<span/><div/> shadow=<span/><content/><div/>
+PASS[11,5]: content=<span/><div/> shadow=<div/><content/><div/>
+PASS[11,6]: content=<span/><div/> shadow=<div/><content/><span/>
+PASS[11,7]: content=<span/><div/> shadow=<span/><content/><span/>
+PASS[11,8]: content=<span/><div/> shadow=<span/><content/><div/>
+PASS[11,9]: content=<span/><div/> shadow=<div/>#text<content/>#text<div/>
+PASS[11,10]: content=<span/><div/> shadow=<div/>#text<content/>#text<span/>
+PASS[11,11]: content=<span/><div/> shadow=<span/>#text<content/>#text<span/>
+PASS[11,12]: content=<span/><div/> shadow=<span/>#text<content/>#text<div/>
+PASS[11,13]: content=<span/><div/> shadow=<div><content/></div>
+PASS[11,14]: content=<span/><div/> shadow=<span><content/></span>

Added: trunk/LayoutTests/fast/dom/shadow/content-element-renderers.html (0 => 90536)


--- trunk/LayoutTests/fast/dom/shadow/content-element-renderers.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/content-element-renderers.html	2011-07-07 04:22:17 UTC (rev 90536)
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+/* relative positioning ensures underlying RenderLayer */
+.container {
+    position: relative;
+}
+</style>
+<script>
+function log(message)
+{
+    var line = document.createElement("div");
+    line.textContent = message;
+    document.getElementById("console").appendChild(line);
+}
+
+var contentSources = [
+  "<div/>",
+  "#text<div/>",
+  "<div/>#text",
+  "#text<div/>#text",
+
+  "<span/>",
+  "#text<span/>",
+  "<span/>#text",
+  "#text<span/>#text",
+
+  "<span/>#text<div/>",
+  "<div/>#text<span/>",
+  "<div/><span/>",
+  "<span/><div/>"
+
+];
+
+var shadowSources = [
+  "<content/>",
+  "<div/><content/><div/>",
+  "<div/><content/><span/>",
+  "<span/><content/><span/>",
+  "<span/><content/><div/>",
+
+  "<div/><content/><div/>",
+  "<div/><content/><span/>",
+  "<span/><content/><span/>",
+  "<span/><content/><div/>",
+
+  "<div/>#text<content/>#text<div/>",
+  "<div/>#text<content/>#text<span/>",
+  "<span/>#text<content/>#text<span/>",
+  "<span/>#text<content/>#text<div/>",
+
+  "<div><content/></div>",
+  "<span><content/></span>"
+];
+
+function createTreeFrom(html)
+{
+    var enhancedHtml = html.replace(/<span\/>/g, "<span> </span>").replace(/<div\/>/g, "<div> </div>").replace(/<content\/>/g, "<content></content>").replace(/#text/g, " ");
+    var root = document.createElement("blockquote");
+    root.innerHTML = enhancedHtml;
+    var contentPlaceholder = root.getElementsByTagName("CONTENT")[0];
+    if (contentPlaceholder) {
+        var contentParent = contentPlaceholder.parentNode;
+        contentParent.replaceChild(window.internals.createShadowContentElement(document), contentPlaceholder);
+    };
+
+    return root;
+}
+
+function moveChildren(fromParent, toParent)
+{
+    var children = fromParent.childNodes;
+    while (fromParent.firstChild)
+        toParent.appendChild(fromParent.firstChild);
+}
+
+function createTargetTree(contentHtml, shadowHtml)
+{
+    var content = createTreeFrom(contentHtml);
+    var shadow = createTreeFrom(shadowHtml);
+    var host = document.createElement("blockquote");
+    var shadowRoot = internals.ensureShadowRoot(host);
+    moveChildren(content, host);
+    moveChildren(shadow, shadowRoot); 
+    return host;
+}
+
+function cleanupContainer(container)
+{
+    var child = container.firstChild;
+    if (child)
+        container.removeChild(child);
+    container.offsetLeft;
+}
+
+function testWithContentAndShadow(contentHtml, shadowHtml, label)
+{
+    var targetContainer = document.getElementById("targetContainer");
+    cleanupContainer(targetContainer);
+    var target = createTargetTree(contentHtml, shadowHtml);
+    targetContainer.appendChild(target);
+    var targetRenderTree = removeContainerLines(window.internals.elementRenderTreeAsText(targetContainer));
+
+    var referenceContainer = document.getElementById("referenceContainer");
+    cleanupContainer(referenceContainer);
+    var separator = "<!-- -->"; // Uses a separator for keeping text node separate.
+    var referenceHtml = shadowHtml.replace("<content/>", (separator + contentHtml + separator));
+    var reference = createTreeFrom(referenceHtml);
+    referenceContainer.appendChild(reference);
+    var referenceRenderTree = removeContainerLines(window.internals.elementRenderTreeAsText(referenceContainer));
+    if (targetRenderTree == referenceRenderTree)
+        log("PASS[" + label + "]: content=" + contentHtml + " shadow=" + shadowHtml);
+    else {
+        log("FAIL[" + label + "]: content=" + contentHtml + " shadow=" + shadowHtml);
+        log("Expected: (for " + reference.innerHTML + ")");
+        log(referenceRenderTree);
+        log("Actual: (for " + target.innerHTML + ")");
+        log(targetRenderTree);
+    }
+}
+
+function removeContainerLines(text)
+{
+    var lines = text.split("\n");
+    lines.splice(0, 2);
+    return lines.join("\n");
+}
+
+function test()
+{
+    layoutTestController.dumpAsText();
+    log("This test compares a shadow-based render tree with one for a reference DOM tree.");
+    log("Note that this test only runs on DRT.");
+
+    for (var i = 0; i < contentSources.length; ++i) {
+        for (var j = 0; j < shadowSources.length; ++j) {
+            var testLabel = i + "," + j;
+            testWithContentAndShadow(contentSources[i], shadowSources[j], testLabel);
+        }
+    } 
+
+    document.getElementById("test").style.display = "none";
+    document.getElementById("console").style.display = "block";
+}
+</script>
+</head>
+<body _onload_="test()">
+<div id="test">
+<div class="container" id="targetContainer"></div>
+<div class="container" id="referenceContainer"></div>
+</div>
+<pre id="console" style="display: none;"></pre>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (90535 => 90536)


--- trunk/Source/WebCore/ChangeLog	2011-07-07 04:20:06 UTC (rev 90535)
+++ trunk/Source/WebCore/ChangeLog	2011-07-07 04:22:17 UTC (rev 90536)
@@ -1,3 +1,26 @@
+2011-07-06  MORITA Hajime  <[email protected]>
+
+        [ShadowContentElement] Redundant RenderText objects are created on the content boundaries.
+        https://bugs.webkit.org/show_bug.cgi?id=63977
+
+        Reviewed by Dimitri Glazkov.
+
+        NodeRenderingContext::nextRenderer() and previousRenderer() didn't work well
+        when it crosses content elements:
+        - It doesn't step into forwarded children of ShadowContentElement.
+        - It doesn't step out from traversing forwarded children to
+          neighbors of the content element of that forwarded chidren.
+        
+        This change makes it to step into and out from content element.
+        
+        Test: fast/dom/shadow/content-element-renderers.html
+
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::firstRendererOf): Added
+        (WebCore::lastRendererOf): Added
+        (WebCore::NodeRenderingContext::nextRenderer):
+        (WebCore::NodeRenderingContext::previousRenderer):
+
 2011-07-06  Gyuyoung Kim  <[email protected]>
 
         [EFL] Add Fullscreen API feature

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (90535 => 90536)


--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2011-07-07 04:20:06 UTC (rev 90535)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2011-07-07 04:22:17 UTC (rev 90536)
@@ -130,14 +130,41 @@
     return lastRenderer;
 }
 
+static RenderObject* firstRendererOf(ShadowContentElement* parent)
+{
+    size_t inclusionCount = parent->inclusionCount();
+    for (size_t i = 0; i < inclusionCount; ++i) {
+        Node* candidate = parent->inclusionAt(i);
+        if (RenderObject* renderer = candidate->renderer())
+            return renderer;
+    }
+
+    return 0;
+}
+
+static RenderObject* lastRendererOf(ShadowContentElement* parent)
+{
+    size_t inclusionCount = parent->inclusionCount();
+    for (size_t i = 0; i < inclusionCount; ++i) {
+        Node* candidate = parent->inclusionAt(inclusionCount - i - 1);
+        if (RenderObject* renderer = candidate->renderer())
+            return renderer;
+    }
+
+    return 0;
+}
+
 RenderObject* NodeRenderingContext::nextRenderer() const
 {
     ASSERT(m_node->renderer() || m_location != LocationUndetermined);
     if (RenderObject* renderer = m_node->renderer())
         return renderer->nextSibling();
 
-    if (m_phase == AttachContentForwarded)
-        return nextRendererOf(m_contentElement, m_node);
+    if (m_phase == AttachContentForwarded) {
+        if (RenderObject* found = nextRendererOf(m_contentElement, m_node))
+            return found;
+        return NodeRenderingContext(m_contentElement).nextRenderer();
+    }
 
     // Avoid an O(n^2) problem with this function by not checking for
     // nextRenderer() when the parent element hasn't attached yet.
@@ -147,6 +174,10 @@
     for (Node* node = m_node->nextSibling(); node; node = node->nextSibling()) {
         if (node->renderer())
             return node->renderer();
+        if (node->isContentElement()) {
+            if (RenderObject* first = firstRendererOf(toShadowContentElement(node)))
+                return first;
+        }
     }
 
     return 0;
@@ -158,14 +189,21 @@
     if (RenderObject* renderer = m_node->renderer())
         return renderer->previousSibling();
 
-    if (m_phase == AttachContentForwarded)
-        return previousRendererOf(m_contentElement, m_node);
+    if (m_phase == AttachContentForwarded) {
+        if (RenderObject* found = previousRendererOf(m_contentElement, m_node))
+            return found;
+        return NodeRenderingContext(m_contentElement).previousRenderer();
+    }
 
     // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
     // however, when I tried adding it, several tests failed.
     for (Node* node = m_node->previousSibling(); node; node = node->previousSibling()) {
         if (node->renderer())
             return node->renderer();
+        if (node->isContentElement()) {
+            if (RenderObject* last = lastRendererOf(toShadowContentElement(node)))
+                return last;
+        }
     }
 
     return 0;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to