зеркало из https://github.com/mozilla/gecko-dev.git
Bug 860857, support custom datatransfer types using a special type, r=smaug,jmathies,mstange
This commit is contained in:
Родитель
d614e66d46
Коммит
a030ec3ce6
|
@ -18,6 +18,10 @@
|
||||||
#include "nsIClipboard.h"
|
#include "nsIClipboard.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
#include "nsIBinaryInputStream.h"
|
||||||
|
#include "nsIBinaryOutputStream.h"
|
||||||
|
#include "nsIStorageStream.h"
|
||||||
|
#include "nsStringStream.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsIScriptObjectPrincipal.h"
|
#include "nsIScriptObjectPrincipal.h"
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
|
@ -80,6 +84,12 @@ const char DataTransfer::sEffects[8][9] = {
|
||||||
"none", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"
|
"none", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used for custom clipboard types.
|
||||||
|
enum CustomClipboardTypeId {
|
||||||
|
eCustomClipboardTypeId_None,
|
||||||
|
eCustomClipboardTypeId_String
|
||||||
|
};
|
||||||
|
|
||||||
DataTransfer::DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
|
DataTransfer::DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
|
||||||
bool aIsExternal, int32_t aClipboardType)
|
bool aIsExternal, int32_t aClipboardType)
|
||||||
: mParent(aParent)
|
: mParent(aParent)
|
||||||
|
@ -710,6 +720,11 @@ DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't allow the custom type to be assigned.
|
||||||
|
if (aFormat.EqualsLiteral(kCustomTypesMime)) {
|
||||||
|
return NS_ERROR_TYPE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't allow non-chrome to add non-string or file data. We'll block file
|
// Don't allow non-chrome to add non-string or file data. We'll block file
|
||||||
// promises as well which are used internally for drags to the desktop.
|
// promises as well which are used internally for drags to the desktop.
|
||||||
if (!nsContentUtils::IsSystemPrincipal(aSubjectPrincipal)) {
|
if (!nsContentUtils::IsSystemPrincipal(aSubjectPrincipal)) {
|
||||||
|
@ -984,29 +999,147 @@ DataTransfer::GetTransferable(uint32_t aIndex, nsILoadContext* aLoadContext)
|
||||||
}
|
}
|
||||||
transferable->Init(aLoadContext);
|
transferable->Init(aLoadContext);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIStorageStream> storageStream;
|
||||||
|
nsCOMPtr<nsIBinaryOutputStream> stream;
|
||||||
|
|
||||||
bool added = false;
|
bool added = false;
|
||||||
|
bool handlingCustomFormats = true;
|
||||||
|
uint32_t totalCustomLength = 0;
|
||||||
|
|
||||||
|
const char* knownFormats[] = { kTextMime, kHTMLMime, kNativeHTMLMime, kRTFMime,
|
||||||
|
kURLMime, kURLDataMime, kURLDescriptionMime, kURLPrivateMime,
|
||||||
|
kPNGImageMime, kJPEGImageMime, kGIFImageMime, kNativeImageMime,
|
||||||
|
kFileMime, kFilePromiseMime, kFilePromiseDirectoryMime,
|
||||||
|
kMozTextInternal, kHTMLContext, kHTMLInfo };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Two passes are made here to iterate over all of the types. First, look for
|
||||||
|
* any types that are not in the list of known types. For this pass, handlingCustomFormats
|
||||||
|
* will be true. Data that corresponds to unknown types will be pulled out and
|
||||||
|
* inserted into a single type (kCustomTypesMime) by writing the data into a stream.
|
||||||
|
*
|
||||||
|
* The second pass will iterate over the formats looking for known types. These are
|
||||||
|
* added as is. The unknown types are all then inserted as a single type (kCustomTypesMime)
|
||||||
|
* in the same position of the first custom type. This model is used to maintain the
|
||||||
|
* format order as best as possible.
|
||||||
|
*
|
||||||
|
* The format of the kCustomTypesMime type is one or more of the following stored sequentially:
|
||||||
|
* <32-bit> type (only none or string is supported)
|
||||||
|
* <32-bit> length of format
|
||||||
|
* <wide string> format
|
||||||
|
* <32-bit> length of data
|
||||||
|
* <wide string> data
|
||||||
|
* A type of eCustomClipboardTypeId_None ends the list, without any following data.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
for (uint32_t f = 0; f < count; f++) {
|
for (uint32_t f = 0; f < count; f++) {
|
||||||
const TransferItem& formatitem = item[f];
|
const TransferItem& formatitem = item[f];
|
||||||
if (!formatitem.mData) { // skip empty items
|
if (!formatitem.mData) { // skip empty items
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t length;
|
// If the data is of one of the well-known formats, use it directly.
|
||||||
|
bool isCustomFormat = true;
|
||||||
|
for (uint32_t f = 0; f < ArrayLength(knownFormats); f++) {
|
||||||
|
if (formatitem.mFormat.EqualsASCII(knownFormats[f])) {
|
||||||
|
isCustomFormat = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lengthInBytes;
|
||||||
nsCOMPtr<nsISupports> convertedData;
|
nsCOMPtr<nsISupports> convertedData;
|
||||||
if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), &length)) {
|
|
||||||
|
if (handlingCustomFormats) {
|
||||||
|
if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), &lengthInBytes)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the underlying drag code uses text/unicode, so use that instead of text/plain
|
// When handling custom types, add the data to the stream if this is a
|
||||||
|
// custom type.
|
||||||
|
if (isCustomFormat) {
|
||||||
|
// If it isn't a string, just ignore it. The dataTransfer is cached in the
|
||||||
|
// drag sesion during drag-and-drop, so non-strings will be available when
|
||||||
|
// dragging locally.
|
||||||
|
nsCOMPtr<nsISupportsString> str(do_QueryInterface(convertedData));
|
||||||
|
if (str) {
|
||||||
|
nsAutoString data;
|
||||||
|
str->GetData(data);
|
||||||
|
|
||||||
|
if (!stream) {
|
||||||
|
// Create a storage stream to write to.
|
||||||
|
NS_NewStorageStream(1024, UINT32_MAX, getter_AddRefs(storageStream));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIOutputStream> outputStream;
|
||||||
|
storageStream->GetOutputStream(0, getter_AddRefs(outputStream));
|
||||||
|
|
||||||
|
stream = do_CreateInstance("@mozilla.org/binaryoutputstream;1");
|
||||||
|
stream->SetOutputStream(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t formatLength = formatitem.mFormat.Length() * sizeof(nsString::char_type);
|
||||||
|
|
||||||
|
stream->Write32(eCustomClipboardTypeId_String);
|
||||||
|
stream->Write32(formatLength);
|
||||||
|
stream->WriteBytes((const char *)formatitem.mFormat.get(), formatLength);
|
||||||
|
stream->Write32(lengthInBytes);
|
||||||
|
stream->WriteBytes((const char *)data.get(), lengthInBytes);
|
||||||
|
|
||||||
|
// The total size of the stream is the format length, the data length,
|
||||||
|
// two integers to hold the lengths and one integer for the string flag.
|
||||||
|
totalCustomLength += formatLength + lengthInBytes + (sizeof(uint32_t) * 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isCustomFormat && stream) {
|
||||||
|
// This is the second pass of the loop (handlingCustomFormats is false).
|
||||||
|
// When encountering the first custom format, append all of the stream
|
||||||
|
// at this position.
|
||||||
|
|
||||||
|
// Write out a terminator.
|
||||||
|
totalCustomLength += sizeof(uint32_t);
|
||||||
|
stream->Write32(eCustomClipboardTypeId_None);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> inputStream;
|
||||||
|
storageStream->NewInputStream(0, getter_AddRefs(inputStream));
|
||||||
|
|
||||||
|
RefPtr<nsStringBuffer> stringBuffer = nsStringBuffer::Alloc(totalCustomLength + 1);
|
||||||
|
|
||||||
|
// Read the data from the string and add a null-terminator as ToString needs it.
|
||||||
|
uint32_t amountRead;
|
||||||
|
inputStream->Read(static_cast<char*>(stringBuffer->Data()), totalCustomLength, &amountRead);
|
||||||
|
static_cast<char*>(stringBuffer->Data())[amountRead] = 0;
|
||||||
|
|
||||||
|
nsCString str;
|
||||||
|
stringBuffer->ToString(totalCustomLength, str);
|
||||||
|
nsCOMPtr<nsISupportsCString> strSupports(do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
|
||||||
|
strSupports->SetData(str);
|
||||||
|
|
||||||
|
nsresult rv = transferable->SetTransferData(kCustomTypesMime, strSupports, totalCustomLength);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
added = true;
|
||||||
|
|
||||||
|
// Clear the stream so it doesn't get used again.
|
||||||
|
stream = nullptr;
|
||||||
|
} else {
|
||||||
|
// This is the second pass of the loop and a known type is encountered.
|
||||||
|
// Add it as is.
|
||||||
|
if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), &lengthInBytes)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The underlying drag code uses text/unicode, so use that instead of text/plain
|
||||||
const char* format;
|
const char* format;
|
||||||
NS_ConvertUTF16toUTF8 utf8format(formatitem.mFormat);
|
NS_ConvertUTF16toUTF8 utf8format(formatitem.mFormat);
|
||||||
if (utf8format.EqualsLiteral("text/plain")) {
|
if (utf8format.EqualsLiteral(kTextMime)) {
|
||||||
format = kUnicodeMime;
|
format = kUnicodeMime;
|
||||||
} else {
|
} else {
|
||||||
format = utf8format.get();
|
format = utf8format.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a converter is set for a format, set the converter for the
|
// If a converter is set for a format, set the converter for the
|
||||||
// transferable and don't add the item
|
// transferable and don't add the item
|
||||||
nsCOMPtr<nsIFormatConverter> converter = do_QueryInterface(convertedData);
|
nsCOMPtr<nsIFormatConverter> converter = do_QueryInterface(convertedData);
|
||||||
if (converter) {
|
if (converter) {
|
||||||
|
@ -1015,13 +1148,17 @@ DataTransfer::GetTransferable(uint32_t aIndex, nsILoadContext* aLoadContext)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = transferable->SetTransferData(format, convertedData, length);
|
nsresult rv = transferable->SetTransferData(format, convertedData, lengthInBytes);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
added = true;
|
added = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlingCustomFormats = !handlingCustomFormats;
|
||||||
|
} while (!handlingCustomFormats);
|
||||||
|
|
||||||
// only return the transferable if data was successfully added to it
|
// only return the transferable if data was successfully added to it
|
||||||
if (added) {
|
if (added) {
|
||||||
|
@ -1152,6 +1289,19 @@ DataTransfer::SetDataWithPrincipal(const nsAString& aFormat,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataTransfer::SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat,
|
||||||
|
nsIVariant* aData,
|
||||||
|
uint32_t aIndex,
|
||||||
|
nsIPrincipal* aPrincipal)
|
||||||
|
{
|
||||||
|
if (aFormat.EqualsLiteral(kCustomTypesMime)) {
|
||||||
|
FillInExternalCustomTypes(aData, aIndex, aPrincipal);
|
||||||
|
} else {
|
||||||
|
SetDataWithPrincipal(aFormat, aData, aIndex, aPrincipal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DataTransfer::GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat)
|
DataTransfer::GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat)
|
||||||
{
|
{
|
||||||
|
@ -1200,11 +1350,19 @@ DataTransfer::CacheExternalDragFormats()
|
||||||
// there isn't a way to get a list of the formats that might be available on
|
// 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
|
// all platforms, so just check for the types that can actually be imported
|
||||||
// XXXndeakin there are some other formats but those are platform specific.
|
// XXXndeakin there are some other formats but those are platform specific.
|
||||||
const char* formats[] = { kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime, kUnicodeMime };
|
const char* formats[] = { kFileMime, kHTMLMime, kRTFMime,
|
||||||
|
kURLMime, kURLDataMime, kUnicodeMime };
|
||||||
|
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
dragSession->GetNumDropItems(&count);
|
dragSession->GetNumDropItems(&count);
|
||||||
for (uint32_t c = 0; c < count; c++) {
|
for (uint32_t c = 0; c < count; c++) {
|
||||||
|
// First, check for the special format that holds custom types.
|
||||||
|
bool supported;
|
||||||
|
dragSession->IsDataFlavorSupported(kCustomTypesMime, &supported);
|
||||||
|
if (supported) {
|
||||||
|
FillInExternalCustomTypes(c, sysPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t f = 0; f < ArrayLength(formats); f++) {
|
for (uint32_t f = 0; f < ArrayLength(formats); f++) {
|
||||||
// IsDataFlavorSupported doesn't take an index as an argument and just
|
// IsDataFlavorSupported doesn't take an index as an argument and just
|
||||||
// checks if any of the items support a particular flavor, even though
|
// checks if any of the items support a particular flavor, even though
|
||||||
|
@ -1241,8 +1399,10 @@ DataTransfer::CacheExternalClipboardFormats()
|
||||||
ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
|
ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
|
||||||
|
|
||||||
// there isn't a way to get a list of the formats that might be available on
|
// 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
|
// all platforms, so just check for the types that can actually be imported.
|
||||||
const char* formats[] = { kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime, kUnicodeMime };
|
// Note that the loop below assumes that kCustomTypesMime will be first.
|
||||||
|
const char* formats[] = { kCustomTypesMime, kFileMime, kHTMLMime, kRTFMime,
|
||||||
|
kURLMime, kURLDataMime, kUnicodeMime };
|
||||||
|
|
||||||
for (uint32_t f = 0; f < mozilla::ArrayLength(formats); ++f) {
|
for (uint32_t f = 0; f < mozilla::ArrayLength(formats); ++f) {
|
||||||
// check each format one at a time
|
// check each format one at a time
|
||||||
|
@ -1251,9 +1411,13 @@ DataTransfer::CacheExternalClipboardFormats()
|
||||||
// if the format is supported, add an item to the array with null as
|
// if the format is supported, add an item to the array with null as
|
||||||
// the data. When retrieved, GetRealData will read the data.
|
// the data. When retrieved, GetRealData will read the data.
|
||||||
if (supported) {
|
if (supported) {
|
||||||
|
if (f == 0) {
|
||||||
|
FillInExternalCustomTypes(0, sysPrincipal);
|
||||||
|
} else {
|
||||||
CacheExternalData(formats[f], 0, sysPrincipal);
|
CacheExternalData(formats[f], 0, sysPrincipal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1335,7 +1499,7 @@ DataTransfer::FillInExternalData(TransferItem& aItem, uint32_t aIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
aItem.mData = variant;
|
aItem.mData = variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DataTransfer::FillAllExternalData()
|
DataTransfer::FillAllExternalData()
|
||||||
|
@ -1352,5 +1516,67 @@ DataTransfer::FillAllExternalData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataTransfer::FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal)
|
||||||
|
{
|
||||||
|
TransferItem item;
|
||||||
|
item.mFormat.AssignLiteral(kCustomTypesMime);
|
||||||
|
|
||||||
|
FillInExternalData(item, aIndex);
|
||||||
|
if (!item.mData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FillInExternalCustomTypes(item.mData, aIndex, aPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataTransfer::FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aPrincipal)
|
||||||
|
{
|
||||||
|
char* chrs;
|
||||||
|
uint32_t len = 0;
|
||||||
|
nsresult rv = aData->GetAsStringWithSize(&len, &chrs);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString str;
|
||||||
|
str.Adopt(chrs, len);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> stringStream;
|
||||||
|
NS_NewCStringInputStream(getter_AddRefs(stringStream), str);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIBinaryInputStream> stream = do_CreateInstance("@mozilla.org/binaryinputstream;1");
|
||||||
|
stream->SetInputStream(stringStream);
|
||||||
|
if (!stream) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t type;
|
||||||
|
do {
|
||||||
|
stream->Read32(&type);
|
||||||
|
if (type == eCustomClipboardTypeId_String) {
|
||||||
|
uint32_t formatLength;
|
||||||
|
stream->Read32(&formatLength);
|
||||||
|
char* formatBytes;
|
||||||
|
stream->ReadBytes(formatLength, &formatBytes);
|
||||||
|
nsAutoString format;
|
||||||
|
format.Adopt(reinterpret_cast<char16_t*>(formatBytes), formatLength / sizeof(char16_t));
|
||||||
|
|
||||||
|
uint32_t dataLength;
|
||||||
|
stream->Read32(&dataLength);
|
||||||
|
char* dataBytes;
|
||||||
|
stream->ReadBytes(dataLength, &dataBytes);
|
||||||
|
nsAutoString data;
|
||||||
|
data.Adopt(reinterpret_cast<char16_t*>(dataBytes), dataLength / sizeof(char16_t));
|
||||||
|
|
||||||
|
RefPtr<nsVariantCC> variant = new nsVariantCC();
|
||||||
|
variant->SetAsAString(data);
|
||||||
|
|
||||||
|
SetDataWithPrincipal(format, variant, aIndex, aPrincipal);
|
||||||
|
}
|
||||||
|
} while (type != eCustomClipboardTypeId_None);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -218,6 +218,13 @@ public:
|
||||||
uint32_t aIndex,
|
uint32_t aIndex,
|
||||||
nsIPrincipal* aPrincipal);
|
nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
|
// Variation of SetDataWithPrincipal with handles extracting
|
||||||
|
// kCustomTypesMime data into separate types.
|
||||||
|
void SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat,
|
||||||
|
nsIVariant* aData,
|
||||||
|
uint32_t aIndex,
|
||||||
|
nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
// returns a weak reference to the drag image
|
// returns a weak reference to the drag image
|
||||||
Element* GetDragImage(int32_t* aX, int32_t* aY)
|
Element* GetDragImage(int32_t* aX, int32_t* aY)
|
||||||
{
|
{
|
||||||
|
@ -261,6 +268,9 @@ protected:
|
||||||
friend class ContentParent;
|
friend class ContentParent;
|
||||||
void FillAllExternalData();
|
void FillAllExternalData();
|
||||||
|
|
||||||
|
void FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal);
|
||||||
|
void FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||||
mozilla::ErrorResult& aRv);
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
|
|
|
@ -3222,6 +3222,9 @@ ContentChild::RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
|
||||||
if (item.data().type() == IPCDataTransferData::TnsString) {
|
if (item.data().type() == IPCDataTransferData::TnsString) {
|
||||||
const nsString& data = item.data().get_nsString();
|
const nsString& data = item.data().get_nsString();
|
||||||
variant->SetAsAString(data);
|
variant->SetAsAString(data);
|
||||||
|
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
|
||||||
|
const nsCString& data = item.data().get_nsCString();
|
||||||
|
variant->SetAsACString(data);
|
||||||
} else if (item.data().type() == IPCDataTransferData::TPBlobChild) {
|
} else if (item.data().type() == IPCDataTransferData::TPBlobChild) {
|
||||||
BlobChild* blob = static_cast<BlobChild*>(item.data().get_PBlobChild());
|
BlobChild* blob = static_cast<BlobChild*>(item.data().get_PBlobChild());
|
||||||
RefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
RefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
||||||
|
@ -3229,8 +3232,8 @@ ContentChild::RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dataTransfer->SetDataWithPrincipal(NS_ConvertUTF8toUTF16(item.flavor()),
|
dataTransfer->SetDataWithPrincipalFromOtherProcess(
|
||||||
variant, i,
|
NS_ConvertUTF8toUTF16(item.flavor()), variant, i,
|
||||||
nsContentUtils::GetSystemPrincipal());
|
nsContentUtils::GetSystemPrincipal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3142,8 +3142,8 @@ TabParent::AddInitialDnDDataTo(DataTransfer* aDataTransfer)
|
||||||
auto* parent = static_cast<BlobParent*>(item.data().get_PBlobParent());
|
auto* parent = static_cast<BlobParent*>(item.data().get_PBlobParent());
|
||||||
RefPtr<BlobImpl> impl = parent->GetBlobImpl();
|
RefPtr<BlobImpl> impl = parent->GetBlobImpl();
|
||||||
variant->SetAsISupports(impl);
|
variant->SetAsISupports(impl);
|
||||||
} else if (item.data().type() == IPCDataTransferData::TnsCString &&
|
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
|
||||||
nsContentUtils::IsFlavorImage(item.flavor())) {
|
if (nsContentUtils::IsFlavorImage(item.flavor())) {
|
||||||
// An image! Get the imgIContainer for it and set it in the variant.
|
// An image! Get the imgIContainer for it and set it in the variant.
|
||||||
nsCOMPtr<imgIContainer> imageContainer;
|
nsCOMPtr<imgIContainer> imageContainer;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
|
@ -3153,11 +3153,14 @@ TabParent::AddInitialDnDDataTo(DataTransfer* aDataTransfer)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
variant->SetAsISupports(imageContainer);
|
variant->SetAsISupports(imageContainer);
|
||||||
|
} else {
|
||||||
|
variant->SetAsACString(item.data().get_nsCString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using system principal here, since once the data is on parent process
|
// Using system principal here, since once the data is on parent process
|
||||||
// side, it can be handled as being from browser chrome or OS.
|
// side, it can be handled as being from browser chrome or OS.
|
||||||
aDataTransfer->SetDataWithPrincipal(NS_ConvertUTF8toUTF16(item.flavor()),
|
aDataTransfer->SetDataWithPrincipalFromOtherProcess(NS_ConvertUTF8toUTF16(item.flavor()),
|
||||||
variant, i,
|
variant, i,
|
||||||
nsContentUtils::GetSystemPrincipal());
|
nsContentUtils::GetSystemPrincipal());
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,7 +453,7 @@ function test_input_copypaste_dataTransfer_multiple() {
|
||||||
ok(exh, "exception occured mozClearDataAt 1");
|
ok(exh, "exception occured mozClearDataAt 1");
|
||||||
|
|
||||||
cd.setData("text/x-moz-url", "http://www.mozilla.org");
|
cd.setData("text/x-moz-url", "http://www.mozilla.org");
|
||||||
cd.mozSetDataAt("text/x-custom", "Custom Text", 0);
|
cd.mozSetDataAt("text/x-custom", "Custom Text with \u0000 null", 0);
|
||||||
is(cd.mozItemCount, 1, "mozItemCount after set multiple types");
|
is(cd.mozItemCount, 1, "mozItemCount after set multiple types");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -479,9 +479,16 @@ function test_input_copypaste_dataTransfer_multiple() {
|
||||||
// disabling the following test. Enable this once bug #840101 is fixed.
|
// disabling the following test. Enable this once bug #840101 is fixed.
|
||||||
if (navigator.appVersion.indexOf("Android") == -1) {
|
if (navigator.appVersion.indexOf("Android") == -1) {
|
||||||
is(cd.getData("text/x-moz-url"), "http://www.mozilla.org", "paste text/x-moz-url multiple types");
|
is(cd.getData("text/x-moz-url"), "http://www.mozilla.org", "paste text/x-moz-url multiple types");
|
||||||
}
|
is(cd.getData("text/x-custom"), "Custom Text with \u0000 null", "paste text/custom multiple types");
|
||||||
// this is empty because only the built-in types are supported at the moment
|
} else {
|
||||||
is(cd.getData("text/x-custom"), "", "paste text/custom multiple types");
|
is(cd.getData("text/x-custom"), "", "paste text/custom multiple types");
|
||||||
|
}
|
||||||
|
|
||||||
|
is(cd.getData("application/x-moz-custom-clipdata"), "", "application/x-moz-custom-clipdata is not present");
|
||||||
|
|
||||||
|
exh = false;
|
||||||
|
try { cd.setData("application/x-moz-custom-clipdata", "Some Data"); } catch (ex) { exh = true; }
|
||||||
|
ok(exh, "exception occured setData with application/x-moz-custom-clipdata");
|
||||||
|
|
||||||
exh = false;
|
exh = false;
|
||||||
try { cd.setData("text/plain", "Text on Paste"); } catch (ex) { exh = true; }
|
try { cd.setData("text/plain", "Text on Paste"); } catch (ex) { exh = true; }
|
||||||
|
|
|
@ -186,6 +186,31 @@ nsClipboard::TransferableFromPasteboard(nsITransferable *aTransferable, NSPasteb
|
||||||
free(clipboardDataPtr);
|
free(clipboardDataPtr);
|
||||||
break;
|
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) ||
|
else if (flavorStr.EqualsLiteral(kJPEGImageMime) ||
|
||||||
flavorStr.EqualsLiteral(kJPGImageMime) ||
|
flavorStr.EqualsLiteral(kJPGImageMime) ||
|
||||||
flavorStr.EqualsLiteral(kPNGImageMime) ||
|
flavorStr.EqualsLiteral(kPNGImageMime) ||
|
||||||
|
@ -367,6 +392,12 @@ nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength,
|
||||||
*outResult = true;
|
*outResult = true;
|
||||||
break;
|
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) ||
|
} else if (!strcmp(aFlavorList[i], kJPEGImageMime) ||
|
||||||
!strcmp(aFlavorList[i], kJPGImageMime) ||
|
!strcmp(aFlavorList[i], kJPGImageMime) ||
|
||||||
!strcmp(aFlavorList[i], kPNGImageMime) ||
|
!strcmp(aFlavorList[i], kPNGImageMime) ||
|
||||||
|
@ -447,6 +478,20 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
||||||
|
|
||||||
free(data);
|
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) ||
|
else if (flavorStr.EqualsLiteral(kPNGImageMime) || flavorStr.EqualsLiteral(kJPEGImageMime) ||
|
||||||
flavorStr.EqualsLiteral(kJPGImageMime) || flavorStr.EqualsLiteral(kGIFImageMime) ||
|
flavorStr.EqualsLiteral(kJPGImageMime) || flavorStr.EqualsLiteral(kGIFImageMime) ||
|
||||||
flavorStr.EqualsLiteral(kNativeImageMime)) {
|
flavorStr.EqualsLiteral(kNativeImageMime)) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ extern NSString* const kWildcardPboardType;
|
||||||
extern NSString* const kCorePboardType_url;
|
extern NSString* const kCorePboardType_url;
|
||||||
extern NSString* const kCorePboardType_urld;
|
extern NSString* const kCorePboardType_urld;
|
||||||
extern NSString* const kCorePboardType_urln;
|
extern NSString* const kCorePboardType_urln;
|
||||||
|
extern NSString* const kCustomTypesPboardType;
|
||||||
|
|
||||||
class nsDragService : public nsBaseDragService
|
class nsDragService : public nsBaseDragService
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@ NSString* const kCorePboardType_url = @"CorePasteboardFlavorType 0x75726C20"; /
|
||||||
NSString* const kCorePboardType_urld = @"CorePasteboardFlavorType 0x75726C64"; // 'urld' desc
|
NSString* const kCorePboardType_urld = @"CorePasteboardFlavorType 0x75726C64"; // 'urld' desc
|
||||||
NSString* const kCorePboardType_urln = @"CorePasteboardFlavorType 0x75726C6E"; // 'urln' title
|
NSString* const kCorePboardType_urln = @"CorePasteboardFlavorType 0x75726C6E"; // 'urln' title
|
||||||
NSString* const kUTTypeURLName = @"public.url-name";
|
NSString* const kUTTypeURLName = @"public.url-name";
|
||||||
|
NSString* const kCustomTypesPboardType = @"org.mozilla.custom-clipdata";
|
||||||
|
|
||||||
nsDragService::nsDragService()
|
nsDragService::nsDragService()
|
||||||
{
|
{
|
||||||
|
@ -110,7 +111,8 @@ static nsresult SetUpDragClipboard(nsISupportsArray* aTransferableArray)
|
||||||
[dragPBoard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
|
[dragPBoard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
|
||||||
forType:currentKey];
|
forType:currentKey];
|
||||||
}
|
}
|
||||||
else if (currentKey == NSTIFFPboardType) {
|
else if (currentKey == NSTIFFPboardType ||
|
||||||
|
currentKey == kCustomTypesPboardType) {
|
||||||
[dragPBoard setData:currentValue forType:currentKey];
|
[dragPBoard setData:currentValue forType:currentKey];
|
||||||
}
|
}
|
||||||
else if (currentKey == NSFilesPromisePboardType ||
|
else if (currentKey == NSFilesPromisePboardType ||
|
||||||
|
@ -474,6 +476,31 @@ nsDragService::GetData(nsITransferable* aTransferable, uint32_t aItemIndex)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (flavorStr.EqualsLiteral(kCustomTypesMime)) {
|
||||||
|
NSString* availableType = [item availableTypeFromArray:[NSArray arrayWithObject:kCustomTypesPboardType]];
|
||||||
|
if (!availableType || !IsValidType(availableType, false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NSData *pasteboardData = [item dataForType:availableType];
|
||||||
|
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, sizeof(nsIInputStream*));
|
||||||
|
free(clipboardDataPtr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
NSString* pString = nil;
|
NSString* pString = nil;
|
||||||
if (flavorStr.EqualsLiteral(kUnicodeMime)) {
|
if (flavorStr.EqualsLiteral(kUnicodeMime)) {
|
||||||
|
@ -610,7 +637,10 @@ nsDragService::IsDataFlavorSupported(const char *aDataFlavor, bool *_retval)
|
||||||
type = (const NSString*)kUTTypeURLName;
|
type = (const NSString*)kUTTypeURLName;
|
||||||
} else if (dataFlavor.EqualsLiteral(kRTFMime)) {
|
} else if (dataFlavor.EqualsLiteral(kRTFMime)) {
|
||||||
type = (const NSString*)kUTTypeRTF;
|
type = (const NSString*)kUTTypeRTF;
|
||||||
|
} else if (dataFlavor.EqualsLiteral(kCustomTypesMime)) {
|
||||||
|
type = (const NSString*)kCustomTypesPboardType;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* availableType = [globalDragPboard availableTypeFromArray:[NSArray arrayWithObjects:(id)type, nil]];
|
NSString* availableType = [globalDragPboard availableTypeFromArray:[NSArray arrayWithObjects:(id)type, nil]];
|
||||||
if (availableType && IsValidType(availableType, allowFileURL)) {
|
if (availableType && IsValidType(availableType, allowFileURL)) {
|
||||||
*_retval = true;
|
*_retval = true;
|
||||||
|
|
|
@ -970,12 +970,14 @@ nsDragService::GetData(nsITransferable * aTransferable,
|
||||||
} // else we try one last ditch effort to find our data
|
} // else we try one last ditch effort to find our data
|
||||||
|
|
||||||
if (dataFound) {
|
if (dataFound) {
|
||||||
|
if (strcmp(flavorStr, kCustomTypesMime) != 0) {
|
||||||
// the DOM only wants LF, so convert from MacOS line endings
|
// the DOM only wants LF, so convert from MacOS line endings
|
||||||
// to DOM line endings.
|
// to DOM line endings.
|
||||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(
|
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(
|
||||||
flavorStr,
|
flavorStr,
|
||||||
&mTargetDragData,
|
&mTargetDragData,
|
||||||
reinterpret_cast<int*>(&mTargetDragDataLen));
|
reinterpret_cast<int*>(&mTargetDragDataLen));
|
||||||
|
}
|
||||||
|
|
||||||
// put it into the transferable.
|
// put it into the transferable.
|
||||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||||
|
|
|
@ -93,7 +93,8 @@ nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboar
|
||||||
rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*));
|
rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else if (flavor.EqualsLiteral(kNativeHTMLMime) ||
|
} else if (flavor.EqualsLiteral(kNativeHTMLMime) ||
|
||||||
flavor.EqualsLiteral(kRTFMime)) {
|
flavor.EqualsLiteral(kRTFMime) ||
|
||||||
|
flavor.EqualsLiteral(kCustomTypesMime)) {
|
||||||
nsCOMPtr<nsISupportsCString> dataWrapper =
|
nsCOMPtr<nsISupportsCString> dataWrapper =
|
||||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
|
@ -49,6 +49,8 @@ interface nsIDOMNode;
|
||||||
// a synthetic flavor, put into the transferable once we know the destination directory of a file drag
|
// a synthetic flavor, put into the transferable once we know the destination directory of a file drag
|
||||||
#define kFilePromiseDirectoryMime "application/x-moz-file-promise-dir"
|
#define kFilePromiseDirectoryMime "application/x-moz-file-promise-dir"
|
||||||
|
|
||||||
|
#define kCustomTypesMime "application/x-moz-custom-clipdata"
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ nsPrimitiveHelpers :: CreatePrimitiveForData ( const char* aFlavor, const void*
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( strcmp(aFlavor,kTextMime) == 0 || strcmp(aFlavor,kNativeHTMLMime) == 0 ||
|
if ( strcmp(aFlavor,kTextMime) == 0 || strcmp(aFlavor,kNativeHTMLMime) == 0 ||
|
||||||
strcmp(aFlavor,kRTFMime) == 0) {
|
strcmp(aFlavor,kRTFMime) == 0 || strcmp(aFlavor,kCustomTypesMime) == 0) {
|
||||||
nsCOMPtr<nsISupportsCString> primitive =
|
nsCOMPtr<nsISupportsCString> primitive =
|
||||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
||||||
if ( primitive ) {
|
if ( primitive ) {
|
||||||
|
@ -133,7 +133,7 @@ nsPrimitiveHelpers :: CreateDataFromPrimitive ( const char* aFlavor, nsISupports
|
||||||
|
|
||||||
*aDataBuff = nullptr;
|
*aDataBuff = nullptr;
|
||||||
|
|
||||||
if ( strcmp(aFlavor,kTextMime) == 0 ) {
|
if ( strcmp(aFlavor,kTextMime) == 0 || strcmp(aFlavor,kCustomTypesMime) == 0) {
|
||||||
nsCOMPtr<nsISupportsCString> plainText ( do_QueryInterface(aPrimitive) );
|
nsCOMPtr<nsISupportsCString> plainText ( do_QueryInterface(aPrimitive) );
|
||||||
if ( plainText ) {
|
if ( plainText ) {
|
||||||
nsAutoCString data;
|
nsAutoCString data;
|
||||||
|
|
|
@ -42,6 +42,7 @@ PRLogModuleInfo* gWin32ClipboardLog = nullptr;
|
||||||
|
|
||||||
// oddly, this isn't in the MSVC headers anywhere.
|
// oddly, this isn't in the MSVC headers anywhere.
|
||||||
UINT nsClipboard::CF_HTML = ::RegisterClipboardFormatW(L"HTML Format");
|
UINT nsClipboard::CF_HTML = ::RegisterClipboardFormatW(L"HTML Format");
|
||||||
|
UINT nsClipboard::CF_CUSTOMTYPES = ::RegisterClipboardFormatW(L"application/x-moz-custom-clipdata");
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
@ -108,6 +109,8 @@ UINT nsClipboard::GetFormat(const char* aMimeStr, bool aMapHTMLMime)
|
||||||
else if (strcmp(aMimeStr, kNativeHTMLMime) == 0 ||
|
else if (strcmp(aMimeStr, kNativeHTMLMime) == 0 ||
|
||||||
aMapHTMLMime && strcmp(aMimeStr, kHTMLMime) == 0)
|
aMapHTMLMime && strcmp(aMimeStr, kHTMLMime) == 0)
|
||||||
format = CF_HTML;
|
format = CF_HTML;
|
||||||
|
else if (strcmp(aMimeStr, kCustomTypesMime) == 0)
|
||||||
|
format = CF_CUSTOMTYPES;
|
||||||
else
|
else
|
||||||
format = ::RegisterClipboardFormatW(NS_ConvertASCIItoUTF16(aMimeStr).get());
|
format = ::RegisterClipboardFormatW(NS_ConvertASCIItoUTF16(aMimeStr).get());
|
||||||
|
|
||||||
|
@ -534,6 +537,9 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
|
||||||
// do that in FindPlatformHTML(). For now, return the allocLen. This
|
// do that in FindPlatformHTML(). For now, return the allocLen. This
|
||||||
// case is mostly to ensure we don't try to call strlen on the buffer.
|
// case is mostly to ensure we don't try to call strlen on the buffer.
|
||||||
*aLen = allocLen;
|
*aLen = allocLen;
|
||||||
|
} else if (fe.cfFormat == CF_CUSTOMTYPES) {
|
||||||
|
// Binary data
|
||||||
|
*aLen = allocLen;
|
||||||
} else if (fe.cfFormat == preferredDropEffect) {
|
} else if (fe.cfFormat == preferredDropEffect) {
|
||||||
// As per the MSDN doc entitled: "Shell Clipboard Formats"
|
// As per the MSDN doc entitled: "Shell Clipboard Formats"
|
||||||
// CFSTR_PREFERREDDROPEFFECT should return a DWORD
|
// CFSTR_PREFERREDDROPEFFECT should return a DWORD
|
||||||
|
@ -682,6 +688,8 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
||||||
NS_IF_RELEASE(imageStream);
|
NS_IF_RELEASE(imageStream);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Treat custom types as a string of bytes.
|
||||||
|
if (strcmp(flavorStr, kCustomTypesMime) != 0) {
|
||||||
// we probably have some form of text. The DOM only wants LF, so convert from Win32 line
|
// we probably have some form of text. The DOM only wants LF, so convert from Win32 line
|
||||||
// endings to DOM line endings.
|
// endings to DOM line endings.
|
||||||
int32_t signedLen = static_cast<int32_t>(dataLen);
|
int32_t signedLen = static_cast<int32_t>(dataLen);
|
||||||
|
@ -693,6 +701,7 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
||||||
if (dataLen > 0 && static_cast<char*>(data)[dataLen - 1] == '\0')
|
if (dataLen > 0 && static_cast<char*>(data)[dataLen - 1] == '\0')
|
||||||
dataLen--;
|
dataLen--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
|
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
|
||||||
free(data);
|
free(data);
|
||||||
|
|
|
@ -60,6 +60,7 @@ public:
|
||||||
static UINT GetFormat(const char* aMimeStr, bool aMapHTMLMime = true);
|
static UINT GetFormat(const char* aMimeStr, bool aMapHTMLMime = true);
|
||||||
|
|
||||||
static UINT CF_HTML;
|
static UINT CF_HTML;
|
||||||
|
static UINT CF_CUSTOMTYPES;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NS_IMETHOD SetNativeClipboardData ( int32_t aWhichClipboard ) override;
|
NS_IMETHOD SetNativeClipboardData ( int32_t aWhichClipboard ) override;
|
||||||
|
|
|
@ -1328,7 +1328,7 @@ HRESULT nsDataObj::GetText(const nsACString & aDataFlavor, FORMATETC& aFE, STGME
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if ( aFE.cfFormat != nsClipboard::CF_CUSTOMTYPES ) {
|
||||||
// we assume that any data that isn't caught above is unicode. This may
|
// we assume that any data that isn't caught above is unicode. This may
|
||||||
// be an erroneous assumption, but is true so far.
|
// be an erroneous assumption, but is true so far.
|
||||||
allocLen += sizeof(char16_t);
|
allocLen += sizeof(char16_t);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче