Commit 217ded8c authored by justing's avatar justing

LayoutTests:

        Reviewed by darin

        <http://bugzilla.opendarwin.org/show_bug.cgi?id=6608>
        REGRESSION: Line disappears when deleting

        Added:
        * editing/deleting/merge-different-styles-expected.checksum: Added.
        * editing/deleting/merge-different-styles-expected.png: Added.
        * editing/deleting/merge-different-styles-expected.txt: Added.
        * editing/deleting/merge-different-styles.html: Added.
        * editing/deleting/merge-no-br-expected.checksum: Added.
        * editing/deleting/merge-no-br-expected.png: Added.
        * editing/deleting/merge-no-br-expected.txt: Added.
        * editing/deleting/merge-no-br.html: Added.
        * editing/deleting/merge-whitespace-pre-expected.checksum: Added.
        * editing/deleting/merge-whitespace-pre-expected.png: Added.
        * editing/deleting/merge-whitespace-pre-expected.txt: Added.
        * editing/deleting/merge-whitespace-pre.html: Added.

        Fixes (not enough style on nodes for the fixes to be reflected in pixel results):
        * editing/deleting/delete-block-merge-contents-005-expected.txt:
        * editing/deleting/delete-block-merge-contents-006-expected.txt:
        * editing/deleting/delete-block-merge-contents-008-expected.txt:

        Equivalent render trees:
        * editing/deleting/delete-3857753-fix-expected.txt:
        * editing/inserting/insert-div-026-expected.txt:
        
        Forgot to checkin these new expected results after fixing the DRT bug:
        * fast/lists/drag-into-marker-expected.checksum:
        * fast/lists/drag-into-marker-expected.png:
        * fast/lists/drag-into-marker-expected.txt:

WebCore:

        Reviewed by darin
        
        <http://bugzilla.opendarwin.org/show_bug.cgi?id=6608>
        REGRESSION: Line disappears when deleting
        
        Rewrote moveNodesAfterNode to address these problems:
        It moved nodes without preserving their style. 
        It traversed over siblings looking for a br to know when
        to stop merging.  If the br was burried inside a span, it 
        wouldn't find it.  If the text is whitespace:pre, it wouldn't
        stop.
        In theory it would crash if the "enclosingInlineElements" of the start of the
        selection to delete and the end of the selection to delete were the
        same.  We think that this will fix these:
        <rdar://problems/3950559&4498113>
        CrashTracer: 2116 crashes in Mail at com.apple.WebCore: khtml::CompositeEditCommand::insertNodeAfter + 32
        CrashTracer: 1569 crashes in Mail at com.apple.WebCore: khtml::DeleteSelectionCommand::moveNodesAfterNode + 340
        But we haven't been able to construct a reproducible case.
        
        * editing/CompositeEditCommand.cpp:
        (WebCore::CompositeEditCommand::removeNodeAndPruneAncestors): Moved from ReplaceSelectionCommand.
        (WebCore::CompositeEditCommand::prune): Ditto.
        * editing/CompositeEditCommand.h:
        * editing/DeleteSelectionCommand.cpp:
        (WebCore::DeleteSelectionCommand::mergeParagraphs):
        (WebCore::DeleteSelectionCommand::doApply):
        * editing/DeleteSelectionCommand.h:
        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::doApply):
        * editing/ReplaceSelectionCommand.h:
        (WebCore::):
        * editing/markup.cpp:
        (WebCore::createMarkup): 
        Was crashing when passed a collapsed range.  I early return an empty string instead.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@13685 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b7b8a03c
