2010-02-23 Tony Chang <tony@chromium.org>
authortony@chromium.org <tony@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Feb 2010 01:46:46 +0000 (01:46 +0000)
committertony@chromium.org <tony@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Feb 2010 01:46:46 +0000 (01:46 +0000)
        Reviewed by Eric Seidel.

        https://bugs.webkit.org/show_bug.cgi?id=34634
        Pasting a list into the middle of another list item should split the target
        list item into two separate list items.  This matches the behavior in other
        browsers.

        * editing/pasteboard/paste-list-004-expected.txt: Added.
        * editing/pasteboard/paste-list-004.html: Added.
2010-02-23  Tony Chang  <tony@chromium.org>

        Reviewed by Eric Seidel.

        https://bugs.webkit.org/show_bug.cgi?id=34634
        Pasting a list into the middle of another list item should split the target
        list item into two separate list items.  This matches the behavior in other
        browsers.

        Test: editing/pasteboard/paste-list-004.html

        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::insertAsListItems):

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

LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/paste-list-004-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/paste-list-004.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/editing/ReplaceSelectionCommand.cpp

index 763a9e2..427cb01 100644 (file)
@@ -1,3 +1,15 @@
+2010-02-23  Tony Chang  <tony@chromium.org>
+
+        Reviewed by Eric Seidel.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34634
+        Pasting a list into the middle of another list item should split the target
+        list item into two separate list items.  This matches the behavior in other
+        browsers.
+
+        * editing/pasteboard/paste-list-004-expected.txt: Added.
+        * editing/pasteboard/paste-list-004.html: Added.
+
 2010-02-23  Alexey Proskuryakov  <ap@apple.com>
 
         Reviewed by Mark Rowe.
diff --git a/LayoutTests/editing/pasteboard/paste-list-004-expected.txt b/LayoutTests/editing/pasteboard/paste-list-004-expected.txt
new file mode 100644 (file)
index 0000000..4c60579
--- /dev/null
@@ -0,0 +1,14 @@
+Pasting a list item into the middle of another list item should split the target list item into two with the pasted content in between.
+
+one two: one two
+three: three
+one two: one two
+:
+four: four
+monsters walking: <span style="background-color:green"><b>monsters walking</b></span>
+one two: one two
+:
+cross the floor: <span style="background-color:green"><b>cross the floor</b></span>
+PASS
+
+
diff --git a/LayoutTests/editing/pasteboard/paste-list-004.html b/LayoutTests/editing/pasteboard/paste-list-004.html
new file mode 100644 (file)
index 0000000..88d7c23
--- /dev/null
@@ -0,0 +1,73 @@
+<body contentEditable="true">
+<p>Pasting a list item into the middle of another list item should split the target list
+item into two with the pasted content in between.</p>
+<ul>
+    <li id="test">one two</li>
+    <li>three four</li>
+    <li><span style="background-color:green"><b>monsters walking cross the floor</b></span></li>
+</ul>
+
+<p id="results">FAIL</p>
+</body>
+<script src="../editing.js"></script>
+<script>
+function escapeHTML(text)
+{
+    return text.replace(/&/g, "&amp;").replace(/</g, "&lt;");
+}
+
+function editingTest()
+{
+    // Select the first list item.
+    extendSelectionForwardByLineCommand();
+    copyCommand();
+
+    // Place the cursor between "three" and "four".
+    moveSelectionForwardByLineCommand();
+    moveSelectionForwardByWordCommand();
+
+    pasteCommand();
+
+    // Place the cursor between "walking" and "cross"
+    for (var i = 0; i < 2; ++i)
+        moveSelectionForwardByLineCommand();
+    for (var i = 0; i < 2; ++i)
+        moveSelectionForwardByWordCommand();
+
+    pasteCommand();
+
+    // Verify that the list is as expected.
+    var listItems = document.getElementsByTagName("li");
+    var results = [
+        "one two",
+        "three",
+        "one two",
+        "",
+        "four",
+        "monsters walking",
+        "one two",
+        "",
+        "cross the floor"
+        ];
+    if (listItems.length != 9)
+        throw "Expected 8 list items, found " + listItems.length;
+    for (var i = 0; i < results.length; ++i) {
+        var actual = listItems[i].innerText.replace(/^\s+/g, "");
+        if (results[i] != actual)
+            throw "Unexpected list item: " + i + "," + results[i] + "," + listItems[i].innerText;
+    }
+
+    // Verify that the cursor is in the right place (on the blank line).
+    var selection = window.getSelection();
+    if (selection.baseNode != listItems[7] || selection.baseOffset != 0 || !selection.isCollapsed)
+        throw "Wrong selection position";
+
+    for (var i = 0; i < listItems.length; ++i) {
+      listItems[i].innerHTML = listItems[i].innerHTML.replace(/&nbsp;/g, "");
+      listItems[i].innerHTML += ": " + escapeHTML(listItems[i].innerHTML);
+    }
+}
+
+runDumpAsTextEditingTest(false);
+document.getElementById("results").innerText = "PASS";
+</script>
index cd85ac2..21daa72 100644 (file)
@@ -1,3 +1,17 @@
+2010-02-23  Tony Chang  <tony@chromium.org>
+
+        Reviewed by Eric Seidel.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34634
+        Pasting a list into the middle of another list item should split the target
+        list item into two separate list items.  This matches the behavior in other
+        browsers.
+
+        Test: editing/pasteboard/paste-list-004.html
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::insertAsListItems):
+
 2010-02-23  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Tim Hatcher and Pavel Feldman.
index bac090c..0e5696e 100644 (file)
@@ -1170,26 +1170,34 @@ Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr<Node> listElement, N
 
     bool isStart = isStartOfParagraph(insertPos);
     bool isEnd = isEndOfParagraph(insertPos);
-
+    bool isMiddle = !isStart && !isEnd;
     Node* lastNode = insertionBlock;
+
+    // If we're in the middle of a list item, we should split it into two separate
+    // list items and insert these nodes between them.
+    if (isMiddle) {
+        int textNodeOffset = insertPos.offsetInContainerNode();
+        if (insertPos.node()->isTextNode() && textNodeOffset > 0)
+            splitTextNode(static_cast<Text*>(insertPos.node()), textNodeOffset);
+        splitTreeToNode(insertPos.node(), lastNode, true);
+    }
+
     while (RefPtr<Node> listItem = listElement->firstChild()) {
         ExceptionCode ec = 0;
         listElement->removeChild(listItem.get(), ec);
         ASSERT(!ec);
-        if (isStart)
+        if (isStart || isMiddle)
             insertNodeBefore(listItem, lastNode);
         else if (isEnd) {
             insertNodeAfter(listItem, lastNode);
             lastNode = listItem.get();
-        } else {
-            // FIXME: If we're in the middle of a list item, we should split it into two separate
-            // list items and insert these nodes between them.  For now, just append the nodes.
-            insertNodeAfter(listItem, lastNode);
-            lastNode = listItem.get();
-        }
+        } else
+            ASSERT_NOT_REACHED();
     }
-    if (isStart)
+    if (isStart || isMiddle)
         lastNode = lastNode->previousSibling();
+    if (isMiddle)
+        insertNodeAfter(createListItemElement(document()), lastNode);
     updateNodesInserted(lastNode);
     return lastNode;
 }