From 88642f71dc37ae05cfad1374ead75bf035c63965 Mon Sep 17 00:00:00 2001 From: Jorg K Date: Mon, 23 Nov 2015 11:04:26 -0800 Subject: [PATCH] Bug 938991 - text/rtf support for clipboard data. r=enndeakin --- dom/events/DataTransfer.cpp | 4 ++-- widget/cocoa/nsClipboard.mm | 21 ++++++++++++++------- widget/cocoa/nsDragService.mm | 11 ++++++++++- widget/nsClipboardProxy.cpp | 3 ++- widget/nsITransferable.idl | 1 + widget/nsPrimitiveHelpers.cpp | 5 +++-- widget/windows/nsClipboard.cpp | 8 ++++++++ 7 files changed, 40 insertions(+), 13 deletions(-) diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index a5eb0b984574..76c75197afd0 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -1237,7 +1237,7 @@ DataTransfer::CacheExternalDragFormats() // there isn't a way to get a list of the formats that might be available on // all platforms, so just check for the types that can actually be imported // XXXndeakin there are some other formats but those are platform specific. - const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime }; + const char* formats[] = { kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime, kUnicodeMime }; uint32_t count; dragSession->GetNumDropItems(&count); @@ -1279,7 +1279,7 @@ DataTransfer::CacheExternalClipboardFormats() // there isn't a way to get a list of the formats that might be available on // all platforms, so just check for the types that can actually be imported - const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime }; + const char* formats[] = { kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime, kUnicodeMime }; for (uint32_t f = 0; f < mozilla::ArrayLength(formats); ++f) { // check each format one at a time diff --git a/widget/cocoa/nsClipboard.mm b/widget/cocoa/nsClipboard.mm index abc7031e88f1..870638ac7e1a 100644 --- a/widget/cocoa/nsClipboard.mm +++ b/widget/cocoa/nsClipboard.mm @@ -153,7 +153,12 @@ nsClipboard::TransferableFromPasteboard(nsITransferable *aTransferable, NSPasteb if (!pString) continue; - NSData* stringData = [pString dataUsingEncoding:NSUnicodeStringEncoding]; + NSData* stringData; + if ([pboardType isEqualToString:NSRTFPboardType]) { + stringData = [pString dataUsingEncoding:NSASCIIStringEncoding]; + } else { + stringData = [pString dataUsingEncoding:NSUnicodeStringEncoding]; + } unsigned int dataLength = [stringData length]; void* clipboardDataPtr = malloc(dataLength); if (!clipboardDataPtr) @@ -581,12 +586,14 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable) bool nsClipboard::IsStringType(const nsCString& aMIMEType, NSString** aPasteboardType) { - if (aMIMEType.EqualsLiteral(kUnicodeMime) || - aMIMEType.EqualsLiteral(kHTMLMime)) { - if (aMIMEType.EqualsLiteral(kUnicodeMime)) - *aPasteboardType = NSStringPboardType; - else - *aPasteboardType = NSHTMLPboardType; + if (aMIMEType.EqualsLiteral(kUnicodeMime)) { + *aPasteboardType = NSStringPboardType; + return true; + } else if (aMIMEType.EqualsLiteral(kRTFMime)) { + *aPasteboardType = NSRTFPboardType; + return true; + } else if (aMIMEType.EqualsLiteral(kHTMLMime)) { + *aPasteboardType = NSHTMLPboardType; return true; } else { return false; diff --git a/widget/cocoa/nsDragService.mm b/widget/cocoa/nsDragService.mm index 6618ff4abea6..121fb131c8f6 100644 --- a/widget/cocoa/nsDragService.mm +++ b/widget/cocoa/nsDragService.mm @@ -493,9 +493,16 @@ nsDragService::GetData(nsITransferable* aTransferable, uint32_t aItemIndex) pString = GetStringForType(item, (const NSString*)kUTTypeURL); } else if (flavorStr.EqualsLiteral(kURLDescriptionMime)) { pString = GetTitleForURL(item); + } else if (flavorStr.EqualsLiteral(kRTFMime)) { + pString = GetStringForType(item, (const NSString*)kUTTypeRTF); } if (pString) { - NSData* stringData = [pString dataUsingEncoding:NSUnicodeStringEncoding]; + NSData* stringData; + if (flavorStr.EqualsLiteral(kRTFMime)) { + stringData = [pString dataUsingEncoding:NSASCIIStringEncoding]; + } else { + stringData = [pString dataUsingEncoding:NSUnicodeStringEncoding]; + } unsigned int dataLength = [stringData length]; void* clipboardDataPtr = malloc(dataLength); if (!clipboardDataPtr) @@ -601,6 +608,8 @@ nsDragService::IsDataFlavorSupported(const char *aDataFlavor, bool *_retval) type = (const NSString*)kUTTypeURL; } else if (dataFlavor.EqualsLiteral(kURLDescriptionMime)) { type = (const NSString*)kUTTypeURLName; + } else if (dataFlavor.EqualsLiteral(kRTFMime)) { + type = (const NSString*)kUTTypeRTF; } NSString* availableType = [globalDragPboard availableTypeFromArray:[NSArray arrayWithObjects:(id)type, nil]]; if (availableType && IsValidType(availableType, allowFileURL)) { diff --git a/widget/nsClipboardProxy.cpp b/widget/nsClipboardProxy.cpp index b88fd1d637f2..28f05ae97d2b 100644 --- a/widget/nsClipboardProxy.cpp +++ b/widget/nsClipboardProxy.cpp @@ -92,7 +92,8 @@ nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboar rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*)); NS_ENSURE_SUCCESS(rv, rv); - } else if (flavor.EqualsLiteral(kNativeHTMLMime)) { + } else if (flavor.EqualsLiteral(kNativeHTMLMime) || + flavor.EqualsLiteral(kRTFMime)) { nsCOMPtr dataWrapper = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); diff --git a/widget/nsITransferable.idl b/widget/nsITransferable.idl index bc19b1b5ab07..ab35d69f9738 100644 --- a/widget/nsITransferable.idl +++ b/widget/nsITransferable.idl @@ -15,6 +15,7 @@ interface nsIDOMNode; // these probably shouldn't live here, but in some central repository shared // by the entire app. #define kTextMime "text/plain" +#define kRTFMime "text/rtf" #define kUnicodeMime "text/unicode" #define kMozTextInternal "text/x-moz-text-internal" // text data which isn't suppoed to be parsed by other apps. #define kHTMLMime "text/html" diff --git a/widget/nsPrimitiveHelpers.cpp b/widget/nsPrimitiveHelpers.cpp index d80bba25b515..fe70262061c3 100644 --- a/widget/nsPrimitiveHelpers.cpp +++ b/widget/nsPrimitiveHelpers.cpp @@ -45,7 +45,8 @@ nsPrimitiveHelpers :: CreatePrimitiveForData ( const char* aFlavor, const void* if ( !aPrimitive ) return; - if ( strcmp(aFlavor,kTextMime) == 0 || strcmp(aFlavor,kNativeHTMLMime) == 0 ) { + if ( strcmp(aFlavor,kTextMime) == 0 || strcmp(aFlavor,kNativeHTMLMime) == 0 || + strcmp(aFlavor,kRTFMime) == 0) { nsCOMPtr primitive = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID); if ( primitive ) { @@ -170,7 +171,7 @@ nsLinebreakHelpers :: ConvertPlatformToDOMLinebreaks ( const char* inFlavor, voi nsresult retVal = NS_OK; - if ( strcmp(inFlavor, "text/plain") == 0 ) { + if ( strcmp(inFlavor, kTextMime) == 0 || strcmp(inFlavor, kRTFMime) == 0) { char* buffAsChars = reinterpret_cast(*ioData); char* oldBuffer = buffAsChars; retVal = nsLinebreakConverter::ConvertLineBreaksInSitu ( &buffAsChars, nsLinebreakConverter::eLinebreakAny, diff --git a/widget/windows/nsClipboard.cpp b/widget/windows/nsClipboard.cpp index 506a6e649470..67cdee82ea80 100644 --- a/widget/windows/nsClipboard.cpp +++ b/widget/windows/nsClipboard.cpp @@ -95,6 +95,8 @@ UINT nsClipboard::GetFormat(const char* aMimeStr) if (strcmp(aMimeStr, kTextMime) == 0 || strcmp(aMimeStr, kUnicodeMime) == 0) format = CF_UNICODETEXT; + else if (strcmp(aMimeStr, kRTFMime) == 0) + format = ::RegisterClipboardFormat(L"Rich Text Format"); else if (strcmp(aMimeStr, kJPEGImageMime) == 0 || strcmp(aMimeStr, kJPGImageMime) == 0 || strcmp(aMimeStr, kPNGImageMime) == 0) @@ -670,6 +672,12 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject, nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &data, &signedLen ); dataLen = signedLen; + if (strcmp(flavorStr, kRTFMime) == 0) { + // RTF on Windows is known to sometimes deliver an extra null byte. + if (dataLen > 0 && static_cast(data)[dataLen - 1] == '\0') + dataLen--; + } + nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) ); free(data); }