<!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>[210773] 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/210773">210773</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2017-01-14 22:45:58 -0800 (Sat, 14 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>De-duplicate some (nearly) identical code in Editor(Mac|IOS).mm
https://bugs.webkit.org/show_bug.cgi?id=167062

Reviewed by Dan Bernstein.

No new tests, just refactoring.

* editing/Editor.cpp:
(WebCore::Editor::fontForSelection):
(WebCore::Editor::styleForSelectionStart):
(WebCore::Editor::adjustedSelectionRange):
* editing/Editor.h:
Move these three functions to Editor and unguard them, because they're
not Cocoa specific.

* platform/spi/cocoa/NSAttributedStringSPI.h:
Move some iOS-only NSAttributedString IPI (so no Internal SDK switch)
to NSAttributedStringSPI.h.

* editing/cocoa/EditorCocoa.mm:
(WebCore::Editor::writeSelectionToPasteboard):
(WebCore::Editor::selectionInWebArchiveFormat):
(WebCore::Editor::replaceSelectionWithAttributedString):
(WebCore::Editor::createFragmentForImageResourceAndAddResource):
(WebCore::Editor::dataInRTFDFormat):
(WebCore::Editor::dataInRTFFormat):
Move these six functions here.
selectionInWebArchiveFormat and replaceSelectionWithAttributedString are
entirely identical; writeSelectionToPasteboard and createFragment...
both have slightly suspicious-looking differences that I left intact
and wrote comments about (especially createFragment..., the other one
is somewhat explicable). The two dataInRTF(D)Format functions used to
be static functions, but for now are required from both EditorCocoa
and Editor(Mac|IOS), so we'll make them static member functions.

* editing/ios/EditorIOS.mm:
(WebCore::Editor::fontForSelection): Deleted.
(WebCore::Editor::selectionInWebArchiveFormat): Deleted.
(WebCore::dataInRTFDFormat): Deleted.
(WebCore::dataInRTFFormat): Deleted.
(WebCore::Editor::writeSelectionToPasteboard): Deleted.
(WebCore::Editor::createFragmentForImageResourceAndAddResource): Deleted.
(WebCore::Editor::replaceSelectionWithAttributedString): Deleted.
* editing/mac/EditorMac.mm:
(WebCore::Editor::fontForSelection): Deleted.
(WebCore::Editor::selectionInWebArchiveFormat): Deleted.
(WebCore::dataInRTFDFormat): Deleted.
(WebCore::dataInRTFFormat): Deleted.
(WebCore::Editor::writeSelectionToPasteboard): Deleted.
(WebCore::Editor::createFragmentForImageResourceAndAddResource): Deleted.
(WebCore::Editor::replaceSelectionWithAttributedString): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</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="#trunkSourceWebCoreeditingcocoaEditorCocoamm">trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm</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>
<li><a href="#trunkSourceWebCoreplatformspicocoaNSAttributedStringSPIh">trunk/Source/WebCore/platform/spi/cocoa/NSAttributedStringSPI.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/ChangeLog        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2017-01-14  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        De-duplicate some (nearly) identical code in Editor(Mac|IOS).mm
+        https://bugs.webkit.org/show_bug.cgi?id=167062
+
+        Reviewed by Dan Bernstein.
+
+        No new tests, just refactoring.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::fontForSelection):
+        (WebCore::Editor::styleForSelectionStart):
+        (WebCore::Editor::adjustedSelectionRange):
+        * editing/Editor.h:
+        Move these three functions to Editor and unguard them, because they're
+        not Cocoa specific.
+
+        * platform/spi/cocoa/NSAttributedStringSPI.h:
+        Move some iOS-only NSAttributedString IPI (so no Internal SDK switch)
+        to NSAttributedStringSPI.h.
+
+        * editing/cocoa/EditorCocoa.mm:
+        (WebCore::Editor::writeSelectionToPasteboard):
+        (WebCore::Editor::selectionInWebArchiveFormat):
+        (WebCore::Editor::replaceSelectionWithAttributedString):
+        (WebCore::Editor::createFragmentForImageResourceAndAddResource):
+        (WebCore::Editor::dataInRTFDFormat):
+        (WebCore::Editor::dataInRTFFormat):
+        Move these six functions here.
+        selectionInWebArchiveFormat and replaceSelectionWithAttributedString are
+        entirely identical; writeSelectionToPasteboard and createFragment...
+        both have slightly suspicious-looking differences that I left intact
+        and wrote comments about (especially createFragment..., the other one
+        is somewhat explicable). The two dataInRTF(D)Format functions used to
+        be static functions, but for now are required from both EditorCocoa
+        and Editor(Mac|IOS), so we'll make them static member functions.
+
+        * editing/ios/EditorIOS.mm:
+        (WebCore::Editor::fontForSelection): Deleted.
+        (WebCore::Editor::selectionInWebArchiveFormat): Deleted.
+        (WebCore::dataInRTFDFormat): Deleted.
+        (WebCore::dataInRTFFormat): Deleted.
+        (WebCore::Editor::writeSelectionToPasteboard): Deleted.
+        (WebCore::Editor::createFragmentForImageResourceAndAddResource): Deleted.
+        (WebCore::Editor::replaceSelectionWithAttributedString): Deleted.
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::fontForSelection): Deleted.
+        (WebCore::Editor::selectionInWebArchiveFormat): Deleted.
+        (WebCore::dataInRTFDFormat): Deleted.
+        (WebCore::dataInRTFFormat): Deleted.
+        (WebCore::Editor::writeSelectionToPasteboard): Deleted.
+        (WebCore::Editor::createFragmentForImageResourceAndAddResource): Deleted.
+        (WebCore::Editor::replaceSelectionWithAttributedString): Deleted.
+
</ins><span class="cx"> 2017-01-14  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Small code cleanup after r210760
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/editing/Editor.cpp        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -56,6 +56,7 @@
</span><span class="cx"> #include &quot;HTMLImageElement.h&quot;
</span><span class="cx"> #include &quot;HTMLInputElement.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><ins>+#include &quot;HTMLSpanElement.h&quot;
</ins><span class="cx"> #include &quot;HitTestResult.h&quot;
</span><span class="cx"> #include &quot;IndentOutdentCommand.h&quot;
</span><span class="cx"> #include &quot;InputEvent.h&quot;
</span><span class="lines">@@ -3646,4 +3647,98 @@
</span><span class="cx">     return *m_frame.document();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;Range&gt; Editor::adjustedSelectionRange()
+{
+    // FIXME: Why do we need to adjust the selection to include the anchor tag it's in?
+    // Whoever wrote this code originally forgot to leave us a comment explaining the rationale.
+    RefPtr&lt;Range&gt; range = selectedRange();
+    Node* commonAncestor = range-&gt;commonAncestorContainer();
+    ASSERT(commonAncestor);
+    auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
+    if (enclosingAnchor &amp;&amp; comparePositions(firstPositionInOrBeforeNode(range-&gt;startPosition().anchorNode()), range-&gt;startPosition()) &gt;= 0)
+        range-&gt;setStart(*enclosingAnchor, 0);
+    return range;
+}
+
+// FIXME: This figures out the current style by inserting a &lt;span&gt;!
+const RenderStyle* Editor::styleForSelectionStart(Frame* frame, Node*&amp; nodeToRemove)
+{
+    nodeToRemove = nullptr;
+
+    if (frame-&gt;selection().isNone())
+        return nullptr;
+
+    Position position = adjustedSelectionStartForStyleComputation(frame-&gt;selection().selection());
+    if (!position.isCandidate() || position.isNull())
+        return nullptr;
+
+    RefPtr&lt;EditingStyle&gt; typingStyle = frame-&gt;selection().typingStyle();
+    if (!typingStyle || !typingStyle-&gt;style())
+        return &amp;position.deprecatedNode()-&gt;renderer()-&gt;style();
+
+    auto styleElement = HTMLSpanElement::create(*frame-&gt;document());
+
+    String styleText = typingStyle-&gt;style()-&gt;asText() + &quot; display: inline&quot;;
+    styleElement-&gt;setAttribute(HTMLNames::styleAttr, styleText);
+
+    styleElement-&gt;appendChild(frame-&gt;document()-&gt;createEditingTextNode(emptyString()));
+
+    auto positionNode = position.deprecatedNode();
+    if (!positionNode || !positionNode-&gt;parentNode() || positionNode-&gt;parentNode()-&gt;appendChild(styleElement).hasException())
+        return nullptr;
+
+    nodeToRemove = styleElement.ptr();
+    
+    frame-&gt;document()-&gt;updateStyleIfNeeded();
+    return styleElement-&gt;renderer() ? &amp;styleElement-&gt;renderer()-&gt;style() : nullptr;
+}
+
+const Font* Editor::fontForSelection(bool&amp; hasMultipleFonts) const
+{
+    hasMultipleFonts = false;
+
+    if (!m_frame.selection().isRange()) {
+        Node* nodeToRemove;
+        auto* style = styleForSelectionStart(&amp;m_frame, nodeToRemove); // sets nodeToRemove
+
+        const Font* font = nullptr;
+        if (style) {
+            font = &amp;style-&gt;fontCascade().primaryFont();
+            if (nodeToRemove)
+                nodeToRemove-&gt;remove();
+        }
+
+        return font;
+    }
+
+    RefPtr&lt;Range&gt; range = m_frame.selection().toNormalizedRange();
+    if (!range)
+        return nullptr;
+
+    Node* startNode = adjustedSelectionStartForStyleComputation(m_frame.selection().selection()).deprecatedNode();
+    if (!startNode)
+        return nullptr;
+
+    const Font* font = nullptr;
+    Node* pastEnd = range-&gt;pastLastNode();
+    // In the loop below, node should eventually match pastEnd and not become null, but we've seen at least one
+    // unreproducible case where this didn't happen, so check for null also.
+    for (Node* node = startNode; node &amp;&amp; node != pastEnd; node = NodeTraversal::next(*node)) {
+        auto renderer = node-&gt;renderer();
+        if (!renderer)
+            continue;
+        // FIXME: Are there any node types that have renderers, but that we should be skipping?
+        const Font&amp; primaryFont = renderer-&gt;style().fontCascade().primaryFont();
+        if (!font)
+            font = &amp;primaryFont;
+        else if (font != &amp;primaryFont) {
+            hasMultipleFonts = true;
+            break;
+        }
+    }
+
+    return font;
+}
+
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.h (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.h        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/editing/Editor.h        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -443,10 +443,11 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;DocumentFragment&gt; webContentFromPasteboard(Pasteboard&amp;, Range&amp; context, bool allowPlainText, bool&amp; chosePlainText);
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT const Font* fontForSelection(bool&amp; hasMultipleFonts) const;
+    WEBCORE_EXPORT static const RenderStyle* styleForSelectionStart(Frame* , Node *&amp;nodeToRemove);
+
</ins><span class="cx"> #if PLATFORM(COCOA)
</span><del>-    WEBCORE_EXPORT static const RenderStyle* styleForSelectionStart(Frame* , Node *&amp;nodeToRemove);
</del><span class="cx">     void getTextDecorationAttributesRespectingTypingStyle(const RenderStyle&amp;, NSMutableDictionary*) const;
</span><del>-    WEBCORE_EXPORT const Font* fontForSelection(bool&amp;) const;
</del><span class="cx">     WEBCORE_EXPORT NSDictionary *fontAttributesForSelectionStart() const;
</span><span class="cx">     WEBCORE_EXPORT String stringSelectionForPasteboard();
</span><span class="cx">     String stringSelectionForPasteboardWithImageAltText();
</span><span class="lines">@@ -512,16 +513,20 @@
</span><span class="cx"> 
</span><span class="cx">     bool unifiedTextCheckerEnabled() const;
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;Range&gt; adjustedSelectionRange();
+
</ins><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     RefPtr&lt;SharedBuffer&gt; selectionInWebArchiveFormat();
</span><span class="cx">     String selectionInHTMLFormat();
</span><span class="cx">     RefPtr&lt;SharedBuffer&gt; imageInWebArchiveFormat(Element&amp;);
</span><del>-    RefPtr&lt;Range&gt; adjustedSelectionRange();
</del><span class="cx">     RefPtr&lt;DocumentFragment&gt; createFragmentForImageResourceAndAddResource(RefPtr&lt;ArchiveResource&gt;&amp;&amp;);
</span><span class="cx">     Ref&lt;DocumentFragment&gt; createFragmentForImageAndURL(const String&amp;);
</span><span class="cx">     RefPtr&lt;DocumentFragment&gt; createFragmentAndAddResources(NSAttributedString *);
</span><span class="cx">     FragmentAndResources createFragment(NSAttributedString *);
</span><span class="cx">     void fillInUserVisibleForm(PasteboardURL&amp;);
</span><ins>+
+    static RefPtr&lt;SharedBuffer&gt; dataInRTFDFormat(NSAttributedString *);
+    static RefPtr&lt;SharedBuffer&gt; dataInRTFFormat(NSAttributedString *);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void postTextStateChangeNotificationForCut(const String&amp;, const VisibleSelection&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingcocoaEditorCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -30,16 +30,23 @@
</span><span class="cx"> #import &quot;CSSValueList.h&quot;
</span><span class="cx"> #import &quot;CSSValuePool.h&quot;
</span><span class="cx"> #import &quot;DocumentFragment.h&quot;
</span><ins>+#import &quot;DocumentLoader.h&quot;
</ins><span class="cx"> #import &quot;EditingStyle.h&quot;
</span><ins>+#import &quot;EditorClient.h&quot;
</ins><span class="cx"> #import &quot;Frame.h&quot;
</span><span class="cx"> #import &quot;FrameSelection.h&quot;
</span><ins>+#import &quot;HTMLConverter.h&quot;
+#import &quot;HTMLImageElement.h&quot;
</ins><span class="cx"> #import &quot;HTMLSpanElement.h&quot;
</span><ins>+#import &quot;LegacyWebArchive.h&quot;
</ins><span class="cx"> #import &quot;NSAttributedStringSPI.h&quot;
</span><ins>+#import &quot;Pasteboard.h&quot;
</ins><span class="cx"> #import &quot;RenderElement.h&quot;
</span><span class="cx"> #import &quot;RenderStyle.h&quot;
</span><span class="cx"> #import &quot;SoftLinking.h&quot;
</span><span class="cx"> #import &quot;Text.h&quot;
</span><span class="cx"> #import &quot;htmlediting.h&quot;
</span><ins>+#import &lt;wtf/BlockObjCExceptions.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> SOFT_LINK_PRIVATE_FRAMEWORK(WebKitLegacy)
</span><span class="lines">@@ -53,39 +60,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-// FIXME: This figures out the current style by inserting a &lt;span&gt;!
-const RenderStyle* Editor::styleForSelectionStart(Frame* frame, Node*&amp; nodeToRemove)
-{
-    nodeToRemove = nullptr;
-    
-    if (frame-&gt;selection().isNone())
-        return nullptr;
-
-    Position position = adjustedSelectionStartForStyleComputation(frame-&gt;selection().selection());
-    if (!position.isCandidate() || position.isNull())
-        return nullptr;
-
-    RefPtr&lt;EditingStyle&gt; typingStyle = frame-&gt;selection().typingStyle();
-    if (!typingStyle || !typingStyle-&gt;style())
-        return &amp;position.deprecatedNode()-&gt;renderer()-&gt;style();
-
-    auto styleElement = HTMLSpanElement::create(*frame-&gt;document());
-
-    String styleText = typingStyle-&gt;style()-&gt;asText() + &quot; display: inline&quot;;
-    styleElement-&gt;setAttribute(HTMLNames::styleAttr, styleText);
-
-    styleElement-&gt;appendChild(frame-&gt;document()-&gt;createEditingTextNode(emptyString()));
-
-    auto positionNode = position.deprecatedNode();
-    if (!positionNode || !positionNode-&gt;parentNode() || positionNode-&gt;parentNode()-&gt;appendChild(styleElement).hasException())
-        return nullptr;
-
-    nodeToRemove = styleElement.ptr();
-
-    frame-&gt;document()-&gt;updateStyleIfNeeded();
-    return styleElement-&gt;renderer() ? &amp;styleElement-&gt;renderer()-&gt;style() : nullptr;
-}
-
</del><span class="cx"> void Editor::getTextDecorationAttributesRespectingTypingStyle(const RenderStyle&amp; style, NSMutableDictionary* result) const
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;EditingStyle&gt; typingStyle = m_frame.selection().typingStyle();
</span><span class="lines">@@ -116,4 +90,99 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Editor::writeSelectionToPasteboard(Pasteboard&amp; pasteboard)
+{
+    NSAttributedString *attributedString = attributedStringFromRange(*selectedRange());
+
+    PasteboardWebContent content;
+    content.canSmartCopyOrDelete = canSmartCopyOrDelete();
+    content.dataInWebArchiveFormat = selectionInWebArchiveFormat();
+    content.dataInRTFDFormat = attributedString.containsAttachments ? dataInRTFDFormat(attributedString) : nullptr;
+    content.dataInRTFFormat = dataInRTFFormat(attributedString);
+    // FIXME: Why don't we want this on iOS?
+#if PLATFORM(MAC)
+    content.dataInHTMLFormat = selectionInHTMLFormat();
+#endif
+    content.dataInStringFormat = stringSelectionForPasteboardWithImageAltText();
+    client()-&gt;getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
+
+    pasteboard.write(content);
</ins><span class="cx"> }
</span><ins>+
+RefPtr&lt;SharedBuffer&gt; Editor::selectionInWebArchiveFormat()
+{
+    RefPtr&lt;LegacyWebArchive&gt; archive = LegacyWebArchive::createFromSelection(&amp;m_frame);
+    if (!archive)
+        return nullptr;
+    return SharedBuffer::wrapCFData(archive-&gt;rawDataRepresentation().get());
+}
+
+void Editor::replaceSelectionWithAttributedString(NSAttributedString *attributedString, MailBlockquoteHandling mailBlockquoteHandling)
+{
+    if (m_frame.selection().isNone())
+        return;
+
+    if (m_frame.selection().selection().isContentRichlyEditable()) {
+        RefPtr&lt;DocumentFragment&gt; fragment = createFragmentAndAddResources(attributedString);
+        if (fragment &amp;&amp; shouldInsertFragment(fragment, selectedRange(), EditorInsertAction::Pasted))
+            pasteAsFragment(fragment.releaseNonNull(), false, false, mailBlockquoteHandling);
+    } else {
+        String text = attributedString.string;
+        if (shouldInsertText(text, selectedRange().get(), EditorInsertAction::Pasted))
+            pasteAsPlainText(text, false);
+    }
+}
+
+RefPtr&lt;DocumentFragment&gt; Editor::createFragmentForImageResourceAndAddResource(RefPtr&lt;ArchiveResource&gt;&amp;&amp; resource)
+{
+    if (!resource)
+        return nullptr;
+
+    // FIXME: Why is this different?
+#if PLATFORM(MAC)
+    String resourceURL = resource-&gt;url().string();
+#else
+    NSURL *URL = resource-&gt;url();
+    String resourceURL = URL.isFileURL ? URL.absoluteString : resource-&gt;url();
+#endif
+
+    if (DocumentLoader* loader = m_frame.loader().documentLoader())
+        loader-&gt;addArchiveResource(resource.releaseNonNull());
+
+    auto imageElement = HTMLImageElement::create(*m_frame.document());
+    imageElement-&gt;setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
+
+    auto fragment = m_frame.document()-&gt;createDocumentFragment();
+    fragment-&gt;appendChild(imageElement);
+    
+    return WTFMove(fragment);
+}
+
+RefPtr&lt;SharedBuffer&gt; Editor::dataInRTFDFormat(NSAttributedString *string)
+{
+    NSUInteger length = string.length;
+    if (!length)
+        return nullptr;
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    return SharedBuffer::wrapNSData([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    return nullptr;
+}
+
+RefPtr&lt;SharedBuffer&gt; Editor::dataInRTFFormat(NSAttributedString *string)
+{
+    NSUInteger length = string.length;
+    if (!length)
+        return nullptr;
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    return SharedBuffer::wrapNSData([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    return nullptr;
+}
+
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreeditingiosEditorIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/ios/EditorIOS.mm (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/ios/EditorIOS.mm        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/editing/ios/EditorIOS.mm        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -62,20 +62,11 @@
</span><span class="cx"> #import &quot;htmlediting.h&quot;
</span><span class="cx"> #import &quot;markup.h&quot;
</span><span class="cx"> #import &lt;MobileCoreServices/MobileCoreServices.h&gt;
</span><del>-#import &lt;wtf/BlockObjCExceptions.h&gt;
</del><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span><span class="cx"> SOFT_LINK_FRAMEWORK(AppSupport)
</span><span class="cx"> SOFT_LINK(AppSupport, CPSharedResourcesDirectory, CFStringRef, (void), ())
</span><span class="cx"> 
</span><del>-@interface NSAttributedString (NSAttributedStringKitAdditions)
-- (id)initWithRTF:(NSData *)data documentAttributes:(NSDictionary **)dict;
-- (id)initWithRTFD:(NSData *)data documentAttributes:(NSDictionary **)dict;
-- (NSData *)RTFFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict;
-- (NSData *)RTFDFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict;
-- (BOOL)containsAttachments;
-@end
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> using namespace HTMLNames;
</span><span class="lines">@@ -165,48 +156,6 @@
</span><span class="cx">     applyParagraphStyle(style.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const Font* Editor::fontForSelection(bool&amp; hasMultipleFonts) const
-{
-    hasMultipleFonts = false;
-
-    if (!m_frame.selection().isRange()) {
-        Node* nodeToRemove;
-        auto* style = styleForSelectionStart(&amp;m_frame, nodeToRemove); // sets nodeToRemove
-
-        const Font* result = nullptr;
-        if (style) {
-            result = &amp;style-&gt;fontCascade().primaryFont();
-            if (nodeToRemove)
-                nodeToRemove-&gt;remove();
-        }
-
-        return result;
-    }
-
-    const Font* font = nullptr;
-    RefPtr&lt;Range&gt; range = m_frame.selection().toNormalizedRange();
-    if (Node* startNode = adjustedSelectionStartForStyleComputation(m_frame.selection().selection()).deprecatedNode()) {
-        Node* pastEnd = range-&gt;pastLastNode();
-        // In the loop below, n should eventually match pastEnd and not become nil, but we've seen at least one
-        // unreproducible case where this didn't happen, so check for null also.
-        for (Node* node = startNode; node &amp;&amp; node != pastEnd; node = NodeTraversal::next(*node)) {
-            auto renderer = node-&gt;renderer();
-            if (!renderer)
-                continue;
-            // FIXME: Are there any node types that have renderers, but that we should be skipping?
-            const Font&amp; primaryFont = renderer-&gt;style().fontCascade().primaryFont();
-            if (!font)
-                font = &amp;primaryFont;
-            else if (font != &amp;primaryFont) {
-                hasMultipleFonts = true;
-                break;
-            }
-        }
-    }
-
-    return font;
-}
-
</del><span class="cx"> NSDictionary* Editor::fontAttributesForSelectionStart() const
</span><span class="cx"> {
</span><span class="cx">     Node* nodeToRemove;
</span><span class="lines">@@ -252,32 +201,6 @@
</span><span class="cx">     applyStyleToSelection(defaultStyle.get(), EditActionChangeAttributes);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static RefPtr&lt;SharedBuffer&gt; dataInRTFDFormat(NSAttributedString *string)
-{
-    NSUInteger length = string.length;
-    if (!length)
-        return nullptr;
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    return SharedBuffer::wrapNSData([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:nil]);
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    return nullptr;
-}
-
-static RefPtr&lt;SharedBuffer&gt; dataInRTFFormat(NSAttributedString *string)
-{
-    NSUInteger length = string.length;
-    if (!length)
-        return nullptr;
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    return SharedBuffer::wrapNSData([string RTFFromRange:NSMakeRange(0, length) documentAttributes:nil]);
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    return nullptr;
-}
-
</del><span class="cx"> String Editor::stringSelectionForPasteboardWithImageAltText()
</span><span class="cx"> {
</span><span class="cx">     String text = selectedTextForDataTransfer();
</span><span class="lines">@@ -285,29 +208,6 @@
</span><span class="cx">     return text;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;SharedBuffer&gt; Editor::selectionInWebArchiveFormat()
-{
-    RefPtr&lt;LegacyWebArchive&gt; archive = LegacyWebArchive::createFromSelection(&amp;m_frame);
-    if (!archive)
-        return nullptr;
-    return SharedBuffer::wrapCFData(archive-&gt;rawDataRepresentation().get());
-}
-
-void Editor::writeSelectionToPasteboard(Pasteboard&amp; pasteboard)
-{
-    NSAttributedString *attributedString = attributedStringFromRange(*selectedRange());
-
-    PasteboardWebContent content;
-    content.canSmartCopyOrDelete = canSmartCopyOrDelete();
-    content.dataInWebArchiveFormat = selectionInWebArchiveFormat();
-    content.dataInRTFDFormat = [attributedString containsAttachments] ? dataInRTFDFormat(attributedString) : 0;
-    content.dataInRTFFormat = dataInRTFFormat(attributedString);
-    content.dataInStringFormat = stringSelectionForPasteboardWithImageAltText();
-    client()-&gt;getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
-
-    pasteboard.write(content);
-}
-
</del><span class="cx"> static void getImage(Element&amp; imageElement, RefPtr&lt;Image&gt;&amp; image, CachedImage*&amp; cachedImage)
</span><span class="cx"> {
</span><span class="cx">     auto* renderer = imageElement.renderer();
</span><span class="lines">@@ -569,42 +469,6 @@
</span><span class="cx">     return WTFMove(fragmentAndResources.fragment);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;DocumentFragment&gt; Editor::createFragmentForImageResourceAndAddResource(RefPtr&lt;ArchiveResource&gt;&amp;&amp; resource)
-{
-    if (!resource)
-        return nullptr;
-
-    NSURL *URL = resource-&gt;url();
-    String resourceURL = [URL isFileURL] ? [URL absoluteString] : resource-&gt;url();
-
-    if (DocumentLoader* loader = m_frame.loader().documentLoader())
-        loader-&gt;addArchiveResource(resource.releaseNonNull());
-
-    auto imageElement = HTMLImageElement::create(*m_frame.document());
-    imageElement-&gt;setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
-
-    auto fragment = m_frame.document()-&gt;createDocumentFragment();
-    fragment-&gt;appendChild(imageElement);
-
-    return WTFMove(fragment);
-}
-
-void Editor::replaceSelectionWithAttributedString(NSAttributedString *attributedString, MailBlockquoteHandling mailBlockquoteHandling)
-{
-    if (m_frame.selection().isNone())
-        return;
-
-    if (m_frame.selection().selection().isContentRichlyEditable()) {
-        RefPtr&lt;DocumentFragment&gt; fragment = createFragmentAndAddResources(attributedString);
-        if (fragment &amp;&amp; shouldInsertFragment(fragment, selectedRange(), EditorInsertAction::Pasted))
-            pasteAsFragment(fragment.releaseNonNull(), false, false, mailBlockquoteHandling);
-    } else {
-        String text = [attributedString string];
-        if (shouldInsertText(text, selectedRange().get(), EditorInsertAction::Pasted))
-            pasteAsPlainText(text, false);
-    }
-}
-
</del><span class="cx"> void Editor::insertDictationPhrases(Vector&lt;Vector&lt;String&gt;&gt;&amp;&amp; dictationPhrases, RetainPtr&lt;id&gt; metadata)
</span><span class="cx"> {
</span><span class="cx">     if (m_frame.selection().isNone())
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingmacEditorMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/EditorMac.mm        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -68,7 +68,6 @@
</span><span class="cx"> #import &quot;WebNSAttributedStringExtras.h&quot;
</span><span class="cx"> #import &quot;htmlediting.h&quot;
</span><span class="cx"> #import &quot;markup.h&quot;
</span><del>-#import &lt;wtf/BlockObjCExceptions.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -105,48 +104,6 @@
</span><span class="cx">     client()-&gt;setInsertionPasteboard(String());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const Font* Editor::fontForSelection(bool&amp; hasMultipleFonts) const
-{
-    hasMultipleFonts = false;
-
-    if (!m_frame.selection().isRange()) {
-        Node* nodeToRemove;
-        auto* style = styleForSelectionStart(&amp;m_frame, nodeToRemove); // sets nodeToRemove
-
-        const Font* result = nullptr;
-        if (style) {
-            result = &amp;style-&gt;fontCascade().primaryFont();
-            if (nodeToRemove)
-                nodeToRemove-&gt;remove();
-        }
-        return result;
-    }
-
-    const Font* font = nullptr;
-    RefPtr&lt;Range&gt; range = m_frame.selection().toNormalizedRange();
-    Node* startNode = adjustedSelectionStartForStyleComputation(m_frame.selection().selection()).deprecatedNode();
-    if (range &amp;&amp; startNode) {
-        Node* pastEnd = range-&gt;pastLastNode();
-        // In the loop below, n should eventually match pastEnd and not become nil, but we've seen at least one
-        // unreproducible case where this didn't happen, so check for null also.
-        for (Node* node = startNode; node &amp;&amp; node != pastEnd; node = NodeTraversal::next(*node)) {
-            auto renderer = node-&gt;renderer();
-            if (!renderer)
-                continue;
-            // FIXME: Are there any node types that have renderers, but that we should be skipping?
-            const Font&amp; primaryFont = renderer-&gt;style().fontCascade().primaryFont();
-            if (!font)
-                font = &amp;primaryFont;
-            else if (font != &amp;primaryFont) {
-                hasMultipleFonts = true;
-                break;
-            }
-        }
-    }
-
-    return font;
-}
-
</del><span class="cx"> NSDictionary* Editor::fontAttributesForSelectionStart() const
</span><span class="cx"> {
</span><span class="cx">     Node* nodeToRemove;
</span><span class="lines">@@ -306,14 +263,6 @@
</span><span class="cx">     return text;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;SharedBuffer&gt; Editor::selectionInWebArchiveFormat()
-{
-    RefPtr&lt;LegacyWebArchive&gt; archive = LegacyWebArchive::createFromSelection(&amp;m_frame);
-    if (!archive)
-        return nullptr;
-    return SharedBuffer::wrapCFData(archive-&gt;rawDataRepresentation().get());
-}
-
</del><span class="cx"> String Editor::selectionInHTMLFormat()
</span><span class="cx"> {
</span><span class="cx">     return createMarkup(*selectedRange(), nullptr, AnnotateForInterchange, false, ResolveNonLocalURLs);
</span><span class="lines">@@ -327,45 +276,6 @@
</span><span class="cx">     return SharedBuffer::wrapCFData(archive-&gt;rawDataRepresentation().get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;Range&gt; Editor::adjustedSelectionRange()
-{
-    // FIXME: Why do we need to adjust the selection to include the anchor tag it's in?
-    // Whoever wrote this code originally forgot to leave us a comment explaining the rationale.
-    RefPtr&lt;Range&gt; range = selectedRange();
-    Node* commonAncestor = range-&gt;commonAncestorContainer();
-    ASSERT(commonAncestor);
-    auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
-    if (enclosingAnchor &amp;&amp; comparePositions(firstPositionInOrBeforeNode(range-&gt;startPosition().anchorNode()), range-&gt;startPosition()) &gt;= 0)
-        range-&gt;setStart(*enclosingAnchor, 0);
-    return range;
-}
-    
-static RefPtr&lt;SharedBuffer&gt; dataInRTFDFormat(NSAttributedString *string)
-{
-    NSUInteger length = string.length;
-    if (!length)
-        return nullptr;
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    return SharedBuffer::wrapNSData([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    return nullptr;
-}
-
-static RefPtr&lt;SharedBuffer&gt; dataInRTFFormat(NSAttributedString *string)
-{
-    NSUInteger length = string.length;
-    if (!length)
-        return nullptr;
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    return SharedBuffer::wrapNSData([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    return nullptr;
-}
-
</del><span class="cx"> RefPtr&lt;SharedBuffer&gt; Editor::dataSelectionForPasteboard(const String&amp; pasteboardType)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: The interface to this function is awkward. We'd probably be better off with three separate functions.
</span><span class="lines">@@ -393,22 +303,6 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::writeSelectionToPasteboard(Pasteboard&amp; pasteboard)
-{
-    NSAttributedString *attributedString = attributedStringFromRange(*selectedRange());
-
-    PasteboardWebContent content;
-    content.canSmartCopyOrDelete = canSmartCopyOrDelete();
-    content.dataInWebArchiveFormat = selectionInWebArchiveFormat();
-    content.dataInRTFDFormat = [attributedString containsAttachments] ? dataInRTFDFormat(attributedString) : 0;
-    content.dataInRTFFormat = dataInRTFFormat(attributedString);
-    content.dataInHTMLFormat = selectionInHTMLFormat();
-    content.dataInStringFormat = stringSelectionForPasteboardWithImageAltText();
-    client()-&gt;getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
-
-    pasteboard.write(content);
-}
-
</del><span class="cx"> static void getImage(Element&amp; imageElement, RefPtr&lt;Image&gt;&amp; image, CachedImage*&amp; cachedImage)
</span><span class="cx"> {
</span><span class="cx">     auto* renderer = imageElement.renderer();
</span><span class="lines">@@ -661,24 +555,6 @@
</span><span class="cx">     return WTFMove(reader.fragment);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;DocumentFragment&gt; Editor::createFragmentForImageResourceAndAddResource(RefPtr&lt;ArchiveResource&gt;&amp;&amp; resource)
-{
-    if (!resource)
-        return nullptr;
-
-    String resourceURL = resource-&gt;url().string();
-    if (DocumentLoader* loader = m_frame.loader().documentLoader())
-        loader-&gt;addArchiveResource(resource.releaseNonNull());
-
-    auto imageElement = HTMLImageElement::create(*m_frame.document());
-    imageElement-&gt;setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
-
-    auto fragment = document().createDocumentFragment();
-    fragment-&gt;appendChild(imageElement);
-
-    return WTFMove(fragment);
-}
-
</del><span class="cx"> Ref&lt;DocumentFragment&gt; Editor::createFragmentForImageAndURL(const String&amp; url)
</span><span class="cx"> {
</span><span class="cx">     auto imageElement = HTMLImageElement::create(*m_frame.document());
</span><span class="lines">@@ -717,22 +593,6 @@
</span><span class="cx">     return WTFMove(fragmentAndResources.fragment);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Editor::replaceSelectionWithAttributedString(NSAttributedString *attributedString, MailBlockquoteHandling mailBlockquoteHandling)
-{
-    if (m_frame.selection().isNone())
-        return;
-
-    if (m_frame.selection().selection().isContentRichlyEditable()) {
-        RefPtr&lt;DocumentFragment&gt; fragment = createFragmentAndAddResources(attributedString);
-        if (fragment &amp;&amp; shouldInsertFragment(fragment, selectedRange(), EditorInsertAction::Pasted))
-            pasteAsFragment(fragment.releaseNonNull(), false, false, mailBlockquoteHandling);
-    } else {
-        String text = [attributedString string];
-        if (shouldInsertText(text, selectedRange().get(), EditorInsertAction::Pasted))
-            pasteAsPlainText(text, false);
-    }
-}
-
</del><span class="cx"> void Editor::applyFontStyles(const String&amp; fontFamily, double fontSize, unsigned fontTraits)
</span><span class="cx"> {
</span><span class="cx">     auto&amp; cssValuePool = CSSValuePool::singleton();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformspicocoaNSAttributedStringSPIh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/spi/cocoa/NSAttributedStringSPI.h (210772 => 210773)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/spi/cocoa/NSAttributedStringSPI.h        2017-01-15 06:27:41 UTC (rev 210772)
+++ trunk/Source/WebCore/platform/spi/cocoa/NSAttributedStringSPI.h        2017-01-15 06:45:58 UTC (rev 210773)
</span><span class="lines">@@ -111,6 +111,14 @@
</span><span class="cx"> // will continue to support it.
</span><span class="cx"> static NSString *const NSSuperscriptAttributeName = @&quot;NSSuperscript&quot;;
</span><span class="cx"> 
</span><ins>+@interface NSAttributedString ()
+- (id)initWithRTF:(NSData *)data documentAttributes:(NSDictionary **)dict;
+- (id)initWithRTFD:(NSData *)data documentAttributes:(NSDictionary **)dict;
+- (NSData *)RTFFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict;
+- (NSData *)RTFDFromRange:(NSRange)range documentAttributes:(NSDictionary *)dict;
+- (BOOL)containsAttachments;
+@end
+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>