Title: [154939] trunk/Source/WebCore
Revision
154939
Author
[email protected]
Date
2013-08-31 23:26:12 -0700 (Sat, 31 Aug 2013)

Log Message

Refactor URL and image writing so layer-violating parts are in Editor, not Pasteboard (Mac-only at first)
https://bugs.webkit.org/show_bug.cgi?id=120573

Reviewed by Andreas Kling.

* editing/Editor.cpp:
(WebCore::Editor::copy): Use writeImageToPasteboard instead of Pasteboard::writeImage on Mac.
(WebCore::Editor::copyURL): Use writeURLToPasteboard instead of Pasteboard::writeURL on Mac.
(WebCore::innerNonSharedElement): Added. Used in copyImage.
(WebCore::Editor::copyImage): Use innerNonSharedElement instead of innerNonSharedNode.
Use writeImageToPasteboard instead of Pasteboard::writeImage on Mac.

* editing/Editor.h: Add new functions, writeURLToPasteboard and writeImageToPasteboard,
both Mac-only for now.

* editing/mac/EditorMac.mm:
(WebCore::Editor::pasteWithPasteboard): Removed unneeded "m_frame.editor()" round trip that
was left behind in this function.
(WebCore::getImage): Added. Helper used by writeImageToPasteboard.
(WebCore::Editor::writeURLToPasteboard): Added. Sets up PasteboardURL and then calls
Pasteboard::write with it.
(WebCore::Editor::writeImageToPasteboard): Added. Sets up PasteboardImage and then calls
Pasteboard::write with it.
* page/DragController.cpp:
(WebCore::DragController::startDrag): Use Editor::writeURLToPasteboard instead of
Pasteboard::writeURL on Mac.

* platform/Pasteboard.h: Added PasteboardURL and PasteboardImage structures.
Declare write functions for PasteboardWebContent, PasteboardURL, and PasteboardImage.
Guard writeURL and writeImage with !PLATFORM(MAC).

* platform/mac/PasteboardMac.mm:
(WebCore::writeURLForTypes): Changed this to take a PasteboardURL.
(WebCore::Pasteboard::write): Renamed writeURL and writeImage to this. Refactor both
to take PasteboardURL and PasteboardImage arguments.
(WebCore::fileWrapper): Renamed from fileWrapperForImage since the fact that this is
for an image is now clear from its argument, a PasteboardImage.
(WebCore::writeFileWrapperAsRTFDAttachment): Changed this function to use early return.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (154938 => 154939)


--- trunk/Source/WebCore/ChangeLog	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/ChangeLog	2013-09-01 06:26:12 UTC (rev 154939)
@@ -1,3 +1,44 @@
+2013-08-31  Darin Adler  <[email protected]>
+
+        Refactor URL and image writing so layer-violating parts are in Editor, not Pasteboard (Mac-only at first)
+        https://bugs.webkit.org/show_bug.cgi?id=120573
+
+        Reviewed by Andreas Kling.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::copy): Use writeImageToPasteboard instead of Pasteboard::writeImage on Mac.
+        (WebCore::Editor::copyURL): Use writeURLToPasteboard instead of Pasteboard::writeURL on Mac.
+        (WebCore::innerNonSharedElement): Added. Used in copyImage.
+        (WebCore::Editor::copyImage): Use innerNonSharedElement instead of innerNonSharedNode.
+        Use writeImageToPasteboard instead of Pasteboard::writeImage on Mac.
+
+        * editing/Editor.h: Add new functions, writeURLToPasteboard and writeImageToPasteboard,
+        both Mac-only for now.
+
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::pasteWithPasteboard): Removed unneeded "m_frame.editor()" round trip that
+        was left behind in this function.
+        (WebCore::getImage): Added. Helper used by writeImageToPasteboard.
+        (WebCore::Editor::writeURLToPasteboard): Added. Sets up PasteboardURL and then calls
+        Pasteboard::write with it.
+        (WebCore::Editor::writeImageToPasteboard): Added. Sets up PasteboardImage and then calls
+        Pasteboard::write with it.
+        * page/DragController.cpp:
+        (WebCore::DragController::startDrag): Use Editor::writeURLToPasteboard instead of
+        Pasteboard::writeURL on Mac.
+
+        * platform/Pasteboard.h: Added PasteboardURL and PasteboardImage structures.
+        Declare write functions for PasteboardWebContent, PasteboardURL, and PasteboardImage.
+        Guard writeURL and writeImage with !PLATFORM(MAC).
+
+        * platform/mac/PasteboardMac.mm:
+        (WebCore::writeURLForTypes): Changed this to take a PasteboardURL.
+        (WebCore::Pasteboard::write): Renamed writeURL and writeImage to this. Refactor both
+        to take PasteboardURL and PasteboardImage arguments.
+        (WebCore::fileWrapper): Renamed from fileWrapperForImage since the fact that this is
+        for an image is now clear from its argument, a PasteboardImage.
+        (WebCore::writeFileWrapperAsRTFDAttachment): Changed this function to use early return.
+
 2013-08-31  Andreas Kling  <[email protected]>
 
         EditCommand constructors should take Document&.

