<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[168650] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/168650">168650</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2014-05-12 15:47:39 -0700 (Mon, 12 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Teach Editor to support more direct replacement of a Node
&lt;rdar://problem/16817952&gt; and https://bugs.webkit.org/show_bug.cgi?id=132834

Reviewed by Enrica Casucci.

The new method &quot;Editor::replaceNodeFromPasteboard&quot; has the intent that the new DocumentFragment
from the pasteboard is as similar to the old Node as possible.

In practice, the new DocumentFragment:
1 - Can represent a single node that's missing various attributes the original Node had.
2 - Can be an unwanted fragment of arbitrary depth when the replacement happens inside Mail.app

This fixes both of these issues.

Add a MailBlockquoteHandling enum class for various Editor operations to pass through to the
ReplaceSelectionCommand:
* editing/Editor.cpp:
(WebCore::Editor::handleTextEvent):
(WebCore::Editor::pasteAsFragment):
(WebCore::Editor::pasteWithPasteboard):
(WebCore::Editor::replaceSelectionWithFragment):
* editing/Editor.h:

* dom/TextEvent.cpp:
(WebCore::TextEvent::createForPlainTextPaste):
(WebCore::TextEvent::createForFragmentPaste):
(WebCore::TextEvent::TextEvent):
* dom/TextEvent.h:
(WebCore::TextEvent::mailBlockquoteHandling):

* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::ReplaceSelectionCommand):
(WebCore::ReplaceSelectionCommand::doApply): Consider whether or not this particular Editor
  operation was meant to give special consideration to Mail's Blockquotes.
* editing/ReplaceSelectionCommand.h:

* editing/efl/EditorEfl.cpp:
(WebCore::Editor::pasteWithPasteboard):
* editing/ios/EditorIOS.mm:
(WebCore::Editor::pasteWithPasteboard):

* editing/mac/EditorMac.mm:
(WebCore::Editor::pasteWithPasteboard):
(WebCore::Editor::readSelectionFromPasteboard):
(WebCore::maybeCopyNodeAttributesToFragment): If the new DocumentFragment represents a single HTML node
  with the same tag name is the original HTML node, copy over most attributes from the original node.
(WebCore::Editor::replaceNodeFromPasteboard): Create the fragment, run it through maybeCopyNodeAttributesToFragment.

