WebCore:

2009-04-15  Justin Garcia  <justin.garcia@apple.com>

        Reviewed by Dan Bernstein.

        https://bugs.webkit.org/show_bug.cgi?id=25204
        Create a fast path for ReplaceSelectionCommand that merges text nodes
        
        During simple pastes, where we're just pasting a text node into a run of text, we would split the current
        text and insert the new node in between.  This is slow and we hit this bug:

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

        in the layout and rendering code where adjacent text nodes don't shape correctly in Arabic.
        
        This change creates a fast path for ReplaceSelectionCommand that inserts text directly into the
        text node that holds the selection (very similar to the fast path we wrote for InsertTextCommand).

        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::doApply):
        (WebCore::ReplaceSelectionCommand::performTrivialReplace):
        * editing/ReplaceSelectionCommand.h:
        * editing/TextIterator.cpp:

LayoutTests:

2009-04-15  Justin Garcia  <justin.garcia@apple.com>

        Reviewed by Dan Bernstein.
        
        https://bugs.webkit.org/show_bug.cgi?id=25204
        Create a fast path for ReplaceSelectionCommand that merges text nodes
        
        Simplified DOM/Render trees:
        * editing/pasteboard/4840662-expected.txt:
        * platform/mac/editing/pasteboard/bad-placeholder-expected.txt:
        * platform/mac/editing/pasteboard/paste-match-style-001-expected.txt:
        * platform/mac/editing/pasteboard/paste-text-019-expected.txt:
        * platform/mac/editing/pasteboard/paste-xml-expected.txt:

        Removed redundant styles that were generated during nesting prevention that is no longer needed:
        * platform/mac/editing/pasteboard/4076267-2-expected.txt:
        * platform/mac/editing/pasteboard/5156401-1-expected.txt:
        
        No longer incorrectly uncollapsing unrendered whitespace:
        * editing/pasteboard/paste-into-anchor-text-expected.txt:
        * platform/mac/editing/pasteboard/5387578-expected.txt:
        
        No longer invalidating the old selected DOM range during a paste:
        * editing/pasteboard/copy-in-password-field-expected.txt:



