summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/mac
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/mac')
-rw-r--r--WebCore/platform/mac/ClipboardMac.mm5
-rw-r--r--WebCore/platform/mac/PasteboardMac.mm189
2 files changed, 177 insertions, 17 deletions
diff --git a/WebCore/platform/mac/ClipboardMac.mm b/WebCore/platform/mac/ClipboardMac.mm
index 0cbb3f6..74a93b6 100644
--- a/WebCore/platform/mac/ClipboardMac.mm
+++ b/WebCore/platform/mac/ClipboardMac.mm
@@ -313,12 +313,11 @@ PassRefPtr<FileList> ClipboardMac::files() const
NSArray *absoluteURLs = absoluteURLsFromPasteboardFilenames(m_pasteboard.get());
NSUInteger count = [absoluteURLs count];
- ScriptExecutionContext* scriptExecutionContext = m_frame->document()->scriptExecutionContext();
RefPtr<FileList> fileList = FileList::create();
for (NSUInteger x = 0; x < count; x++) {
NSURL *absoluteURL = [NSURL URLWithString:[absoluteURLs objectAtIndex:x]];
ASSERT([absoluteURL isFileURL]);
- fileList->append(File::create(scriptExecutionContext, [absoluteURL path]));
+ fileList->append(File::create([absoluteURL path]));
}
return fileList.release(); // We will always return a FileList, sometimes empty
}
@@ -373,7 +372,7 @@ void ClipboardMac::writeRange(Range* range, Frame* frame)
{
ASSERT(range);
ASSERT(frame);
- Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selectionGranularity() == WordGranularity, frame);
+ Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame);
}
void ClipboardMac::writePlainText(const String& text)
diff --git a/WebCore/platform/mac/PasteboardMac.mm b/WebCore/platform/mac/PasteboardMac.mm
index bba7cac..0625287 100644
--- a/WebCore/platform/mac/PasteboardMac.mm
+++ b/WebCore/platform/mac/PasteboardMac.mm
@@ -31,16 +31,22 @@
#import "DOMRangeInternal.h"
#import "Document.h"
#import "DocumentFragment.h"
+#import "DocumentLoader.h"
#import "Editor.h"
#import "EditorClient.h"
#import "Frame.h"
+#import "FrameLoaderClient.h"
#import "HitTestResult.h"
+#import "HTMLAnchorElement.h"
+#import "HTMLNames.h"
#import "Image.h"
#import "KURL.h"
#import "LegacyWebArchive.h"
#import "LoaderNSURLExtras.h"
#import "MIMETypeRegistry.h"
+#import "Page.h"
#import "RenderImage.h"
+#import "Text.h"
#import "WebCoreNSStringExtras.h"
#import "markup.h"
@@ -139,7 +145,8 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange,
Pasteboard::generalPasteboard(); // Initializes pasteboard types.
ASSERT(selectedRange);
- NSAttributedString *attributedString = [[[NSAttributedString alloc] _initWithDOMRange:kit(selectedRange)] autorelease];
+ NSAttributedString *attributedString = [[[NSAttributedString alloc] initWithString:selectedRange->text()] autorelease];
+
#ifdef BUILDING_ON_TIGER
// 4930197: Mail overrides [WebHTMLView pasteboardTypesForSelection] in order to add another type to the pasteboard
// after WebKit does. On Tiger we must call this function so that Mail code will be executed, meaning that
@@ -362,12 +369,124 @@ String Pasteboard::plainText(Frame* frame)
return String();
}
+
+PassRefPtr<DocumentFragment> Pasteboard::documentFragmentWithImageResource(Frame* frame, PassRefPtr<ArchiveResource> resource)
+{
+ if (DocumentLoader* loader = frame->loader()->documentLoader())
+ loader->addArchiveResource(resource.get());
+
+ RefPtr<Element> imageElement = frame->document()->createElement(HTMLNames::imgTag, false);
+ if (!imageElement)
+ return 0;
+
+ NSURL *URL = resource->url();
+ imageElement->setAttribute(HTMLNames::srcAttr, [URL isFileURL] ? [URL absoluteString] : resource->url());
+ RefPtr<DocumentFragment> fragment = frame->document()->createDocumentFragment();
+ if (fragment) {
+ ExceptionCode ec;
+ fragment->appendChild(imageElement, ec);
+ return fragment.release();
+ }
+ return 0;
+}
+
+PassRefPtr<DocumentFragment> Pasteboard::documentFragmentWithRtf(Frame* frame, NSString* pboardType)
+{
+ if (!frame || !frame->document() || !frame->document()->isHTMLDocument())
+ return 0;
+
+ NSAttributedString *string = nil;
+ if (pboardType == NSRTFDPboardType)
+ string = [[NSAttributedString alloc] initWithRTFD:[m_pasteboard.get() dataForType:NSRTFDPboardType] documentAttributes:NULL];
+ if (string == nil)
+ string = [[NSAttributedString alloc] initWithRTF:[m_pasteboard.get() dataForType:NSRTFPboardType] documentAttributes:NULL];
+ if (string == nil)
+ return nil;
+
+ bool wasDeferringCallbacks = frame->page()->defersLoading();
+ if (!wasDeferringCallbacks)
+ frame->page()->setDefersLoading(true);
+
+ Vector<RefPtr<ArchiveResource> > resources;
+ RefPtr<DocumentFragment> fragment = frame->editor()->client()->documentFragmentFromAttributedString(string, resources);
+
+ size_t size = resources.size();
+ if (size) {
+ DocumentLoader* loader = frame->loader()->documentLoader();
+ for (size_t i = 0; i < size; ++i)
+ loader->addArchiveResource(resources[i]);
+ }
+
+ if (!wasDeferringCallbacks)
+ frame->page()->setDefersLoading(false);
+
+ [string release];
+ return fragment.release();
+}
+
+#define WebDataProtocolScheme @"webkit-fake-url"
+
+static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
+{
+ CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault);
+ NSString *UUIDString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUIDRef);
+ CFRelease(UUIDRef);
+ NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/%@", WebDataProtocolScheme, UUIDString, relativePart]];
+ CFRelease(UUIDString);
+ return URL;
+}
+
PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText)
{
NSArray *types = [m_pasteboard.get() types];
+ RefPtr<DocumentFragment> fragment;
chosePlainText = false;
+ if ([types containsObject:WebArchivePboardType]) {
+ RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData([m_pasteboard.get() dataForType:WebArchivePboardType]).get());
+ if (coreArchive) {
+ RefPtr<ArchiveResource> mainResource = coreArchive->mainResource();
+ if (mainResource) {
+ NSString *MIMEType = mainResource->mimeType();
+ if (!frame || !frame->document())
+ return 0;
+ if (frame->loader()->client()->canShowMIMETypeAsHTML(MIMEType)) {
+ NSString *markupString = [[NSString alloc] initWithData:[mainResource->data()->createNSData() autorelease] encoding:NSUTF8StringEncoding];
+ // FIXME: seems poor form to do this as a side effect of getting a document fragment
+ if (DocumentLoader* loader = frame->loader()->documentLoader())
+ loader->addAllArchiveResources(coreArchive.get());
+
+ fragment = createFragmentFromMarkup(frame->document(), markupString, mainResource->url(), FragmentScriptingNotAllowed);
+ [markupString release];
+ } else if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType))
+ fragment = documentFragmentWithImageResource(frame, mainResource);
+ }
+ }
+ if (fragment)
+ return fragment.release();
+ }
+
+ if ([types containsObject:NSFilenamesPboardType]) {
+ NSArray* paths = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType];
+ NSEnumerator* enumerator = [paths objectEnumerator];
+ NSString* path;
+ Vector< RefPtr<Node> > refNodesVector;
+ Vector<Node*> nodesVector;
+
+ while ((path = [enumerator nextObject]) != nil) {
+ // Non-image file types; _web_userVisibleString is appropriate here because this will
+ // be pasted as visible text.
+ NSString *url = frame->editor()->client()->userVisibleString([NSURL fileURLWithPath:path]);
+ RefPtr<Node> textNode = frame->document()->createTextNode(url);
+ refNodesVector.append(textNode.get());
+ nodesVector.append(textNode.get());
+ }
+ fragment = createFragmentFromNodes(frame->document(), nodesVector);
+ if (fragment && fragment->firstChild())
+ return fragment.release();
+ }
+
if ([types containsObject:NSHTMLPboardType]) {
NSString *HTMLString = [m_pasteboard.get() stringForType:NSHTMLPboardType];
// This is a hack to make Microsoft's HTML pasteboard data work. See 3778785.
@@ -377,24 +496,66 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
HTMLString = [HTMLString substringFromIndex:range.location];
}
}
- if ([HTMLString length] != 0) {
- // FIXME: FragmentScriptingNotAllowed is a HACK and should
- // be removed or replaced with an enum with a better name.
- // FragmentScriptingNotAllowed causes the Parser to remove children
- // of <script> tags (so javascript doesn't show up in pastes).
- RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", FragmentScriptingNotAllowed);
- if (fragment)
- return fragment.release();
+ if ([HTMLString length] != 0 &&
+ (fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", FragmentScriptingNotAllowed)))
+ return fragment.release();
+ }
+
+ if ([types containsObject:NSRTFDPboardType] &&
+ (fragment = documentFragmentWithRtf(frame, NSRTFDPboardType)))
+ return fragment.release();
+
+ if ([types containsObject:NSRTFPboardType] &&
+ (fragment = documentFragmentWithRtf(frame, NSRTFPboardType)))
+ return fragment.release();
+
+ if ([types containsObject:NSTIFFPboardType] &&
+ (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSTIFFPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"image.tiff"), "image/tiff", "", ""))))
+ return fragment.release();
+
+ if ([types containsObject:NSPDFPboardType] &&
+ (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSPDFPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"application.pdf"), "application/pdf", "", ""))))
+ return fragment.release();
+
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
+ if ([types containsObject:NSPICTPboardType] &&
+ (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSPICTPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"image.pict"), "image/pict", "", ""))))
+ return fragment.release();
+#endif
+
+ // Only 10.5 and higher support setting and retrieving pasteboard types with UTIs, but we don't believe
+ // that any applications on Tiger put types for which we only have a UTI, like PNG, on the pasteboard.
+ if ([types containsObject:(NSString*)kUTTypePNG] &&
+ (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:(NSString*)kUTTypePNG] copy] autorelease]), uniqueURLWithRelativePart(@"image.png"), "image/png", "", ""))))
+ return fragment.release();
+
+ if ([types containsObject:NSURLPboardType]) {
+ NSURL *URL = [NSURL URLFromPasteboard:m_pasteboard.get()];
+ Document* document = frame->document();
+ ASSERT(document);
+ if (!document)
+ return 0;
+ RefPtr<Element> anchor = document->createElement(HTMLNames::aTag, false);
+ NSString *URLString = [URL absoluteString]; // Original data is ASCII-only, so there is no need to precompose.
+ if ([URLString length] == 0)
+ return nil;
+ NSString *URLTitleString = [[m_pasteboard.get() stringForType:WebURLNamePboardType] precomposedStringWithCanonicalMapping];
+ ExceptionCode ec;
+ anchor->setAttribute(HTMLNames::hrefAttr, URLString);
+ anchor->appendChild(document->createTextNode(URLTitleString), ec);
+ fragment = document->createDocumentFragment();
+ if (fragment) {
+ fragment->appendChild(anchor, ec);
+ return fragment.release();
}
}
-
+
if (allowPlainText && [types containsObject:NSStringPboardType]) {
chosePlainText = true;
- RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]);
- if (fragment)
- return fragment.release();
+ fragment = createFragmentFromText(context.get(), [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]);
+ return fragment.release();
}
-
+
return 0;
}