Title: [118945] trunk
Revision
118945
Author
[email protected]
Date
2012-05-30 11:36:00 -0700 (Wed, 30 May 2012)

Log Message

comparePositions in htmlediting should consider nested Shadow DOM.
https://bugs.webkit.org/show_bug.cgi?id=87623

Reviewed by Ryosuke Niwa.

Source/WebCore:

comparePositions in htmlediting.cpp didn't consider nested Shadow DOM.
This patch makes it possible to compare the nodes in nested Shadow DOM.

The algorithm is: we calculate the common tree scope of node A and B, and
adjust the nodes to the treeScope, then compare them. If the adjusted nodes
are the same, we check the shadow descendent of each node.

Test: editing/shadow/compare-positions-in-nested-shadow.html

* dom/TreeScope.cpp:
(WebCore::listTreeScopes):
(WebCore):
(WebCore::commonTreeScope):
* dom/TreeScope.h:
(WebCore):
* editing/htmlediting.cpp:
(WebCore::comparePositions):

LayoutTests:

* editing/shadow/compare-positions-in-nested-shadow-expected.txt: Added.
* editing/shadow/compare-positions-in-nested-shadow.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (118944 => 118945)


--- trunk/LayoutTests/ChangeLog	2012-05-30 18:33:02 UTC (rev 118944)
+++ trunk/LayoutTests/ChangeLog	2012-05-30 18:36:00 UTC (rev 118945)
@@ -1,3 +1,13 @@
+2012-05-30  Shinya Kawanaka  <[email protected]>
+
+        comparePositions in htmlediting should consider nested Shadow DOM.
+        https://bugs.webkit.org/show_bug.cgi?id=87623
+
+        Reviewed by Ryosuke Niwa.
+
+        * editing/shadow/compare-positions-in-nested-shadow-expected.txt: Added.
+        * editing/shadow/compare-positions-in-nested-shadow.html: Added.
+
 2012-05-30  Erik Arvidsson  <[email protected]>
 
         [V8] Clean up V8LazyEventListener to use one less function call

Added: trunk/LayoutTests/editing/shadow/compare-positions-in-nested-shadow-expected.txt (0 => 118945)


--- trunk/LayoutTests/editing/shadow/compare-positions-in-nested-shadow-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/shadow/compare-positions-in-nested-shadow-expected.txt	2012-05-30 18:36:00 UTC (rev 118945)
@@ -0,0 +1,7 @@
+PASS selection2.anchorNode is selection2.focusNode
+PASS selection2.anchorOffset is 5
+PASS selection2.focusOffset is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/editing/shadow/compare-positions-in-nested-shadow.html (0 => 118945)


--- trunk/LayoutTests/editing/shadow/compare-positions-in-nested-shadow.html	                        (rev 0)
+++ trunk/LayoutTests/editing/shadow/compare-positions-in-nested-shadow.html	2012-05-30 18:36:00 UTC (rev 118945)
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script src=""
+<script src=""
+
+<div id="host1"></div>
+<div id="host2"></div>
+<pre id="console"></pre>
+
+<script>
+function createBox(name) {
+    var div = document.createElement('div');
+    div.style.width = '100px';
+    div.style.height = '100px';
+    return div;
+}
+
+function createNestedShadowDOM(host, content) {
+    var shadowRoot = new WebKitShadowRoot(host);
+    var div = document.createElement('div');
+    shadowRoot.appendChild(div);
+
+    var nestedShadowRoot = new WebKitShadowRoot(div);
+    var divInNestedShadowRoot = document.createElement('div');
+    divInNestedShadowRoot.innerHTML = content;
+    nestedShadowRoot.appendChild(divInNestedShadowRoot);
+
+    return nestedShadowRoot;
+}
+
+var nestedShadowRoot1 = createNestedShadowDOM(host1, 'FUTAMI');
+var nestedShadowRoot2 = createNestedShadowDOM(host2, 'AMAMI');
+
+var div1 = nestedShadowRoot1.firstChild;
+var div2 = nestedShadowRoot2.firstChild;
+
+if (window.eventSender) {
+    mouseMoveToElem(div2);
+    eventSender.mouseDown();
+    mouseMoveToElem(div1);
+    eventSender.mouseUp();
+
+    var selection2 = nestedShadowRoot2.getSelection();
+    shouldBe('selection2.anchorNode', 'selection2.focusNode');
+
+    shouldBe('selection2.anchorOffset', '5');
+    shouldBe('selection2.focusOffset', '0');
+}
+
+var successfullyParsed = true;
+</script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (118944 => 118945)


--- trunk/Source/WebCore/ChangeLog	2012-05-30 18:33:02 UTC (rev 118944)
+++ trunk/Source/WebCore/ChangeLog	2012-05-30 18:36:00 UTC (rev 118945)
@@ -1,3 +1,28 @@
+2012-05-30  Shinya Kawanaka  <[email protected]>
+
+        comparePositions in htmlediting should consider nested Shadow DOM.
+        https://bugs.webkit.org/show_bug.cgi?id=87623
+
+        Reviewed by Ryosuke Niwa.
+
+        comparePositions in htmlediting.cpp didn't consider nested Shadow DOM.
+        This patch makes it possible to compare the nodes in nested Shadow DOM.
+
+        The algorithm is: we calculate the common tree scope of node A and B, and
+        adjust the nodes to the treeScope, then compare them. If the adjusted nodes
+        are the same, we check the shadow descendent of each node.
+
+        Test: editing/shadow/compare-positions-in-nested-shadow.html
+
+        * dom/TreeScope.cpp:
+        (WebCore::listTreeScopes):
+        (WebCore):
+        (WebCore::commonTreeScope):
+        * dom/TreeScope.h:
+        (WebCore):
+        * editing/htmlediting.cpp:
+        (WebCore::comparePositions):
+
 2012-05-30  Erik Arvidsson  <[email protected]>
 
         [V8] Clean up V8LazyEventListener to use one less function call