2006-04-04 Justin Garcia <justin.garcia@apple.com>
Reviewed by darin
<http://bugzilla.opendarwin.org/show_bug.cgi?id=6608>
REGRESSION: Line disappears when deleting
Added:
* editing/deleting/merge-different-styles-expected.checksum: Added.
* editing/deleting/merge-different-styles-expected.png: Added.
* editing/deleting/merge-different-styles-expected.txt: Added.
* editing/deleting/merge-different-styles.html: Added.
* editing/deleting/merge-no-br-expected.checksum: Added.
* editing/deleting/merge-no-br-expected.png: Added.
* editing/deleting/merge-no-br-expected.txt: Added.
* editing/deleting/merge-no-br.html: Added.
* editing/deleting/merge-whitespace-pre-expected.checksum: Added.
* editing/deleting/merge-whitespace-pre-expected.png: Added.
* editing/deleting/merge-whitespace-pre-expected.txt: Added.
* editing/deleting/merge-whitespace-pre.html: Added.
Fixes (not enough style on nodes for the fixes to be reflected in pixel results):
* editing/deleting/delete-block-merge-contents-005-expected.txt:
* editing/deleting/delete-block-merge-contents-006-expected.txt:
* editing/deleting/delete-block-merge-contents-008-expected.txt:
Equivalent render trees:
* editing/deleting/delete-3857753-fix-expected.txt:
* editing/inserting/insert-div-026-expected.txt:
Forgot to checkin these new expected results after fixing the DRT bug:
* fast/lists/drag-into-marker-expected.checksum:
* fast/lists/drag-into-marker-expected.png:
* fast/lists/drag-into-marker-expected.txt:
2006-04-03 Alexey Proskuryakov <ap@nypop.com>
Reviewed by Darin.
......
......@@ -16,12 +16,13 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584 [border: (2px solid #FF0000)]
RenderBlock {DIV} at (14,14) size 756x28
RenderInline {B} at (0,0) size 25x28
RenderInline {B} at (0,0) size 37x28
RenderText {TEXT} at (0,0) size 25x28
text run at (0,0) width 25: "on"
RenderInline {I} at (0,0) size 12x28
RenderText {TEXT} at (25,0) size 12x28
text run at (25,0) width 12: "o"
RenderInline {SPAN} at (0,0) size 12x28
RenderInline {I} at (0,0) size 12x28
RenderText {TEXT} at (25,0) size 12x28
text run at (25,0) width 12: "o"
RenderBlock {DIV} at (14,42) size 756x28
RenderInline {B} at (0,0) size 54x28
RenderText {TEXT} at (0,0) size 54x28
......
......@@ -21,8 +21,10 @@ layer at (0,0) size 800x600
RenderText {TEXT} at (40,0) size 44x28
text run at (40,0) width 44: "Two"
RenderBlock {DIV} at (0,28) size 756x28
RenderText {TEXT} at (0,0) size 57x28
text run at (0,0) width 57: "Three"
RenderBlock (anonymous) at (0,0) size 756x0
RenderBlock {DIV} at (0,0) size 756x28
RenderText {TEXT} at (0,0) size 57x28
text run at (0,0) width 57: "Three"
RenderBlock (anonymous) at (0,56) size 756x28
RenderText {TEXT} at (0,0) size 45x28
text run at (0,0) width 45: "Four"
......
......@@ -21,9 +21,11 @@ layer at (0,0) size 800x600
RenderText {TEXT} at (40,0) size 44x28
text run at (40,0) width 44: "Two"
RenderBlock {DIV} at (0,28) size 756x28
RenderText {TEXT} at (0,0) size 57x28
text run at (0,0) width 57: "Three"
RenderBR {BR} at (0,0) size 0x0
RenderBlock (anonymous) at (0,0) size 756x0
RenderBlock {DIV} at (0,0) size 756x28
RenderText {TEXT} at (0,0) size 57x28
text run at (0,0) width 57: "Three"
RenderBR {BR} at (0,0) size 0x0
RenderBlock (anonymous) at (0,56) size 756x28
RenderText {TEXT} at (0,0) size 45x28
text run at (0,0) width 45: "Four"
......
......@@ -20,10 +20,13 @@ layer at (0,0) size 800x600
text run at (0,0) width 40: "One"
RenderText {TEXT} at (40,0) size 44x28
text run at (40,0) width 44: "Two"
RenderBlock {DIV} at (0,28) size 756x28
RenderText {TEXT} at (0,0) size 57x28
text run at (0,0) width 57: "Three"
RenderBlock {DIV} at (0,56) size 756x28
RenderText {TEXT} at (0,0) size 45x28
text run at (0,0) width 45: "Four"
RenderBlock {DIV} at (0,28) size 756x56
RenderBlock {DIV} at (0,0) size 756x28
RenderBlock (anonymous) at (0,0) size 756x0
RenderBlock {DIV} at (0,0) size 756x28
RenderText {TEXT} at (0,0) size 57x28
text run at (0,0) width 57: "Three"
RenderBlock (anonymous) at (0,28) size 756x28
RenderText {TEXT} at (0,0) size 45x28
text run at (0,0) width 45: "Four"
caret: position 3 of child 0 {TEXT} of child 1 {DIV} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
8937848c887642505b659c38720e1ecf
\ No newline at end of file
EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 5 of DIV > BODY > HTML > #document
EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > DIV > DIV > BODY > HTML > #document to 3 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 784x36
RenderText {TEXT} at (0,0) size 749x36
text run at (0,0) width 345: "This places the caret before the 'b' in 'bar' and Deletes. "
text run at (345,0) width 404: "'foo' and 'bar' should end up on the same line, but neither should"
text run at (0,18) width 82: "change style."
RenderBlock {DIV} at (0,52) size 784x18
RenderBlock {DIV} at (0,0) size 784x18
RenderText {TEXT} at (0,0) size 21x18
text run at (0,0) width 21: "foo"
RenderInline {B} at (0,0) size 24x18
RenderText {TEXT} at (21,0) size 24x18
text run at (21,0) width 24: "bar"
caret: position 3 of child 0 {TEXT} of child 1 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
<p>This places the caret before the 'b' in 'bar' and Deletes. 'foo' and 'bar' should end up on the same line, but neither should change style.</p>
<div contenteditable="true">
<div>foo</div>
<div id="test" style="font-weight:bold">bar</div>
</div>
<script>
var s = window.getSelection();
var e = document.getElementById("test");
s.setPosition(e, 0);
document.execCommand("Delete");
</script>
\ No newline at end of file
bf0b12e550a7656ad7493d7ba478a458
\ No newline at end of file
EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 5 of DIV > BODY > HTML > #document
EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > DIV > DIV > BODY > HTML > #document to 3 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 784x36
RenderText {TEXT} at (0,0) size 782x36
text run at (0,0) width 782: "This places the caret before the 'T' in 'Two' and Deletes. 'One' and 'Two' should be merged but the blocks containing 'Three'"
text run at (0,18) width 230: "and 'Four' should remain untouched."
RenderBlock {DIV} at (8,52) size 768x176
RenderBlock {DIV} at (16,16) size 736x40 [border: (3px solid #FF0000)]
RenderText {TEXT} at (11,11) size 27x18
text run at (11,11) width 27: "One"
RenderText {TEXT} at (38,11) size 30x18
text run at (38,11) width 30: "Two"
RenderBlock {DIV} at (16,64) size 736x96 [border: (3px solid #008000)]
RenderBlock (anonymous) at (11,11) size 714x0
RenderBlock {DIV} at (19,19) size 698x40 [border: (3px solid #000000)]
RenderText {TEXT} at (11,11) size 37x18
text run at (11,11) width 37: "Three"
RenderBlock (anonymous) at (11,67) size 714x18
RenderText {TEXT} at (0,0) size 30x18
text run at (0,0) width 30: "Four"
caret: position 3 of child 0 {TEXT} of child 1 {DIV} of child 2 {DIV} of child 1 {BODY} of child 0 {HTML} of document
<style>
div {
margin: 0.5em;
padding: 0.5em;
}
</style>
<p>This places the caret before the 'T' in 'Two' and Deletes. 'One' and 'Two' should be merged but the blocks containing 'Three' and 'Four' should remain untouched.</p>
<div contenteditable="true">
<div style="border: 3px solid red;">One</div>
<div id="test"style="border: 3px solid green;">Two<div style="border: 3px solid black;">Three</div>Four</div>
</div>
<script>
var s = window.getSelection();
var e = document.getElementById("test");
s.setPosition(e, 0);
document.execCommand("Delete");
</script>
\ No newline at end of file
69b5ac145e0e49f098a165c742188fb8
\ No newline at end of file
EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 5 of DIV > BODY > HTML > #document
EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of PRE > DIV > BODY > HTML > #document to 0 of PRE > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > DIV > DIV > BODY > HTML > #document to 3 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 784x579
RenderBlock {P} at (0,0) size 784x18
RenderText {TEXT} at (0,0) size 781x18
text run at (0,0) width 339: "This places the caret before the 'b' in 'bar' and Delete. "
text run at (339,0) width 442: "'foo' and 'bar' should end up on the same line with 'baz' on the second."
RenderBlock {P} at (0,34) size 784x18
RenderText {TEXT} at (0,0) size 532x18
text run at (0,0) width 532: "This demonstrates a bug, which is that 'bar' changes size when it's merged with 'foo'."
RenderBlock {DIV} at (0,68) size 784x46
RenderBlock {DIV} at (0,0) size 784x18
RenderText {TEXT} at (0,0) size 21x18
text run at (0,0) width 21: "foo"
RenderInline {FONT} at (0,0) size 30x18
RenderInline {SPAN} at (0,0) size 30x18
RenderText {TEXT} at (21,0) size 30x18
text run at (21,0) width 30: "bar"
RenderBlock {PRE} at (0,31) size 784x15
RenderText {TEXT} at (0,0) size 24x15
text run at (0,0) width 24: "baz"
caret: position 3 of child 0 {TEXT} of child 1 {DIV} of child 4 {DIV} of child 0 {BODY} of child 0 {HTML} of document
<p>This places the caret before the 'b' in 'bar' and Delete. 'foo' and 'bar' should end up on the same line with 'baz' on the second.</p>
<p>This demonstrates a bug, which is that 'bar' changes size when it's merged with 'foo'.</p>
<div contenteditable="true">
<div>foo</div>
<pre id="test">bar
baz</pre>
</div>
<script>
var s = window.getSelection();
var e = document.getElementById("test");
s.setPosition(e, 0);
document.execCommand("Delete");
</script>
\ No newline at end of file
......@@ -48,9 +48,10 @@ layer at (0,0) size 800x600
text run at (462,28) width 12: "x"
RenderBlock {DIV} at (0,236) size 784x32
RenderBlock {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
RenderInline {B} at (0,0) size 20x28
RenderInline {B} at (0,0) size 32x28
RenderText {TEXT} at (2,2) size 20x28
text run at (2,2) width 20: "fo"
RenderText {TEXT} at (22,2) size 12x28
text run at (22,2) width 12: "x"
RenderInline {SPAN} at (0,0) size 12x28
RenderText {TEXT} at (22,2) size 12x28
text run at (22,2) width 12: "x"
caret: position 3 of child 0 {TEXT} of child 0 {B} of child 1 {DIV} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
df27ed25b1f079512d5aad0ce5771c69
\ No newline at end of file
720296de5356ea7c8b963a39d88d5ff2
\ No newline at end of file
......@@ -30,14 +30,5 @@ layer at (0,0) size 800x600
text run at (743,36) width 21: "So,"
text run at (0,54) width 371: "this test drags a bit of text over the list marker and drops it. "
text run at (371,54) width 386: "It should be pasted into the list item, which is contenteditable."
RenderBlock {P} at (0,161) size 784x36
RenderInline {B} at (0,0) size 771x36
RenderText {TEXT} at (0,0) size 771x36
text run at (0,0) width 713: "This test case demonstrates a bug in DumpRenderTree's drag and drop support, which is that the source "
text run at (713,0) width 58: "is copied"
text run at (0,18) width 113: "on drop, not cut."
RenderText {TEXT} at (113,18) size 173x18
text run at (113,18) width 4: " "
text run at (117,18) width 169: "So you'll see 'world' twice."
selection start: position 0 of child 0 {TEXT} of child 0 {SPAN} of child 0 {LI} of child 1 {UL} of child 0 {BODY} of child 0 {HTML} of document
selection end: position 6 of child 0 {TEXT} of child 0 {SPAN} of child 0 {LI} of child 1 {UL} of child 0 {BODY} of child 0 {HTML} of document
2006-04-04 Justin Garcia <justin.garcia@apple.com>
Reviewed by darin
<http://bugzilla.opendarwin.org/show_bug.cgi?id=6608>
REGRESSION: Line disappears when deleting
Rewrote moveNodesAfterNode to address these problems:
It moved nodes without preserving their style.
It traversed over siblings looking for a br to know when
to stop merging. If the br was burried inside a span, it
wouldn't find it. If the text is whitespace:pre, it wouldn't
stop.
In theory it would crash if the "enclosingInlineElements" of the start of the
selection to delete and the end of the selection to delete were the
same. We think that this will fix these:
<rdar://problems/3950559&4498113>
CrashTracer: 2116 crashes in Mail at com.apple.WebCore: khtml::CompositeEditCommand::insertNodeAfter + 32
CrashTracer: 1569 crashes in Mail at com.apple.WebCore: khtml::DeleteSelectionCommand::moveNodesAfterNode + 340
But we haven't been able to construct a reproducible case.
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::removeNodeAndPruneAncestors): Moved from ReplaceSelectionCommand.
(WebCore::CompositeEditCommand::prune): Ditto.
* editing/CompositeEditCommand.h:
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::mergeParagraphs):
(WebCore::DeleteSelectionCommand::doApply):
* editing/DeleteSelectionCommand.h:
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::doApply):
* editing/ReplaceSelectionCommand.h:
(WebCore::):
* editing/markup.cpp:
(WebCore::createMarkup):
Was crashing when passed a collapsed range. I early return an empty string instead.
2006-04-04 John Sullivan <sullivan@apple.com>
Reviewed by Adele Peterson.
......@@ -227,6 +227,25 @@ void CompositeEditCommand::removeNodePreservingChildren(Node *removeChild)
applyCommandToComposite(cmd);
}
void CompositeEditCommand::removeNodeAndPruneAncestors(Node* node)
{
RefPtr<Node> parent = node->parentNode();
removeNode(node);
prune(parent);
}
void CompositeEditCommand::prune(PassRefPtr<Node> node)
{
while (node) {
RefPtr<Node> parent = node->parentNode();
// If you change this rule you may have to add an updateLayout() here.
if (node->renderer() && node->renderer()->firstChild())
return;
removeNode(node.get());
node = parent;
}
}
void CompositeEditCommand::splitTextNode(Text *text, int offset)
{
EditCommandPtr cmd(new SplitTextNodeCommand(document(), text, offset));
......
......@@ -75,6 +75,8 @@ protected:
void removeChildrenInRange(WebCore::Node *node, int from, int to);
void removeNode(WebCore::Node *removeChild);
void removeNodePreservingChildren(WebCore::Node *node);
void removeNodeAndPruneAncestors(Node* node);
void prune(PassRefPtr<Node> node);
void replaceTextInNode(WebCore::Text *node, int offset, int count, const WebCore::String &replacementText);
WebCore::Position positionOutsideTabSpan(const WebCore::Position& pos);
void insertNodeAtTabSpanPosition(WebCore::Node *node, const WebCore::Position& pos);
......
......@@ -35,8 +35,10 @@
#include "Position.h"
#include "htmlediting.h"
#include "HTMLNames.h"
#include "markup.h"
#include "render_line.h"
#include "RenderObject.h"
#include "ReplaceSelectionCommand.h"
#include "VisiblePosition.h"
#include "TextIterator.h"
#include "visible_units.h"
......@@ -490,87 +492,66 @@ void DeleteSelectionCommand::fixupWhitespace()
}
}
// This function moves nodes in the block containing startNode to dstBlock, starting
// from startNode and proceeding to the end of the paragraph. Nodes in the block containing
// startNode that appear in document order before startNode are not moved.
// This function is an important helper for deleting selections that cross paragraph
// boundaries.
void DeleteSelectionCommand::moveNodesAfterNode()
// If a selection ended in a different paragraph than it started in, we must merge
// the two paragraphs after deleting the selection.
void DeleteSelectionCommand::mergeParagraphs()
{
if (!m_mergeBlocksAfterDelete)
return;
if (m_endBlock == m_startBlock)
return;
Node *startNode = m_downstreamEnd.node();
Node *dstNode = m_upstreamStart.node();
if (!startNode->inDocument() || !dstNode->inDocument())
return;
Node *startBlock = startNode->enclosingBlockFlowElement();
// FIXME: Deletion should adjust selection endpoints as it removes nodes so that we never get into this state (4099839).
if (!m_downstreamEnd.node()->inDocument() || !m_upstreamStart.node()->inDocument())
return;
// Do not move content between parts of a table.
if (isTableStructureNode(startBlock))
if (isTableStructureNode(m_downstreamEnd.node()->enclosingBlockFlowElement()) || isTableStructureNode(m_upstreamStart.node()->enclosingBlockFlowElement()))
return;
VisiblePosition startOfParagraphToMove(m_downstreamEnd);
VisiblePosition mergeDestination(m_upstreamStart);
// Now that we are about to add content, check to see if a placeholder element
// can be removed.
removeBlockPlaceholder(startBlock);
// Move the subtree containing node
Node *node = startNode->enclosingInlineElement();
// Insert after the subtree containing dstNode
Node *refNode = dstNode->enclosingInlineElement();
// Preserve nesting when deleting to the beginning of an ancestor block
Node *dstBlock = refNode->enclosingBlockFlowElement();
if (startBlock->isAncestor(dstBlock) && isStartOfBlock(VisiblePosition(m_upstreamStart)))
if (mergeDestination == startOfParagraphToMove)
return;
// Do the move.
Node *rootNode = refNode->rootEditableElement();
while (node && node->isAncestor(startBlock)) {
Node *moveNode = node;
node = node->nextSibling();
removeNode(moveNode);
if (moveNode->hasTagName(brTag) && !moveNode->renderer()) {
// Just remove this node, and don't put it back.
// If the BR was not rendered (since it was at the end of a block, for instance),
// putting it back in the document might make it appear, and that is not desirable.
break;
}
if (refNode == rootNode)
insertNodeAt(moveNode, refNode, 0);
else
insertNodeAfter(moveNode, refNode);
refNode = moveNode;
if (moveNode->hasTagName(brTag))
break;
}
// If the startBlock no longer has any kids, we may need to deal with adding a BR
// to make the layout come out right. Consider this document:
//
// One
// <div>Two</div>
// Three
//
// Placing the insertion before before the 'T' of 'Two' and hitting delete will
// move the contents of the div to the block containing 'One' and delete the div.
// This will have the side effect of moving 'Three' on to the same line as 'One'
// and 'Two'. This is undesirable. We fix this up by adding a BR before the 'Three'.
// This may not be ideal, but it is better than nothing.
updateLayout();
if (!startBlock->renderer() || startBlock->renderer()->isEmpty()) {
removeNode(startBlock);
updateLayout();
if (refNode->renderer() && refNode->renderer()->inlineBox() && refNode->renderer()->inlineBox()->nextOnLineExists()) {
insertNodeAfter(createBreakElement(document()).get(), refNode);
}
}
// FIXME: The above early return should be all we need.
if (m_endBlock == m_startBlock)
return;
VisiblePosition endOfParagraphToMove = endOfParagraph(startOfParagraphToMove);
Position start = startOfParagraphToMove.deepEquivalent().upstream();
// We upstream() the end so that we don't include collapsed whitespace in the move.
// If we must later add a br after the merged paragraph, doing so would cause the moved unrendered space to become rendered.
Position end = endOfParagraphToMove.deepEquivalent().upstream();
RefPtr<Range> range = new Range(document(), start.node(), start.offset(), end.node(), end.offset());
// FIXME: This is an inefficient way to preserve style on nodes in the paragraph to move. It
// shouldn't matter though, since moved paragraphs will usually be quite small.
RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(document(), range->toHTML(), "");
setEndingSelection(Selection(startOfParagraphToMove.deepEquivalent(), endOfParagraphToMove.deepEquivalent(), DOWNSTREAM));
deleteSelection(false, false);
// The above deletion leaves a placeholder (it always does when a whole paragraph is deleted).
// We remove it and prune it's parents since we want to remove all traces of the paragraph to move.
Node* placeholder = endingSelection().end().node();
// FIXME: Deletion has bugs and it doesn't always add a placeholder. If it fails, still do pruning.
if (placeholder->hasTagName(brTag))
removeNodeAndPruneAncestors(placeholder);
else
prune(placeholder);
// Add a br if pruning an empty block level element caused a collapse. For example:
// foo
// <div>bar</div>
// baz
// Placing the cursor before 'bar' and hitting delete will merge 'foo' and 'bar' and prune the empty div.
if (!isEndOfParagraph(mergeDestination))
insertNodeAt(createBreakElement(document()).get(), m_upstreamStart.node(), m_upstreamStart.offset());
setEndingSelection(mergeDestination);
EditCommandPtr cmd(new ReplaceSelectionCommand(document(), fragment.get(), false));
applyCommandToComposite(cmd);
}
void DeleteSelectionCommand::calculateEndingPosition()
......@@ -694,8 +675,7 @@ void DeleteSelectionCommand::doApply()
insertPlaceholderForAncestorBlockContent();
handleGeneralDelete();
// Do block merge if start and end of selection are in different blocks.
moveNodesAfterNode();
mergeParagraphs();
calculateEndingPosition();
fixupWhitespace();
......
......@@ -49,7 +49,7 @@ private:
bool handleSpecialCaseBRDelete();
void handleGeneralDelete();
void fixupWhitespace();
void moveNodesAfterNode();
void mergeParagraphs();
void calculateEndingPosition();
void calculateTypingStyleAfterDelete(WebCore::Node *insertedPlaceholder);
void clearTransientState();
......
......@@ -285,21 +285,6 @@ static String &matchNearestBlockquoteColorString()
return matchNearestBlockquoteColorString;
}
// FIXME: Move this somewhere so that the other editing operations can use it to clean up after themselves.
void ReplaceSelectionCommand::removeNodeAndPruneAncestors(Node* node)
{
Node* parent = node->parentNode();
removeNode(node);
while (parent) {
Node* nextParent = parent->parentNode();
// If you change this rule you may have to add an updateLayout() here.
if (parent->renderer() && parent->renderer()->firstChild())
return;
removeNode(parent);
parent = nextParent;
}
}
void ReplaceSelectionCommand::fixupNodeStyles(const NodeVector& nodes, const RenderingInfoMap& renderingInfo)
{
// This function uses the mapped "desired style" to apply the additional style needed, if any,
......@@ -501,6 +486,9 @@ void ReplaceSelectionCommand::doApply()
ReplacementFragment fragment(document(), m_documentFragment.get(), m_matchStyle, selection.rootEditableElement());
if (fragment.type() == EmptyFragment)
return;
if (m_matchStyle)
m_insertionStyle = styleAtPosition(selection.start());
......
......@@ -35,6 +35,8 @@ namespace WebCore {
class DocumentFragment;
enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
class RenderingInfo : public Shared<RenderingInfo> {
public:
RenderingInfo(PassRefPtr<CSSMutableStyleDeclaration>, bool);
......@@ -57,8 +59,6 @@ public:
ReplacementFragment(Document*, DocumentFragment*, bool, Element*);
~ReplacementFragment();
enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
Node *firstChild() const;
Node *lastChild() const;
......@@ -130,7 +130,6 @@ private:
void updateNodesInserted(Node *);
void fixupNodeStyles(const NodeVector&, const RenderingInfoMap&);
void removeLinePlaceholderIfNeeded(Node *);
void removeNodeAndPruneAncestors(Node*);
RefPtr<Node> m_firstNodeInserted;
RefPtr<Node> m_lastNodeInserted;
......
......@@ -326,6 +326,9 @@ DeprecatedString createMarkup(const Range *range, DeprecatedPtrList<Node> *nodes
static const DeprecatedString interchangeNewlineString = DeprecatedString("<br class=\"") + AppleInterchangeNewline + "\">";
ExceptionCode ec = 0;
if (range->collapsed(ec))
return "";
ASSERT(ec == 0);
Node *commonAncestor = range->commonAncestorContainer(ec);
ASSERT(ec == 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment