De-duplicate some (nearly) identical code in Editor(Mac|IOS).mm
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 15 Jan 2017 06:45:58 +0000 (06:45 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 15 Jan 2017 06:45:58 +0000 (06:45 +0000)
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.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210773 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/cocoa/EditorCocoa.mm
Source/WebCore/editing/ios/EditorIOS.mm
Source/WebCore/editing/mac/EditorMac.mm
Source/WebCore/platform/spi/cocoa/NSAttributedStringSPI.h

index 54194e6..c8a2cc3 100644 (file)
@@ -1,3 +1,57 @@
+2017-01-14  Tim Horton  <timothy_horton@apple.com>
+
+        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.
+
 2017-01-14  Zalan Bujtas  <zalan@apple.com>
 
         Small code cleanup after r210760
index 4d3841b..08e5391 100644 (file)
@@ -56,6 +56,7 @@
 #include "HTMLImageElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "HTMLSpanElement.h"
 #include "HitTestResult.h"
 #include "IndentOutdentCommand.h"
 #include "InputEvent.h"
@@ -3646,4 +3647,98 @@ Document& Editor::document() const
     return *m_frame.document();
 }
 
+RefPtr<Range> 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<Range> range = selectedRange();
+    Node* commonAncestor = range->commonAncestorContainer();
+    ASSERT(commonAncestor);
+    auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
+    if (enclosingAnchor && comparePositions(firstPositionInOrBeforeNode(range->startPosition().anchorNode()), range->startPosition()) >= 0)
+        range->setStart(*enclosingAnchor, 0);
+    return range;
+}
+
+// FIXME: This figures out the current style by inserting a <span>!
+const RenderStyle* Editor::styleForSelectionStart(Frame* frame, Node*& nodeToRemove)
+{
+    nodeToRemove = nullptr;
+
+    if (frame->selection().isNone())
+        return nullptr;
+
+    Position position = adjustedSelectionStartForStyleComputation(frame->selection().selection());
+    if (!position.isCandidate() || position.isNull())
+        return nullptr;
+
+    RefPtr<EditingStyle> typingStyle = frame->selection().typingStyle();
+    if (!typingStyle || !typingStyle->style())
+        return &position.deprecatedNode()->renderer()->style();
+
+    auto styleElement = HTMLSpanElement::create(*frame->document());
+
+    String styleText = typingStyle->style()->asText() + " display: inline";
+    styleElement->setAttribute(HTMLNames::styleAttr, styleText);
+
+    styleElement->appendChild(frame->document()->createEditingTextNode(emptyString()));
+
+    auto positionNode = position.deprecatedNode();
+    if (!positionNode || !positionNode->parentNode() || positionNode->parentNode()->appendChild(styleElement).hasException())
+        return nullptr;
+
+    nodeToRemove = styleElement.ptr();
+    
+    frame->document()->updateStyleIfNeeded();
+    return styleElement->renderer() ? &styleElement->renderer()->style() : nullptr;
+}
+
+const Font* Editor::fontForSelection(bool& hasMultipleFonts) const
+{
+    hasMultipleFonts = false;
+
+    if (!m_frame.selection().isRange()) {
+        Node* nodeToRemove;
+        auto* style = styleForSelectionStart(&m_frame, nodeToRemove); // sets nodeToRemove
+
+        const Font* font = nullptr;
+        if (style) {
+            font = &style->fontCascade().primaryFont();
+            if (nodeToRemove)
+                nodeToRemove->remove();
+        }
+
+        return font;
+    }
+
+    RefPtr<Range> 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->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 && node != pastEnd; node = NodeTraversal::next(*node)) {
+        auto renderer = node->renderer();
+        if (!renderer)
+            continue;
+        // FIXME: Are there any node types that have renderers, but that we should be skipping?
+        const Font& primaryFont = renderer->style().fontCascade().primaryFont();
+        if (!font)
+            font = &primaryFont;
+        else if (font != &primaryFont) {
+            hasMultipleFonts = true;
+            break;
+        }
+    }
+
+    return font;
+}
+
+
 } // namespace WebCore
index 7330ebb..567c65b 100644 (file)
@@ -443,10 +443,11 @@ public:
 
     RefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, Range& context, bool allowPlainText, bool& chosePlainText);
 
-#if PLATFORM(COCOA)
+    WEBCORE_EXPORT const Font* fontForSelection(bool& hasMultipleFonts) const;
     WEBCORE_EXPORT static const RenderStyle* styleForSelectionStart(Frame* , Node *&nodeToRemove);
+
+#if PLATFORM(COCOA)
     void getTextDecorationAttributesRespectingTypingStyle(const RenderStyle&, NSMutableDictionary*) const;
-    WEBCORE_EXPORT const Font* fontForSelection(bool&) const;
     WEBCORE_EXPORT NSDictionary *fontAttributesForSelectionStart() const;
     WEBCORE_EXPORT String stringSelectionForPasteboard();
     String stringSelectionForPasteboardWithImageAltText();
@@ -512,16 +513,20 @@ private:
 
     bool unifiedTextCheckerEnabled() const;
 
+    RefPtr<Range> adjustedSelectionRange();
+
 #if PLATFORM(COCOA)
     RefPtr<SharedBuffer> selectionInWebArchiveFormat();
     String selectionInHTMLFormat();
     RefPtr<SharedBuffer> imageInWebArchiveFormat(Element&);
-    RefPtr<Range> adjustedSelectionRange();
     RefPtr<DocumentFragment> createFragmentForImageResourceAndAddResource(RefPtr<ArchiveResource>&&);
     Ref<DocumentFragment> createFragmentForImageAndURL(const String&);
     RefPtr<DocumentFragment> createFragmentAndAddResources(NSAttributedString *);
     FragmentAndResources createFragment(NSAttributedString *);
     void fillInUserVisibleForm(PasteboardURL&);
+
+    static RefPtr<SharedBuffer> dataInRTFDFormat(NSAttributedString *);
+    static RefPtr<SharedBuffer> dataInRTFFormat(NSAttributedString *);
 #endif
 
     void postTextStateChangeNotificationForCut(const String&, const VisibleSelection&);
index c57d64d..0a5d35f 100644 (file)
 #import "CSSValueList.h"
 #import "CSSValuePool.h"
 #import "DocumentFragment.h"
+#import "DocumentLoader.h"
 #import "EditingStyle.h"
+#import "EditorClient.h"
 #import "Frame.h"
 #import "FrameSelection.h"
+#import "HTMLConverter.h"
+#import "HTMLImageElement.h"
 #import "HTMLSpanElement.h"
+#import "LegacyWebArchive.h"
 #import "NSAttributedStringSPI.h"
+#import "Pasteboard.h"
 #import "RenderElement.h"
 #import "RenderStyle.h"
 #import "SoftLinking.h"
 #import "Text.h"
 #import "htmlediting.h"
+#import <wtf/BlockObjCExceptions.h>
 
 #if PLATFORM(IOS)
 SOFT_LINK_PRIVATE_FRAMEWORK(WebKitLegacy)
