LayoutTests:
authorjusting <justing@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Nov 2006 03:52:33 +0000 (03:52 +0000)
committerjusting <justing@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Nov 2006 03:52:33 +0000 (03:52 +0000)
        Reviewed by darin

        <rdar://problem/4062865>
        Copy/paste of a select element fails to include the options

        Updated to reflect fix:
        * editing/pasteboard/4641033-expected.checksum:
        * editing/pasteboard/4641033-expected.png:
        * editing/pasteboard/4641033-expected.txt:
        * editing/pasteboard/4641033.html:

        Added:
        * editing/inserting/before-after-input-element-expected.checksum: Added.
        * editing/inserting/before-after-input-element-expected.png: Added.
        * editing/inserting/before-after-input-element-expected.txt: Added.
        * editing/inserting/before-after-input-element.html: Added.
        * editing/pasteboard/input-field-1-expected.checksum: Added.
        * editing/pasteboard/input-field-1-expected.png: Added.
        * editing/pasteboard/input-field-1-expected.txt: Added.
        * editing/pasteboard/input-field-1.html: Added.
        * editing/pasteboard/select-element-1-expected.checksum: Added.
        * editing/pasteboard/select-element-1-expected.png: Added.
        * editing/pasteboard/select-element-1-expected.txt: Added.
        * editing/pasteboard/select-element-1.html: Added.
        * editing/selection/select-element-paragraph-boundary-expected.checksum: Added.
        * editing/selection/select-element-paragraph-boundary-expected.png: Added.
        * editing/selection/select-element-paragraph-boundary-expected.txt: Added.
        * editing/selection/select-element-paragraph-boundary.html: Added.

WebCore:

        Reviewed by darin

        <rdar://problem/4062865>
        Copy/paste of a select element fails to include the options

        * editing/SelectionController.cpp:
        (WebCore::SelectionController::modify): Added paragraphBoundary.
        * editing/htmlediting.cpp:
        (WebCore::canHaveChildrenForEditing): Added checks for input elements
        and textareas.  Insertion operations would fail when performed just
        before/after one of these elements b/c the content would be put inside
        the element.
        (WebCore::enclosingNodeWithTag): Fixed a problem when calling these in non
        editable content, and made the code to stop at an root faster (don't check
        isDescendantOf on every iteration).
        (WebCore::enclosingNodeOfType): Ditto.
        (WebCore::enclosingList): Ditto.
        (WebCore::enclosingListChild): Ditto.  Added a FIXME, this function seems
        inappropriately named.
        * editing/markup.cpp:
        (WebCore::startMarkup): Use the text node's value instead of its rendered
        content for text nodes inside select elements.  One might also turn off
        annotation when createMarkup enters a select element, but createMarkup
        is iterative, not recursive, so doing so would be complicated.
        (WebCore::createMarkup): Add markup for unrendered nodes if they are
        descendants of a select element.
        * editing/visible_units.cpp:
        (WebCore::startOfParagraph): Migrate to isBlock/enclosingBlock.  Fixes bug
        where various replaced elements can't be copied when they are the only
        thing selected.
        (WebCore::endOfParagraph): Ditto.

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

