WebCore:
authorjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 May 2008 18:59:37 +0000 (18:59 +0000)
committerjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 May 2008 18:59:37 +0000 (18:59 +0000)
2008-05-07  Justin Garcia  <justin.garcia@apple.com>

        Reviewed by John Sullivan.

        <rdar://problem/5666354> Crashes in Mail at WebCore::RemoveNodeCommand::doApply

        When a single tab or series of tabs was copied, we weren't putting them into a
        tab span.  On Paste, we would be given a text node with a single tab or series
        of tabs in it, and we would crash when inserting it at the start of a block
        (where that kind of text becomes completely unrendered).

        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds): Clean
        up correctly and early return if we removed everything that was inserted.
        * editing/markup.cpp:
        (WebCore::createMarkup):  Include the tab span when the only thing copied
        was a tab or a series of tabs.

LayoutTests:

2008-05-07  Justin Garcia  <justin.garcia@apple.com>

        Reviewed by John Sullivan.

        <rdar://problem/5666354> Crashes in Mail at WebCore::RemoveNodeCommand::doApply

        * editing/pasteboard/5761530-1-expected.txt: Added.
        * editing/pasteboard/5761530-1.html: Added.
        * editing/pasteboard/5761530-2-expected.txt: Added.
        * editing/pasteboard/5761530-2.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/5761530-1-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/5761530-1.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/5761530-2-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/5761530-2.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/editing/ReplaceSelectionCommand.cpp
WebCore/editing/markup.cpp

index 12b7939..ca1b8ed 100644 (file)
@@ -1,3 +1,14 @@
+2008-05-07  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by John Sullivan.
+
+        <rdar://problem/5666354> Crashes in Mail at WebCore::RemoveNodeCommand::doApply
+
+        * editing/pasteboard/5761530-1-expected.txt: Added.
+        * editing/pasteboard/5761530-1.html: Added.
+        * editing/pasteboard/5761530-2-expected.txt: Added.
+        * editing/pasteboard/5761530-2.html: Added.
+
 2008-05-07  David Kilzer  <ddkilzer@apple.com>
 
         Bug 18900: Password field has focus but can't type text (i.rememberthemilk.com)
diff --git a/LayoutTests/editing/pasteboard/5761530-1-expected.txt b/LayoutTests/editing/pasteboard/5761530-1-expected.txt
new file mode 100644 (file)
index 0000000..30ecdfe
--- /dev/null
@@ -0,0 +1,3 @@
+This tests to see that tabs are put into tab spans when they are copied individually. The pasted tab should be inside of a tab span, not a style span. To run the test manually, paste and then inspect the editable region, and ensure that there is a tab span at the beginning of the editable div.
+
+<span class="Apple-tab-span" style="white-space: pre; ">       </span><span class="Apple-tab-span" style="white-space:pre;"> </span>xxx
diff --git a/LayoutTests/editing/pasteboard/5761530-1.html b/LayoutTests/editing/pasteboard/5761530-1.html
new file mode 100644 (file)
index 0000000..478c326
--- /dev/null
@@ -0,0 +1,15 @@
+<div id="description">This tests to see that tabs are put into tab spans when they are copied individually.  The pasted tab should be inside of a tab span, not a style span.  To run the test manually, paste and then inspect the editable region, and ensure that there is a tab span at the beginning of the editable div.</div>
+<div id="edit" contenteditable="true"><span class="Apple-tab-span" style="white-space:pre;">   </span>xxx</div>
+<script>
+if (window.layoutTestController)
+       window.layoutTestController.dumpAsText();
+edit = document.getElementById("edit");
+
+window.getSelection().setPosition(edit, 0);
+window.getSelection().modify("extend", "forward", "character");
+document.execCommand("Copy");
+window.getSelection().modify("move", "backward", "character");
+document.execCommand("Paste");
+if (window.layoutTestController)
+    document.body.innerText = document.getElementById("description").innerText + "\n\n" + edit.innerHTML;
+</script>
diff --git a/LayoutTests/editing/pasteboard/5761530-2-expected.txt b/LayoutTests/editing/pasteboard/5761530-2-expected.txt
new file mode 100644 (file)
index 0000000..7ca90e1
--- /dev/null
@@ -0,0 +1 @@
+This tests for a crash when inserting a text node at the start of a block where it will be become unrendered. The test should not crash.
diff --git a/LayoutTests/editing/pasteboard/5761530-2.html b/LayoutTests/editing/pasteboard/5761530-2.html
new file mode 100644 (file)
index 0000000..9a6051b
--- /dev/null
@@ -0,0 +1,11 @@
+<div id="description">This tests for a crash when inserting a text node at the start of a block where it will be become unrendered. The test should not crash.</div>
+<div id="edit" contenteditable="true"><span class="Apple-tab-span" style="white-space:pre;">   </span>xxx</div>
+<script>
+if (window.layoutTestController)
+    window.layoutTestController.dumpAsText();
+edit = document.getElementById("edit");
+window.getSelection().setPosition(edit, 0);
+document.execCommand("InsertHTML", false, "    ");
+if (window.layoutTestController)
+    document.body.innerText = document.getElementById("description").innerText;
+</script>
index 535c74d..032e31a 100644 (file)
@@ -1,3 +1,21 @@
+2008-05-07  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by John Sullivan.
+
+        <rdar://problem/5666354> Crashes in Mail at WebCore::RemoveNodeCommand::doApply
+        
+        When a single tab or series of tabs was copied, we weren't putting them into a 
+        tab span.  On Paste, we would be given a text node with a single tab or series
+        of tabs in it, and we would crash when inserting it at the start of a block
+        (where that kind of text becomes completely unrendered).
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds): Clean
+        up correctly and early return if we removed everything that was inserted.
+        * editing/markup.cpp:
+        (WebCore::createMarkup):  Include the tab span when the only thing copied
+        was a tab or a series of tabs.
+
 2008-05-07  Julien Chaffraix  <jchaffraix@webkit.org>
 
         Reviewed by Adam Roben.