git-svn-id: svn://svn.chromium.org/blink/trunk@42549 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent a53b1527
2009-04-15 Justin Garcia <justin.garcia@apple.com>
Reviewed by Dan Bernstein.
https://bugs.webkit.org/show_bug.cgi?id=25204
Create a fast path for ReplaceSelectionCommand that merges text nodes
Simplified DOM/Render trees:
* editing/pasteboard/4840662-expected.txt:
* platform/mac/editing/pasteboard/bad-placeholder-expected.txt:
* platform/mac/editing/pasteboard/paste-match-style-001-expected.txt:
* platform/mac/editing/pasteboard/paste-text-019-expected.txt:
* platform/mac/editing/pasteboard/paste-xml-expected.txt:
Removed redundant styles that were generated during nesting prevention that is no longer needed:
* platform/mac/editing/pasteboard/4076267-2-expected.txt:
* platform/mac/editing/pasteboard/5156401-1-expected.txt:
No longer incorrectly uncollapsing unrendered whitespace:
* editing/pasteboard/paste-into-anchor-text-expected.txt:
* platform/mac/editing/pasteboard/5387578-expected.txt:
No longer invalidating the old selected DOM range during a paste:
* editing/pasteboard/copy-in-password-field-expected.txt:
2009-04-15 Dan Bernstein <mitz@apple.com>
Reviewed by Dave Hyatt.
......
This tests for a crash when pasting into a link that is display:block. 'bar' is pasted between 'foo' and 'baz', and must be part of the link in order to acheive the expected paragraph structure. It should be part of the link but of the default font style. 'bar' shouldn't be underlined and the second style span is unnecessary, since its only property is overridden by its only child.
<a id="anchor" href="http://www.google.com/" style="display:block;">foo<span class="Apple-style-span" style="color: rgb(0, 0, 0); -webkit-text-decorations-in-effect: none; ">bar<span class="Apple-style-span" style="-webkit-text-decorations-in-effect: none; "><a id="anchor" href="http://www.google.com/" style="display: inline !important; ">baz</a></span></span></a>
<a id="anchor" href="http://www.google.com/" style="display:block;">foobarbaz</a>
......@@ -4,8 +4,7 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldInsertText:[not modified] replacingDOMRange:range from 0 of #text > DIV to 14 of #text > DIV givenAction:WebViewInsertActionPasted
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 14 of #text > DIV to 14 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV to 14 of #text > DIV toDOMRange:range from 14 of #text > DIV to 14 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
This test verifies that copying is disabled for password fields by attempting to copy from a password field and paste into a textfield. If the test passes, you'll see a of 'PASS' message below, and the textfield will remain unmodified.
......
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 11 of #text > A > B > TD > TR > TBODY > TABLE > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 11 of #text > A > B > TD > TR > TBODY > TABLE > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 5 of #text > B > A > TD > TR > TBODY > TABLE > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 5 of #text > B > A > TD > TR > TBODY > TABLE > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document toDOMRange:range from 16 of #text > B > A > TD > TR > TBODY > TABLE > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document to 16 of #text > B > A > TD > TR > TBODY > TABLE > TD > TR > TBODY > TABLE > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
Canton Repository (subscription) all 7hello world9 news articles                            
Canton Repository (subscription) all 7hello world9 news articles
......@@ -10,7 +10,7 @@ EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV > DIV
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertText:there should be a single trailing space between the '.' and the last character in this sentence replacingDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 96 of #text > DIV > DIV > BODY > HTML > #document to 96 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 96 of #text > DIV > DIV > BODY > HTML > #document to 96 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 96 of #text > DIV > DIV > BODY > HTML > #document to 96 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
......@@ -23,10 +23,7 @@ layer at (0,0) size 800x600
text run at (0,0) width 381: "This tests to see if trailing spaces are lost during a copy/paste"
RenderBlock {HR} at (0,34) size 784x2 [border: (1px inset #000000)]
RenderBlock {DIV} at (0,44) size 784x26 [border: (2px solid #FFAAAA)]
RenderBlock (anonymous) at (2,2) size 780x0
RenderBlock {DIV} at (2,2) size 780x22 [border: (2px solid #AAAAFF)]
RenderText {#text} at (2,2) size 569x18
text run at (2,2) width 569: "there should be a single trailing space between the '.' and the last character in this sentence "
RenderText {#text} at (571,2) size 4x18
text run at (571,2) width 4: "."
caret: position 96 of child 0 {#text} of child 0 {DIV} of child 5 {DIV} of child 1 {BODY} of child 0 {HTML} of document
RenderText {#text} at (2,2) size 573x18
text run at (2,2) width 573: "there should be a single trailing space between the '.' and the last character in this sentence ."
caret: position 96 of child 0 {#text} of child 1 {DIV} of child 5 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -12,12 +12,6 @@ layer at (0,0) size 800x600
RenderTableRow {TR} at (0,2) size 144x22
RenderTableCell {TD} at (2,2) size 140x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderInline {A} at (0,0) size 136x18 [color=#0000EE]
RenderText {#text} at (2,2) size 10x18
text run at (2,2) width 10: "T"
RenderText {#text} at (12,2) size 122x18
text run at (12,2) width 122: "his should be a link"
RenderInline {SPAN} at (0,0) size 4x18 [color=#000000]
RenderInline {A} at (0,0) size 4x18 [color=#0000EE]
RenderText {#text} at (134,2) size 4x18
text run at (134,2) width 4: "."
caret: position 20 of child 1 {#text} of child 0 {A} of child 0 {TD} of child 0 {TR} of child 0 {TBODY} of child 1 {TABLE} of child 3 {DIV} of child 0 {BODY} of child 0 {HTML} of document
RenderText {#text} at (2,2) size 136x18
text run at (2,2) width 136: "This should be a link."
caret: position 21 of child 0 {#text} of child 0 {A} of child 0 {TD} of child 0 {TR} of child 0 {TBODY} of child 1 {TABLE} of child 3 {DIV} of child 0 {BODY} of child 0 {HTML} of document
......@@ -10,14 +10,11 @@ layer at (0,0) size 800x600
text run at (0,18) width 110: "tickled the crash. "
text run at (110,18) width 333: "You should see 'Hello World' in the table cell below."
RenderBlock {DIV} at (0,52) size 784x28
RenderTable {TABLE} at (0,0) size 93x28 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 91x26
RenderTableRow {TR} at (0,2) size 91x22
RenderTableCell {TD} at (2,2) size 87x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 54x18
text run at (2,2) width 54: "Hello W"
RenderText {#text} at (56,2) size 25x18
text run at (56,2) width 25: "orld"
RenderText {#text} at (81,2) size 4x18
text run at (81,2) width 4: " "
caret: position 4 of child 1 {#text} of child 1 {TD} of child 0 {TR} of child 1 {TBODY} of child 1 {TABLE} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
RenderTable {TABLE} at (0,0) size 89x28 [border: (1px outset #808080)]
RenderTableSection {TBODY} at (1,1) size 87x26
RenderTableRow {TR} at (0,2) size 87x22
RenderTableCell {TD} at (2,2) size 83x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
RenderText {#text} at (2,2) size 79x18
text run at (2,2) width 79: "Hello World"
text run at (81,2) width 0: " \x{9}\x{9} \x{9}\x{9}"
caret: position 11 of child 0 {#text} of child 1 {TD} of child 0 {TR} of child 1 {TBODY} of child 1 {TABLE} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
......@@ -2,7 +2,7 @@ EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML
EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
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 11 of #text > DIV > BODY > HTML > #document to 11 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 5 of #text > DIV > BODY > HTML > #document to 5 of #text > DIV > BODY > HTML > #document toDOMRange:range from 16 of #text > DIV > BODY > HTML > #document to 16 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
layer at (0,0) size 800x600
......@@ -20,11 +20,9 @@ layer at (0,0) size 800x600
text run at (695,0) width 61: "Once that"
text run at (0,18) width 763: "happens, we don't want to make matters worse by removing them if they are acting as line breaks instead of placeholders."
RenderBlock {DIV} at (0,104) size 784x36
RenderText {#text} at (0,0) size 28x18
text run at (0,0) width 28: "First"
RenderText {#text} at (28,0) size 71x18
text run at (28,0) width 71: " paragraph."
RenderText {#text} at (0,0) size 99x18
text run at (0,0) width 99: "First paragraph."
RenderBR {BR} at (99,14) size 0x0
RenderText {#text} at (0,18) size 118x18
text run at (0,18) width 118: "Second paragraph."
caret: position 11 of child 1 {#text} of child 4 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 16 of child 0 {#text} of child 4 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -12,7 +12,7 @@ EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 1 of
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertText:b replacingDOMRange:range from 1 of #text > B > DIV > DIV > BODY > HTML > #document to 1 of #text > B > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > B > DIV > DIV > BODY > HTML > #document to 1 of #text > B > DIV > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > B > DIV > DIV > BODY > HTML > #document to 1 of #text > B > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > B > DIV > DIV > BODY > HTML > #document to 1 of #text > B > DIV > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > B > DIV > DIV > BODY > HTML > #document to 2 of #text > B > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
layer at (0,0) size 800x600
......@@ -42,10 +42,6 @@ layer at (0,0) size 800x600
RenderBlock {DIV} at (0,236) size 784x32
RenderBlock {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
RenderInline {B} at (0,0) size 25x28
RenderText {#text} at (2,2) size 12x28
text run at (2,2) width 12: "a"
RenderText {#text} at (14,2) size 13x28
text run at (14,2) width 13: "b"
RenderBlock (anonymous) at (0,32) size 784x0
RenderText {#text} at (0,0) size 0x0
caret: position 1 of child 1 {#text} of child 0 {B} of child 1 {DIV} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
RenderText {#text} at (2,2) size 25x28
text run at (2,2) width 25: "ab"
caret: position 2 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
......@@ -14,7 +14,7 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldInsertText:Bar replacingDOMRange:range from 4 of #text > SPAN > DIV > BODY > HTML > #document to 4 of #text > SPAN > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 4 of #text > SPAN > DIV > BODY > HTML > #document to 4 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > SPAN > DIV > BODY > HTML > #document to 3 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 4 of #text > SPAN > DIV > BODY > HTML > #document to 4 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 7 of #text > SPAN > DIV > BODY > HTML > #document to 7 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
layer at (0,0) size 800x600
......@@ -52,8 +52,7 @@ layer at (0,0) size 800x600
RenderInline {SPAN} at (0,0) size 78x28
RenderText {#text} at (2,2) size 78x28
text run at (2,2) width 78: "Foo Bar"
RenderText {#text} at (80,2) size 40x28
text run at (80,2) width 40: " baz"
RenderText {#text} at (120,2) size 35x28
text run at (120,2) width 35: "Bar"
caret: position 3 of child 2 {#text} of child 1 {SPAN} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
RenderText {#text} at (80,2) size 75x28
text run at (80,2) width 75: " bazBar"
RenderText {#text} at (0,0) size 0x0
caret: position 7 of child 1 {#text} of child 1 {SPAN} of child 3 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -10,7 +10,7 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldInsertText:bar replacingDOMRange:range from 7 of #text > span > div > body > html > #document to 7 of #text > span > div > body > html > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 4 of #text > span > div > body > html > #document to 4 of #text > span > div > body > html > #document toDOMRange:range from 3 of #text > span > div > body > html > #document to 3 of #text > span > div > body > html > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > span > div > body > html > #document to 7 of #text > span > div > body > html > #document toDOMRange:range from 10 of #text > span > div > body > html > #document to 10 of #text > span > div > body > html > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
layer at (0,0) size 800x600
......@@ -20,11 +20,7 @@ layer at (0,0) size 800x72
RenderBody {body} at (8,8) size 784x56
RenderBlock {div} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {span} at (0,0) size 140x28
RenderText {#text} at (14,14) size 69x28
text run at (14,14) width 69: "foo bar"
RenderText {#text} at (83,14) size 31x28
text run at (83,14) width 31: "bar"
RenderText {#text} at (114,14) size 40x28
text run at (114,14) width 40: " baz"
RenderText {#text} at (14,14) size 140x28
text run at (14,14) width 140: "foo barbar baz"
RenderText {#text} at (0,0) size 0x0
caret: position 3 of child 1 {#text} of child 1 {span} of child 1 {div} of child 3 {body} of child 1 {html} of document
caret: position 10 of child 0 {#text} of child 1 {span} of child 1 {div} of child 3 {body} of child 1 {html} of document
2009-04-15 Justin Garcia <justin.garcia@apple.com>
Reviewed by Dan Bernstein.
https://bugs.webkit.org/show_bug.cgi?id=25204
Create a fast path for ReplaceSelectionCommand that merges text nodes
During simple pastes, where we're just pasting a text node into a run of text, we would split the current
text and insert the new node in between. This is slow and we hit this bug:
https://bugs.webkit.org/show_bug.cgi?id=6148
in the layout and rendering code where adjacent text nodes don't shape correctly in Arabic.
This change creates a fast path for ReplaceSelectionCommand that inserts text directly into the
text node that holds the selection (very similar to the fast path we wrote for InsertTextCommand).
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::doApply):
(WebCore::ReplaceSelectionCommand::performTrivialReplace):
* editing/ReplaceSelectionCommand.h:
* editing/TextIterator.cpp:
2009-04-15 Adam Langley <agl@google.com>
Reviewed by Darin Fisher.
......@@ -690,7 +690,8 @@ void ReplaceSelectionCommand::mergeEndIfNeeded()
moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove), destination);
// Merging forward will remove m_lastLeafInserted from the document.
// FIXME: Maintain positions for the start and end of inserted content instead of keeping nodes. The nodes are
// only ever used to create positions where inserted content starts/ends.
// only ever used to create positions where inserted content starts/ends. Also, we sometimes insert content
// directly into text nodes already in the document, in which case tracking inserted nodes is inadequate.
if (mergeForward) {
m_lastLeafInserted = destination.previous().deepEquivalent().node();
if (!m_firstNodeInserted->inDocument())
......@@ -711,6 +712,9 @@ void ReplaceSelectionCommand::doApply()
Element* currentRoot = selection.rootEditableElement();
ReplacementFragment fragment(document(), m_documentFragment.get(), m_matchStyle, selection);
if (performTrivialReplace(fragment))
return;
if (m_matchStyle)
m_insertionStyle = styleAtPosition(selection.start());
......@@ -822,6 +826,9 @@ void ReplaceSelectionCommand::doApply()
bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertionPos);
// FIXME: When pasting rich content we're often prevented from heading down the fast path by style spans. Try
// again here if they've been removed.
// We're finished if there is nothing to add.
if (fragment.isEmpty() || !fragment.firstChild())
return;
......@@ -1093,4 +1100,38 @@ void ReplaceSelectionCommand::updateNodesInserted(Node *node)
m_lastLeafInserted = node->lastDescendant();
}
// During simple pastes, where we're just pasting a text node into a run of text, we insert the text node
// directly into the text node that holds the selection. This is much faster than the generalized code in
// ReplaceSelectionCommand, and works around <https://bugs.webkit.org/show_bug.cgi?id=6148> since we don't
// split text nodes.
bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& fragment)
{
if (!fragment.firstChild() || fragment.firstChild() != fragment.lastChild() || !fragment.firstChild()->isTextNode())
return false;
// FIXME: Would be nice to handle smart replace in the fast path.
if (m_smartReplace || fragment.hasInterchangeNewlineAtStart() || fragment.hasInterchangeNewlineAtEnd())
return false;
Text* textNode = static_cast<Text*>(fragment.firstChild());
// Our fragment creation code handles tabs, spaces, and newlines, so we don't have to worry about those here.
String text(textNode->data());
Position start = endingSelection().start();
Position end = endingSelection().end();
if (start.anchorNode() != end.anchorNode() || !start.anchorNode()->isTextNode())
return false;
replaceTextInNode(static_cast<Text*>(start.anchorNode()), start.offsetInContainerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), text);
end = Position(start.anchorNode(), start.offsetInContainerNode() + text.length());
VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, end);
setEndingSelection(selectionAfterReplace);
return true;
}
} // namespace WebCore
......@@ -31,6 +31,7 @@
namespace WebCore {
class DocumentFragment;
class ReplacementFragment;
class ReplaceSelectionCommand : public CompositeEditCommand {
public:
......@@ -74,6 +75,8 @@ private:
VisiblePosition positionAtStartOfInsertedContent();
VisiblePosition positionAtEndOfInsertedContent();
bool performTrivialReplace(const ReplacementFragment&);
RefPtr<Node> m_firstNodeInserted;
RefPtr<Node> m_lastLeafInserted;
......
......@@ -42,7 +42,7 @@ public:
VisibleSelection();
VisibleSelection(const Position&, EAffinity);
VisibleSelection(const Position&, const Position&, EAffinity);
VisibleSelection(const Position&, const Position&, EAffinity = SEL_DEFAULT_AFFINITY);
VisibleSelection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY);
......
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