26 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/inserting/before-after-input-element-expected.checksum [new file with mode: 0644]
LayoutTests/editing/inserting/before-after-input-element-expected.png [new file with mode: 0644]
LayoutTests/editing/inserting/before-after-input-element-expected.txt [new file with mode: 0644]
LayoutTests/editing/inserting/before-after-input-element.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/4641033-expected.checksum
LayoutTests/editing/pasteboard/4641033-expected.png
LayoutTests/editing/pasteboard/4641033-expected.txt
LayoutTests/editing/pasteboard/4641033.html
LayoutTests/editing/pasteboard/input-field-1-expected.checksum [new file with mode: 0644]
LayoutTests/editing/pasteboard/input-field-1-expected.png [new file with mode: 0644]
LayoutTests/editing/pasteboard/input-field-1-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/input-field-1.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/select-element-1-expected.checksum [new file with mode: 0644]
LayoutTests/editing/pasteboard/select-element-1-expected.png [new file with mode: 0644]
LayoutTests/editing/pasteboard/select-element-1-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/select-element-1.html [new file with mode: 0644]
LayoutTests/editing/selection/select-element-paragraph-boundary-expected.checksum [new file with mode: 0644]
LayoutTests/editing/selection/select-element-paragraph-boundary-expected.png [new file with mode: 0644]
LayoutTests/editing/selection/select-element-paragraph-boundary-expected.txt [new file with mode: 0644]
LayoutTests/editing/selection/select-element-paragraph-boundary.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/editing/SelectionController.cpp
WebCore/editing/htmlediting.cpp
WebCore/editing/markup.cpp
WebCore/editing/visible_units.cpp

index aba52ea..4741059 100644 (file)
@@ -1,3 +1,34 @@
+2006-11-01  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by darin
+        
+        <rdar://problem/4062865>
+        Copy/paste of a select element fails to include the options
+
+        Updated to reflect fix:
+        * editing/pasteboard/4641033-expected.checksum:
+        * editing/pasteboard/4641033-expected.png:
+        * editing/pasteboard/4641033-expected.txt:
+        * editing/pasteboard/4641033.html:
+        
+        Added:
+        * editing/inserting/before-after-input-element-expected.checksum: Added.
+        * editing/inserting/before-after-input-element-expected.png: Added.
+        * editing/inserting/before-after-input-element-expected.txt: Added.
+        * editing/inserting/before-after-input-element.html: Added.
+        * editing/pasteboard/input-field-1-expected.checksum: Added.
+        * editing/pasteboard/input-field-1-expected.png: Added.
+        * editing/pasteboard/input-field-1-expected.txt: Added.
+        * editing/pasteboard/input-field-1.html: Added.
+        * editing/pasteboard/select-element-1-expected.checksum: Added.
+        * editing/pasteboard/select-element-1-expected.png: Added.
+        * editing/pasteboard/select-element-1-expected.txt: Added.
+        * editing/pasteboard/select-element-1.html: Added.
+        * editing/selection/select-element-paragraph-boundary-expected.checksum: Added.
+        * editing/selection/select-element-paragraph-boundary-expected.png: Added.
+        * editing/selection/select-element-paragraph-boundary-expected.txt: Added.
+        * editing/selection/select-element-paragraph-boundary.html: Added.
+
 2006-11-01  Kevin McCullough  <KMcCullough@apple.com>
 
         - temporarily passing a test so that it does not interfere with others testing.
