diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index 5c1176b5a0d0..842d33e87130 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -1818,6 +1818,8 @@ NSEvent* gLastDragEvent = nil; NSURLPboardType, NSFilesPromisePboardType, kWildcardPboardType, + kCorePasteboardFlavorType_url, + kCorePasteboardFlavorType_urln, nil]]; return self; diff --git a/widget/src/cocoa/nsClipboard.mm b/widget/src/cocoa/nsClipboard.mm index 912d1f664af1..9ec71caa99a7 100644 --- a/widget/src/cocoa/nsClipboard.mm +++ b/widget/src/cocoa/nsClipboard.mm @@ -46,6 +46,8 @@ #include "nsIImage.h" #include "nsILocalFile.h" #include "nsStringStream.h" +#include "nsDragService.h" +#include "nsEscape.h" // Screenshots use the (undocumented) png pasteboard type. #define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil @@ -469,7 +471,42 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable) else if (flavorStr.EqualsLiteral(kFilePromiseMime)) { [pasteboardOutputDict setObject:[NSArray arrayWithObject:@""] forKey:NSFilesPromisePboardType]; } + else if (flavorStr.EqualsLiteral(kURLMime)) { + PRUint32 len = 0; + nsCOMPtr genericURL; + rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericURL), &len); + nsCOMPtr urlObject(do_QueryInterface(genericURL)); + nsAutoString url; + urlObject->GetData(url); + + // A newline embedded in the URL means that the form is actually URL + title. + PRInt32 newlinePos = url.FindChar(PRUnichar('\n')); + if (newlinePos >= 0) { + url.Truncate(newlinePos); + + nsAutoString urlTitle; + urlObject->GetData(urlTitle); + urlTitle.Mid(urlTitle, newlinePos + 1, len - (newlinePos + 1)); + + NSString *nativeTitle = [[NSString alloc] initWithCharacters:urlTitle.get() length:urlTitle.Length()]; + // be nice to Carbon apps, normalize the receiver's contents using Form C. + [pasteboardOutputDict setObject:[nativeTitle precomposedStringWithCanonicalMapping] forKey:kCorePasteboardFlavorType_urln]; + [nativeTitle release]; + } + + // The Finder doesn't like getting random binary data aka + // Unicode, so change it into an escaped URL containing only + // ASCII. + nsCAutoString utf8Data = NS_ConvertUTF16toUTF8(url.get(), url.Length()); + nsCAutoString escData; + NS_EscapeURL(utf8Data.get(), utf8Data.Length(), esc_OnlyNonASCII|esc_AlwaysCopy, escData); + + // printf("Escaped url is %s, length %d\n", escData.get(), escData.Length()); + + NSString *nativeURL = [NSString stringWithUTF8String:escData.get()]; + [pasteboardOutputDict setObject:nativeURL forKey:kCorePasteboardFlavorType_url]; + } // If it wasn't a type that we recognize as exportable we don't put it on the system // clipboard. We'll just access it from our cached transferable when we need it. } diff --git a/widget/src/cocoa/nsDragService.h b/widget/src/cocoa/nsDragService.h index d840b88e873b..5b3285ef7a86 100644 --- a/widget/src/cocoa/nsDragService.h +++ b/widget/src/cocoa/nsDragService.h @@ -44,6 +44,8 @@ #include extern NSString* const kWildcardPboardType; +extern NSString* const kCorePasteboardFlavorType_url; +extern NSString* const kCorePasteboardFlavorType_urln; class nsDragService : public nsBaseDragService { diff --git a/widget/src/cocoa/nsDragService.mm b/widget/src/cocoa/nsDragService.mm index c87fea4c3f66..683148e10198 100644 --- a/widget/src/cocoa/nsDragService.mm +++ b/widget/src/cocoa/nsDragService.mm @@ -83,6 +83,8 @@ extern NSEvent* gLastDragEvent; nsISupportsArray *gDraggedTransferables = nsnull; NSString* const kWildcardPboardType = @"MozillaWildcard"; +NSString* const kCorePasteboardFlavorType_url = @"CorePasteboardFlavorType 0x75726C20"; // 'url ' url +NSString* const kCorePasteboardFlavorType_urln = @"CorePasteboardFlavorType 0x75726C6E"; // 'urln' title nsDragService::nsDragService() { @@ -131,7 +133,9 @@ static nsresult SetUpDragClipboard(nsISupportsArray* aTransferableArray) for (unsigned int i = 0; i < typeCount; i++) { NSString* currentKey = [types objectAtIndex:i]; id currentValue = [pasteboardOutputDict valueForKey:currentKey]; - if (currentKey == NSStringPboardType) { + if (currentKey == NSStringPboardType || + currentKey == kCorePasteboardFlavorType_url || + currentKey == kCorePasteboardFlavorType_urln) { [dragPBoard setString:currentValue forType:currentKey]; } else if (currentKey == NSTIFFPboardType) {