index d2f51e0..d2c5166 100644 (file)
@@ -399,7 +399,13 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds()
         m_lastLeafInserted->isTextNode() && 
         !enclosingNodeWithTag(Position(m_lastLeafInserted.get(), 0), selectTag) && 
         !enclosingNodeWithTag(Position(m_lastLeafInserted.get(), 0), scriptTag)) {
-        RefPtr<Node> previous = m_firstNodeInserted == m_lastLeafInserted ? 0 : m_lastLeafInserted->traversePreviousNode();
+        if (m_firstNodeInserted == m_lastLeafInserted) {
+            removeNode(m_lastLeafInserted.get());
+            m_lastLeafInserted = 0;
+            m_firstNodeInserted = 0;
+            return;
+        }
+        RefPtr<Node> previous = m_lastLeafInserted->traversePreviousNode();
         removeNode(m_lastLeafInserted.get());
         m_lastLeafInserted = previous;
     }
@@ -408,7 +414,13 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds()
     // it is a top level node in the fragment and the user can't insert into those elements.
     if (!m_firstNodeInserted->renderer() && 
         m_firstNodeInserted->isTextNode()) {
-        RefPtr<Node> next = m_firstNodeInserted == m_lastLeafInserted ? 0 : m_firstNodeInserted->traverseNextSibling();
+        if (m_firstNodeInserted == m_lastLeafInserted) {
+            removeNode(m_firstNodeInserted.get());
+            m_firstNodeInserted = 0;
+            m_lastLeafInserted = 0;
+            return;
+        }
+        RefPtr<Node> next = m_firstNodeInserted->traverseNextSibling();
         removeNode(m_firstNodeInserted.get());
         m_firstNodeInserted = next;
     }
index 7b36769..d6e2107 100644 (file)
@@ -845,6 +845,15 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
             specialCommonAncestor = enclosingNodeOfType(Position(checkAncestor, 0), &elementHasTextDecorationProperty);
     }
     
+    // If a single tab is selected, commonAncestor will be a text node inside a tab span.
+    // If two or more tabs are selected, commonAncestor will be the tab span.
+    // In either case, if there is a specialCommonAncestor already, it will necessarily be above 
+    // any tab span that needs to be included.
+    if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor))
+        specialCommonAncestor = commonAncestor->parentNode();
+    if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
+        specialCommonAncestor = commonAncestor;
+        
     if (Node *enclosingAnchor = enclosingNodeWithTag(Position(specialCommonAncestor ? specialCommonAncestor : commonAncestor, 0), aTag))
         specialCommonAncestor = enclosingAnchor;