Modified: trunk/Source/WebCore/dom/TreeScope.cpp (118944 => 118945)


--- trunk/Source/WebCore/dom/TreeScope.cpp	2012-05-30 18:33:02 UTC (rev 118944)
+++ trunk/Source/WebCore/dom/TreeScope.cpp	2012-05-30 18:36:00 UTC (rev 118945)
@@ -41,6 +41,7 @@
 #include "Page.h"
 #include "ShadowRoot.h"
 #include "TreeScopeAdopter.h"
+#include <wtf/Vector.h>
 #include <wtf/text/AtomicString.h>
 #include <wtf/text/CString.h>
 
@@ -231,5 +232,38 @@
     return node;
 }
 
+static void listTreeScopes(Node* node, Vector<TreeScope*, 5>& treeScopes)
+{
+    while (true) {
+        treeScopes.append(node->treeScope());
+        Node* ancestor = node->shadowAncestorNode();
+        if (node == ancestor)
+            break;
+        node = ancestor;
+    }
+}
+
+TreeScope* commonTreeScope(Node* nodeA, Node* nodeB)
+{
+    if (!nodeA || !nodeB)
+        return 0;
+
+    if (nodeA->treeScope() == nodeB->treeScope())
+        return nodeA->treeScope();
+
+    Vector<TreeScope*, 5> treeScopesA;
+    listTreeScopes(nodeA, treeScopesA);
+
+    Vector<TreeScope*, 5> treeScopesB;
+    listTreeScopes(nodeB, treeScopesB);
+
+    size_t indexA = treeScopesA.size();
+    size_t indexB = treeScopesB.size();
+
+    for (; indexA > 0 && indexB > 0 && treeScopesA[indexA - 1] == treeScopesB[indexB - 1]; --indexA, --indexB) { }
+
+    return treeScopesA[indexA] == treeScopesB[indexB] ? treeScopesA[indexA] : 0;
+}
+
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/dom/TreeScope.h (118944 => 118945)


--- trunk/Source/WebCore/dom/TreeScope.h	2012-05-30 18:33:02 UTC (rev 118944)
+++ trunk/Source/WebCore/dom/TreeScope.h	2012-05-30 18:36:00 UTC (rev 118945)
@@ -110,6 +110,8 @@
     return m_elementsById.containsMultiple(id.impl());
 }
 
+TreeScope* commonTreeScope(Node*, Node*);
+
 } // namespace WebCore
 
 #endif // TreeScope_h

Modified: trunk/Source/WebCore/editing/htmlediting.cpp (118944 => 118945)


--- trunk/Source/WebCore/editing/htmlediting.cpp	2012-05-30 18:33:02 UTC (rev 118944)
+++ trunk/Source/WebCore/editing/htmlediting.cpp	2012-05-30 18:36:00 UTC (rev 118945)
@@ -72,32 +72,28 @@
 // could be inside a shadow tree. Only works for non-null values.
 int comparePositions(const Position& a, const Position& b)
 {
-    Node* nodeA = a.deprecatedNode();
+    TreeScope* commonScope = commonTreeScope(a.containerNode(), b.containerNode());
+
+    ASSERT(commonScope);
+    if (!commonScope)
+        return 0;
+
+    Node* nodeA = commonScope->ancestorInThisScope(a.deprecatedNode());
     ASSERT(nodeA);
-    Node* nodeB = b.deprecatedNode();
+    bool hasDescendentA = nodeA != a.deprecatedNode();
+    int offsetA = hasDescendentA ? 0 : a.deprecatedEditingOffset();
+
+    Node* nodeB = commonScope->ancestorInThisScope(b.deprecatedNode());
     ASSERT(nodeB);
-    int offsetA = a.deprecatedEditingOffset();
-    int offsetB = b.deprecatedEditingOffset();
+    bool hasDescendentB = nodeB != b.deprecatedNode();
+    int offsetB = hasDescendentB ? 0 : b.deprecatedEditingOffset();
 
-    Node* shadowAncestorA = nodeA->shadowAncestorNode();
-    if (shadowAncestorA == nodeA)
-        shadowAncestorA = 0;
-    Node* shadowAncestorB = nodeB->shadowAncestorNode();
-    if (shadowAncestorB == nodeB)
-        shadowAncestorB = 0;
-
     int bias = 0;
-    if (shadowAncestorA != shadowAncestorB) {
-        if (shadowAncestorA) {
-            nodeA = shadowAncestorA;
-            offsetA = 0;
-            bias = 1;
-        }
-        if (shadowAncestorB) {
-            nodeB = shadowAncestorB;
-            offsetB = 0;
+    if (nodeA == nodeB) {
+        if (hasDescendentA)
             bias = -1;
-        }
+        else if (hasDescendentB)
+            bias = 1;
     }
 
     ExceptionCode ec;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to