diff --git a/LayoutTests/editing/inserting/before-after-input-element-expected.checksum b/LayoutTests/editing/inserting/before-after-input-element-expected.checksum
new file mode 100644 (file)
index 0000000..687308b
--- /dev/null
@@ -0,0 +1 @@
+114cf64c553812a9157e892b023e7259
\ No newline at end of file
diff --git a/LayoutTests/editing/inserting/before-after-input-element-expected.png b/LayoutTests/editing/inserting/before-after-input-element-expected.png
new file mode 100644 (file)
index 0000000..8699a62
Binary files /dev/null and b/LayoutTests/editing/inserting/before-after-input-element-expected.png differ
diff --git a/LayoutTests/editing/inserting/before-after-input-element-expected.txt b/LayoutTests/editing/inserting/before-after-input-element-expected.txt
new file mode 100644 (file)
index 0000000..d59d416
--- /dev/null
@@ -0,0 +1,27 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 5 of #text > DIV > BODY > HTML > #document to 5 of #text > DIV > BODY > HTML > #document toDOMRange:range from 5 of #text > DIV > BODY > HTML > #document to 5 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of DIV > BODY > HTML > #document to 2 of DIV > BODY > HTML > #document toDOMRange:range from 5 of #text > DIV > BODY > HTML > #document to 5 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 332x18
+          text run at (0,0) width 332: "This tests text insertion before/after an input element."
+      RenderBlock {DIV} at (0,34) size 784x23
+        RenderText {#text} at (0,2) size 35x18
+          text run at (0,2) width 35: "Hello"
+        RenderTextField {INPUT} at (37,2) size 148x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+        RenderText {#text} at (187,2) size 40x18
+          text run at (187,2) width 40: "World"
+layer at (48,47) size 142x13
+  RenderBlock {DIV} at (3,3) size 142x13
+caret: position 5 of child 2 {#text} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/editing/inserting/before-after-input-element.html b/LayoutTests/editing/inserting/before-after-input-element.html
new file mode 100644 (file)
index 0000000..ff87eed
--- /dev/null
@@ -0,0 +1,13 @@
+<p>This tests text insertion before/after an input element.</p>
+<div id="div" contenteditable="true"><input type="text"></div>
+
+<script>
+var div = document.getElementById("div");
+var sel = window.getSelection();
+sel.setPosition(div, 0);
+
+document.execCommand("InsertText", false, "Hello");
+sel.setPosition(div, div.childNodes.length);
+
+document.execCommand("InsertText", false, "World");
+</script>
\ No newline at end of file
index 13f1de5..c304c8a 100644 (file)
@@ -1 +1 @@
-92ba3052cc1b24599ea7eb8666eae2a4
\ No newline at end of file
+0b5df9dee82211eee3dc09b171ac8e1e
\ No newline at end of file
index 0fadb0c..eab2153 100644 (file)
Binary files a/LayoutTests/editing/pasteboard/4641033-expected.png and b/LayoutTests/editing/pasteboard/4641033-expected.png differ
index 4cf5834..70d6929 100644 (file)
@@ -3,7 +3,7 @@ EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML
 EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 3 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > DIV > BODY > HTML > #document to 1 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
 layer at (0,0) size 800x600
@@ -16,23 +16,15 @@ layer at (0,0) size 800x600
           text run at (0,0) width 660: "This tests for a bug when creating markup for a selection that contained unrendered nodes with children. "
           text run at (660,0) width 109: "You should see a"
           text run at (0,18) width 248: "picture of abe followed by a select box."
-      RenderBlock {P} at (0,52) size 784x18
-        RenderInline {B} at (0,0) size 639x18
-          RenderText {#text} at (0,0) size 195x18
-            text run at (0,0) width 195: "This currently demonstrates "
-          RenderInline {A} at (0,0) size 56x18 [color=#0000EE]
-            RenderText {#text} at (195,0) size 56x18
-              text run at (195,0) width 56: "4641033"
-          RenderText {#text} at (251,0) size 384x18
-            text run at (251,0) width 384: " Copy/paste of a select element fails to include the options"
-          RenderText {#text} at (635,0) size 4x18
-            text run at (635,0) width 4: "."
-      RenderBlock {DIV} at (0,86) size 784x110
+      RenderBlock {DIV} at (0,52) size 784x110
         RenderImage {IMG} at (0,0) size 76x103
         RenderText {#text} at (76,89) size 4x18
           text run at (76,89) width 4: " "
-        RenderMenuList {SELECT} at (82,90) size 36x18 [bgcolor=#FFFFFF]
-      RenderBlock (anonymous) at (0,196) size 784x110
+        RenderMenuList {SELECT} at (82,90) size 52x18 [bgcolor=#FFFFFF]
+          RenderBlock (anonymous) at (8,2) size 21x13
+            RenderText at (0,0) size 7x13
+              text run at (0,0) width 7: "1"
+      RenderBlock (anonymous) at (0,162) size 784x110
         RenderImage {IMG} at (0,0) size 76x103
         RenderText {#text} at (76,89) size 4x18
           text run at (76,89) width 4: " "
@@ -42,4 +34,4 @@ layer at (0,0) size 800x600
               text run at (0,0) width 7: "1"
         RenderText {#text} at (0,0) size 0x0
         RenderText {#text} at (0,0) size 0x0
-caret: position 1 of child 2 {SELECT} of child 4 {DIV} of child 0 {BODY} of child 0 {HTML} of document
+caret: position 1 of child 1 {#text} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
index d0f6ed6..03b67d4 100644 (file)
@@ -1,5 +1,4 @@
 <p>This tests for a bug when creating markup for a selection that contained unrendered nodes with children.  You should see a picture of abe followed by a select box.</p>
-<p><b>This currently demonstrates <a href="rdar://problem/4641033">4641033</a> Copy/paste of a select element fails to include the options</a>.</b></p>
 <div id="paste" contenteditable="true"></div>
 
 <img id="start" src="../resources/abe.jpg">
diff --git a/LayoutTests/editing/pasteboard/input-field-1-expected.checksum b/LayoutTests/editing/pasteboard/input-field-1-expected.checksum
new file mode 100644 (file)
index 0000000..8950b39
--- /dev/null
@@ -0,0 +1 @@
+1299cb5be0da19a52631a49040947f6e
\ No newline at end of file
diff --git a/LayoutTests/editing/pasteboard/input-field-1-expected.png b/LayoutTests/editing/pasteboard/input-field-1-expected.png
new file mode 100644 (file)
index 0000000..04c5128
Binary files /dev/null and b/LayoutTests/editing/pasteboard/input-field-1-expected.png differ
diff --git a/LayoutTests/editing/pasteboard/input-field-1-expected.txt b/LayoutTests/editing/pasteboard/input-field-1-expected.txt
new file mode 100644 (file)
index 0000000..9c34c9c
--- /dev/null
@@ -0,0 +1,33 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document toDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 1 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document toDOMRange:range from 3 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 235x18
+          text run at (0,0) width 235: "This tests Copy/Paste of a input field."
+      RenderBlock {DIV} at (0,34) size 784x23
+        RenderTextField {INPUT} at (2,2) size 148x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+        RenderText {#text} at (152,2) size 4x18
+          text run at (152,2) width 4: " "
+        RenderTextField {INPUT} at (158,2) size 148x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
+      RenderBlock {UL} at (0,73) size 784x18
+        RenderListItem {LI} at (40,0) size 744x18
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 43x18
+            text run at (0,0) width 43: "Passed"
+layer at (13,47) size 142x13
+  RenderBlock {DIV} at (3,3) size 142x13
+layer at (169,47) size 142x13
+  RenderBlock {DIV} at (3,3) size 142x13
+caret: position 1 of child 2 {INPUT} of child 2 {DIV} of child 1 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/editing/pasteboard/input-field-1.html b/LayoutTests/editing/pasteboard/input-field-1.html
new file mode 100644 (file)
index 0000000..b691124
--- /dev/null
@@ -0,0 +1,30 @@
+<script>
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+function shouldBe(expected, actual) {
+    if (expected != actual)
+        log("Failure. Expected: " + expected + ", Actual: " + actual);
+    else
+        log("Passed");
+}
+</script>
+
+<p>This tests Copy/Paste of a input field.</p>
+<div id="div" contenteditable="true"><input type="text"></div>
+<ul id="console"></ul>
+<script>
+var div = document.getElementById("div");
+div.focus();
+document.execCommand("SelectAll");
+
+document.execCommand("Copy");
+var sel = window.getSelection();
+sel.modify("move", "forward", "character");
+document.execCommand("Paste");
+
+shouldBe(document.getElementsByTagName("input").length, 2);
+</script>
\ No newline at end of file
diff --git a/LayoutTests/editing/pasteboard/select-element-1-expected.checksum b/LayoutTests/editing/pasteboard/select-element-1-expected.checksum
new file mode 100644 (file)
index 0000000..5d533ca
--- /dev/null
@@ -0,0 +1 @@
+dbf502fc8287a1d31be3e0addfee9157
\ No newline at end of file
diff --git a/LayoutTests/editing/pasteboard/select-element-1-expected.png b/LayoutTests/editing/pasteboard/select-element-1-expected.png
new file mode 100644 (file)
index 0000000..8bd5e5d
Binary files /dev/null and b/LayoutTests/editing/pasteboard/select-element-1-expected.png differ
diff --git a/LayoutTests/editing/pasteboard/select-element-1-expected.txt b/LayoutTests/editing/pasteboard/select-element-1-expected.txt
new file mode 100644 (file)
index 0000000..afd18ae
--- /dev/null
@@ -0,0 +1,57 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 3 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 1 of DIV > BODY > HTML > #document to 7 of SELECT > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of DIV > BODY > HTML > #document to 7 of SELECT > DIV > BODY > HTML > #document toDOMRange:range from 1 of DIV > BODY > HTML > #document to 7 of SELECT > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldDeleteDOMRange:range from 1 of DIV > BODY > HTML > #document to 7 of SELECT > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 35 of SELECT > DIV > BODY > HTML > #document to 35 of SELECT > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 473x18
+          text run at (0,0) width 253: "This tests copy/paste of select elements. "
+          text run at (253,0) width 220: "All the options should be included."
+      RenderBlock {DIV} at (0,34) size 784x13
+        RenderInline {FONT} at (0,0) size 0x13
+          RenderInline {SPAN} at (0,0) size 0x13
+            RenderBR {BR} at (0,0) size 0x13
+      RenderBlock {DIV} at (0,47) size 784x22
+        RenderMenuList {SELECT} at (2,2) size 62x18 [bgcolor=#FFFFFF]
+          RenderBlock (anonymous) at (8,2) size 31x13
+            RenderText at (0,0) size 22x13
+              text run at (0,0) width 22: "One"
+      RenderBlock {UL} at (0,85) size 784x72
+        RenderListItem {LI} at (40,0) size 744x18
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 43x18
+            text run at (0,0) width 43: "Passed"
+        RenderListItem {LI} at (40,18) size 744x18
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 43x18
+            text run at (0,0) width 43: "Passed"
+        RenderListItem {LI} at (40,36) size 744x18
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 43x18
+            text run at (0,0) width 43: "Passed"
+        RenderListItem {LI} at (40,54) size 744x18
+          RenderListMarker at (-17,0) size 7x18
+          RenderText {#text} at (0,0) size 43x18
+            text run at (0,0) width 43: "Passed"
+caret: position 35 of child 0 {SELECT} of child 4 {DIV} of child 1 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/editing/pasteboard/select-element-1.html b/LayoutTests/editing/pasteboard/select-element-1.html
new file mode 100644 (file)
index 0000000..130afb1
--- /dev/null
@@ -0,0 +1,42 @@
+<script>
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+function shouldBe(expected, actual) {
+    if (expected != actual)
+        log("Failure. Expected: " + expected + ", Actual: " + actual);
+    else
+        log("Passed");
+}
+</script>
+<p>This tests copy/paste of select elements.  All the options should be included.</p>
+<div id="copy" contenteditable="true">
+    <select id="select">
+        <option>One</option>
+        <option>Two</option>
+        <option>Three</option>
+    </select>
+</div>
+
+<div id="paste" contenteditable="true"></div>
+<ul id="console"></ul>
+<script>
+var copy = document.getElementById("copy");
+copy.focus();
+document.execCommand("SelectAll");
+document.execCommand("Cut");
+
+shouldBe(document.getElementById("select"), null);
+
+var paste = document.getElementById("paste");
+paste.focus();
+document.execCommand("Paste");
+
+var select = document.getElementById("select");
+shouldBe(select.options[0].value, "One");
+shouldBe(select.options[1].value, "Two");
+shouldBe(select.options[2].value, "Three");
+</script>
\ No newline at end of file
diff --git a/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.checksum b/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.checksum
new file mode 100644 (file)
index 0000000..60212c2
--- /dev/null
@@ -0,0 +1 @@
+5d69c92ad6af34ebc8a456c517def77b
\ No newline at end of file
diff --git a/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.png b/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.png
new file mode 100644 (file)
index 0000000..d175a0e
Binary files /dev/null and b/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.png differ
diff --git a/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.txt b/LayoutTests/editing/selection/select-element-paragraph-boundary-expected.txt
new file mode 100644 (file)
index 0000000..1195463
--- /dev/null
@@ -0,0 +1,20 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {P} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 750x36
+          text run at (0,0) width 326: "This tests paragraphBoundary selection navigation. "
+          text run at (326,0) width 424: "The caret should be at the end of the paragraph below, just after the"
+          text run at (0,18) width 67: "select box."
+      RenderBlock {DIV} at (0,52) size 784x22
+        RenderMenuList {SELECT} at (2,2) size 38x18 [bgcolor=#FFFFFF]
+          RenderBlock (anonymous) at (8,2) size 7x13
+            RenderText at (0,0) size 7x13
+              text run at (0,0) width 7: "1"
+caret: position 1 of child 0 {SELECT} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/editing/selection/select-element-paragraph-boundary.html b/LayoutTests/editing/selection/select-element-paragraph-boundary.html
new file mode 100644 (file)
index 0000000..a52ea12
--- /dev/null
@@ -0,0 +1,10 @@
+<p>This tests paragraphBoundary selection navigation.  The caret should be at the end of the paragraph below, just after the select box.</p>
+<div id="div" contenteditable="true"><select><option>1</option></select></div>
+
+<script>
+var sel = window.getSelection();
+var div = document.getElementById("div");
+
+sel.setPosition(div, 0);
+sel.modify("move", "forward", "paragraphBoundary");
+</script>
\ No newline at end of file
index 8accc26..7ddbd1e 100644 (file)
@@ -1,3 +1,37 @@
+2006-11-01  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by darin
+
+        <rdar://problem/4062865>
+        Copy/paste of a select element fails to include the options
+        
+        * editing/SelectionController.cpp:
+        (WebCore::SelectionController::modify): Added paragraphBoundary.
+        * editing/htmlediting.cpp:
+        (WebCore::canHaveChildrenForEditing): Added checks for input elements
+        and textareas.  Insertion operations would fail when performed just 
+        before/after one of these elements b/c the content would be put inside 
+        the element.
+        (WebCore::enclosingNodeWithTag): Fixed a problem when calling these in non
+        editable content, and made the code to stop at an root faster (don't check
+        isDescendantOf on every iteration).
+        (WebCore::enclosingNodeOfType): Ditto.
+        (WebCore::enclosingList): Ditto.
+        (WebCore::enclosingListChild): Ditto.  Added a FIXME, this function seems
+        inappropriately named.
+        * editing/markup.cpp:
+        (WebCore::startMarkup): Use the text node's value instead of its rendered
+        content for text nodes inside select elements.  One might also turn off
+        annotation when createMarkup enters a select element, but createMarkup
+        is iterative, not recursive, so doing so would be complicated.
+        (WebCore::createMarkup): Add markup for unrendered nodes if they are 
+        descendants of a select element.
+        * editing/visible_units.cpp:
+        (WebCore::startOfParagraph): Migrate to isBlock/enclosingBlock.  Fixes bug
+        where various replaced elements can't be copied when they are the only
+        thing selected.
+        (WebCore::endOfParagraph): Ditto.
+
 2006-11-01  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Adam.
index f17596a..a222ef4 100644 (file)
@@ -438,6 +438,8 @@ bool SelectionController::modify(const String &alterString, const String &direct
         granularity = ParagraphGranularity;
     else if (granularityStringLower == "lineboundary")
         granularity = LineBoundary;
+    else if (granularityStringLower == "paragraphboundary")
+        granularity = ParagraphBoundary;
     else if (granularityStringLower == "documentboundary")
         granularity = DocumentBoundary;
     else
index efac6df..818fbd4 100644 (file)
@@ -51,6 +51,7 @@ bool isAtomicNode(const Node *node)
     return node && (!node->hasChildNodes() || editingIgnoresContent(node));
 }
 
+// FIXME: This function needs a comment.
 bool editingIgnoresContent(const Node *node)
 {
     if (!node || !node->isHTMLElement())
@@ -78,6 +79,8 @@ bool canHaveChildrenForEditing(const Node* node)
            !node->hasTagName(brTag) &&
            !node->hasTagName(imgTag) &&
            !node->hasTagName(buttonTag) &&
+           !node->hasTagName(inputTag) &&
+           !node->hasTagName(textareaTag) &&
            !node->hasTagName(objectTag) &&
            !node->hasTagName(iframeTag) &&
            !node->isTextNode();
@@ -543,12 +546,16 @@ Node* enclosingNodeWithTag(Node* node, const QualifiedName& tagName)
 {
     if (!node)
         return 0;
-    Node* root = (node->inDocument()) ? node->rootEditableElement() : highestAncestor(node);
-    ASSERT(root);
-    for (Node* n = node->parentNode(); n && (n == root || n->isDescendantOf(root)); n = n->parentNode())
+        
+    Node* root = highestEditableRoot(Position(node, 0));
+    
+    for (Node* n = node->parentNode(); n; n = n->parentNode()) {
         if (n->hasTagName(tagName))
             return n;
-            
+        if (n == root)
+            return 0;
+    }
+    
     return 0;
 }
 
@@ -558,13 +565,14 @@ Node* enclosingNodeOfType(Node* node, bool (*nodeIsOfType)(Node*))
         return 0;
         
     Node* root = highestEditableRoot(Position(node, 0));
-    if (!root)
-        root = highestAncestor(node);
-        
-    for (Node* n = node->parentNode(); n && (n == root || n->isDescendantOf(root)); n = n->parentNode())
+    
+    for (Node* n = node->parentNode(); n; n = n->parentNode()) {
         if ((*nodeIsOfType)(n))
             return n;
-            
+        if (n == root)
+            return 0;
+    }
+    
     return 0;
 }
 
@@ -584,12 +592,16 @@ Node* enclosingList(Node* node)
 {
     if (!node)
         return 0;
-    Node* root = (node->inDocument()) ? node->rootEditableElement() : highestAncestor(node);
-    ASSERT(root);
-    for (Node* n = node->parentNode(); n && (n == root || n->isDescendantOf(root)); n = n->parentNode())
+        
+    Node* root = highestEditableRoot(Position(node, 0));
+    
+    for (Node* n = node->parentNode(); n; n = n->parentNode()) {
         if (n->hasTagName(ulTag) || n->hasTagName(olTag))
             return n;
-            
+        if (n == root)
+            return 0;
+    }
+    
     return 0;
 }
 
@@ -599,11 +611,14 @@ Node* enclosingListChild (Node *node)
         return 0;
     // Check for a list item element, or for a node whose parent is a list element.  Such a node
     // will appear visually as a list item (but without a list marker)
-    Node* root = (node->inDocument()) ? node->rootEditableElement() : highestAncestor(node);
-    ASSERT(root);
-    for (Node *n = node; n && n->parentNode() && (n == root || n->isDescendantOf(root)); n = n->parentNode()) {
+    Node* root = highestEditableRoot(Position(node, 0));
+    
+    // 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;
+        if (n == root)
+            return 0;
     }
     
     return 0;
index 67ffb2f..f1b52c9 100644 (file)
@@ -127,7 +127,9 @@ static DeprecatedString startMarkup(const Node *node, const Range *range, EAnnot
                         || parent->hasTagName(xmpTag))
                     return stringValueForRange(node, range).deprecatedString();
             }
-            DeprecatedString markup = annotate ? escapeTextForMarkup(renderedText(node, range)) : escapeTextForMarkup(stringValueForRange(node, range).deprecatedString());            
+            bool useRenderedText = annotate && !enclosingNodeWithTag(const_cast<Node*>(node), selectTag);
+            
+            DeprecatedString markup = useRenderedText ? escapeTextForMarkup(renderedText(node, range)) : escapeTextForMarkup(stringValueForRange(node, range).deprecatedString());            
             if (defaultStyle) {
                 Node *element = node->parentNode();
                 if (element) {
@@ -358,8 +360,8 @@ DeprecatedString createMarkup(const Range *range, Vector<Node*>* nodes, EAnnotat
             continue;
         
         // Add the node to the markup.
-        // FIXME: Add markup for nodes without renderers to fix <rdar://problem/4062865>. Also see the three checks below.
-        if (n->renderer()) {
+        // FIXME: Add markup for nodes without renderers Also see the three checks below.
+        if (n->renderer() || enclosingNodeWithTag(n, selectTag)) {
             markups.append(startMarkup(n, range, annotate, defaultStyle.get()));
             if (nodes)
                 nodes->append(n);
@@ -367,7 +369,7 @@ DeprecatedString createMarkup(const Range *range, Vector<Node*>* nodes, EAnnotat
         
         if (n->firstChild() == 0) {
             // Node has no children, add its close tag now.
-            if (n->renderer()) {
+            if (n->renderer() || enclosingNodeWithTag(n, selectTag)) {
                 markups.append(endMarkup(n));
                 lastClosed = n;
             }
@@ -405,7 +407,7 @@ DeprecatedString createMarkup(const Range *range, Vector<Node*>* nodes, EAnnotat
                     }
                 }
             }
-        } else if (n->renderer())
+        } else if (n->renderer() || enclosingNodeWithTag(n, selectTag))
             // Node is an ancestor, set it to close eventually.
             ancestorsToClose.append(n);
     }
index e9c8dc1..2de3d0f 100644 (file)
@@ -578,7 +578,7 @@ VisiblePosition startOfParagraph(const VisiblePosition &c)
         && p.offset() == maxDeepOffset(startNode))
         return VisiblePosition(Position(startNode, 0));
 
-    Node *startBlock = startNode->enclosingBlockFlowElement();
+    Node* startBlock = enclosingBlock(startNode);
 
     Node *node = startNode;
     int offset = p.offset();
@@ -597,8 +597,8 @@ VisiblePosition startOfParagraph(const VisiblePosition &c)
             n = n->traversePreviousNodePostOrder(startBlock);
             continue;
         }
-        // FIXME: isBlockFlow should not exclude non-inline tables
-        if (r->isBR() || r->isBlockFlow() || (r->isTable() && !r->isInline()))
+        
+        if (r->isBR() || isBlock(n))
             break;
             
         if (r->isText()) {
@@ -640,7 +640,7 @@ VisiblePosition endOfParagraph(const VisiblePosition &c)
         && p.offset() == 0)
         return VisiblePosition(Position(startNode, maxDeepOffset(startNode)));
     
-    Node *startBlock = startNode->enclosingBlockFlowElement();
+    Node* startBlock = enclosingBlock(startNode);
     Node *stayInsideBlock = startBlock;
     
     Node *node = startNode;
@@ -661,8 +661,7 @@ VisiblePosition endOfParagraph(const VisiblePosition &c)
             continue;
         }
         
-        // FIXME: isBlockFlow should not exclude non-inline tables
-        if (r->isBR() || r->isBlockFlow() || (r->isTable() && !r->isInline()))
+        if (r->isBR() || isBlock(n))
             break;
             
         // FIXME: We avoid returning a position where the renderer can't accept the caret.