diff options
Diffstat (limited to 'widget/cocoa/nsClipboard.mm')
-rw-r--r-- | widget/cocoa/nsClipboard.mm | 775 |
1 files changed, 0 insertions, 775 deletions
diff --git a/widget/cocoa/nsClipboard.mm b/widget/cocoa/nsClipboard.mm deleted file mode 100644 index 4146f17851..0000000000 --- a/widget/cocoa/nsClipboard.mm +++ /dev/null @@ -1,775 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozilla/Logging.h" - -#include "mozilla/Unused.h" - -#include "gfxPlatform.h" -#include "nsArrayUtils.h" -#include "nsCOMPtr.h" -#include "nsClipboard.h" -#include "nsString.h" -#include "nsISupportsPrimitives.h" -#include "nsXPIDLString.h" -#include "nsPrimitiveHelpers.h" -#include "nsMemory.h" -#include "nsIFile.h" -#include "nsStringStream.h" -#include "nsDragService.h" -#include "nsEscape.h" -#include "nsPrintfCString.h" -#include "nsObjCExceptions.h" -#include "imgIContainer.h" -#include "nsCocoaUtils.h" - -using mozilla::gfx::DataSourceSurface; -using mozilla::gfx::SourceSurface; -using mozilla::LogLevel; - -// Screenshots use the (undocumented) png pasteboard type. -#define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil - -extern PRLogModuleInfo* sCocoaLog; - -extern void EnsureLogInitialized(); - -mozilla::StaticRefPtr<nsITransferable> nsClipboard::sSelectionCache; - -nsClipboard::nsClipboard() - : mCachedClipboard(-1) - , mChangeCount(0) - , mIgnoreEmptyNotification(false) -{ - EnsureLogInitialized(); -} - -nsClipboard::~nsClipboard() -{ - EmptyClipboard(kGlobalClipboard); - EmptyClipboard(kFindClipboard); - ClearSelectionCache(); -} - -NS_IMPL_ISUPPORTS(nsClipboard, nsIClipboard) - -// We separate this into its own function because after an @try, all local -// variables within that function get marked as volatile, and our C++ type -// system doesn't like volatile things. -static NSData* -GetDataFromPasteboard(NSPasteboard* aPasteboard, NSString* aType) -{ - NSData *data = nil; - @try { - data = [aPasteboard dataForType:aType]; - } @catch (NSException* e) { - NS_WARNING(nsPrintfCString("Exception raised while getting data from the pasteboard: \"%s - %s\"", - [[e name] UTF8String], [[e reason] UTF8String]).get()); - mozilla::Unused << e; - } - return data; -} - -void -nsClipboard::SetSelectionCache(nsITransferable *aTransferable) -{ - sSelectionCache = aTransferable; -} - -void -nsClipboard::ClearSelectionCache() -{ - sSelectionCache = nullptr; -} - -NS_IMETHODIMP -nsClipboard::SetNativeClipboardData(int32_t aWhichClipboard) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !mTransferable) - return NS_ERROR_FAILURE; - - mIgnoreEmptyNotification = true; - - NSDictionary* pasteboardOutputDict = PasteboardDictFromTransferable(mTransferable); - if (!pasteboardOutputDict) - return NS_ERROR_FAILURE; - - unsigned int outputCount = [pasteboardOutputDict count]; - NSArray* outputKeys = [pasteboardOutputDict allKeys]; - NSPasteboard* cocoaPasteboard; - if (aWhichClipboard == kFindClipboard) { - cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard]; - [cocoaPasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; - } else { - // Write everything else out to the general pasteboard. - cocoaPasteboard = [NSPasteboard generalPasteboard]; - [cocoaPasteboard declareTypes:outputKeys owner:nil]; - } - - for (unsigned int i = 0; i < outputCount; i++) { - NSString* currentKey = [outputKeys objectAtIndex:i]; - id currentValue = [pasteboardOutputDict valueForKey:currentKey]; - if (aWhichClipboard == kFindClipboard) { - if (currentKey == NSStringPboardType) - [cocoaPasteboard setString:currentValue forType:currentKey]; - } else { - if (currentKey == NSStringPboardType || - currentKey == kCorePboardType_url || - currentKey == kCorePboardType_urld || - currentKey == kCorePboardType_urln) { - [cocoaPasteboard setString:currentValue forType:currentKey]; - } else if (currentKey == NSHTMLPboardType) { - [cocoaPasteboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue)) - forType:currentKey]; - } else { - [cocoaPasteboard setData:currentValue forType:currentKey]; - } - } - } - - mCachedClipboard = aWhichClipboard; - mChangeCount = [cocoaPasteboard changeCount]; - - mIgnoreEmptyNotification = false; - - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -nsresult -nsClipboard::TransferableFromPasteboard(nsITransferable *aTransferable, NSPasteboard *cocoaPasteboard) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - // get flavor list that includes all acceptable flavors (including ones obtained through conversion) - nsCOMPtr<nsIArray> flavorList; - nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList)); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - - uint32_t flavorCount; - flavorList->GetLength(&flavorCount); - - for (uint32_t i = 0; i < flavorCount; i++) { - nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i); - if (!currentFlavor) - continue; - - nsXPIDLCString flavorStr; - currentFlavor->ToString(getter_Copies(flavorStr)); // i has a flavr - - // printf("looking for clipboard data of type %s\n", flavorStr.get()); - - NSString *pboardType = nil; - if (nsClipboard::IsStringType(flavorStr, &pboardType)) { - NSString* pString = [cocoaPasteboard stringForType:pboardType]; - if (!pString) - continue; - - 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) - return NS_ERROR_OUT_OF_MEMORY; - [stringData getBytes:clipboardDataPtr]; - - // The DOM only wants LF, so convert from MacOS line endings to DOM line endings. - int32_t signedDataLength = dataLength; - nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr, &clipboardDataPtr, &signedDataLength); - dataLength = signedDataLength; - - // skip BOM (Byte Order Mark to distinguish little or big endian) - char16_t* clipboardDataPtrNoBOM = (char16_t*)clipboardDataPtr; - if ((dataLength > 2) && - ((clipboardDataPtrNoBOM[0] == 0xFEFF) || - (clipboardDataPtrNoBOM[0] == 0xFFFE))) { - dataLength -= sizeof(char16_t); - clipboardDataPtrNoBOM += 1; - } - - nsCOMPtr<nsISupports> genericDataWrapper; - nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtrNoBOM, dataLength, - getter_AddRefs(genericDataWrapper)); - aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength); - free(clipboardDataPtr); - break; - } - else if (flavorStr.EqualsLiteral(kCustomTypesMime)) { - NSString* type = [cocoaPasteboard availableTypeFromArray:[NSArray arrayWithObject:kCustomTypesPboardType]]; - if (!type) { - continue; - } - - NSData* pasteboardData = GetDataFromPasteboard(cocoaPasteboard, type); - if (!pasteboardData) { - continue; - } - - unsigned int dataLength = [pasteboardData length]; - void* clipboardDataPtr = malloc(dataLength); - if (!clipboardDataPtr) { - return NS_ERROR_OUT_OF_MEMORY; - } - [pasteboardData getBytes:clipboardDataPtr]; - - nsCOMPtr<nsISupports> genericDataWrapper; - nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtr, dataLength, - getter_AddRefs(genericDataWrapper)); - - aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength); - free(clipboardDataPtr); - } - else if (flavorStr.EqualsLiteral(kJPEGImageMime) || - flavorStr.EqualsLiteral(kJPGImageMime) || - flavorStr.EqualsLiteral(kPNGImageMime) || - flavorStr.EqualsLiteral(kGIFImageMime)) { - // Figure out if there's data on the pasteboard we can grab (sanity check) - NSString *type = [cocoaPasteboard availableTypeFromArray:[NSArray arrayWithObjects:IMAGE_PASTEBOARD_TYPES]]; - if (!type) - continue; - - // Read data off the clipboard - NSData *pasteboardData = GetDataFromPasteboard(cocoaPasteboard, type); - if (!pasteboardData) - continue; - - // Figure out what type we're converting to - CFStringRef outputType = NULL; - if (flavorStr.EqualsLiteral(kJPEGImageMime) || - flavorStr.EqualsLiteral(kJPGImageMime)) - outputType = CFSTR("public.jpeg"); - else if (flavorStr.EqualsLiteral(kPNGImageMime)) - outputType = CFSTR("public.png"); - else if (flavorStr.EqualsLiteral(kGIFImageMime)) - outputType = CFSTR("com.compuserve.gif"); - else - continue; - - // Use ImageIO to interpret the data on the clipboard and transcode. - // Note that ImageIO, like all CF APIs, allows NULLs to propagate freely - // and safely in most cases (like ObjC). A notable exception is CFRelease. - NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: - (NSNumber*)kCFBooleanTrue, kCGImageSourceShouldAllowFloat, - (type == NSTIFFPboardType ? @"public.tiff" : @"public.png"), - kCGImageSourceTypeIdentifierHint, nil]; - - CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)pasteboardData, - (CFDictionaryRef)options); - NSMutableData *encodedData = [NSMutableData data]; - CGImageDestinationRef dest = CGImageDestinationCreateWithData((CFMutableDataRef)encodedData, - outputType, - 1, NULL); - CGImageDestinationAddImageFromSource(dest, source, 0, NULL); - bool successfullyConverted = CGImageDestinationFinalize(dest); - - if (successfullyConverted) { - // Put the converted data in a form Gecko can understand - nsCOMPtr<nsIInputStream> byteStream; - NS_NewByteInputStream(getter_AddRefs(byteStream), (const char*)[encodedData bytes], - [encodedData length], NS_ASSIGNMENT_COPY); - - aTransferable->SetTransferData(flavorStr, byteStream, sizeof(nsIInputStream*)); - } - - if (dest) - CFRelease(dest); - if (source) - CFRelease(source); - - if (successfullyConverted) - break; - else - continue; - } - } - - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -NS_IMETHODIMP -nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhichClipboard) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !aTransferable) - return NS_ERROR_FAILURE; - - NSPasteboard* cocoaPasteboard; - if (aWhichClipboard == kFindClipboard) { - cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard]; - } else { - cocoaPasteboard = [NSPasteboard generalPasteboard]; - } - if (!cocoaPasteboard) - return NS_ERROR_FAILURE; - - // get flavor list that includes all acceptable flavors (including ones obtained through conversion) - nsCOMPtr<nsIArray> flavorList; - nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList)); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - - uint32_t flavorCount; - flavorList->GetLength(&flavorCount); - - // If we were the last ones to put something on the pasteboard, then just use the cached - // transferable. Otherwise clear it because it isn't relevant any more. - if (mCachedClipboard == aWhichClipboard && - mChangeCount == [cocoaPasteboard changeCount]) { - if (mTransferable) { - for (uint32_t i = 0; i < flavorCount; i++) { - nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i); - if (!currentFlavor) - continue; - - nsXPIDLCString flavorStr; - currentFlavor->ToString(getter_Copies(flavorStr)); - - nsCOMPtr<nsISupports> dataSupports; - uint32_t dataSize = 0; - rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(dataSupports), &dataSize); - if (NS_SUCCEEDED(rv)) { - aTransferable->SetTransferData(flavorStr, dataSupports, dataSize); - return NS_OK; // maybe try to fill in more types? Is there a point? - } - } - } - } else { - EmptyClipboard(aWhichClipboard); - } - - // at this point we can't satisfy the request from cache data so let's look - // for things other people put on the system clipboard - - return nsClipboard::TransferableFromPasteboard(aTransferable, cocoaPasteboard); - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -// returns true if we have *any* of the passed in flavors available for pasting -NS_IMETHODIMP -nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength, - int32_t aWhichClipboard, bool* outResult) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - *outResult = false; - - if ((aWhichClipboard != kGlobalClipboard) || !aFlavorList) - return NS_OK; - - // first see if we have data for this in our cached transferable - if (mTransferable) { - nsCOMPtr<nsIArray> transferableFlavorList; - nsresult rv = mTransferable->FlavorsTransferableCanImport(getter_AddRefs(transferableFlavorList)); - if (NS_SUCCEEDED(rv)) { - uint32_t transferableFlavorCount; - transferableFlavorList->GetLength(&transferableFlavorCount); - for (uint32_t j = 0; j < transferableFlavorCount; j++) { - nsCOMPtr<nsISupportsCString> currentTransferableFlavor = - do_QueryElementAt(transferableFlavorList, j); - if (!currentTransferableFlavor) - continue; - nsXPIDLCString transferableFlavorStr; - currentTransferableFlavor->ToString(getter_Copies(transferableFlavorStr)); - - for (uint32_t k = 0; k < aLength; k++) { - if (transferableFlavorStr.Equals(aFlavorList[k])) { - *outResult = true; - return NS_OK; - } - } - } - } - } - - NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard]; - - for (uint32_t i = 0; i < aLength; i++) { - nsDependentCString mimeType(aFlavorList[i]); - NSString *pboardType = nil; - - if (nsClipboard::IsStringType(mimeType, &pboardType)) { - NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:pboardType]]; - if (availableType && [availableType isEqualToString:pboardType]) { - *outResult = true; - break; - } - } else if (!strcmp(aFlavorList[i], kCustomTypesMime)) { - NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:kCustomTypesPboardType]]; - if (availableType) { - *outResult = true; - break; - } - } else if (!strcmp(aFlavorList[i], kJPEGImageMime) || - !strcmp(aFlavorList[i], kJPGImageMime) || - !strcmp(aFlavorList[i], kPNGImageMime) || - !strcmp(aFlavorList[i], kGIFImageMime)) { - NSString* availableType = [generalPBoard availableTypeFromArray: - [NSArray arrayWithObjects:IMAGE_PASTEBOARD_TYPES]]; - if (availableType) { - *outResult = true; - break; - } - } - } - - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -NS_IMETHODIMP -nsClipboard::SupportsFindClipboard(bool *_retval) -{ - NS_ENSURE_ARG_POINTER(_retval); - *_retval = true; - return NS_OK; -} - -// This function converts anything that other applications might understand into the system format -// and puts it into a dictionary which it returns. -// static -NSDictionary* -nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - - if (!aTransferable) - return nil; - - NSMutableDictionary* pasteboardOutputDict = [NSMutableDictionary dictionary]; - - nsCOMPtr<nsIArray> flavorList; - nsresult rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList)); - if (NS_FAILED(rv)) - return nil; - - uint32_t flavorCount; - flavorList->GetLength(&flavorCount); - for (uint32_t i = 0; i < flavorCount; i++) { - nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i); - if (!currentFlavor) - continue; - - nsXPIDLCString flavorStr; - currentFlavor->ToString(getter_Copies(flavorStr)); - - MOZ_LOG(sCocoaLog, LogLevel::Info, ("writing out clipboard data of type %s (%d)\n", flavorStr.get(), i)); - - NSString *pboardType = nil; - - if (nsClipboard::IsStringType(flavorStr, &pboardType)) { - void* data = nullptr; - uint32_t dataSize = 0; - nsCOMPtr<nsISupports> genericDataWrapper; - rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize); - nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize); - - NSString* nativeString; - if (data) - nativeString = [NSString stringWithCharacters:(const unichar*)data length:(dataSize / sizeof(char16_t))]; - else - nativeString = [NSString string]; - - // be nice to Carbon apps, normalize the receiver's contents using Form C. - nativeString = [nativeString precomposedStringWithCanonicalMapping]; - - [pasteboardOutputDict setObject:nativeString forKey:pboardType]; - - free(data); - } - else if (flavorStr.EqualsLiteral(kCustomTypesMime)) { - void* data = nullptr; - uint32_t dataSize = 0; - nsCOMPtr<nsISupports> genericDataWrapper; - rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize); - nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize); - - if (data) { - NSData* nativeData = [NSData dataWithBytes:data length:dataSize]; - - [pasteboardOutputDict setObject:nativeData forKey:kCustomTypesPboardType]; - free(data); - } - } - else if (flavorStr.EqualsLiteral(kPNGImageMime) || flavorStr.EqualsLiteral(kJPEGImageMime) || - flavorStr.EqualsLiteral(kJPGImageMime) || flavorStr.EqualsLiteral(kGIFImageMime) || - flavorStr.EqualsLiteral(kNativeImageMime)) { - uint32_t dataSize = 0; - nsCOMPtr<nsISupports> transferSupports; - aTransferable->GetTransferData(flavorStr, getter_AddRefs(transferSupports), &dataSize); - nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports)); - if (!ptrPrimitive) - continue; - - nsCOMPtr<nsISupports> primitiveData; - ptrPrimitive->GetData(getter_AddRefs(primitiveData)); - - nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData)); - if (!image) { - NS_WARNING("Image isn't an imgIContainer in transferable"); - continue; - } - - RefPtr<SourceSurface> surface = - image->GetFrame(imgIContainer::FRAME_CURRENT, - imgIContainer::FLAG_SYNC_DECODE); - if (!surface) { - continue; - } - CGImageRef imageRef = NULL; - rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &imageRef); - if (NS_FAILED(rv) || !imageRef) { - continue; - } - - // Convert the CGImageRef to TIFF data. - CFMutableDataRef tiffData = CFDataCreateMutable(kCFAllocatorDefault, 0); - CGImageDestinationRef destRef = CGImageDestinationCreateWithData(tiffData, - CFSTR("public.tiff"), - 1, - NULL); - CGImageDestinationAddImage(destRef, imageRef, NULL); - bool successfullyConverted = CGImageDestinationFinalize(destRef); - - CGImageRelease(imageRef); - if (destRef) - CFRelease(destRef); - - if (!successfullyConverted) { - if (tiffData) - CFRelease(tiffData); - continue; - } - - [pasteboardOutputDict setObject:(NSMutableData*)tiffData forKey:NSTIFFPboardType]; - if (tiffData) - CFRelease(tiffData); - } - else if (flavorStr.EqualsLiteral(kFileMime)) { - uint32_t len = 0; - nsCOMPtr<nsISupports> genericFile; - rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericFile), &len); - if (NS_FAILED(rv)) { - continue; - } - - nsCOMPtr<nsIFile> file(do_QueryInterface(genericFile)); - if (!file) { - nsCOMPtr<nsISupportsInterfacePointer> ptr(do_QueryInterface(genericFile)); - - if (ptr) { - ptr->GetData(getter_AddRefs(genericFile)); - file = do_QueryInterface(genericFile); - } - } - - if (!file) { - continue; - } - - nsAutoString fileURI; - rv = file->GetPath(fileURI); - if (NS_FAILED(rv)) { - continue; - } - - NSString* str = nsCocoaUtils::ToNSString(fileURI); - NSArray* fileList = [NSArray arrayWithObjects:str, nil]; - [pasteboardOutputDict setObject:fileList forKey:NSFilenamesPboardType]; - } - else if (flavorStr.EqualsLiteral(kFilePromiseMime)) { - [pasteboardOutputDict setObject:[NSArray arrayWithObject:@""] forKey:NSFilesPromisePboardType]; - } - else if (flavorStr.EqualsLiteral(kURLMime)) { - uint32_t len = 0; - nsCOMPtr<nsISupports> genericURL; - rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericURL), &len); - nsCOMPtr<nsISupportsString> urlObject(do_QueryInterface(genericURL)); - - nsAutoString url; - urlObject->GetData(url); - - // A newline embedded in the URL means that the form is actually URL + title. - int32_t newlinePos = url.FindChar(char16_t('\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:reinterpret_cast<const unichar*>(urlTitle.get()) - length:urlTitle.Length()]; - // be nice to Carbon apps, normalize the receiver's contents using Form C. - [pasteboardOutputDict setObject:[nativeTitle precomposedStringWithCanonicalMapping] forKey:kCorePboardType_urln]; - // Also put the title out as 'urld', since some recipients will look for that. - [pasteboardOutputDict setObject:[nativeTitle precomposedStringWithCanonicalMapping] forKey:kCorePboardType_urld]; - [nativeTitle release]; - } - - // The Finder doesn't like getting random binary data aka - // Unicode, so change it into an escaped URL containing only - // ASCII. - nsAutoCString utf8Data = NS_ConvertUTF16toUTF8(url.get(), url.Length()); - nsAutoCString 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:kCorePboardType_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. - } - - return pasteboardOutputDict; - - NS_OBJC_END_TRY_ABORT_BLOCK_NIL; -} - -bool nsClipboard::IsStringType(const nsCString& aMIMEType, NSString** aPasteboardType) -{ - 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; - } -} - -NSString* nsClipboard::WrapHtmlForSystemPasteboard(NSString* aString) -{ - NSString* wrapped = - [NSString stringWithFormat: - @"<html>" - "<head>" - "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">" - "</head>" - "<body>" - "%@" - "</body>" - "</html>", aString]; - return wrapped; -} - -/** - * Sets the transferable object - * - */ -NS_IMETHODIMP -nsClipboard::SetData(nsITransferable* aTransferable, nsIClipboardOwner* anOwner, - int32_t aWhichClipboard) -{ - NS_ASSERTION (aTransferable, "clipboard given a null transferable"); - - if (aWhichClipboard == kSelectionCache) { - if (aTransferable) { - SetSelectionCache(aTransferable); - return NS_OK; - } - return NS_ERROR_FAILURE; - } - - if (aTransferable == mTransferable && anOwner == mClipboardOwner) { - return NS_OK; - } - bool selectClipPresent; - SupportsSelectionClipboard(&selectClipPresent); - bool findClipPresent; - SupportsFindClipboard(&findClipPresent); - if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard) { - return NS_ERROR_FAILURE; - } - - EmptyClipboard(aWhichClipboard); - - mClipboardOwner = anOwner; - mTransferable = aTransferable; - - nsresult rv = NS_ERROR_FAILURE; - if (mTransferable) { - rv = SetNativeClipboardData(aWhichClipboard); - } - - return rv; -} - -/** - * Gets the transferable object - * - */ -NS_IMETHODIMP -nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) -{ - NS_ASSERTION (aTransferable, "clipboard given a null transferable"); - - bool selectClipPresent; - SupportsSelectionClipboard(&selectClipPresent); - bool findClipPresent; - SupportsFindClipboard(&findClipPresent); - if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard) - return NS_ERROR_FAILURE; - - if (aTransferable) { - return GetNativeClipboardData(aTransferable, aWhichClipboard); - } - - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsClipboard::EmptyClipboard(int32_t aWhichClipboard) -{ - if (aWhichClipboard == kSelectionCache) { - ClearSelectionCache(); - return NS_OK; - } - - bool selectClipPresent; - SupportsSelectionClipboard(&selectClipPresent); - bool findClipPresent; - SupportsFindClipboard(&findClipPresent); - if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard) { - return NS_ERROR_FAILURE; - } - - if (mIgnoreEmptyNotification) { - return NS_OK; - } - - if (mClipboardOwner) { - mClipboardOwner->LosingOwnership(mTransferable); - mClipboardOwner = nullptr; - } - - mTransferable = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -nsClipboard::SupportsSelectionClipboard(bool* _retval) -{ - *_retval = false; // we don't support the selection clipboard by default. - return NS_OK; -} |