Title: [108480] trunk
Revision
108480
Author
shin...@chromium.org
Date
2012-02-22 04:06:34 -0800 (Wed, 22 Feb 2012)

Log Message

firstRendererOf() should also return a fallback element renderer in NodeRenderingContext.
https://bugs.webkit.org/show_bug.cgi?id=79180

Reviewed by Hajime Morita.

Source/WebCore:

Currently we have handled AttachingFallback in some special mannger, however if firstRendererOf
and lastRendererOf return a fallback element renderer, we don't need to handle it in such a manner.

We have introduced new attaching phase: AttachingFallbacked, and AttachingNotFallbacked.
They are used for fallback elements.

Added new test cases in:
  fast/dom/shadow/shadow-contents-fallback.html
  fast/dom/shadow/shadow-contents-fallback-dynamic.html

* dom/NodeRenderingContext.cpp:
(WebCore::NodeRenderingContext::NodeRenderingContext):
(WebCore::firstRendererOf):
(WebCore::lastRendererOf):
(WebCore::NodeRenderingContext::nextRenderer):
(WebCore::NodeRenderingContext::previousRenderer):
(WebCore::NodeRenderingContext::shouldCreateRenderer):
* dom/NodeRenderingContext.h:
* html/shadow/InsertionPoint.h:
(WebCore::isInsertionPoint):
(WebCore):
(WebCore::toInsertionPoint):

LayoutTests:

Added new test cases, e.g. <content> in <content>, with display:none.

* fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt:
* fast/dom/shadow/shadow-contents-fallback-dynamic.html:
* fast/dom/shadow/shadow-contents-fallback-expected.txt:
* fast/dom/shadow/shadow-contents-fallback.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (108479 => 108480)


--- trunk/LayoutTests/ChangeLog	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/LayoutTests/ChangeLog	2012-02-22 12:06:34 UTC (rev 108480)
@@ -1,3 +1,17 @@
+2012-02-22  Shinya Kawanaka  <shin...@chromium.org>
+
+        firstRendererOf() should also return a fallback element renderer in NodeRenderingContext.
+        https://bugs.webkit.org/show_bug.cgi?id=79180
+
+        Reviewed by Hajime Morita.
+
+        Added new test cases, e.g. <content> in <content>, with display:none.
+
+        * fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt:
+        * fast/dom/shadow/shadow-contents-fallback-dynamic.html:
+        * fast/dom/shadow/shadow-contents-fallback-expected.txt:
+        * fast/dom/shadow/shadow-contents-fallback.html:
+
 2012-02-22  Sheriff Bot  <webkit.review....@gmail.com>
 
         Unreviewed, rolling out r108468.

Modified: trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt (108479 => 108480)


--- trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic-expected.txt	2012-02-22 12:06:34 UTC (rev 108480)
@@ -22,5 +22,11 @@
 PASS
 testComplexReplace
 PASS
+testContentInContent
+PASS
+testContentInContentFallback
+PASS
+testContentInContentFallbackDirect
+PASS
 TEST COMPLETED
 

Modified: trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic.html (108479 => 108480)


--- trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic.html	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-dynamic.html	2012-02-22 12:06:34 UTC (rev 108480)
@@ -319,8 +319,6 @@
 
     var selectContent = document.createElement('span');
     selectContent.setAttribute('id', 'complex-3');
-    {
-    }
     appendShadow(selectContent, 'span');
 
     target.appendChild(document.createTextNode('[WONT SELECTED]'));
@@ -342,6 +340,96 @@
     setTimeout(f, 0);
 }
 