Modified: trunk/Source/WebCore/editing/Editor.cpp (154938 => 154939)


--- trunk/Source/WebCore/editing/Editor.cpp	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/editing/Editor.cpp	2013-09-01 06:26:12 UTC (rev 154939)
@@ -1074,9 +1074,13 @@
             canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
     } else {
         Document* document = m_frame.document();
-        if (HTMLImageElement* imageElement = imageElementFromImageDocument(document))
+        if (HTMLImageElement* imageElement = imageElementFromImageDocument(document)) {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+            writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *imageElement, document->url(), document->title());
+#else
             Pasteboard::createForCopyAndPaste()->writeImage(imageElement, document->url(), document->title());
-        else {
+#endif
+        } else {
 #if PLATFORM(MAC) && !PLATFORM(IOS)
             writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
 #else
@@ -1160,16 +1164,39 @@
 
 void Editor::copyURL(const KURL& url, const String& title, Pasteboard& pasteboard)
 {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+    writeURLToPasteboard(pasteboard, url, title);
+#else
     pasteboard.writeURL(url, title, &m_frame);
+#endif
 }
 
+// FIXME: Should this be a member function of HitTestResult?
+static Element* innerNonSharedElement(const HitTestResult& result)
+{
+    Node* node = result.innerNonSharedNode();
+    if (!node)
+        return 0;
+    if (node->isElementNode())
+        return toElement(node);
+    return node->parentElement();
+}
+
 void Editor::copyImage(const HitTestResult& result)
 {
+    Element* element = innerNonSharedElement(result);
+    if (!element)
+        return;
+
     KURL url = ""
     if (url.isEmpty())
         url = ""
 
-    Pasteboard::createForCopyAndPaste()->writeImage(result.innerNonSharedNode(), url, result.altDisplayString());
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+    writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *element, url, result.altDisplayString());
+#else
+    Pasteboard::createForCopyAndPaste()->writeImage(element, url, result.altDisplayString());
+#endif
 }
 
 bool Editor::isContinuousSpellCheckingEnabled() const

Modified: trunk/Source/WebCore/editing/Editor.h (154938 => 154939)


--- trunk/Source/WebCore/editing/Editor.h	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/editing/Editor.h	2013-09-01 06:26:12 UTC (rev 154939)
@@ -395,6 +395,8 @@
     String stringSelectionForPasteboard();
     String stringSelectionForPasteboardWithImageAltText();
     PassRefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName);
+    void writeURLToPasteboard(Pasteboard&, const KURL&, const String& title);
+    void writeImageToPasteboard(Pasteboard&, Element& imageElement, const KURL&, const String& title);
 #endif
 
     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);

Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (154938 => 154939)


--- trunk/Source/WebCore/editing/mac/EditorMac.mm	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm	2013-09-01 06:26:12 UTC (rev 154939)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +45,8 @@
 #import "PlatformStrategies.h"
 #import "Range.h"
 #import "RenderBlock.h"
+#import "RenderImage.h"
+#import "ResourceBuffer.h"
 #import "RuntimeApplicationChecks.h"
 #import "Sound.h"
 #import "StylePropertySet.h"
@@ -77,11 +79,11 @@
     RefPtr<Range> range = selectedRange();
     bool choosePlainText;
     
-    m_frame.editor().client()->setInsertionPasteboard(NSGeneralPboard);
+    client()->setInsertionPasteboard(NSGeneralPboard);
     RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(&m_frame, range, allowPlainText, choosePlainText);
     if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted))
         pasteAsFragment(fragment, canSmartReplaceWithPasteboard(pasteboard), false);
-    m_frame.editor().client()->setInsertionPasteboard(String());
+    client()->setInsertionPasteboard(String());
 }
 
 bool Editor::insertParagraphSeparatorInQuotedContent()
@@ -346,4 +348,52 @@
     pasteboard.writeAfterSettingTypes(content);
 }
 
+static void getImage(Element& imageElement, RefPtr<Image>& image, CachedImage*& cachedImage)
+{
+    RenderObject* renderer = imageElement.renderer();
+    if (!renderer || !renderer->isImage())
+        return;
+
+    CachedImage* tentativeCachedImage = toRenderImage(renderer)->cachedImage();
+    if (!tentativeCachedImage || tentativeCachedImage->errorOccurred()) {
+        tentativeCachedImage = 0;
+        return;
+    }
+
+    image = cachedImage->imageForRenderer(renderer);
+    if (!image)
+        return;
+
+    cachedImage = tentativeCachedImage;
+}
+
+void Editor::writeURLToPasteboard(Pasteboard& pasteboard, const KURL& url, const String& title)
+{
+    PasteboardURL pasteboardURL;
+    pasteboardURL.url = ""
+    pasteboardURL.title = title;
+    pasteboardURL.userVisibleForm = client()->userVisibleString(pasteboardURL.url);
+
+    pasteboard.write(pasteboardURL);
+}
+
+void Editor::writeImageToPasteboard(Pasteboard& pasteboard, Element& imageElement, const KURL& url, const String& title)
+{
+    PasteboardImage pasteboardImage;
+
+    CachedImage* cachedImage;
+    getImage(imageElement, pasteboardImage.image, cachedImage);
+    if (!pasteboardImage.image)
+        return;
+    ASSERT(cachedImage);
+
+    pasteboardImage.url.url = ""
+    pasteboardImage.url.title = title;
+    pasteboardImage.url.userVisibleForm = client()->userVisibleString(pasteboardImage.url.url);
+    pasteboardImage.resourceData = cachedImage->resourceBuffer()->sharedBuffer();
+    pasteboardImage.resourceMIMEType = cachedImage->response().mimeType();
+
+    pasteboard.write(pasteboardImage);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/DragController.cpp (154938 => 154939)


--- trunk/Source/WebCore/page/DragController.cpp	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/page/DragController.cpp	2013-09-01 06:26:12 UTC (rev 154939)
@@ -837,7 +837,11 @@
         if (!clipboard->pasteboard().hasData())
             // Simplify whitespace so the title put on the clipboard resembles what the user sees
             // on the web page. This includes replacing newlines with spaces.
+#if PLATFORM(MAC)
+            src->editor().writeURLToPasteboard(clipboard->pasteboard(), linkURL, hitTestResult.textContent().simplifyWhiteSpace());
+#else
             clipboard->pasteboard().writeURL(linkURL, hitTestResult.textContent().simplifyWhiteSpace(), src);
+#endif
 
         if (src->selection().isCaret() && src->selection().isContentEditable()) {
             // a user can initiate a drag on a link without having any text

Modified: trunk/Source/WebCore/platform/Pasteboard.h (154938 => 154939)


--- trunk/Source/WebCore/platform/Pasteboard.h	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/platform/Pasteboard.h	2013-09-01 06:26:12 UTC (rev 154939)
@@ -27,6 +27,7 @@
 #define Pasteboard_h
 
 #include "DragImage.h"
+#include "KURL.h"
 #include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
@@ -89,6 +90,23 @@
 #endif
 };
 
+struct PasteboardURL {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+    KURL url;
+    String title;
+    String userVisibleForm;
+#endif
+};
+
+struct PasteboardImage {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+    PasteboardURL url;
+    RefPtr<Image> image;
+    RefPtr<SharedBuffer> resourceData;
+    String resourceMIMEType;
+#endif
+};
+
 class Pasteboard {
     WTF_MAKE_NONCOPYABLE(Pasteboard); WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -137,16 +155,21 @@
     void setTypes(const PasteboardWebContent&);
     void writeAfterSettingTypes(const PasteboardWebContent&);
 
+    void write(const PasteboardWebContent&);
+    void write(const PasteboardURL&);
+    void write(const PasteboardImage&);
+
     bool writeString(const String& type, const String& data);
 #if !(PLATFORM(MAC) && !PLATFORM(IOS))
     void writeSelection(Range*, bool canSmartCopyOrDelete, Frame*, ShouldSerializeSelectedTextForClipboard = DefaultSelectedTextType); // FIXME: Layering violation.
 #endif
     void writeMarkup(const String& markup);
     void writePlainText(const String&, SmartReplaceOption);
-#if !PLATFORM(IOS)
+#if !PLATFORM(MAC)
     void writeURL(const KURL&, const String&, Frame* = 0); // FIXME: Layering violation.
     void writeImage(Node*, const KURL&, const String& title); // FIXME: Layering violation.
-#else
+#endif
+#if PLATFORM(IOS)
     void writeImage(Node*, Frame*); // FIXME: Layering violation.
     void writePlainText(const String&, Frame*); // FIXME: Layering violation.
     static NSArray* supportedPasteboardTypes();

Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (154938 => 154939)


--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm	2013-09-01 05:30:31 UTC (rev 154938)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm	2013-09-01 06:26:12 UTC (rev 154939)
@@ -187,25 +187,25 @@
         m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(0, WebSmartPastePboardType, m_pasteboardName);
 }
 
-static long writeURLForTypes(const Vector<String>& types, const String& pasteboardName, const KURL& url, const String& titleStr, Frame* frame)
+static long writeURLForTypes(const Vector<String>& types, const String& pasteboardName, const PasteboardURL& pasteboardURL)
 {
     long newChangeCount = platformStrategies()->pasteboardStrategy()->setTypes(types, pasteboardName);
     
-    ASSERT(!url.isEmpty());
+    ASSERT(!pasteboardURL.url.isEmpty());
     
-    NSURL *cocoaURL = url;
-    NSString *userVisibleString = frame->editor().client()->userVisibleString(cocoaURL);
-    
-    NSString *title = (NSString*)titleStr;
-    if ([title length] == 0) {
+    NSURL *cocoaURL = pasteboardURL.url;
+    NSString *userVisibleString = pasteboardURL.userVisibleForm;
+    NSString *title = (NSString *)pasteboardURL.title;
+    if (![title length]) {
         title = [[cocoaURL path] lastPathComponent];
-        if ([title length] == 0)
+        if (![title length])
             title = userVisibleString;
     }
+
     if (types.contains(WebURLsWithTitlesPboardType)) {
         Vector<String> paths;
         paths.append([cocoaURL absoluteString]);
-        paths.append(titleStr.stripWhiteSpace());
+        paths.append(pasteboardURL.title.stripWhiteSpace());
         newChangeCount = platformStrategies()->pasteboardStrategy()->setPathnamesForType(paths, WebURLsWithTitlesPboardType, pasteboardName);
     }
     if (types.contains(String(NSURLPboardType)))
@@ -220,65 +220,45 @@
     return newChangeCount;
 }
     
-void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
+void Pasteboard::write(const PasteboardURL& pasteboardURL)
 {
-    m_changeCount = writeURLForTypes(writableTypesForURL(), m_pasteboardName, url, titleStr, frame);
+    m_changeCount = writeURLForTypes(writableTypesForURL(), m_pasteboardName, pasteboardURL);
 }
 
-static NSFileWrapper* fileWrapperForImage(CachedResource* resource, NSURL *url)
+static NSFileWrapper* fileWrapper(const PasteboardImage& pasteboardImage)
 {
-    ResourceBuffer* coreData = resource->resourceBuffer();
-    NSData *data = "" alloc] initWithBytes:coreData->data() length:coreData->size()] autorelease];
+    NSData *data = ""
     NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease];
