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)