+function testContentInContent(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div>{SHADOW: <span>S1</span><span>S2</span>}</div>";
+
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content1);
+    root.appendChild(document.createTextNode("}"));
+
+    document.getElementById('actual-container').appendChild(target);
+
+    var f = (function(target, content1, callIfDone) {
+        return function() {
+            var content2 = internals.createContentElement(document);
+            content2.setAttribute('select', 'span');
+            content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+            content1.appendChild(content2);
+            callIfDone();
+        };
+    })(target, content1, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+function testContentInContentFallback(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div>{SHADOW: <span>CONTENT 2 FALLBACK</span>}</div>";
+
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content1);
+    root.appendChild(document.createTextNode("}"));
+
+    document.getElementById('actual-container').appendChild(target);
+
+    var f = (function(target, content1, callIfDone) {
+        return function() {
+            var content2 = internals.createContentElement(document);
+            content2.setAttribute('select', 'div');
+            content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+            content1.appendChild(content2);
+            callIfDone();
+        };
+    })(target, content1, callIfDone);
+
+    setTimeout(f, 0);
+}
+
+function testContentInContentFallbackDirect(callIfDone) {
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>CONTENT 2 FALLBACK</span></div>";
+
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+    root.appendChild(content1);
+
+    document.getElementById('actual-container').appendChild(target);
+
+    var f = (function(target, content1, callIfDone) {
+        return function() {
+            var content2 = internals.createContentElement(document);
+            content2.setAttribute('select', 'div');
+            content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+            content1.appendChild(content2);
+            callIfDone();
+        };
+    })(target, content1, callIfDone);
+
+    setTimeout(f, 0);
+}
+
 var testFuncs = [
     testAppendFallback,
     testAppendFallbackDeep,
@@ -355,7 +443,9 @@
     testComplexAppend,
     testComplexRemove,
     testComplexReplace,
-
+    testContentInContent,
+    testContentInContentFallback,
+    testContentInContentFallbackDirect
 ];
 
 function doTestIfLeft() {

Modified: trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-expected.txt (108479 => 108480)


--- trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-expected.txt	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback-expected.txt	2012-02-22 12:06:34 UTC (rev 108480)
@@ -6,4 +6,9 @@
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
+PASS
+PASS
 

Modified: trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback.html (108479 => 108480)


--- trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback.html	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-contents-fallback.html	2012-02-22 12:06:34 UTC (rev 108480)
@@ -214,6 +214,132 @@
         "<div>{SHADOW: <span>{INNER: <span>{SHADOW: <span>{INNER: <span>FALLBACK</span>}</span>}</span>}</span>}</span></div>";
 }
 
+function testContentkWithDisplayNone() {
+    var target = document.createElement('div');
+
+    var span1 = createSpanWithText('NOT RENDERED');
+    span1.style.display = 'none';
+    var span2 = createSpanWithText('NOT RENDERED');
+    span2.style.display = 'none';
+    var span3 = createSpanWithText('NOT RENDERED');
+    span3.style.display = 'none';
+
+    target.appendChild(span1);
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(span2);
+    target.appendChild(createSpanWithText('S2'));
+    target.appendChild(span3);
+
+    var root = internals.ensureShadowRoot(target);
+    var content = internals.createContentElement(document);
+    content.setAttribute('select', 'span');
+    content.appendChild(createSpanWithText('FALLBACK'));
+
+    var s = createSpanWithText('NOT RENDERED');
+    s.style.display = 'none';
+    root.appendChild(s);
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content);
+    root.appendChild(document.createTextNode("}"));
+
+    document.getElementById('actual-container').appendChild(target);
+    document.getElementById('expect-container').innerHTML =
+        "<div>{SHADOW: <span>S1</span><span>S2</span>}</div>";
+}
+
+function testContentInContent() {
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content2 = internals.createContentElement(document);
+    content2.setAttribute('select', 'span');
+    content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+    content1.appendChild(content2);
+
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content1);
+    root.appendChild(document.createTextNode("}"));
+
+    document.getElementById('actual-container').appendChild(target);
+    document.getElementById('expect-container').innerHTML =
+        "<div>{SHADOW: <span>S1</span><span>S2</span>}</div>";
+}
+
+function testContentInContentFallback() {
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content2 = internals.createContentElement(document);
+    content2.setAttribute('select', 'div');
+    content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+    content1.appendChild(content2);
+
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content1);
+    root.appendChild(document.createTextNode("}"));
+
+    document.getElementById('actual-container').appendChild(target);
+    document.getElementById('expect-container').innerHTML =
+        "<div>{SHADOW: <span>CONTENT 2 FALLBACK</span>}</div>";
+}
+
+function testContentInContentFallbackWithDisplayNone() {
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content2 = internals.createContentElement(document);
+    content2.setAttribute('select', 'div');
+    content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+    content1.appendChild(content2);
+
+    var s = createSpanWithText('NOT RENDERED');
+    s.style.display = 'none';
+    root.appendChild(s);
+    root.appendChild(document.createTextNode("{SHADOW: "));
+    root.appendChild(content1);
+    root.appendChild(document.createTextNode("}"));
+
+    document.getElementById('actual-container').appendChild(target);
+    document.getElementById('expect-container').innerHTML =
+        "<div>{SHADOW: <span>CONTENT 2 FALLBACK</span>}</div>";
+}
+
+function testContentInContentFallbackDirect() {
+    var target = document.createElement('div');
+    target.appendChild(createSpanWithText('S1'));
+    target.appendChild(createSpanWithText('S2'));
+
+    var root = internals.ensureShadowRoot(target);
+    var content2 = internals.createContentElement(document);
+    content2.setAttribute('select', 'div');
+    content2.appendChild(createSpanWithText('CONTENT 2 FALLBACK'));
+
+    var content1 = internals.createContentElement(document);
+    content1.setAttribute('select', 'div');
+    content1.appendChild(content2);
+
+    root.appendChild(content1);
+
+    document.getElementById('actual-container').appendChild(target);
+    document.getElementById('expect-container').innerHTML =
+        "<div><span>CONTENT 2 FALLBACK</span></div>";
+}
+
 var testFuncs = [
     testFallback,
     testFallbackDeep,
@@ -222,8 +348,13 @@
     testComplexFallback,
     testComplexFallbackDeep,
     testComplexFallbackAgain,
-    testComplexFallbackDeepAgain
-]
+    testComplexFallbackDeepAgain,
+    testContentkWithDisplayNone,
+    testContentInContent,
+    testContentInContentFallback,
+    testContentInContentFallbackWithDisplayNone,
+    testContentInContentFallbackDirect
+];
 
 function doTest() {
     layoutTestController.dumpAsText();

Modified: trunk/Source/WebCore/ChangeLog (108479 => 108480)


--- trunk/Source/WebCore/ChangeLog	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/Source/WebCore/ChangeLog	2012-02-22 12:06:34 UTC (rev 108480)
@@ -1,3 +1,33 @@
+2012-02-22  Shinya Kawanaka  <shin...@chromium.org>
+
+        firstRendererOf() should also return a fallback element renderer in NodeRenderingContext.
+        https://bugs.webkit.org/show_bug.cgi?id=79180
+
+        Reviewed by Hajime Morita.
+
+        Currently we have handled AttachingFallback in some special mannger, however if firstRendererOf
+        and lastRendererOf return a fallback element renderer, we don't need to handle it in such a manner.
+
+        We have introduced new attaching phase: AttachingFallbacked, and AttachingNotFallbacked.
+        They are used for fallback elements.
+
+        Added new test cases in:
+          fast/dom/shadow/shadow-contents-fallback.html
+          fast/dom/shadow/shadow-contents-fallback-dynamic.html
+
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::NodeRenderingContext::NodeRenderingContext):
+        (WebCore::firstRendererOf):
+        (WebCore::lastRendererOf):
+        (WebCore::NodeRenderingContext::nextRenderer):
+        (WebCore::NodeRenderingContext::previousRenderer):
+        (WebCore::NodeRenderingContext::shouldCreateRenderer):
+        * dom/NodeRenderingContext.h:
+        * html/shadow/InsertionPoint.h:
+        (WebCore::isInsertionPoint):
+        (WebCore):
+        (WebCore::toInsertionPoint):
+
 2012-02-22  Csaba Osztrogonác  <o...@webkit.org>
 
         [Qt] Unreviewed gardening after r108464.

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (108479 => 108480)


--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp	2012-02-22 12:06:34 UTC (rev 108480)
@@ -79,13 +79,13 @@
             return;
         }
 
-        if (parent->isContentElement()) {
-            HTMLContentElement* shadowContentElement = toHTMLContentElement(parent);
-            if (!shadowContentElement->hasSelection()) {
-                m_phase = AttachingFallback;
-                m_parentNodeForRenderingAndStyle = NodeRenderingContext(parent).parentNodeForRenderingAndStyle();
-                return;
-            }
+        if (isInsertionPoint(parent)) {
+            if (toInsertionPoint(parent)->hasSelection())
+                m_phase = AttachingNotFallbacked;
+            else
+                m_phase = AttachingFallbacked;
+            m_parentNodeForRenderingAndStyle = NodeRenderingContext(parent).parentNodeForRenderingAndStyle();
+            return;
         }
     }
 