-    String coreMIMEType = resource->response().mimeType();
-    NSString *MIMEType = nil;
-    if (!coreMIMEType.isNull())
-        MIMEType = coreMIMEType;
-    [wrapper setPreferredFilename:suggestedFilenameWithMIMEType(url, MIMEType)];
+    [data release];
+    [wrapper setPreferredFilename:suggestedFilenameWithMIMEType(pasteboardImage.url.url, pasteboardImage.resourceMIMEType)];
     return wrapper;
 }
 
-static void writeFileWrapperAsRTFDAttachment(NSFileWrapper* wrapper, const String& pasteboardName, long& newChangeCount)
+static void writeFileWrapperAsRTFDAttachment(NSFileWrapper *wrapper, const String& pasteboardName, long& newChangeCount)
 {
     NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:wrapper];
-    
     NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:attachment];
     [attachment release];
-    
-    NSData *RTFDData = [string RTFDFromRange:NSMakeRange(0, [string length]) documentAttributes:nil];
-    if (RTFDData)
-        newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(RTFDData).get(), NSRTFDPboardType, pasteboardName);
-}
 
-void Pasteboard::writeImage(Node* node, const KURL& url, const String& title)
-{
-    ASSERT(node);
-
-    if (!(node->renderer() && node->renderer()->isImage()))
+    NSData *RTFDData = [string RTFDFromRange:NSMakeRange(0, [string length]) documentAttributes:nil];
+    if (!RTFDData)
         return;
 
-    NSURL *cocoaURL = url;
-    ASSERT(cocoaURL);
+    newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(RTFDData).get(), NSRTFDPboardType, pasteboardName);
+}
 