@@ -53,39 +60,6 @@ SOFT_LINK(WebKitLegacy, _WebCreateFragment, void, (WebCore::Document& document,
 
 namespace WebCore {
 
-// FIXME: This figures out the current style by inserting a <span>!
-const RenderStyle* Editor::styleForSelectionStart(Frame* frame, Node*& nodeToRemove)
-{
-    nodeToRemove = nullptr;
-    
-    if (frame->selection().isNone())
-        return nullptr;
-
-    Position position = adjustedSelectionStartForStyleComputation(frame->selection().selection());
-    if (!position.isCandidate() || position.isNull())
-        return nullptr;
-
-    RefPtr<EditingStyle> typingStyle = frame->selection().typingStyle();
-    if (!typingStyle || !typingStyle->style())
-        return &position.deprecatedNode()->renderer()->style();
-
-    auto styleElement = HTMLSpanElement::create(*frame->document());
-
-    String styleText = typingStyle->style()->asText() + " display: inline";
-    styleElement->setAttribute(HTMLNames::styleAttr, styleText);
-
-    styleElement->appendChild(frame->document()->createEditingTextNode(emptyString()));
-
-    auto positionNode = position.deprecatedNode();
-    if (!positionNode || !positionNode->parentNode() || positionNode->parentNode()->appendChild(styleElement).hasException())
-        return nullptr;
-
-    nodeToRemove = styleElement.ptr();
-
-    frame->document()->updateStyleIfNeeded();
-    return styleElement->renderer() ? &styleElement->renderer()->style() : nullptr;
-}
-
 void Editor::getTextDecorationAttributesRespectingTypingStyle(const RenderStyle& style, NSMutableDictionary* result) const
 {
     RefPtr<EditingStyle> typingStyle = m_frame.selection().typingStyle();
@@ -116,4 +90,99 @@ FragmentAndResources Editor::createFragment(NSAttributedString *string)
     return result;
 }
 
+void Editor::writeSelectionToPasteboard(Pasteboard& 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()->getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
+
+    pasteboard.write(content);
+}
+
+RefPtr<SharedBuffer> Editor::selectionInWebArchiveFormat()
+{
+    RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(&m_frame);
+    if (!archive)
+        return nullptr;
+    return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
+}
+
+void Editor::replaceSelectionWithAttributedString(NSAttributedString *attributedString, MailBlockquoteHandling mailBlockquoteHandling)
+{
+    if (m_frame.selection().isNone())
+        return;
+
+    if (m_frame.selection().selection().isContentRichlyEditable()) {
+        RefPtr<DocumentFragment> fragment = createFragmentAndAddResources(attributedString);
+        if (fragment && 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<DocumentFragment> Editor::createFragmentForImageResourceAndAddResource(RefPtr<ArchiveResource>&& resource)
+{
+    if (!resource)
+        return nullptr;
+
+    // FIXME: Why is this different?
+#if PLATFORM(MAC)
+    String resourceURL = resource->url().string();
+#else
+    NSURL *URL = resource->url();
+    String resourceURL = URL.isFileURL ? URL.absoluteString : resource->url();
+#endif
+
+    if (DocumentLoader* loader = m_frame.loader().documentLoader())
+        loader->addArchiveResource(resource.releaseNonNull());
+
+    auto imageElement = HTMLImageElement::create(*m_frame.document());
+    imageElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
+
+    auto fragment = m_frame.document()->createDocumentFragment();
+    fragment->appendChild(imageElement);
+    
+    return WTFMove(fragment);
+}
+
+RefPtr<SharedBuffer> 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<SharedBuffer> 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;
+}
+
+
 }
index c5e8c29..3ae7154 100644 (file)
 #import "htmlediting.h"
 #import "markup.h"
 #import <MobileCoreServices/MobileCoreServices.h>
-#import <wtf/BlockObjCExceptions.h>
 #include <wtf/text/StringBuilder.h>
 
 SOFT_LINK_FRAMEWORK(AppSupport)
 SOFT_LINK(AppSupport, CPSharedResourcesDirectory, CFStringRef, (void), ())
 
-@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
-
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -165,48 +156,6 @@ void Editor::setTextAlignmentForChangedBaseWritingDirection(WritingDirection dir
     applyParagraphStyle(style.get());
 }
 
-const Font* Editor::fontForSelection(bool& hasMultipleFonts) const
-{
-    hasMultipleFonts = false;
-
-    if (!m_frame.selection().isRange()) {
-        Node* nodeToRemove;
-        auto* style = styleForSelectionStart(&m_frame, nodeToRemove); // sets nodeToRemove
-
-        const Font* result = nullptr;
-        if (style) {
-            result = &style->fontCascade().primaryFont();
-            if (nodeToRemove)
-                nodeToRemove->remove();
-        }
-
-        return result;
-    }
-
-    const Font* font = nullptr;
-    RefPtr<Range> range = m_frame.selection().toNormalizedRange();
-    if (Node* startNode = adjustedSelectionStartForStyleComputation(m_frame.selection().selection()).deprecatedNode()) {
-        Node* pastEnd = range->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 && node != pastEnd; node = NodeTraversal::next(*node)) {
-            auto renderer = node->renderer();
-            if (!renderer)
-                continue;
-            // FIXME: Are there any node types that have renderers, but that we should be skipping?
-            const Font& primaryFont = renderer->style().fontCascade().primaryFont();
-            if (!font)
-                font = &primaryFont;
-            else if (font != &primaryFont) {
-                hasMultipleFonts = true;
-                break;
-            }
-        }
-    }
-
-    return font;
-}
-
 NSDictionary* Editor::fontAttributesForSelectionStart() const
 {
     Node* nodeToRemove;
@@ -252,32 +201,6 @@ void Editor::removeUnchangeableStyles()
     applyStyleToSelection(defaultStyle.get(), EditActionChangeAttributes);
 }
 
-static RefPtr<SharedBuffer> 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<SharedBuffer> 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;
-}
-
 String Editor::stringSelectionForPasteboardWithImageAltText()
 {
     String text = selectedTextForDataTransfer();
@@ -285,29 +208,6 @@ String Editor::stringSelectionForPasteboardWithImageAltText()
     return text;
 }
 
-RefPtr<SharedBuffer> Editor::selectionInWebArchiveFormat()
-{
-    RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(&m_frame);
-    if (!archive)
-        return nullptr;
-    return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
-}
-
-void Editor::writeSelectionToPasteboard(Pasteboard& 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()->getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
-
-    pasteboard.write(content);
-}
-
 static void getImage(Element& imageElement, RefPtr<Image>& image, CachedImage*& cachedImage)
 {
     auto* renderer = imageElement.renderer();
@@ -569,42 +469,6 @@ RefPtr<DocumentFragment> Editor::createFragmentAndAddResources(NSAttributedStrin
     return WTFMove(fragmentAndResources.fragment);
 }
 
-RefPtr<DocumentFragment> Editor::createFragmentForImageResourceAndAddResource(RefPtr<ArchiveResource>&& resource)
-{
-    if (!resource)
-        return nullptr;
-
-    NSURL *URL = resource->url();
-    String resourceURL = [URL isFileURL] ? [URL absoluteString] : resource->url();
-
-    if (DocumentLoader* loader = m_frame.loader().documentLoader())
-        loader->addArchiveResource(resource.releaseNonNull());
-
-    auto imageElement = HTMLImageElement::create(*m_frame.document());
-    imageElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
-
-    auto fragment = m_frame.document()->createDocumentFragment();
-    fragment->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<DocumentFragment> fragment = createFragmentAndAddResources(attributedString);
-        if (fragment && 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);
-    }
-}
-
 void Editor::insertDictationPhrases(Vector<Vector<String>>&& dictationPhrases, RetainPtr<id> metadata)
 {
     if (m_frame.selection().isNone())
index b54bbd1..7ab9ff7 100644 (file)
@@ -68,7 +68,6 @@
 #import "WebNSAttributedStringExtras.h"
 #import "htmlediting.h"
 #import "markup.h"
-#import <wtf/BlockObjCExceptions.h>
 
 namespace WebCore {
 
@@ -105,48 +104,6 @@ void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, Ma
     client()->setInsertionPasteboard(String());
 }
 
-const Font* Editor::fontForSelection(bool& hasMultipleFonts) const
-{
-    hasMultipleFonts = false;
-
-    if (!m_frame.selection().isRange()) {
-        Node* nodeToRemove;
-        auto* style = styleForSelectionStart(&m_frame, nodeToRemove); // sets nodeToRemove
-
-        const Font* result = nullptr;
-        if (style) {
-            result = &style->fontCascade().primaryFont();
-            if (nodeToRemove)
-                nodeToRemove->remove();
-        }
-        return result;
-    }
-
-    const Font* font = nullptr;
-    RefPtr<Range> range = m_frame.selection().toNormalizedRange();
-    Node* startNode = adjustedSelectionStartForStyleComputation(m_frame.selection().selection()).deprecatedNode();
-    if (range && startNode) {
-        Node* pastEnd = range->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 && node != pastEnd; node = NodeTraversal::next(*node)) {
-            auto renderer = node->renderer();
-            if (!renderer)
-                continue;
-            // FIXME: Are there any node types that have renderers, but that we should be skipping?
-            const Font& primaryFont = renderer->style().fontCascade().primaryFont();
-            if (!font)
-                font = &primaryFont;
-            else if (font != &primaryFont) {
-                hasMultipleFonts = true;
-                break;
-            }
-        }
-    }
-
-    return font;
-}
-
 NSDictionary* Editor::fontAttributesForSelectionStart() const
 {
     Node* nodeToRemove;
@@ -306,14 +263,6 @@ String Editor::stringSelectionForPasteboardWithImageAltText()
     return text;
 }
 
-RefPtr<SharedBuffer> Editor::selectionInWebArchiveFormat()
-{
-    RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(&m_frame);
-    if (!archive)
-        return nullptr;
-    return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
-}
-
 String Editor::selectionInHTMLFormat()
 {
     return createMarkup(*selectedRange(), nullptr, AnnotateForInterchange, false, ResolveNonLocalURLs);
@@ -327,45 +276,6 @@ RefPtr<SharedBuffer> Editor::imageInWebArchiveFormat(Element& imageElement)
     return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
 }
 
-RefPtr<Range> 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<Range> range = selectedRange();
-    Node* commonAncestor = range->commonAncestorContainer();
-    ASSERT(commonAncestor);
-    auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
-    if (enclosingAnchor && comparePositions(firstPositionInOrBeforeNode(range->startPosition().anchorNode()), range->startPosition()) >= 0)
-        range->setStart(*enclosingAnchor, 0);
-    return range;
-}
-    
-static RefPtr<SharedBuffer> 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<SharedBuffer> 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;
-}
-
 RefPtr<SharedBuffer> Editor::dataSelectionForPasteboard(const String& pasteboardType)
 {
     // FIXME: The interface to this function is awkward. We'd probably be better off with three separate functions.
@@ -393,22 +303,6 @@ RefPtr<SharedBuffer> Editor::dataSelectionForPasteboard(const String& pasteboard
     return nullptr;
 }
 
-void Editor::writeSelectionToPasteboard(Pasteboard& 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()->getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
-
-    pasteboard.write(content);
-}
-
 static void getImage(Element& imageElement, RefPtr<Image>& image, CachedImage*& cachedImage)
 {
     auto* renderer = imageElement.renderer();
@@ -661,24 +555,6 @@ RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard
     return WTFMove(reader.fragment);
 }
 
-RefPtr<DocumentFragment> Editor::createFragmentForImageResourceAndAddResource(RefPtr<ArchiveResource>&& resource)
-{
-    if (!resource)
-        return nullptr;
-
-    String resourceURL = resource->url().string();
-    if (DocumentLoader* loader = m_frame.loader().documentLoader())
-        loader->addArchiveResource(resource.releaseNonNull());
-
-    auto imageElement = HTMLImageElement::create(*m_frame.document());
-    imageElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, resourceURL);
-
-    auto fragment = document().createDocumentFragment();
-    fragment->appendChild(imageElement);
-
-    return WTFMove(fragment);
-}
-
 Ref<DocumentFragment> Editor::createFragmentForImageAndURL(const String& url)
 {
     auto imageElement = HTMLImageElement::create(*m_frame.document());
@@ -717,22 +593,6 @@ RefPtr<DocumentFragment> Editor::createFragmentAndAddResources(NSAttributedStrin
     return WTFMove(fragmentAndResources.fragment);
 }
 
-void Editor::replaceSelectionWithAttributedString(NSAttributedString *attributedString, MailBlockquoteHandling mailBlockquoteHandling)
-{
-    if (m_frame.selection().isNone())
-        return;
-
-    if (m_frame.selection().selection().isContentRichlyEditable()) {
-        RefPtr<DocumentFragment> fragment = createFragmentAndAddResources(attributedString);
-        if (fragment && 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);
-    }
-}
-
 void Editor::applyFontStyles(const String& fontFamily, double fontSize, unsigned fontTraits)
 {
     auto& cssValuePool = CSSValuePool::singleton();
index e7c2bab..406f291 100644 (file)
@@ -111,6 +111,14 @@ SOFT_LINK_CONSTANT(UIFoundation, NSCocoaVersionDocumentAttribute, NSString *)
 // will continue to support it.
 static NSString *const NSSuperscriptAttributeName = @"NSSuperscript";
 
+@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
+
 #endif
 
 #endif