Reviewed by Darin Adler.
[WebKit-https.git] / WebCore / editing / ReplaceSelectionCommand.cpp
index d1dffbd..05fe5a0 100644 (file)
@@ -123,7 +123,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
     
     Node* shadowAncestorNode = editableRoot->shadowAncestorNode();
     
-    if (!editableRoot->getHTMLEventListener(webkitBeforeTextInsertedEvent) &&
+    if (!editableRoot->eventListenerForType(webkitBeforeTextInsertedEvent) &&
         // FIXME: Remove these checks once textareas and textfields actually register an event handler.
         !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestorNode->renderer()->isTextField()) &&
         !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestorNode->renderer()->isTextArea()) &&
@@ -140,7 +140,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
     // Give the root a chance to change the text.
     RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
     ExceptionCode ec = 0;
-    editableRoot->dispatchEvent(evt, ec, true);
+    editableRoot->dispatchEvent(evt, ec);
     ASSERT(ec == 0);
     if (text != evt->text() || !editableRoot->isContentRichlyEditable()) {
         restoreTestRenderingNodesToFragment(holder.get());
@@ -720,13 +720,11 @@ void ReplaceSelectionCommand::doApply()
     
     // Paste at start or end of link goes outside of link.
     insertionPos = positionAvoidingSpecialElementBoundary(insertionPos);
-
-    Frame *frame = document()->frame();
     
-    // FIXME: Improve typing style.
-    // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
-    frame->clearTypingStyle();
-    setTypingStyle(0);
+    // FIXME: Can this wait until after the operation has been performed?  There doesn't seem to be
+    // any work performed after this that queries or uses the typing style.
+    if (Frame* frame = document()->frame())
+        frame->clearTypingStyle();
     
     bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertionPos);
     
@@ -767,7 +765,8 @@ void ReplaceSelectionCommand::doApply()
     if (!handledStyleSpans)
         handleStyleSpans();
     
-    if (!m_firstNodeInserted)
+    // Mutation events (bug 20161) may have already removed the inserted content
+    if (!m_firstNodeInserted || !m_firstNodeInserted->inDocument())
         return;
     
     endOfInsertedContent = positionAtEndOfInsertedContent();
@@ -795,6 +794,17 @@ void ReplaceSelectionCommand::doApply()
         VisiblePosition destination = startOfInsertedContent.previous();
         VisiblePosition startOfParagraphToMove = startOfInsertedContent;
         
+        // Merging the the first paragraph of inserted content with the content that came
+        // before the selection that was pasted into would also move content after 
+        // the selection that was pasted into if: only one paragraph was being pasted, 
+        // and it was not wrapped in a block, the selection that was pasted into ended 
+        // at the end of a block and the next paragraph didn't start at the start of a block.
+        // Insert a line break just after the inserted content to separate it from what 
+        // comes after and prevent that from happening.
+        VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
+        if (startOfParagraph(endOfInsertedContent) == startOfParagraphToMove)
+            insertNodeAt(createBreakElement(document()).get(), endOfInsertedContent.deepEquivalent());
+        
         // 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.
         moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove), destination);