WebCore:
authorbfulgham@webkit.org <bfulgham@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 28 Jun 2009 03:13:52 +0000 (03:13 +0000)
committerbfulgham@webkit.org <bfulgham@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 28 Jun 2009 03:13:52 +0000 (03:13 +0000)
2009-06-27  Ryosuke Niwa  <rniwa@google.com>

        Reviewed by Eric Seidel.

        https://bugs.webkit.org/show_bug.cgi?id=26762

        Clean up for IndentOutdentCommand::indentRegion, and solved most of problems related to the bug 21712.
        https://bugs.webkit.org/show_bug.cgi?id=21712

        Added few utility functions to htmlediting.h/cpp

        isVisibilyAdjacent checks whether the first position is visibly next to the second position.
        i.e. there is no visible node between the first and second positions

        canMergeLists checks whether two lists can be merged.
        It checks the type of list, the editing boundary, and adjacency of the lists.

        Tests: editing/execCommand/indent-nested-lists-1.html
               editing/execCommand/indent-nested-lists-2.html
               editing/execCommand/indent-nested-lists-3.html
               editing/execCommand/indent-nested-lists-4.html
               editing/execCommand/indent-nested-lists-5.html
               editing/execCommand/indent-nested-lists-6.html
               editing/execCommand/indent-nested-lists-7.html
               editing/execCommand/outdent-nested-lists-1.html
               editing/execCommand/outdent-nested-lists-2.html
               editing/execCommand/outdent-nested-lists-3.html
               editing/execCommand/outdent-nested-lists-4.html

        * editing/IndentOutdentCommand.cpp:
        (WebCore::IndentOutdentCommand::prepareBlockquoteLevelForInsertion):
        (WebCore::IndentOutdentCommand::tryIndentingAsListItem):
        (WebCore::IndentOutdentCommand::indentIntoBlockquote):
        (WebCore::IndentOutdentCommand::indentRegion):
        * editing/IndentOutdentCommand.h:
        * editing/htmlediting.cpp:
        (WebCore::enclosingListChild):
        (WebCore::canMergeLists):
        (WebCore::isVisibilyAdjacent):
        * editing/htmlediting.h:

LayoutTests:

2009-06-27  Ryosuke Niwa  <set EMAIL_ADDRESS environment variable>

        Reviewed by Eric Seidel.

        https://bugs.webkit.org/show_bug.cgi?id=26762

        Clean up for IndentOutdentCommand::indentRegion, and solved most of problems related to the bug 21712.
        https://bugs.webkit.org/show_bug.cgi?id=21712

        The following test cases are intended for 21712, but included here
        since this patch already solved a lot of problems.

        * editing/execCommand/indent-nested-lists-1-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-1.html: Added.
        * editing/execCommand/indent-nested-lists-2-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-2.html: Added.
        * editing/execCommand/indent-nested-lists-3-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-3.html: Added.
        * editing/execCommand/indent-nested-lists-4-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-4.html: Added.
        * editing/execCommand/indent-nested-lists-5-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-5.html: Added.
        * editing/execCommand/indent-nested-lists-6-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-6.html: Added.
        * editing/execCommand/indent-nested-lists-7-expected.txt: Added.
        * editing/execCommand/indent-nested-lists-7.html: Added.
        * editing/execCommand/outdent-nested-lists-1-expected.txt: Added.
        * editing/execCommand/outdent-nested-lists-1.html: Added.
        * editing/execCommand/outdent-nested-lists-2-expected.txt: Added.
        * editing/execCommand/outdent-nested-lists-2.html: Added.
        * editing/execCommand/outdent-nested-lists-3-expected.txt: Added.
        * editing/execCommand/outdent-nested-lists-3.html: Added.
        * editing/execCommand/outdent-nested-lists-4-expected.txt: Added.
        * editing/execCommand/outdent-nested-lists-4.html: Added.

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

