Reviewed by darin
<http://bugzilla.opendarwin.org/show_bug.cgi?id=8402>
Fix interchange newline handling and avoid use of test rendering info
* editing/pasteboard/interchange-newline-1-expected.checksum: Added.
* editing/pasteboard/interchange-newline-1-expected.png: Added.
* editing/pasteboard/interchange-newline-1-expected.txt: Added.
* editing/pasteboard/interchange-newline-1.html: Added.
* editing/pasteboard/interchange-newline-2-expected.checksum: Added.
* editing/pasteboard/interchange-newline-2-expected.png: Added.
* editing/pasteboard/interchange-newline-2-expected.txt: Added.
* editing/pasteboard/interchange-newline-2.html: Added.
* editing/pasteboard/interchange-newline-3-expected.checksum: Added.
* editing/pasteboard/interchange-newline-3-expected.png: Added.
* editing/pasteboard/interchange-newline-3-expected.txt: Added.
* editing/pasteboard/interchange-newline-3.html: Added.
WebCore:
Reviewed by darin
<http://bugzilla.opendarwin.org/show_bug.cgi?id=8402>
Fix interchange newline handling and avoid use of test rendering info
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::doApply):
Fixed bugs in handling of interchange newlines at the end of incoming
fragments. Removed the use of !fragment.isBlockFlow since it isn't
correct and relies on information gathered during the test insertion, which
we're trying to get rid of.
* editing/VisiblePosition.h:
(WebCore::VisiblePosition::rootEditableElement): Added for convenience.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@13896
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2006-04-17 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by darin
+
+ <http://bugzilla.opendarwin.org/show_bug.cgi?id=8402>
+ Fix interchange newline handling and avoid use of test rendering info
+
+ * editing/pasteboard/interchange-newline-1-expected.checksum: Added.
+ * editing/pasteboard/interchange-newline-1-expected.png: Added.
+ * editing/pasteboard/interchange-newline-1-expected.txt: Added.
+ * editing/pasteboard/interchange-newline-1.html: Added.
+ * editing/pasteboard/interchange-newline-2-expected.checksum: Added.
+ * editing/pasteboard/interchange-newline-2-expected.png: Added.
+ * editing/pasteboard/interchange-newline-2-expected.txt: Added.
+ * editing/pasteboard/interchange-newline-2.html: Added.
+ * editing/pasteboard/interchange-newline-3-expected.checksum: Added.
+ * editing/pasteboard/interchange-newline-3-expected.png: Added.
+ * editing/pasteboard/interchange-newline-3-expected.txt: Added.
+ * editing/pasteboard/interchange-newline-3.html: Added.
+
2006-04-16 Mitz Pettel <opendarwin.org@mitzpettel.com>
Reviewed by Darin.
--- /dev/null
+c2919a0891c0a1113e13df666f60d564
\ No newline at end of file
--- /dev/null
+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
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 0 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+ RenderCanvas 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 784x54
+ RenderText {#text} at (0,0) size 762x54
+ text run at (0,0) width 762: "There is an interchange newline at the end of the incoming fragment, so the last bit of pasted content and the content after"
+ text run at (0,18) width 446: "the position where the paste occured should be in separate paragraphs. "
+ text run at (446,18) width 316: "The last bit of pasted content is a div wrapped in a"
+ text run at (0,36) width 476: "span, which breaks the old code in paste that handled interchange newlines."
+ RenderBlock {DIV} at (0,70) size 784x54
+ RenderBlock (anonymous) at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 8x18
+ text run at (0,0) width 8: "x"
+ RenderText {#text} at (8,0) size 21x18
+ text run at (8,0) width 21: "foo"
+ RenderBlock {DIV} at (0,18) size 784x36
+ RenderBlock (anonymous) at (0,0) size 784x0
+ RenderInline {SPAN} at (0,0) size 0x0
+ RenderBlock (anonymous) at (0,0) size 784x18
+ RenderBlock {DIV} at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 20x18
+ text run at (0,0) width 20: "bar"
+ RenderBlock (anonymous) at (0,18) size 784x18
+ RenderInline {SPAN} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 8x18
+ text run at (0,0) width 8: "x"
+caret: position 0 of child 1 {#text} of child 2 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
--- /dev/null
+<p>There is an interchange newline at the end of the incoming fragment, so the last bit of pasted content and the content after the position where the paste occured should be in separate paragraphs. The last bit of pasted content is a div wrapped in a span, which breaks the old code in paste that handled interchange newlines.</p>
+
+<div id="test" contenteditable="true">xx</div>
+
+<script>
+var s = window.getSelection();
+var e = document.getElementById("test");
+
+s.setPosition(e, 0);
+s.modify("move", "forward", "character");
+document.execCommand("InsertHTML", false, "<div>foo</div><span><div>bar</div></span><br class='Apple-interchange-newline'>");
+</script>
\ No newline at end of file
--- /dev/null
+cd3d7c9791dfe1c8b547b9728e680d7a
\ No newline at end of file
--- /dev/null
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 2 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+ RenderCanvas 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 737x36
+ text run at (0,0) width 448: "This demonstrates a bug in interchange newline handling during paste. "
+ text run at (448,0) width 289: "The selection being pasted into spans multiple"
+ text run at (0,18) width 488: "blocks, which breaks the old code in paste that handled interchange newlines."
+ RenderBlock {DIV} at (0,52) size 784x54
+ RenderBlock {DIV} at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 5x18
+ text run at (0,0) width 5: "f"
+ RenderText {#text} at (5,0) size 20x18
+ text run at (5,0) width 20: "bar"
+ RenderBlock (anonymous) at (0,18) size 784x18
+ RenderText {#text} at (0,0) size 22x18
+ text run at (0,0) width 22: "baz"
+ RenderBlock {DIV} at (0,36) size 784x18
+ RenderText {#text} at (0,0) size 12x18
+ text run at (0,0) width 12: "ar"
+caret: position 0 of child 0 {#text} of child 2 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
--- /dev/null
+<p>This demonstrates a bug in interchange newline handling during paste. The selection being pasted into spans multiple blocks, which breaks the old code in paste that handled interchange newlines.</p>
+
+<div id="test" contenteditable="true"><div>foo</div>bar</div>
+
+<script>
+var s = window.getSelection();
+var e = document.getElementById("test");
+
+s.setPosition(e, 0);
+s.modify("move", "forward", "character");
+s.modify("extend", "forward", "line");
+document.execCommand("InsertHTML", false, "<div>bar</div>baz<br class='Apple-interchange-newline'>");
+</script>
\ No newline at end of file
--- /dev/null
+0a8b3f2fdc9979691c1b009ec533ffef
\ No newline at end of file
--- /dev/null
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+layer at (0,0) size 800x600
+ RenderCanvas 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 784x54
+ RenderText {#text} at (0,0) size 783x54
+ text run at (0,0) width 448: "This demonstrates a bug in interchange newline handling during paste. "
+ text run at (448,0) width 306: "There is an interchange newline at the end of the"
+ text run at (0,18) width 431: "incoming fragment and so the caret should end up on an empty line. "
+ text run at (431,18) width 352: "The editable region is followed by non-editable content,"
+ text run at (0,36) width 439: "which breaks the old code in paste that handled interchange newlines."
+ RenderBlock {DIV} at (0,70) size 784x54
+ RenderBlock (anonymous) at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 21x18
+ text run at (0,0) width 21: "foo"
+ RenderBlock {DIV} at (0,18) size 784x18
+ RenderText {#text} at (0,0) size 20x18
+ text run at (0,0) width 20: "bar"
+ RenderBlock {DIV} at (0,36) size 784x18
+ RenderBR {BR} at (0,0) size 0x18
+ RenderBlock (anonymous) at (0,124) size 784x18
+ RenderText {#text} at (0,0) size 178x18
+ text run at (0,0) width 178: "This is non-editable content."
+caret: position 0 of child 0 {BR} of child 2 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
--- /dev/null
+<p>This demonstrates a bug in interchange newline handling during paste. There is an interchange newline at the end of the incoming fragment and so the caret should end up on an empty line. The editable region is followed by non-editable content, which breaks the old code in paste that handled interchange newlines.</p>
+
+<div id="test" contenteditable="true"></div>
+This is non-editable content.
+
+<script>
+var s = window.getSelection();
+var e = document.getElementById("test");
+
+s.setPosition(e, 0);
+document.execCommand("InsertHTML", false, "foo<div>bar</div><br class='Apple-interchange-newline'>");
+</script>
\ No newline at end of file
+2006-04-17 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by darin
+
+ <http://bugzilla.opendarwin.org/show_bug.cgi?id=8402>
+ Fix interchange newline handling and avoid use of test rendering info
+
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::doApply):
+ Fixed bugs in handling of interchange newlines at the end of incoming
+ fragments. Removed the use of !fragment.isBlockFlow since it isn't
+ correct and relies on information gathered during the test insertion, which
+ we're trying to get rid of.
+ * editing/VisiblePosition.h:
+ (WebCore::VisiblePosition::rootEditableElement): Added for convenience.
+
2006-04-16 Mitz Pettel <opendarwin.org@mitzpettel.com>
Reviewed by Darin.
if (!selection.isContentRichlyEditable())
m_matchStyle = true;
- ReplacementFragment fragment(document(), m_documentFragment.get(), m_matchStyle, selection.rootEditableElement());
+ Element* currentRoot = selection.rootEditableElement();
+ ReplacementFragment fragment(document(), m_documentFragment.get(), m_matchStyle, currentRoot);
if (fragment.type() == EmptyFragment)
return;
Node *insertionBlock = insertionPos.node()->enclosingBlockFlowElement();
Node* insertionRoot = insertionPos.node()->rootEditableElement();
bool insertionBlockIsRoot = insertionBlock == insertionRoot;
- VisiblePosition visibleInsertionPos(insertionPos, DOWNSTREAM);
+ VisiblePosition visibleInsertionPos(insertionPos);
fragment.removeNode(refNode);
if (!insertionBlockIsRoot && fragment.isBlockFlow(refNode.get()) && isStartOfBlock(visibleInsertionPos))
insertNodeBeforeAndUpdateNodesInserted(refNode.get(), insertionBlock);
// a paragraph, but the above splitting should eventually be only about preventing nesting.
ASSERT(isEndOfParagraph(visibleInsertionPos));
VisiblePosition next = visibleInsertionPos.next();
- if (next.isNull() || next.deepEquivalent().node()->rootEditableElement() != insertionRoot) {
+ if (next.isNull() || next.rootEditableElement() != insertionRoot) {
setEndingSelection(visibleInsertionPos);
insertParagraphSeparator();
next = visibleInsertionPos.next();
lastPositionToSelect = endingSelection().end().downstream();
}
else {
- bool insertParagraph = false;
- VisiblePosition pos(insertionPos, VP_DEFAULT_AFFINITY);
+ VisiblePosition pos(insertionPos);
+ VisiblePosition next = pos.next();
- if (startBlock == endBlock && !fragment.isBlockFlow(m_lastTopNodeInserted.get())) {
- insertParagraph = true;
- } else {
- // Handle end-of-document case.
- updateLayout();
- if (isEndOfDocument(pos))
- insertParagraph = true;
- }
- if (insertParagraph) {
+ if (!isEndOfParagraph(pos) || next.isNull() || next.rootEditableElement() != currentRoot) {
setEndingSelection(insertionPos, DOWNSTREAM);
insertParagraphSeparator();
- VisiblePosition next = pos.next();
+ next = pos.next();
// Select up to the paragraph separator that was added.
lastPositionToSelect = next.deepEquivalent().downstream();
void debugPosition(const char* msg = "") const;
static Position deepEquivalent(const Position&);
+
+ Element* rootEditableElement() const { return m_deepPosition.isNotNull() ? m_deepPosition.node()->rootEditableElement() : 0; }
#ifndef NDEBUG
void formatForDebugger(char* buffer, unsigned length) const;