-    RenderImage* renderer = toRenderImage(node->renderer());
-    CachedImage* cachedImage = renderer->cachedImage();
-    if (!cachedImage || cachedImage->errorOccurred())
-        return;
-
-    m_changeCount = writeURLForTypes(writableTypesForImage(), m_pasteboardName, cocoaURL, nsStringNilIfEmpty(title), node->document().frame());
-    
-    Image* image = cachedImage->imageForRenderer(renderer);
-    if (!image)
-        return;
-    NSData *imageData = (NSData *)[image->getNSImage() TIFFRepresentation];
+void Pasteboard::write(const PasteboardImage& pasteboardImage)
+{
+    NSData *imageData = [pasteboardImage.image->getNSImage() TIFFRepresentation];
     if (!imageData)
         return;
-    m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(imageData), NSTIFFPboardType, m_pasteboardName);
 
-    String MIMEType = cachedImage->response().mimeType();
-    ASSERT(MIMETypeRegistry::isSupportedImageResourceMIMEType(MIMEType));
+    // FIXME: Why can we assert this? It doesn't seem like it's guaranteed.
+    ASSERT(MIMETypeRegistry::isSupportedImageResourceMIMEType(pasteboardImage.resourceMIMEType));
 
-    writeFileWrapperAsRTFDAttachment(fileWrapperForImage(cachedImage, cocoaURL), m_pasteboardName, m_changeCount);
+    m_changeCount = writeURLForTypes(writableTypesForImage(), m_pasteboardName, pasteboardImage.url);
+    m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(imageData), NSTIFFPboardType, m_pasteboardName);
+    writeFileWrapperAsRTFDAttachment(fileWrapper(pasteboardImage), m_pasteboardName, m_changeCount);
 }
 
 void Pasteboard::writePasteboard(const Pasteboard& pasteboard)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to