28 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/execCommand/indent-nested-lists-1-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-1.html [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-2-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-2.html [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-3-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-3.html [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-4-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-4.html [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-5-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-5.html [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-6-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-6.html [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-7-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/indent-nested-lists-7.html [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-1-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-1.html [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-2-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-2.html [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-3-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-3.html [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-4-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/outdent-nested-lists-4.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/editing/IndentOutdentCommand.cpp
WebCore/editing/IndentOutdentCommand.h
WebCore/editing/htmlediting.cpp
WebCore/editing/htmlediting.h

index d649098..e975b0f 100644 (file)
@@ -1,3 +1,38 @@
+2009-06-27  Ryosuke Niwa  <set EMAIL_ADDRESS environment variable>
+
+        Reviewed by Eric Seidel.
+
+        https://bugs.webkit.org/show_bug.cgi?id=26762
+
+        Clean up for IndentOutdentCommand::indentRegion, and solved most of problems related to the bug 21712.
+        https://bugs.webkit.org/show_bug.cgi?id=21712
+        
+        The following test cases are intended for 21712, but included here
+        since this patch already solved a lot of problems.
+
+        * editing/execCommand/indent-nested-lists-1-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-1.html: Added.
+        * editing/execCommand/indent-nested-lists-2-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-2.html: Added.
+        * editing/execCommand/indent-nested-lists-3-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-3.html: Added.
+        * editing/execCommand/indent-nested-lists-4-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-4.html: Added.
+        * editing/execCommand/indent-nested-lists-5-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-5.html: Added.
+        * editing/execCommand/indent-nested-lists-6-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-6.html: Added.
+        * editing/execCommand/indent-nested-lists-7-expected.txt: Added.
+        * editing/execCommand/indent-nested-lists-7.html: Added.
+        * editing/execCommand/outdent-nested-lists-1-expected.txt: Added.
+        * editing/execCommand/outdent-nested-lists-1.html: Added.
+        * editing/execCommand/outdent-nested-lists-2-expected.txt: Added.
+        * editing/execCommand/outdent-nested-lists-2.html: Added.
+        * editing/execCommand/outdent-nested-lists-3-expected.txt: Added.
+        * editing/execCommand/outdent-nested-lists-3.html: Added.
+        * editing/execCommand/outdent-nested-lists-4-expected.txt: Added.
+        * editing/execCommand/outdent-nested-lists-4.html: Added.
+
 2009-06-27  Daniel Bates  <dbates@intudata.com>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-1-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-1-expected.txt
new file mode 100644 (file)
index 0000000..41ba507
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 9 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > OL > DIV > BODY > HTML > #document to 5 of #text > LI > OL > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three". You should see numbers 1 and 2 before "three" and "four" respectively.
+one
+two
+three
+four
+Before: <li>one</li> <li>two</li> <li id="test">three</li> <ol><li>four</li></ol>
+After: <li>one</li> <li>two</li> <ol><li id="test">three</li><li>four</li></ol>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-1.html b/LayoutTests/editing/execCommand/indent-nested-lists-1.html
new file mode 100644 (file)
index 0000000..c5e5461
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests indenting "three".  You should see numbers 1 and 2 before "three" and "four" respectively.
+<ol id="e" contenteditable="true">
+<li>one</li>
+<li>two</li>
+<li id="test">three</li>
+<ol><li>four</li></ol>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-2-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-2-expected.txt
new file mode 100644 (file)
index 0000000..c15aef4
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 9 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 4 of #text > LI > OL > DIV > BODY > HTML > #document to 4 of #text > LI > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three". You should see numbers 1 and 2 before "two" and "three" respectively.
+one
+two
+three
+four
+Before: <li>one</li> <ol><li>two</li></ol> <li id="test">three</li> <li>four</li>
+After: <li>one</li> <ol><li>two</li><li id="test">three</li></ol> <li>four</li>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-2.html b/LayoutTests/editing/execCommand/indent-nested-lists-2.html
new file mode 100644 (file)
index 0000000..4c7a23c
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests indenting "three".  You should see numbers 1 and 2 before "two" and "three" respectively.
+<ol id="e" contenteditable="true">
+<li>one</li>
+<ol><li>two</li></ol>
+<li id="test">three</li>
+<li>four</li>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-3-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-3-expected.txt
new file mode 100644 (file)
index 0000000..996afe0
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 4 of #text > LI > UL > BODY > HTML > #document to 2 of #text > SPAN > LI > UL > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three". You should see 1, 2, and 3 before "two", "three", and "four" respectively.
+one
+two
+three
+four
+Before: <li>one</li> <ol><li>two</li></ol> <li id="test">three</li> <ol><li>four</li></ol>
+After: <li>one</li> <ol><li>two</li><li id="test">three</li><li>four</li></ol>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-3.html b/LayoutTests/editing/execCommand/indent-nested-lists-3.html
new file mode 100644 (file)
index 0000000..4b61151
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div contenteditable="true">
+This tests indenting "three". You should see 1, 2, and 3 before "two", "three", and "four" respectively.
+<ol id="div">
+<li>one</li>
+<ol><li>two</li></ol>
+<li id="test">three</li>
+<ol><li>four</li></ol>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var div = document.getElementById('div');
+
+document.getElementById('c1').appendChild(document.createTextNode(div.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(div.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-4-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-4-expected.txt
new file mode 100644 (file)
index 0000000..c4fd0e5
--- /dev/null
@@ -0,0 +1,15 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 11 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 4 of #text > LI > UL > BODY > HTML > #document to 7 of #text > SPAN > LI > UL > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three" and "four". You should see 1 through 4 in order before numbers "two" through "five".
+one
+two
+three
+four
+five
+Before: <li>one</li> <ol><li>two</li></ol> <li id="test1">three</li> <li id="test2">four</li> <ol><li>five</li></ol>
+After: <li>one</li> <ol><li>two</li><li id="test1">three</li><li id="test2">four</li><li>five</li></ol>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-4.html b/LayoutTests/editing/execCommand/indent-nested-lists-4.html
new file mode 100644 (file)
index 0000000..1c77f58
--- /dev/null
@@ -0,0 +1,40 @@
+<html>
+<body>
+<div>
+This tests indenting "three" and "four".  You should see 1 through 4 in order before numbers "two" through "five".
+<ol id="e" contenteditable="true">
+<li>one</li>
+<ol><li>two</li></ol>
+<li id="test1">three</li>
+<li id="test2">four</li>
+<ol><li>five</li></ol>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.setStart(document.getElementById('test1'),0);
+r.setEnd(document.getElementById('test2'),1);
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-5-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-5-expected.txt
new file mode 100644 (file)
index 0000000..85db034
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 9 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 4 of #text > LI > UL > OL > DIV > BODY > HTML > #document to 4 of #text > LI > UL > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three". You should see 1, 2, and then a bullet before numbers "two", "three", and "four" respectively.
+one
+two
+three
+four
+Before: <li>one</li> <ol><li>two</li></ol> <li id="test">three</li> <ul><li>four</li></ul>
+After: <li>one</li> <ol><li>two</li><li id="test">three</li></ol> <ul><li>four</li></ul>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-5.html b/LayoutTests/editing/execCommand/indent-nested-lists-5.html
new file mode 100644 (file)
index 0000000..2c30f5f
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests indenting "three".  You should see 1, 2, and then a bullet before numbers "two", "three", and "four" respectively.
+<ol id="e" contenteditable="true">
+<li>one</li>
+<ol><li>two</li></ol>
+<li id="test">three</li>
+<ul><li>four</li></ul>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-6-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-6-expected.txt
new file mode 100644 (file)
index 0000000..48f312c
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 9 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > OL > DIV > BODY > HTML > #document to 5 of #text > LI > OL > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three". You should see a bullet then 1 and 2 before numbers "two", "three", and "four" respectively.
+one
+two
+three
+four
+Before: <li>one</li> <ul><li>two</li></ul> <li id="test">three</li> <ol><li>four</li></ol>
+After: <li>one</li> <ul><li>two</li></ul> <ol><li id="test">three</li><li>four</li></ol>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-6.html b/LayoutTests/editing/execCommand/indent-nested-lists-6.html
new file mode 100644 (file)
index 0000000..2a7179c
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests indenting "three".  You should see a bullet then 1 and 2 before numbers "two", "three", and "four" respectively.
+<ol id="e" contenteditable="true">
+<li>one</li>
+<ul><li>two</li></ul>
+<li id="test">three</li>
+<ol><li>four</li></ol>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-7-expected.txt b/LayoutTests/editing/execCommand/indent-nested-lists-7-expected.txt
new file mode 100644 (file)
index 0000000..e31db05
--- /dev/null
@@ -0,0 +1,16 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 11 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > OL > DIV > BODY > HTML > #document to 4 of #text > LI > OL > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests indenting "three" and "four". You should see 1 before "two", "three", and "five" but 2 before "four". Neither "two" nor "five" should be the part of new nested list since there is text between "two" and "three", and "five" is unordered.
+one
+two
+aaa
+three
+four
+five
+Before: <li>one</li> <ol><li>two</li></ol> aaa <li id="test3">three</li> <li id="test4">four</li> <ul><li>five</li></ul>
+After: <li>one</li> <ol><li>two</li></ol> aaa <ol><li id="test3">three</li><li id="test4">four</li></ol> <ul><li>five</li></ul>
diff --git a/LayoutTests/editing/execCommand/indent-nested-lists-7.html b/LayoutTests/editing/execCommand/indent-nested-lists-7.html
new file mode 100644 (file)
index 0000000..d88ba6c
--- /dev/null
@@ -0,0 +1,42 @@
+<html>
+<body>
+<div>
+This tests indenting "three" and "four".  You should see 1 before "two", "three", and "five" but 2 before "four".
+Neither "two" nor "five" should be the part of new nested list since there is text between "two" and "three", and "five" is unordered.
+<ol id="e" contenteditable="true">
+<li>one</li>
+<ol><li>two</li></ol>
+aaa
+<li id="test3">three</li>
+<li id="test4">four</li>
+<ul><li>five</li></ul>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.setStart(document.getElementById('test3'),0);
+r.setEnd(document.getElementById('test4'),1);
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Indent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-1-expected.txt b/LayoutTests/editing/execCommand/outdent-nested-lists-1-expected.txt
new file mode 100644 (file)
index 0000000..a76cd3f
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 7 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > DIV > BODY > HTML > #document to 5 of #text > LI > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests outdenting "three". You should see 2 and 3 before "three" and "four" respectively.
+one
+two
+three
+four
+Before: <li>one</li> <ol><li>two</li> <li id="test">three</li></ol> <li>four</li>
+After: <li>one</li> <ol><li>two</li> </ol><li>three</li> <li>four</li>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-1.html b/LayoutTests/editing/execCommand/outdent-nested-lists-1.html
new file mode 100644 (file)
index 0000000..ceb671c
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests outdenting "three".  You should see 2 and 3 before "three" and "four" respectively.
+<ol id="e" contenteditable="true">
+<li>one</li>
+<ol><li>two</li>
+<li id="test">three</li></ol>
+<li>four</li>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Outdent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-2-expected.txt b/LayoutTests/editing/execCommand/outdent-nested-lists-2-expected.txt
new file mode 100644 (file)
index 0000000..9d768f9
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 5 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > DIV > BODY > HTML > #document to 3 of #text > LI > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests outdenting "one". You see 1 before "one" but 1 and 2 before "two" and "three" respectively.
+one
+two
+three
+four
+Before: <ol><li id="test">one</li> <li>two</li> <li>three</li></ol> <li>four</li>
+After: <li>one</li><ol> <li>two</li> <li>three</li></ol> <li>four</li>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-2.html b/LayoutTests/editing/execCommand/outdent-nested-lists-2.html
new file mode 100644 (file)
index 0000000..028749f
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests outdenting "one".  You see 1 before "one" but 1 and 2 before "two" and "three" respectively.
+<ol id="e" contenteditable="true">
+<ol><li id="test">one</li>
+<li>two</li>
+<li>three</li></ol>
+<li>four</li>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Outdent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-3-expected.txt b/LayoutTests/editing/execCommand/outdent-nested-lists-3-expected.txt
new file mode 100644 (file)
index 0000000..9eb02c5
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of OL > DIV > BODY > HTML > #document to 5 of OL > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > DIV > BODY > HTML > #document to 3 of #text > LI > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests outdenting "two". You should see 1 before "one", "two", and "three" but 2 before "four".
+one
+two
+three
+four
+Before: <ol><li>one</li> <li id="test">two</li> <li>three</li></ol> <li>four</li>
+After: <ol><li>one</li> </ol><li>two</li><ol> <li>three</li></ol> <li>four</li>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-3.html b/LayoutTests/editing/execCommand/outdent-nested-lists-3.html
new file mode 100644 (file)
index 0000000..7be0734
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<div>
+This tests outdenting "two".  You should see 1 before "one", "two", and "three" but 2 before "four".
+<ol id="e" contenteditable="true">
+<ol><li>one</li>
+<li id="test">two</li>
+<li>three</li></ol>
+<li>four</li>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.selectNode(document.getElementById('test'));
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Outdent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-4-expected.txt b/LayoutTests/editing/execCommand/outdent-nested-lists-4-expected.txt
new file mode 100644 (file)
index 0000000..3c4184d
--- /dev/null
@@ -0,0 +1,14 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > LI > OL > DIV > BODY > HTML > #document to 4 of #text > LI > OL > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+This tests outdenting ordered lists that contains an unordered-list. You should see 1 through 3 before numbers "two" through "four".
+one
+two
+three
+four
+Before: <ol><li>one</li> <li id="start">two</li></ol> <ul><li>three</li></ul> <ol><li id="end">four</li></ol>
+After: <ol><li>one</li> </ol><li>two</li> <li>three</li> <li>four</li>
diff --git a/LayoutTests/editing/execCommand/outdent-nested-lists-4.html b/LayoutTests/editing/execCommand/outdent-nested-lists-4.html
new file mode 100644 (file)
index 0000000..3513d8b
--- /dev/null
@@ -0,0 +1,39 @@
+<html>
+<body>
+<div contenteditable="true">
+This tests outdenting ordered lists that contains an unordered-list.  You should see 1 through 3 before numbers "two" through "four".
+<ol id="e">
+<ol><li>one</li>
+<li id="start">two</li></ol>
+<ul><li>three</li></ul>
+<ol><li id="end">four</li></ol>
+</ol>
+</div>
+
+<ul>
+<li>Before:<span id="c1"></span></li>
+<li>After:<span id="c2"></span></li>
+</ul>
+
+<script type="text/javascript">
+
+if (window.layoutTestController) {
+    layoutTestController.dumpEditingCallbacks();
+    layoutTestController.dumpAsText();
+}
+
+var e = document.getElementById('e');
+
+document.getElementById('c1').appendChild(document.createTextNode(e.innerHTML));
+
+var s = window.getSelection();
+var r = document.createRange();
+r.setStart(document.getElementById('start'),0);
+r.setEnd(document.getElementById('end'),1);
+s.removeAllRanges();
+s.addRange(r);
+document.execCommand("Outdent", false, "");
+
+document.getElementById('c2').appendChild(document.createTextNode(e.innerHTML));
+
+</script>
index 56e4879..ee86866 100644 (file)
@@ -1,3 +1,44 @@
+2009-06-27  Ryosuke Niwa  <rniwa@google.com>
+
+        Reviewed by Eric Seidel.
+
+        https://bugs.webkit.org/show_bug.cgi?id=26762
+
+        Clean up for IndentOutdentCommand::indentRegion, and solved most of problems related to the bug 21712.
+        https://bugs.webkit.org/show_bug.cgi?id=21712
+
+        Added few utility functions to htmlediting.h/cpp
+
+        isVisibilyAdjacent checks whether the first position is visibly next to the second position.
+        i.e. there is no visible node between the first and second positions
+
+        canMergeLists checks whether two lists can be merged.
+        It checks the type of list, the editing boundary, and adjacency of the lists.
+
+        Tests: editing/execCommand/indent-nested-lists-1.html
+               editing/execCommand/indent-nested-lists-2.html
+               editing/execCommand/indent-nested-lists-3.html
+               editing/execCommand/indent-nested-lists-4.html
+               editing/execCommand/indent-nested-lists-5.html
+               editing/execCommand/indent-nested-lists-6.html
+               editing/execCommand/indent-nested-lists-7.html
+               editing/execCommand/outdent-nested-lists-1.html
+               editing/execCommand/outdent-nested-lists-2.html
+               editing/execCommand/outdent-nested-lists-3.html
+               editing/execCommand/outdent-nested-lists-4.html
+
+        * editing/IndentOutdentCommand.cpp:
+        (WebCore::IndentOutdentCommand::prepareBlockquoteLevelForInsertion):
+        (WebCore::IndentOutdentCommand::tryIndentingAsListItem):
+        (WebCore::IndentOutdentCommand::indentIntoBlockquote):
+        (WebCore::IndentOutdentCommand::indentRegion):
+        * editing/IndentOutdentCommand.h:
+        * editing/htmlediting.cpp:
+        (WebCore::enclosingListChild):
+        (WebCore::canMergeLists):
+        (WebCore::isVisibilyAdjacent):
+        * editing/htmlediting.h:
+
 2009-06-27  Pavel Feldman  <pfeldman@chromium.org>
 
         Reviewed by Timothy Hatcher.
index 0f9b106..3922367 100644 (file)
@@ -78,7 +78,7 @@ IndentOutdentCommand::IndentOutdentCommand(Document* document, EIndentType typeO
 
 // This function is a workaround for moveParagraph's tendency to strip blockquotes. It updates lastBlockquote to point to the
 // correct level for the current paragraph, and returns a pointer to a placeholder br where the insertion should be performed.
-PassRefPtr<Element> IndentOutdentCommand::prepareBlockquoteLevelForInsertion(VisiblePosition& currentParagraph, RefPtr<Element>& lastBlockquote)
+PassRefPtr<Element> IndentOutdentCommand::prepareBlockquoteLevelForInsertion(const VisiblePosition& currentParagraph, RefPtr<Element>& lastBlockquote)
 {
     int currentBlockquoteLevel = 0;
     int lastBlockquoteLevel = 0;
@@ -107,6 +107,62 @@ PassRefPtr<Element> IndentOutdentCommand::prepareBlockquoteLevelForInsertion(Vis
     return placeholder.release();
 }
 
+bool IndentOutdentCommand::tryIndentingAsListItem(const VisiblePosition& endOfCurrentParagraph)
+{
+    // If our selection is not inside a list, bail out.
+    Node* lastNodeInSelectedParagraph = endOfCurrentParagraph.deepEquivalent().node();
+    RefPtr<Element> listNode = enclosingList(lastNodeInSelectedParagraph);
+    if (!listNode)
+        return false;
+
+    HTMLElement* selectedListItem = enclosingListChild(lastNodeInSelectedParagraph);
+
+    // FIXME: previousElementSibling does not ignore non-rendered content like <span></span>.  Should we?
+    Element* previousList = selectedListItem->previousElementSibling();
+    Element* nextList = selectedListItem->nextElementSibling();
+
+    RefPtr<Element> newList = document()->createElement(listNode->tagQName(), false);
+    RefPtr<Element> newListItem = selectedListItem->cloneElementWithoutChildren();
+    RefPtr<Element> placeholder = createBreakElement(document());
+    insertNodeBefore(newList, selectedListItem);
+    appendNode(newListItem, newList);
+    appendNode(placeholder, newListItem);
+
+    moveParagraph(startOfParagraph(endOfCurrentParagraph), endOfCurrentParagraph, VisiblePosition(Position(placeholder, 0)), true);
+
+    if (canMergeLists(previousList, newList.get()))
+        mergeIdenticalElements(previousList, newList);
+    if (canMergeLists(newList.get(), nextList))
+        mergeIdenticalElements(newList, nextList);
+
+    return true;
+}
+    
+void IndentOutdentCommand::indentIntoBlockquote(const VisiblePosition& endOfCurrentParagraph, const VisiblePosition& endOfNextParagraph, RefPtr<Element>& targetBlockquote)
+{
+    Node* enclosingCell = 0;
+
+    if (!targetBlockquote) {
+        // Create a new blockquote and insert it as a child of the root editable element. We accomplish
+        // this by splitting all parents of the current paragraph up to that point.
+        targetBlockquote = createIndentBlockquoteElement(document());
+        Position start = startOfParagraph(endOfCurrentParagraph).deepEquivalent();
+        enclosingCell = enclosingNodeOfType(start, &isTableCell);
+        Node* nodeToSplitTo = enclosingCell ? enclosingCell : editableRootForPosition(start);
+        RefPtr<Node> startOfNewBlock = splitTreeToNode(start.node(), nodeToSplitTo);
+        insertNodeBefore(targetBlockquote, startOfNewBlock);
+    }
+
+    RefPtr<Element> insertionPoint = prepareBlockquoteLevelForInsertion(endOfCurrentParagraph, targetBlockquote);
+
+    // Don't put the next paragraph in the blockquote we just created for this paragraph unless 
+    // the next paragraph is in the same cell.
+    if (enclosingCell && enclosingCell != enclosingNodeOfType(endOfNextParagraph.deepEquivalent(), &isTableCell))
+        targetBlockquote = 0;
+
+    moveParagraph(startOfParagraph(endOfCurrentParagraph), endOfCurrentParagraph, VisiblePosition(Position(insertionPoint, 0)), true);
+}
+
 void IndentOutdentCommand::indentRegion()
 {
     VisibleSelection selection = selectionForParagraphIteration(endingSelection());
@@ -117,7 +173,7 @@ void IndentOutdentCommand::indentRegion()
 
     ASSERT(!startOfSelection.isNull());
     ASSERT(!endOfSelection.isNull());
-    
+
     // Special case empty root editable elements because there's nothing to split
     // and there's nothing to move.
     Position start = startOfSelection.deepEquivalent().downstream();
@@ -129,58 +185,21 @@ void IndentOutdentCommand::indentRegion()
         setEndingSelection(VisibleSelection(Position(placeholder.get(), 0), DOWNSTREAM));
         return;
     }
-    
-    RefPtr<Element> previousListNode;
-    RefPtr<Element> newListNode;
-    RefPtr<Element> newBlockquote;
+
+    RefPtr<Element> blockquoteForNextIndent;
     VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection);
     VisiblePosition endAfterSelection = endOfParagraph(endOfParagraph(endOfSelection).next());
     while (endOfCurrentParagraph != endAfterSelection) {
         // Iterate across the selected paragraphs...
         VisiblePosition endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next());
-        RefPtr<Element> listNode = enclosingList(endOfCurrentParagraph.deepEquivalent().node());
-        RefPtr<Element> insertionPoint;
-        if (listNode) {
-            RefPtr<Element> placeholder = createBreakElement(document());
-            insertionPoint = placeholder;
-            newBlockquote = 0;
-            RefPtr<Element> listItem = createListItemElement(document());
-            if (listNode == previousListNode) {
-                // The previous paragraph was inside the same list, so add this list item to the list we already created
-                appendNode(listItem, newListNode);
-                appendNode(placeholder, listItem);
-            } else {
-                // Clone the list element, insert it before the current paragraph, and move the paragraph into it.
-                RefPtr<Element> clonedList = listNode->cloneElementWithoutChildren();
-                insertNodeBefore(clonedList, enclosingListChild(endOfCurrentParagraph.deepEquivalent().node()));
-                appendNode(listItem, clonedList);
-                appendNode(placeholder, listItem);
-                newListNode = clonedList;
-                previousListNode = listNode;
-            }
-        } else if (newBlockquote)
-            // The previous paragraph was put into a new blockquote, so move this paragraph there as well
-            insertionPoint = prepareBlockquoteLevelForInsertion(endOfCurrentParagraph, newBlockquote);
-        else {
-            // Create a new blockquote and insert it as a child of the root editable element. We accomplish
-            // this by splitting all parents of the current paragraph up to that point.
-            RefPtr<Element> blockquote = createIndentBlockquoteElement(document());
-            Position start = startOfParagraph(endOfCurrentParagraph).deepEquivalent();
-            
-            Node* enclosingCell = enclosingNodeOfType(start, &isTableCell);
-            Node* nodeToSplitTo = enclosingCell ? enclosingCell : editableRootForPosition(start);
-            RefPtr<Node> startOfNewBlock = splitTreeToNode(start.node(), nodeToSplitTo);
-            insertNodeBefore(blockquote, startOfNewBlock);
-            newBlockquote = blockquote;
-            insertionPoint = prepareBlockquoteLevelForInsertion(endOfCurrentParagraph, newBlockquote);
-            // Don't put the next paragraph in the blockquote we just created for this paragraph unless 
-            // the next paragraph is in the same cell.
-            if (enclosingCell && enclosingCell != enclosingNodeOfType(endOfNextParagraph.deepEquivalent(), &isTableCell))
-                newBlockquote = 0;
-        }
-        moveParagraph(startOfParagraph(endOfCurrentParagraph), endOfCurrentParagraph, VisiblePosition(Position(insertionPoint, 0)), true);
-        // moveParagraph should not destroy content that contains endOfNextParagraph, but if it does, return here
-        // to avoid a crash.
+        if (tryIndentingAsListItem(endOfCurrentParagraph))
+            blockquoteForNextIndent = 0;
+        else
+            indentIntoBlockquote(endOfCurrentParagraph, endOfNextParagraph, blockquoteForNextIndent);
+            // blockquoteForNextIndent maybe updated
+            // this is due to the way prepareBlockquoteLevelForInsertion was designed.
+        // Sanity check: Make sure our moveParagraph calls didn't remove endOfNextParagraph.deepEquivalent().node()
+        // If somehow we did, return to prevent crashes.
         if (endOfNextParagraph.isNotNull() && !endOfNextParagraph.deepEquivalent().node()->inDocument()) {
             ASSERT_NOT_REACHED();
             return;
index bb1a1d2..419f832 100644 (file)
@@ -49,7 +49,9 @@ private:
     void indentRegion();
     void outdentRegion();
     void outdentParagraph();
-    PassRefPtr<Element> prepareBlockquoteLevelForInsertion(VisiblePosition&, RefPtr<Element>&);
+    PassRefPtr<Element> prepareBlockquoteLevelForInsertion(const VisiblePosition&, RefPtr<Element>&);
+    bool tryIndentingAsListItem(const VisiblePosition&);
+    void indentIntoBlockquote(const VisiblePosition&, const VisiblePosition&, RefPtr<Element>&);
 
     EIndentType m_typeOfAction;
     int m_marginInPixels;
index a4c1f83..c0bf009 100644 (file)
@@ -665,7 +665,7 @@ HTMLElement* enclosingList(Node* node)
     return 0;
 }
 
-Node* enclosingListChild(Node *node)
+HTMLElement* enclosingListChild(Node *node)
 {
     if (!node)
         return 0;
@@ -676,7 +676,7 @@ Node* enclosingListChild(Node *node)
     // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
     for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
         if (n->hasTagName(liTag) || isListElement(n->parentNode()))
-            return n;
+            return static_cast<HTMLElement*>(n);
         if (n == root || isTableCell(n))
             return 0;
     }
@@ -738,6 +738,18 @@ HTMLElement* outermostEnclosingList(Node* node)
     return list;
 }
 
+bool canMergeLists(Element* firstList, Element* secondList)
+{
+    if (!firstList || !secondList)
+        return false;
+
+    return firstList->hasTagName(secondList->tagQName())// make sure the list types match (ol vs. ul)
+    && isContentEditable(firstList) && isContentEditable(secondList)// both lists are editable
+    && firstList->rootEditableElement() == secondList->rootEditableElement()// don't cross editing boundaries
+    && isVisibilyAdjacent(positionAfterNode(firstList), positionBeforeNode(secondList));
+    // Make sure there is no visible content between this li and the previous list
+}
+
 Node* highestAncestor(Node* node)
 {
     ASSERT(node);
@@ -971,6 +983,11 @@ int indexForVisiblePosition(VisiblePosition& visiblePosition)
     return TextIterator::rangeLength(range.get(), true);
 }
 
+bool isVisibilyAdjacent(const Position& first, const Position& second)
+{
+    return VisiblePosition(first) == VisiblePosition(second.upstream());
+}
+
 PassRefPtr<Range> avoidIntersectionWithNode(const Range* range, Node* node)
 {
     if (!range)
index 374b512..25ff847 100644 (file)
@@ -123,7 +123,8 @@ Node* enclosingAnchorElement(const Position&);
 bool isListElement(Node*);
 HTMLElement* enclosingList(Node*);
 HTMLElement* outermostEnclosingList(Node*);
-Node* enclosingListChild(Node*);
+HTMLElement* enclosingListChild(Node*);
+bool canMergeLists(Element* firstList, Element* secondList);
 Node* highestAncestor(Node*);
 bool isTableElement(Node*);
 bool isTableCell(const Node*);
@@ -134,7 +135,7 @@ bool lineBreakExistsAtVisiblePosition(const VisiblePosition&);
 VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
 
 int indexForVisiblePosition(VisiblePosition&);
-
+bool isVisibilyAdjacent(const Position& first, const Position& second);
 }
 
 #endif