* WebCore.exp.in:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoredomTextEventcpp">trunk/Source/WebCore/dom/TextEvent.cpp</a></li>
<li><a href="#trunkSourceWebCoredomTextEventh">trunk/Source/WebCore/dom/TextEvent.h</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorh">trunk/Source/WebCore/editing/Editor.h</a></li>
<li><a href="#trunkSourceWebCoreeditingReplaceSelectionCommandcpp">trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingReplaceSelectionCommandh">trunk/Source/WebCore/editing/ReplaceSelectionCommand.h</a></li>
<li><a href="#trunkSourceWebCoreeditingeflEditorEflcpp">trunk/Source/WebCore/editing/efl/EditorEfl.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingiosEditorIOSmm">trunk/Source/WebCore/editing/ios/EditorIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreeditingmacEditorMacmm">trunk/Source/WebCore/editing/mac/EditorMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/ChangeLog        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2014-05-12  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Teach Editor to support more direct replacement of a Node
+        &lt;rdar://problem/16817952&gt; and https://bugs.webkit.org/show_bug.cgi?id=132834
+
+        Reviewed by Enrica Casucci.
+
+        The new method &quot;Editor::replaceNodeFromPasteboard&quot; has the intent that the new DocumentFragment
+        from the pasteboard is as similar to the old Node as possible.
+
+        In practice, the new DocumentFragment:
+        1 - Can represent a single node that's missing various attributes the original Node had.
+        2 - Can be an unwanted fragment of arbitrary depth when the replacement happens inside Mail.app
+
+        This fixes both of these issues.
+
+        Add a MailBlockquoteHandling enum class for various Editor operations to pass through to the
+        ReplaceSelectionCommand:
+        * editing/Editor.cpp:
+        (WebCore::Editor::handleTextEvent):
+        (WebCore::Editor::pasteAsFragment):
+        (WebCore::Editor::pasteWithPasteboard):
+        (WebCore::Editor::replaceSelectionWithFragment):
+        * editing/Editor.h:
+
+        * dom/TextEvent.cpp:
+        (WebCore::TextEvent::createForPlainTextPaste):
+        (WebCore::TextEvent::createForFragmentPaste):
+        (WebCore::TextEvent::TextEvent):
+        * dom/TextEvent.h:
+        (WebCore::TextEvent::mailBlockquoteHandling):
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::ReplaceSelectionCommand):
+        (WebCore::ReplaceSelectionCommand::doApply): Consider whether or not this particular Editor
+          operation was meant to give special consideration to Mail's Blockquotes.
+        * editing/ReplaceSelectionCommand.h:
+
+        * editing/efl/EditorEfl.cpp:
+        (WebCore::Editor::pasteWithPasteboard):
+        * editing/ios/EditorIOS.mm:
+        (WebCore::Editor::pasteWithPasteboard):
+
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::pasteWithPasteboard):
+        (WebCore::Editor::readSelectionFromPasteboard):
+        (WebCore::maybeCopyNodeAttributesToFragment): If the new DocumentFragment represents a single HTML node
+          with the same tag name is the original HTML node, copy over most attributes from the original node.
+        (WebCore::Editor::replaceNodeFromPasteboard): Create the fragment, run it through maybeCopyNodeAttributesToFragment.
+
+        * WebCore.exp.in:
+
</ins><span class="cx"> 2014-05-12  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Progress on web timing.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -1150,7 +1150,7 @@
</span><span class="cx"> __ZN7WebCore6Editor13rangeForPointERKNS_8IntPointE
</span><span class="cx"> __ZN7WebCore6Editor14setCompositionERKN3WTF6StringERKNS1_6VectorINS_20CompositionUnderlineELm0ENS1_15CrashOnOverflowEEEjj
</span><span class="cx"> __ZN7WebCore6Editor14simplifyMarkupEPNS_4NodeES2_
</span><del>-__ZN7WebCore6Editor15pasteAsFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbb
</del><ins>+__ZN7WebCore6Editor15pasteAsFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbNS_22MailBlockquoteHandlingE
</ins><span class="cx"> __ZN7WebCore6Editor16pasteAsPlainTextEv
</span><span class="cx"> __ZN7WebCore6Editor17cancelCompositionEv
</span><span class="cx"> __ZN7WebCore6Editor17insertOrderedListEv
</span><span class="lines">@@ -1170,7 +1170,7 @@
</span><span class="cx"> __ZN7WebCore6Editor26increaseSelectionListLevelEv
</span><span class="cx"> __ZN7WebCore6Editor26toggleOverwriteModeEnabledEv
</span><span class="cx"> __ZN7WebCore6Editor26writeSelectionToPasteboardERNS_10PasteboardE
</span><del>-__ZN7WebCore6Editor28replaceSelectionWithFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbb
</del><ins>+__ZN7WebCore6Editor28replaceSelectionWithFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbbNS_22MailBlockquoteHandlingE
</ins><span class="cx"> __ZN7WebCore6Editor28updateEditorUINowIfScheduledEv
</span><span class="cx"> __ZN7WebCore6Editor29canDecreaseSelectionListLevelEv
</span><span class="cx"> __ZN7WebCore6Editor29canIncreaseSelectionListLevelEv
</span><span class="lines">@@ -2257,7 +2257,7 @@
</span><span class="cx"> __ZN7WebCore6Editor24advanceToNextMisspellingEb
</span><span class="cx"> __ZN7WebCore6Editor25replaceNodeFromPasteboardEPNS_4NodeERKN3WTF6StringE
</span><span class="cx"> __ZN7WebCore6Editor26dataSelectionForPasteboardERKN3WTF6StringE
</span><del>-__ZN7WebCore6Editor27readSelectionFromPasteboardERKN3WTF6StringE
</del><ins>+__ZN7WebCore6Editor27readSelectionFromPasteboardERKN3WTF6StringENS_22MailBlockquoteHandlingE
</ins><span class="cx"> __ZN7WebCore6Editor28stringSelectionForPasteboardEv
</span><span class="cx"> __ZN7WebCore6Editor28toggleAutomaticLinkDetectionEv
</span><span class="cx"> __ZN7WebCore6Editor30toggleAutomaticTextReplacementEv
</span></span></pre></div>
<a id="trunkSourceWebCoredomTextEventcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/TextEvent.cpp (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/TextEvent.cpp        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/dom/TextEvent.cpp        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include &quot;TextEvent.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DocumentFragment.h&quot;
</span><ins>+#include &quot;Editor.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -43,12 +44,12 @@
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;TextEvent&gt; TextEvent::createForPlainTextPaste(PassRefPtr&lt;AbstractView&gt; view, const String&amp; data, bool shouldSmartReplace)
</span><span class="cx"> {
</span><del>-    return adoptRef(new TextEvent(view, data, 0, shouldSmartReplace, false));
</del><ins>+    return adoptRef(new TextEvent(view, data, 0, shouldSmartReplace, false, MailBlockquoteHandling::RespectBlockquote));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;TextEvent&gt; TextEvent::createForFragmentPaste(PassRefPtr&lt;AbstractView&gt; view, PassRefPtr&lt;DocumentFragment&gt; data, bool shouldSmartReplace, bool shouldMatchStyle)
</del><ins>+PassRefPtr&lt;TextEvent&gt; TextEvent::createForFragmentPaste(PassRefPtr&lt;AbstractView&gt; view, PassRefPtr&lt;DocumentFragment&gt; data, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx"> {
</span><del>-    return adoptRef(new TextEvent(view, &quot;&quot;, data, shouldSmartReplace, shouldMatchStyle));
</del><ins>+    return adoptRef(new TextEvent(view, &quot;&quot;, data, shouldSmartReplace, shouldMatchStyle, mailBlockquoteHandling));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;TextEvent&gt; TextEvent::createForDrop(PassRefPtr&lt;AbstractView&gt; view, const String&amp; data)
</span><span class="lines">@@ -65,6 +66,7 @@
</span><span class="cx">     : m_inputType(TextEventInputKeyboard)
</span><span class="cx">     , m_shouldSmartReplace(false)
</span><span class="cx">     , m_shouldMatchStyle(false)
</span><ins>+    , m_mailBlockquoteHandling(MailBlockquoteHandling::RespectBlockquote)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -75,17 +77,18 @@
</span><span class="cx">     , m_pastingFragment(0)
</span><span class="cx">     , m_shouldSmartReplace(false)
</span><span class="cx">     , m_shouldMatchStyle(false)
</span><ins>+    , m_mailBlockquoteHandling(MailBlockquoteHandling::RespectBlockquote)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TextEvent::TextEvent(PassRefPtr&lt;AbstractView&gt; view, const String&amp; data, PassRefPtr&lt;DocumentFragment&gt; pastingFragment,
-                     bool shouldSmartReplace, bool shouldMatchStyle)
</del><ins>+TextEvent::TextEvent(PassRefPtr&lt;AbstractView&gt; view, const String&amp; data, PassRefPtr&lt;DocumentFragment&gt; pastingFragment, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx">     : UIEvent(eventNames().textInputEvent, true, true, view, 0)
</span><span class="cx">     , m_inputType(TextEventInputPaste)
</span><span class="cx">     , m_data(data)
</span><span class="cx">     , m_pastingFragment(pastingFragment)
</span><span class="cx">     , m_shouldSmartReplace(shouldSmartReplace)
</span><span class="cx">     , m_shouldMatchStyle(shouldMatchStyle)
</span><ins>+    , m_mailBlockquoteHandling(mailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -95,6 +98,7 @@
</span><span class="cx">     , m_data(data)
</span><span class="cx">     , m_shouldSmartReplace(false)
</span><span class="cx">     , m_shouldMatchStyle(false)
</span><ins>+    , m_mailBlockquoteHandling(MailBlockquoteHandling::RespectBlockquote)
</ins><span class="cx">     , m_dictationAlternatives(dictationAlternatives)
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoredomTextEventh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/TextEvent.h (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/TextEvent.h        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/dom/TextEvent.h        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -35,14 +35,16 @@
</span><span class="cx"> 
</span><span class="cx">     class DocumentFragment;
</span><span class="cx"> 
</span><ins>+    enum class MailBlockquoteHandling;
+
</ins><span class="cx">     class TextEvent : public UIEvent {
</span><span class="cx">     public:
</span><span class="cx"> 
</span><span class="cx">         static PassRefPtr&lt;TextEvent&gt; create();
</span><span class="cx">         static PassRefPtr&lt;TextEvent&gt; create(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, TextEventInputType = TextEventInputKeyboard);
</span><del>-        static PassRefPtr&lt;TextEvent&gt; createForPlainTextPaste(PassRefPtr&lt;AbstractView&gt; view, const String&amp; data, bool shouldSmartReplace);
-        static PassRefPtr&lt;TextEvent&gt; createForFragmentPaste(PassRefPtr&lt;AbstractView&gt; view, PassRefPtr&lt;DocumentFragment&gt; data, bool shouldSmartReplace, bool shouldMatchStyle);
-        static PassRefPtr&lt;TextEvent&gt; createForDrop(PassRefPtr&lt;AbstractView&gt; view, const String&amp; data);
</del><ins>+        static PassRefPtr&lt;TextEvent&gt; createForPlainTextPaste(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, bool shouldSmartReplace);
+        static PassRefPtr&lt;TextEvent&gt; createForFragmentPaste(PassRefPtr&lt;AbstractView&gt;, PassRefPtr&lt;DocumentFragment&gt; data, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling);
+        static PassRefPtr&lt;TextEvent&gt; createForDrop(PassRefPtr&lt;AbstractView&gt;, const String&amp; data);
</ins><span class="cx">         static PassRefPtr&lt;TextEvent&gt; createForDictation(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, const Vector&lt;DictationAlternative&gt;&amp; dictationAlternatives);
</span><span class="cx"> 
</span><span class="cx">         virtual ~TextEvent();
</span><span class="lines">@@ -62,6 +64,7 @@
</span><span class="cx"> 
</span><span class="cx">         bool shouldSmartReplace() const { return m_shouldSmartReplace; }
</span><span class="cx">         bool shouldMatchStyle() const { return m_shouldMatchStyle; }
</span><ins>+        MailBlockquoteHandling mailBlockquoteHandling() const { return m_mailBlockquoteHandling; }
</ins><span class="cx">         DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); }
</span><span class="cx">         const Vector&lt;DictationAlternative&gt;&amp; dictationAlternatives() const { return m_dictationAlternatives; }
</span><span class="cx"> 
</span><span class="lines">@@ -69,8 +72,7 @@
</span><span class="cx">         TextEvent();
</span><span class="cx"> 
</span><span class="cx">         TextEvent(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, TextEventInputType = TextEventInputKeyboard);
</span><del>-        TextEvent(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, PassRefPtr&lt;DocumentFragment&gt;,
-                  bool shouldSmartReplace, bool shouldMatchStyle);
</del><ins>+        TextEvent(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, PassRefPtr&lt;DocumentFragment&gt;, bool shouldSmartReplace, bool shouldMatchStyle, MailBlockquoteHandling);
</ins><span class="cx">         TextEvent(PassRefPtr&lt;AbstractView&gt;, const String&amp; data, const Vector&lt;DictationAlternative&gt;&amp; dictationAlternatives);
</span><span class="cx"> 
</span><span class="cx">         virtual bool isTextEvent() const override;
</span><span class="lines">@@ -81,6 +83,7 @@
</span><span class="cx">         RefPtr&lt;DocumentFragment&gt; m_pastingFragment;
</span><span class="cx">         bool m_shouldSmartReplace;
</span><span class="cx">         bool m_shouldMatchStyle;
</span><ins>+        MailBlockquoteHandling m_mailBlockquoteHandling;
</ins><span class="cx">         Vector&lt;DictationAlternative&gt; m_dictationAlternatives;
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/Editor.cpp        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -266,7 +266,7 @@
</span><span class="cx">             if (client()-&gt;performsTwoStepPaste(event-&gt;pastingFragment()))
</span><span class="cx">                 return true;
</span><span class="cx"> #endif
</span><del>-            replaceSelectionWithFragment(event-&gt;pastingFragment(), false, event-&gt;shouldSmartReplace(), event-&gt;shouldMatchStyle());
</del><ins>+            replaceSelectionWithFragment(event-&gt;pastingFragment(), false, event-&gt;shouldSmartReplace(), event-&gt;shouldMatchStyle(), event-&gt;mailBlockquoteHandling());
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="lines">@@ -528,12 +528,12 @@
</span><span class="cx">     target-&gt;dispatchEvent(TextEvent::createForPlainTextPaste(document().domWindow(), pastingText, smartReplace), IGNORE_EXCEPTION);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::pasteAsFragment(PassRefPtr&lt;DocumentFragment&gt; pastingFragment, bool smartReplace, bool matchStyle)
</del><ins>+void Editor::pasteAsFragment(PassRefPtr&lt;DocumentFragment&gt; pastingFragment, bool smartReplace, bool matchStyle, MailBlockquoteHandling respectsMailBlockquote)
</ins><span class="cx"> {
</span><span class="cx">     Node* target = findEventTargetFromSelection();
</span><span class="cx">     if (!target)
</span><span class="cx">         return;
</span><del>-    target-&gt;dispatchEvent(TextEvent::createForFragmentPaste(document().domWindow(), pastingFragment, smartReplace, matchStyle), IGNORE_EXCEPTION);
</del><ins>+    target-&gt;dispatchEvent(TextEvent::createForFragmentPaste(document().domWindow(), pastingFragment, smartReplace, matchStyle, respectsMailBlockquote), IGNORE_EXCEPTION);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Editor::pasteAsPlainTextBypassingDHTML()
</span><span class="lines">@@ -565,7 +565,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(COCOA) &amp;&amp; !PLATFORM(EFL)
</span><del>-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText)
</del><ins>+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Range&gt; range = selectedRange();
</span><span class="cx">     if (!range)
</span><span class="lines">@@ -574,7 +574,7 @@
</span><span class="cx">     bool chosePlainText;
</span><span class="cx">     RefPtr&lt;DocumentFragment&gt; fragment = pasteboard-&gt;documentFragment(m_frame, *range, allowPlainText, chosePlainText);
</span><span class="cx">     if (fragment &amp;&amp; shouldInsertFragment(fragment, range, EditorInsertActionPasted))
</span><del>-        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText);
</del><ins>+        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, mailBlockquoteHandling);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -597,7 +597,7 @@
</span><span class="cx">     return client()-&gt;shouldInsertNode(fragment.get(), replacingDOMRange.get(), givenAction);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::replaceSelectionWithFragment(PassRefPtr&lt;DocumentFragment&gt; fragment, bool selectReplacement, bool smartReplace, bool matchStyle)
</del><ins>+void Editor::replaceSelectionWithFragment(PassRefPtr&lt;DocumentFragment&gt; fragment, bool selectReplacement, bool smartReplace, bool matchStyle, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx">     VisibleSelection selection = m_frame.selection().selection();
</span><span class="cx">     if (selection.isNone() || !selection.isContentEditable() || !fragment)
</span><span class="lines">@@ -610,6 +610,9 @@
</span><span class="cx">         options |= ReplaceSelectionCommand::SmartReplace;
</span><span class="cx">     if (matchStyle)
</span><span class="cx">         options |= ReplaceSelectionCommand::MatchStyle;
</span><ins>+    if (mailBlockquoteHandling == MailBlockquoteHandling::IgnoreBlockquote)
+        options |= ReplaceSelectionCommand::IgnoreMailBlockquote;
+
</ins><span class="cx">     applyCommand(ReplaceSelectionCommand::create(document(), fragment, options, EditActionPaste));
</span><span class="cx">     revealSelectionAfterEditingOperation();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.h (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.h        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/Editor.h        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -90,6 +90,11 @@
</span><span class="cx"> enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
</span><span class="cx"> enum EditorParagraphSeparator { EditorParagraphSeparatorIsDiv, EditorParagraphSeparatorIsP };
</span><span class="cx"> 
</span><ins>+enum class MailBlockquoteHandling {
+    RespectBlockquote,
+    IgnoreBlockquote,
+};
+
</ins><span class="cx"> class Editor {
</span><span class="cx"> public:
</span><span class="cx">     explicit Editor(Frame&amp;);
</span><span class="lines">@@ -335,7 +340,7 @@
</span><span class="cx">     void handleAlternativeTextUIResult(const String&amp; correction);
</span><span class="cx">     void dismissCorrectionPanelAsIgnored();
</span><span class="cx"> 
</span><del>-    void pasteAsFragment(PassRefPtr&lt;DocumentFragment&gt;, bool smartReplace, bool matchStyle);
</del><ins>+    void pasteAsFragment(PassRefPtr&lt;DocumentFragment&gt;, bool smartReplace, bool matchStyle, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
</ins><span class="cx">     void pasteAsPlainText(const String&amp;, bool smartReplace);
</span><span class="cx"> 
</span><span class="cx">     // This is only called on the mac where paste is implemented primarily at the WebKit level.
</span><span class="lines">@@ -377,7 +382,7 @@
</span><span class="cx">     void textDidChangeInTextArea(Element*);
</span><span class="cx">     WritingDirection baseWritingDirectionForSelectionStart() const;
</span><span class="cx"> 
</span><del>-    void replaceSelectionWithFragment(PassRefPtr&lt;DocumentFragment&gt;, bool selectReplacement, bool smartReplace, bool matchStyle);
</del><ins>+    void replaceSelectionWithFragment(PassRefPtr&lt;DocumentFragment&gt;, bool selectReplacement, bool smartReplace, bool matchStyle, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
</ins><span class="cx">     void replaceSelectionWithText(const String&amp;, bool selectReplacement, bool smartReplace);
</span><span class="cx">     bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const;
</span><span class="cx">     void updateMarkersForWordsAffectedByEditing(bool onlyHandleWordsContainingSelection);
</span><span class="lines">@@ -431,7 +436,7 @@
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="cx">     bool canCopyExcludingStandaloneImages();
</span><span class="cx">     void takeFindStringFromSelection();
</span><del>-    void readSelectionFromPasteboard(const String&amp; pasteboardName);
</del><ins>+    void readSelectionFromPasteboard(const String&amp; pasteboardName, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
</ins><span class="cx">     void replaceNodeFromPasteboard(Node*, const String&amp; pasteboardName);
</span><span class="cx">     PassRefPtr&lt;SharedBuffer&gt; dataSelectionForPasteboard(const String&amp; pasteboardName);
</span><span class="cx"> #endif // !PLATFORM(IOS)
</span><span class="lines">@@ -450,7 +455,7 @@
</span><span class="cx">     bool canDeleteRange(Range*) const;
</span><span class="cx">     bool canSmartReplaceWithPasteboard(Pasteboard&amp;);
</span><span class="cx">     void pasteAsPlainTextWithPasteboard(Pasteboard&amp;);
</span><del>-    void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
</del><ins>+    void pasteWithPasteboard(Pasteboard*, bool allowPlainText, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
</ins><span class="cx">     String plainTextFromPasteboard(const PasteboardPlainText&amp;);
</span><span class="cx"> 
</span><span class="cx">     void revealSelectionAfterEditingOperation(const ScrollAlignment&amp; = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingReplaceSelectionCommandcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -378,6 +378,7 @@
</span><span class="cx">     , m_editAction(editAction)
</span><span class="cx">     , m_sanitizeFragment(options &amp; SanitizeFragment)
</span><span class="cx">     , m_shouldMergeEnd(false)
</span><ins>+    , m_ignoreMailBlockquote(options &amp; IgnoreMailBlockquote)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -933,12 +934,12 @@
</span><span class="cx">     Node* startBlock = enclosingBlock(visibleStart.deepEquivalent().deprecatedNode());
</span><span class="cx">     
</span><span class="cx">     Position insertionPos = selection.start();
</span><del>-    bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailBlockquote, CanCrossEditingBoundary);
</del><ins>+    bool shouldHandleMailBlockquote = enclosingNodeOfType(insertionPos, isMailBlockquote, CanCrossEditingBoundary) &amp;&amp; !m_ignoreMailBlockquote;
</ins><span class="cx">     bool selectionIsPlainText = !selection.isContentRichlyEditable();
</span><span class="cx">     Element* currentRoot = selection.rootEditableElement();
</span><span class="cx"> 
</span><del>-    if ((selectionStartWasStartOfParagraph &amp;&amp; selectionEndWasEndOfParagraph &amp;&amp; !startIsInsideMailBlockquote) ||
-        startBlock == currentRoot || isListItem(startBlock) || selectionIsPlainText)
</del><ins>+    if ((selectionStartWasStartOfParagraph &amp;&amp; selectionEndWasEndOfParagraph &amp;&amp; !shouldHandleMailBlockquote)
+        || startBlock == currentRoot || isListItem(startBlock) || selectionIsPlainText)
</ins><span class="cx">         m_preventNesting = false;
</span><span class="cx">     
</span><span class="cx">     if (selection.isRange()) {
</span><span class="lines">@@ -948,7 +949,7 @@
</span><span class="cx">         // will leave hanging block(s).
</span><span class="cx">         // Merge blocks if the start of the selection was in a Mail blockquote, since we handle  
</span><span class="cx">         // that case specially to prevent nesting. 
</span><del>-        bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfParagraph(visibleEnd) || isStartOfBlock(visibleStart);
</del><ins>+        bool mergeBlocksAfterDelete = shouldHandleMailBlockquote || isEndOfParagraph(visibleEnd) || isStartOfBlock(visibleStart);
</ins><span class="cx">         // FIXME: We should only expand to include fully selected special elements if we are copying a 
</span><span class="cx">         // selection and pasting it on top of itself.
</span><span class="cx">         deleteSelection(false, mergeBlocksAfterDelete, true, false);
</span><span class="lines">@@ -977,7 +978,7 @@
</span><span class="cx">         // As long as the  div styles are the same, visually you'd expect: &lt;div&gt;xbar&lt;/div&gt;&lt;div&gt;bar&lt;/div&gt;&lt;div&gt;bazx&lt;/div&gt;, 
</span><span class="cx">         // not &lt;div&gt;xbar&lt;div&gt;bar&lt;/div&gt;&lt;div&gt;bazx&lt;/div&gt;&lt;/div&gt;.
</span><span class="cx">         // Don't do this if the selection started in a Mail blockquote.
</span><del>-        if (m_preventNesting &amp;&amp; !startIsInsideMailBlockquote &amp;&amp; !isEndOfParagraph(visibleStart) &amp;&amp; !isStartOfParagraph(visibleStart)) {
</del><ins>+        if (m_preventNesting &amp;&amp; !shouldHandleMailBlockquote &amp;&amp; !isEndOfParagraph(visibleStart) &amp;&amp; !isStartOfParagraph(visibleStart)) {
</ins><span class="cx">             insertParagraphSeparator();
</span><span class="cx">             setEndingSelection(endingSelection().visibleStart().previous());
</span><span class="cx">         }
</span><span class="lines">@@ -987,7 +988,7 @@
</span><span class="cx">     // We don't want any of the pasted content to end up nested in a Mail blockquote, so first break 
</span><span class="cx">     // out of any surrounding Mail blockquotes. Unless we're inserting in a table, in which case
</span><span class="cx">     // breaking the blockquote will prevent the content from actually being inserted in the table.
</span><del>-    if (startIsInsideMailBlockquote &amp;&amp; m_preventNesting &amp;&amp; !(enclosingNodeOfType(insertionPos, &amp;isTableStructureNode))) { 
</del><ins>+    if (shouldHandleMailBlockquote &amp;&amp; m_preventNesting &amp;&amp; !(enclosingNodeOfType(insertionPos, &amp;isTableStructureNode))) {
</ins><span class="cx">         applyCommandToComposite(BreakBlockquoteCommand::create(document())); 
</span><span class="cx">         // This will leave a br between the split. 
</span><span class="cx">         Node* br = endingSelection().start().deprecatedNode(); 
</span><span class="lines">@@ -1016,7 +1017,7 @@
</span><span class="cx">     
</span><span class="cx">     // Adjust insertionPos to prevent nesting.
</span><span class="cx">     // If the start was in a Mail blockquote, we will have already handled adjusting insertionPos above.
</span><del>-    if (m_preventNesting &amp;&amp; insertionBlock &amp;&amp; !isTableCell(insertionBlock.get()) &amp;&amp; !startIsInsideMailBlockquote) {
</del><ins>+    if (m_preventNesting &amp;&amp; insertionBlock &amp;&amp; !isTableCell(insertionBlock.get()) &amp;&amp; !shouldHandleMailBlockquote) {
</ins><span class="cx">         ASSERT(insertionBlock != currentRoot);
</span><span class="cx">         VisiblePosition visibleInsertionPos(insertionPos);
</span><span class="cx">         if (isEndOfBlock(visibleInsertionPos) &amp;&amp; !(isStartOfBlock(visibleInsertionPos) &amp;&amp; fragment.hasInterchangeNewlineAtEnd()))
</span><span class="lines">@@ -1162,7 +1163,7 @@
</span><span class="cx">     // the start merge so that the start merge doesn't effect our decision.
</span><span class="cx">     m_shouldMergeEnd = shouldMergeEnd(selectionEndWasEndOfParagraph);
</span><span class="cx">     
</span><del>-    if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasInterchangeNewlineAtStart(), startIsInsideMailBlockquote)) {
</del><ins>+    if (shouldMergeStart(selectionStartWasStartOfParagraph, fragment.hasInterchangeNewlineAtStart(), shouldHandleMailBlockquote)) {
</ins><span class="cx">         VisiblePosition startOfParagraphToMove = positionAtStartOfInsertedContent();
</span><span class="cx">         VisiblePosition destination = startOfParagraphToMove.previous();
</span><span class="cx">         // We need to handle the case where we need to merge the end
</span><span class="lines">@@ -1211,7 +1212,7 @@
</span><span class="cx">                 } else {
</span><span class="cx">                     // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph
</span><span class="cx">                     // block's style seems to annoy users.
</span><del>-                    insertParagraphSeparator(true, !startIsInsideMailBlockquote &amp;&amp; highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
</del><ins>+                    insertParagraphSeparator(true, !shouldHandleMailBlockquote &amp;&amp; highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
</ins><span class="cx">                         isMailBlockquote, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()-&gt;parentNode()));
</span><span class="cx">                 }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingReplaceSelectionCommandh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.h (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.h        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.h        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -42,7 +42,8 @@
</span><span class="cx">         MatchStyle = 1 &lt;&lt; 2,
</span><span class="cx">         PreventNesting = 1 &lt;&lt; 3,
</span><span class="cx">         MovingParagraph = 1 &lt;&lt; 4,
</span><del>-        SanitizeFragment = 1 &lt;&lt; 5
</del><ins>+        SanitizeFragment = 1 &lt;&lt; 5,
+        IgnoreMailBlockquote = 1 &lt;&lt; 6,
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     typedef unsigned CommandOptions;
</span><span class="lines">@@ -115,6 +116,7 @@
</span><span class="cx">     EditAction m_editAction;
</span><span class="cx">     bool m_sanitizeFragment;
</span><span class="cx">     bool m_shouldMergeEnd;
</span><ins>+    bool m_ignoreMailBlockquote;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingeflEditorEflcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/efl/EditorEfl.cpp (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/efl/EditorEfl.cpp        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/efl/EditorEfl.cpp        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::pasteWithPasteboard(Pasteboard*, bool)
</del><ins>+void Editor::pasteWithPasteboard(Pasteboard*, bool, MailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx">     notImplemented();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingiosEditorIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/ios/EditorIOS.mm (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/ios/EditorIOS.mm        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/ios/EditorIOS.mm        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -551,7 +551,7 @@
</span><span class="cx">     return reader.fragment.release();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText)
</del><ins>+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Range&gt; range = selectedRange();
</span><span class="cx"> 
</span><span class="lines">@@ -561,7 +561,7 @@
</span><span class="cx">         fragment = webContentFromPasteboard(*pasteboard, *range, allowPlainText, chosePlainText);
</span><span class="cx"> 
</span><span class="cx">     if (fragment &amp;&amp; shouldInsertFragment(fragment, range, EditorInsertActionPasted))
</span><del>-        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false);
</del><ins>+        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false, mailBlockquoteHandling);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;DocumentFragment&gt; Editor::createFragmentAndAddResources(NSAttributedString *string)
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingmacEditorMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (168649 => 168650)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/EditorMac.mm        2014-05-12 22:21:16 UTC (rev 168649)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm        2014-05-12 22:47:39 UTC (rev 168650)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">     [[NSApplication sharedApplication] orderFrontColorPanel:nil];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText)
</del><ins>+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Range&gt; range = selectedRange();
</span><span class="cx"> 
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     RefPtr&lt;DocumentFragment&gt; fragment = webContentFromPasteboard(*pasteboard, *range, allowPlainText, chosePlainText);
</span><span class="cx"> 
</span><span class="cx">     if (fragment &amp;&amp; shouldInsertFragment(fragment, range, EditorInsertActionPasted))
</span><del>-        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false);
</del><ins>+        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), false, mailBlockquoteHandling);
</ins><span class="cx"> 
</span><span class="cx">     client()-&gt;setInsertionPasteboard(String());
</span><span class="cx"> }
</span><span class="lines">@@ -257,15 +257,39 @@
</span><span class="cx">     platformStrategies()-&gt;pasteboardStrategy()-&gt;setStringForType(m_frame.displayStringModifiedByEncoding(selectedTextForDataTransfer()), NSStringPboardType, NSFindPboard);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::readSelectionFromPasteboard(const String&amp; pasteboardName)
</del><ins>+void Editor::readSelectionFromPasteboard(const String&amp; pasteboardName, MailBlockquoteHandling mailBlockquoteHandling)
</ins><span class="cx"> {
</span><span class="cx">     Pasteboard pasteboard(pasteboardName);
</span><span class="cx">     if (m_frame.selection().selection().isContentRichlyEditable())
</span><del>-        pasteWithPasteboard(&amp;pasteboard, true);
</del><ins>+        pasteWithPasteboard(&amp;pasteboard, true, mailBlockquoteHandling);
</ins><span class="cx">     else
</span><span class="cx">         pasteAsPlainTextWithPasteboard(pasteboard);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void maybeCopyNodeAttributesToFragment(Node* node, DocumentFragment* fragment)
+{
+    // This is only supported for single-Node fragments.
+    Node* firstChild = fragment-&gt;firstChild();
+    if (firstChild != fragment-&gt;lastChild())
+        return;
+
+    // And only supported for HTML elements.
+    if (!node-&gt;isHTMLElement() || !firstChild-&gt;isHTMLElement())
+        return;
+
+    // And only if the source Element and destination Element have the same HTML tag name.
+    const Element&amp; oldElement = toHTMLElement(*node);
+    Element&amp; newElement = toHTMLElement(*firstChild);
+    if (!oldElement.hasTagName(newElement.tagQName()))
+        return;
+
+    for (const Attribute&amp; attribute : oldElement.attributesIterator()) {
+        if (newElement.hasAttribute(attribute.name()))
+            continue;
+        newElement.setAttribute(attribute.name(), attribute.value());
+    }
+}
+
</ins><span class="cx"> void Editor::replaceNodeFromPasteboard(Node* node, const String&amp; pasteboardName)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(node);
</span><span class="lines">@@ -276,7 +300,25 @@
</span><span class="cx">     RefPtr&lt;Range&gt; range = Range::create(node-&gt;document(), Position(node, Position::PositionIsBeforeAnchor), Position(node, Position::PositionIsAfterAnchor));
</span><span class="cx">     m_frame.selection().setSelection(VisibleSelection(range.get()), FrameSelection::DoNotSetFocus);
</span><span class="cx"> 
</span><del>-    readSelectionFromPasteboard(pasteboardName);
</del><ins>+    Pasteboard pasteboard(pasteboardName);
+
+    if (!m_frame.selection().selection().isContentRichlyEditable()) {
+        pasteAsPlainTextWithPasteboard(pasteboard);
+        return;
+    }
+
+    // FIXME: How can this hard-coded pasteboard name be right, given that the passed-in pasteboard has a name?
+    client()-&gt;setInsertionPasteboard(NSGeneralPboard);
+
+    bool chosePlainText;
+    RefPtr&lt;DocumentFragment&gt; fragment = webContentFromPasteboard(pasteboard, *range, true, chosePlainText);
+
+    maybeCopyNodeAttributesToFragment(node, fragment.get());
+
+    if (fragment &amp;&amp; shouldInsertFragment(fragment, range, EditorInsertActionPasted))
+        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(pasteboard), false, MailBlockquoteHandling::IgnoreBlockquote);
+
+    client()-&gt;setInsertionPasteboard(String());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // FIXME: Makes no sense that selectedTextForDataTransfer always includes alt text, but stringSelectionForPasteboard does not.
</span></span></pre>
</div>
</div>

</body>
</html>