@@ -149,22 +149,30 @@
 
 static RenderObject* firstRendererOf(InsertionPoint* parent)
 {
-    for (HTMLContentSelection* selection = parent->selections()->first(); selection; selection = selection->next()) {
-        if (RenderObject* renderer = selection->node()->renderer())
-            return renderer;
+    if (parent->hasSelection()) {
+        for (HTMLContentSelection* selection = parent->selections()->first(); selection; selection = selection->next()) {
+            if (RenderObject* renderer = selection->node()->renderer())
+                return renderer;
+        }
+
+        return 0;
     }
 
-    return 0;
+    return NodeRenderingContext(parent).nextRenderer();
 }
 
 static RenderObject* lastRendererOf(InsertionPoint* parent)
 {
-    for (HTMLContentSelection* selection = parent->selections()->last(); selection; selection = selection->previous()) {
-        if (RenderObject* renderer = selection->node()->renderer())
-            return renderer;
+    if (parent->hasSelection()) {
+        for (HTMLContentSelection* selection = parent->selections()->last(); selection; selection = selection->previous()) {
+            if (RenderObject* renderer = selection->node()->renderer())
+                return renderer;
+        }
+
+        return 0;
     }
 
-    return 0;
+    return NodeRenderingContext(parent).previousRenderer();
 }
 
 RenderObject* NodeRenderingContext::nextRenderer() const
@@ -182,9 +190,9 @@
         return NodeRenderingContext(m_insertionPoint).nextRenderer();
     }
 
-    // Avoid an O(n^2) problem with this function by not checking for
+    // Avoid an O(N^2) problem with this function by not checking for
     // nextRenderer() when the parent element hasn't attached yet.
-    if (m_node->parentOrHostNode() && !m_node->parentOrHostNode()->attached() && m_phase != AttachingFallback)
+    if (m_node->parentOrHostNode() && !m_node->parentOrHostNode()->attached())
         return 0;
 
     for (Node* node = m_node->nextSibling(); node; node = node->nextSibling()) {
@@ -194,15 +202,13 @@
                 continue;
             return node->renderer();
         }
-        if (node->isContentElement()) {
-            if (RenderObject* first = firstRendererOf(toHTMLContentElement(node)))
+
+        if (isInsertionPoint(node)) {
+            if (RenderObject* first = firstRendererOf(toInsertionPoint(node)))
                 return first;
         }
     }
 
-    if (m_phase == AttachingFallback)
-        return NodeRenderingContext(m_node->parentNode()).nextRenderer();
-
     return 0;
 }
 
@@ -231,15 +237,12 @@
                 continue;
             return node->renderer();
         }
-        if (node->isContentElement()) {
-            if (RenderObject* last = lastRendererOf(toHTMLContentElement(node)))
+        if (isInsertionPoint(node)) {
+            if (RenderObject* last = lastRendererOf(toInsertionPoint(node)))
                 return last;
         }
     }
 
-    if (m_phase == AttachingFallback)
-        return NodeRenderingContext(m_node->parentNode()).previousRenderer();
-
     return 0;
 }
 
@@ -268,7 +271,7 @@
     ASSERT(m_phase != Calculating);
     ASSERT(parentNodeForRenderingAndStyle());
 
-    if (m_phase == AttachingNotInTree || m_phase == AttachingNotDistributed)
+    if (m_phase == AttachingNotInTree || m_phase == AttachingNotDistributed || m_phase == AttachingNotFallbacked)
         return false;
 
     RenderObject* parentRenderer = this->parentRenderer();

Modified: trunk/Source/WebCore/dom/NodeRenderingContext.h (108479 => 108480)


--- trunk/Source/WebCore/dom/NodeRenderingContext.h	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.h	2012-02-22 12:06:34 UTC (rev 108480)
@@ -71,10 +71,11 @@
         Calculating,
         AttachingStraight,
         AttachingNotInTree,
+        AttachingDistributed,
         AttachingNotDistributed,
-        AttachingDistributed,
+        AttachingFallbacked,
+        AttachingNotFallbacked,
         AttachingShadowChild,
-        AttachingFallback,
     };
 
     AttachingPhase m_phase;

Modified: trunk/Source/WebCore/html/shadow/InsertionPoint.h (108479 => 108480)


--- trunk/Source/WebCore/html/shadow/InsertionPoint.h	2012-02-22 11:46:50 UTC (rev 108479)
+++ trunk/Source/WebCore/html/shadow/InsertionPoint.h	2012-02-22 12:06:34 UTC (rev 108480)
@@ -48,6 +48,22 @@
     HTMLContentSelectionList m_selections;
 };
 
+inline bool isInsertionPoint(Node* node)
+{
+    // FIXME: <shadow> should also be InsertionPoint.
+    // https://bugs.webkit.org/show_bug.cgi?id=78596
+    if (!node || node->isContentElement())
+        return true;
+
+    return false;
+}
+
+inline InsertionPoint* toInsertionPoint(Node* node)
+{
+    ASSERT(isInsertionPoint(node));
+    return static_cast<InsertionPoint*>(node);
+}
+
 } // namespace WebCore
 
 #endif // InsertionPoint_h
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to