author | Andrea Marchesini <amarchesini@mozilla.com> |
Fri, 22 Apr 2016 15:53:20 +0200 | |
changeset 294467 | 50dd2630d804c1a11778d8e44bced4f855338179 |
parent 294466 | 46ac1843cd89aa95ce8b6f0e97db82d7cb997e8e |
child 294491 | 56d0b315df5f0748becbc7a02168b53f0068d1e0 |
push id | 75555 |
push user | amarchesini@mozilla.com |
push date | Fri, 22 Apr 2016 13:53:34 +0000 |
treeherder | mozilla-inbound@50dd2630d804 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwatt |
bugs | 1266702 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/events/DataTransfer.cpp | file | annotate | diff | comparison | revisions | |
dom/events/DataTransfer.h | file | annotate | diff | comparison | revisions |
--- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -203,18 +203,19 @@ DataTransfer::GetDropEffect(nsAString& a NS_IMETHODIMP DataTransfer::SetDropEffect(const nsAString& aDropEffect) { // the drop effect can only be 'none', 'copy', 'move' or 'link'. for (uint32_t e = 0; e <= nsIDragService::DRAGDROP_ACTION_LINK; e++) { if (aDropEffect.EqualsASCII(sEffects[e])) { // don't allow copyMove if (e != (nsIDragService::DRAGDROP_ACTION_COPY | - nsIDragService::DRAGDROP_ACTION_MOVE)) + nsIDragService::DRAGDROP_ACTION_MOVE)) { mDropEffect = e; + } break; } } return NS_OK; } NS_IMETHODIMP @@ -308,28 +309,30 @@ DataTransfer::GetFileListInternal(ErrorR mFileList = new FileList(static_cast<nsIDOMDataTransfer*>(this)); uint32_t count = mItems.Length(); for (uint32_t i = 0; i < count; i++) { nsCOMPtr<nsIVariant> variant; aRv = GetDataAtInternal(NS_ConvertUTF8toUTF16(kFileMime), i, aSubjectPrincipal, getter_AddRefs(variant)); - if (aRv.Failed()) { + if (NS_WARN_IF(aRv.Failed())) { return nullptr; } - if (!variant) + if (!variant) { continue; + } nsCOMPtr<nsISupports> supports; nsresult rv = variant->GetAsISupports(getter_AddRefs(supports)); - if (NS_FAILED(rv)) + if (NS_WARN_IF(NS_FAILED(rv))) { continue; + } nsCOMPtr<nsIFile> file = do_QueryInterface(supports); RefPtr<File> domFile; if (file) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default, "nsIFile objects are not expected on the content process"); @@ -362,22 +365,23 @@ DataTransfer::GetFileListInternal(ErrorR return mFileList; } NS_IMETHODIMP DataTransfer::GetFiles(nsIDOMFileList** aFileList) { ErrorResult rv; - NS_IF_ADDREF(*aFileList = GetFileListInternal(rv, nsContentUtils::GetSystemPrincipal())); + NS_IF_ADDREF(*aFileList = + GetFileListInternal(rv, nsContentUtils::GetSystemPrincipal())); return rv.StealNSResult(); } already_AddRefed<DOMStringList> -DataTransfer::Types() +DataTransfer::Types() const { RefPtr<DOMStringList> types = new DOMStringList(); if (mItems.Length()) { bool addFile = false; const nsTArray<TransferItem>& item = mItems[0]; for (uint32_t i = 0; i < item.Length(); i++) { const nsString& format = item[i].mFormat; types->Add(format); @@ -407,17 +411,19 @@ DataTransfer::GetTypes(nsISupports** aTy void DataTransfer::GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv) { // return an empty string if data for the format was not found aData.Truncate(); nsCOMPtr<nsIVariant> data; - nsresult rv = GetDataAtInternal(aFormat, 0, nsContentUtils::SubjectPrincipal(), getter_AddRefs(data)); + nsresult rv = + GetDataAtInternal(aFormat, 0, nsContentUtils::SubjectPrincipal(), + getter_AddRefs(data)); if (NS_FAILED(rv)) { if (rv != NS_ERROR_DOM_INDEX_SIZE_ERR) { aRv.Throw(rv); } return; } if (data) { @@ -431,25 +437,28 @@ DataTransfer::GetData(const nsAString& a if (lowercaseFormat.EqualsLiteral("url")) { int32_t lastidx = 0, idx; int32_t length = stringdata.Length(); while (lastidx < length) { idx = stringdata.FindChar('\n', lastidx); // lines beginning with # are comments if (stringdata[lastidx] == '#') { - if (idx == -1) + if (idx == -1) { break; + } } else { - if (idx == -1) + if (idx == -1) { aData.Assign(Substring(stringdata, lastidx)); - else + } else { aData.Assign(Substring(stringdata, lastidx, idx - lastidx)); - aData = nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(aData, true); + } + aData = nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(aData, + true); return; } lastidx = idx + 1; } } else { aData = stringdata; } @@ -466,17 +475,18 @@ DataTransfer::GetData(const nsAString& a void DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData, ErrorResult& aRv) { RefPtr<nsVariantCC> variant = new nsVariantCC(); variant->SetAsAString(aData); - aRv = SetDataAtInternal(aFormat, variant, 0, nsContentUtils::SubjectPrincipal()); + aRv = SetDataAtInternal(aFormat, variant, 0, + nsContentUtils::SubjectPrincipal()); } void DataTransfer::ClearData(const Optional<nsAString>& aFormat, ErrorResult& aRv) { if (mReadOnly) { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return; @@ -569,47 +579,52 @@ DataTransfer::MozTypesAt(uint32_t aIndex aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return nullptr; } RefPtr<DOMStringList> types = new DOMStringList(); if (aIndex < mItems.Length()) { // note that you can retrieve the types regardless of their principal nsTArray<TransferItem>& item = mItems[aIndex]; - for (uint32_t i = 0; i < item.Length(); i++) + for (uint32_t i = 0; i < item.Length(); i++) { types->Add(item[i].mFormat); + } } return types.forget(); } NS_IMETHODIMP DataTransfer::MozTypesAt(uint32_t aIndex, nsISupports** aTypes) { ErrorResult rv; RefPtr<DOMStringList> types = MozTypesAt(aIndex, rv); types.forget(aTypes); return rv.StealNSResult(); } nsresult -DataTransfer::GetDataAtNoSecurityCheck(const nsAString& aFormat, uint32_t aIndex, +DataTransfer::GetDataAtNoSecurityCheck(const nsAString& aFormat, + uint32_t aIndex, nsIVariant** aData) { - return GetDataAtInternal(aFormat, aIndex, nsContentUtils::GetSystemPrincipal(), aData); + return GetDataAtInternal(aFormat, aIndex, + nsContentUtils::GetSystemPrincipal(), aData); } nsresult DataTransfer::GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex, - nsIPrincipal* aSubjectPrincipal, nsIVariant** aData) + nsIPrincipal* aSubjectPrincipal, + nsIVariant** aData) { *aData = nullptr; - if (aFormat.IsEmpty()) + if (aFormat.IsEmpty()) { return NS_OK; + } if (aIndex >= mItems.Length()) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } // Only the first item is valid for clipboard events if (aIndex > 0 && (mEventMessage == eCut || mEventMessage == eCopy || @@ -654,17 +669,18 @@ DataTransfer::GetDataAtInternal(const ns nsIScriptContext* c = pt->GetContextForEventHandlers(&rv); NS_ENSURE_TRUE(c && NS_SUCCEEDED(rv), NS_ERROR_DOM_SECURITY_ERR); nsIGlobalObject* go = c->GetGlobalObject(); NS_ENSURE_TRUE(go, NS_ERROR_DOM_SECURITY_ERR); nsCOMPtr<nsIScriptObjectPrincipal> sp = do_QueryInterface(go); MOZ_ASSERT(sp, "This cannot fail on the main thread."); nsIPrincipal* dataPrincipal = sp->GetPrincipal(); NS_ENSURE_TRUE(dataPrincipal, NS_ERROR_DOM_SECURITY_ERR); - NS_ENSURE_TRUE(aSubjectPrincipal->Subsumes(dataPrincipal), NS_ERROR_DOM_SECURITY_ERR); + NS_ENSURE_TRUE(aSubjectPrincipal->Subsumes(dataPrincipal), + NS_ERROR_DOM_SECURITY_ERR); } } *aData = formatitem.mData; NS_IF_ADDREF(*aData); return NS_OK; } } @@ -673,17 +689,18 @@ DataTransfer::GetDataAtInternal(const ns void DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat, uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aRv) { nsCOMPtr<nsIVariant> data; - aRv = GetDataAtInternal(aFormat, aIndex, nsContentUtils::SubjectPrincipal(), getter_AddRefs(data)); + aRv = GetDataAtInternal(aFormat, aIndex, nsContentUtils::SubjectPrincipal(), + getter_AddRefs(data)); if (aRv.Failed()) { return; } if (!data) { aRetval.setNull(); return; } @@ -692,17 +709,18 @@ DataTransfer::MozGetDataAt(JSContext* aC if (!VariantToJsval(aCx, data, aRetval)) { aRv = NS_ERROR_FAILURE; return; } } nsresult DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData, - uint32_t aIndex, nsIPrincipal* aSubjectPrincipal) + uint32_t aIndex, + nsIPrincipal* aSubjectPrincipal) { if (aFormat.IsEmpty()) { return NS_OK; } if (mReadOnly) { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; } @@ -748,17 +766,18 @@ void DataTransfer::MozSetDataAt(JSContext* aCx, const nsAString& aFormat, JS::Handle<JS::Value> aData, uint32_t aIndex, ErrorResult& aRv) { nsCOMPtr<nsIVariant> data; aRv = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData, getter_AddRefs(data)); if (!aRv.Failed()) { - aRv = SetDataAtInternal(aFormat, data, aIndex, nsContentUtils::SubjectPrincipal()); + aRv = SetDataAtInternal(aFormat, data, aIndex, + nsContentUtils::SubjectPrincipal()); } } void DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex, ErrorResult& aRv) { if (mReadOnly) { @@ -804,33 +823,36 @@ DataTransfer::MozClearDataAtHelper(const // count backwards so that the count and index don't have to be adjusted // after removing an element for (int32_t i = item.Length() - 1; i >= 0; i--) { TransferItem& formatitem = item[i]; if (clearall || formatitem.mFormat.Equals(format)) { // don't allow removing data that has a stronger principal bool subsumes; if (formatitem.mPrincipal && principal && - (NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes)) { + (NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || + !subsumes)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } item.RemoveElementAt(i); // if a format was specified, break out. Otherwise, loop around until // all formats have been removed - if (!clearall) + if (!clearall) { break; + } } } // if the last format for an item is removed, remove the entire item - if (!item.Length()) + if (!item.Length()) { mItems.RemoveElementAt(aIndex); + } } NS_IMETHODIMP DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex) { ErrorResult rv; MozClearDataAt(aFormat, aIndex, rv); return rv.StealNSResult(); @@ -1001,40 +1023,44 @@ DataTransfer::GetTransferable(uint32_t a nsCOMPtr<nsIStorageStream> storageStream; nsCOMPtr<nsIBinaryOutputStream> stream; 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 }; + 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. + * 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 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: + * 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. + * A type of eCustomClipboardTypeId_None ends the list, without any following + * data. */ do { for (uint32_t f = 0; f < count; f++) { const TransferItem& formatitem = item[f]; if (!formatitem.mData) { // skip empty items continue; } @@ -1046,114 +1072,129 @@ DataTransfer::GetTransferable(uint32_t a break; } } uint32_t lengthInBytes; nsCOMPtr<nsISupports> convertedData; if (handlingCustomFormats) { - if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), &lengthInBytes)) { + if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), + &lengthInBytes)) { continue; } // 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. + // 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); + 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->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); + // 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); + RefPtr<nsStringBuffer> stringBuffer = + nsStringBuffer::Alloc(totalCustomLength + 1); - // Read the data from the string and add a null-terminator as ToString needs it. + // 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); + 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)); + nsCOMPtr<nsISupportsCString> + strSupports(do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID)); strSupports->SetData(str); - nsresult rv = transferable->SetTransferData(kCustomTypesMime, strSupports, totalCustomLength); + 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)) { + if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), + &lengthInBytes)) { continue; } - // The underlying drag code uses text/unicode, so use that instead of text/plain + // The underlying drag code uses text/unicode, so use that instead of + // text/plain const char* format; NS_ConvertUTF16toUTF8 utf8format(formatitem.mFormat); if (utf8format.EqualsLiteral(kTextMime)) { format = kUnicodeMime; } else { format = utf8format.get(); } // If a converter is set for a format, set the converter for the // transferable and don't add the item - nsCOMPtr<nsIFormatConverter> converter = do_QueryInterface(convertedData); + nsCOMPtr<nsIFormatConverter> converter = + do_QueryInterface(convertedData); if (converter) { transferable->AddDataFlavor(format); transferable->SetConverter(converter); continue; } - nsresult rv = transferable->SetTransferData(format, convertedData, lengthInBytes); + nsresult rv = transferable->SetTransferData(format, convertedData, + lengthInBytes); if (NS_FAILED(rv)) { return nullptr; } added = true; } } @@ -1166,65 +1207,69 @@ DataTransfer::GetTransferable(uint32_t a } return nullptr; } bool DataTransfer::ConvertFromVariant(nsIVariant* aVariant, nsISupports** aSupports, - uint32_t* aLength) + uint32_t* aLength) const { *aSupports = nullptr; *aLength = 0; uint16_t type; aVariant->GetDataType(&type); if (type == nsIDataType::VTYPE_INTERFACE || type == nsIDataType::VTYPE_INTERFACE_IS) { nsCOMPtr<nsISupports> data; - if (NS_FAILED(aVariant->GetAsISupports(getter_AddRefs(data)))) - return false; + if (NS_FAILED(aVariant->GetAsISupports(getter_AddRefs(data)))) { + return false; + } nsCOMPtr<nsIFlavorDataProvider> fdp = do_QueryInterface(data); if (fdp) { // for flavour data providers, use kFlavorHasDataProvider (which has the // value 0) as the length. fdp.forget(aSupports); *aLength = nsITransferable::kFlavorHasDataProvider; } else { // wrap the item in an nsISupportsInterfacePointer nsCOMPtr<nsISupportsInterfacePointer> ptrSupports = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID); - if (!ptrSupports) + if (!ptrSupports) { return false; + } ptrSupports->SetData(data); ptrSupports.forget(aSupports); *aLength = sizeof(nsISupportsInterfacePointer *); } return true; } char16_t* chrs; uint32_t len = 0; nsresult rv = aVariant->GetAsWStringWithSize(&len, &chrs); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { return false; + } nsAutoString str; str.Adopt(chrs, len); nsCOMPtr<nsISupportsString> strSupports(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); - if (!strSupports) + if (!strSupports) { return false; + } strSupports->SetData(str); strSupports.forget(aSupports); // each character is two bytes *aLength = str.Length() << 1; @@ -1253,18 +1298,20 @@ DataTransfer::SetDataWithPrincipal(const nsTArray<TransferItem>& item = mItems[aIndex]; uint32_t count = item.Length(); for (uint32_t i = 0; i < count; i++) { TransferItem& itemformat = item[i]; if (itemformat.mFormat.Equals(format)) { // don't allow replacing data that has a stronger principal bool subsumes; if (itemformat.mPrincipal && aPrincipal && - (NS_FAILED(aPrincipal->Subsumes(itemformat.mPrincipal, &subsumes)) || !subsumes)) + (NS_FAILED(aPrincipal->Subsumes(itemformat.mPrincipal, + &subsumes)) || !subsumes)) { return NS_ERROR_DOM_SECURITY_ERR; + } itemformat.mPrincipal = aPrincipal; itemformat.mData = aData; return NS_OK; } } // add a new format @@ -1298,54 +1345,69 @@ DataTransfer::SetDataWithPrincipalFromOt if (aFormat.EqualsLiteral(kCustomTypesMime)) { FillInExternalCustomTypes(aData, aIndex, aPrincipal); } else { SetDataWithPrincipal(aFormat, aData, aIndex, aPrincipal); } } void -DataTransfer::GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat) +DataTransfer::GetRealFormat(const nsAString& aInFormat, + nsAString& aOutFormat) const { // treat text/unicode as equivalent to text/plain nsAutoString lowercaseFormat; nsContentUtils::ASCIIToLower(aInFormat, lowercaseFormat); - if (lowercaseFormat.EqualsLiteral("text") || lowercaseFormat.EqualsLiteral("text/unicode")) + if (lowercaseFormat.EqualsLiteral("text") || + lowercaseFormat.EqualsLiteral("text/unicode")) { aOutFormat.AssignLiteral("text/plain"); - else if (lowercaseFormat.EqualsLiteral("url")) + return; + } + + if (lowercaseFormat.EqualsLiteral("url")) { aOutFormat.AssignLiteral("text/uri-list"); - else - aOutFormat.Assign(lowercaseFormat); + return; + } + + aOutFormat.Assign(lowercaseFormat); } void -DataTransfer::CacheExternalData(const char* aFormat, uint32_t aIndex, nsIPrincipal* aPrincipal) +DataTransfer::CacheExternalData(const char* aFormat, uint32_t aIndex, + nsIPrincipal* aPrincipal) { if (strcmp(aFormat, kUnicodeMime) == 0) { - SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nullptr, aIndex, aPrincipal); - } else { - if (strcmp(aFormat, kURLDataMime) == 0) { - SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nullptr, aIndex, aPrincipal); - } - SetDataWithPrincipal(NS_ConvertUTF8toUTF16(aFormat), nullptr, aIndex, aPrincipal); + SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nullptr, aIndex, + aPrincipal); + return; } + + if (strcmp(aFormat, kURLDataMime) == 0) { + SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nullptr, aIndex, + aPrincipal); + return; + } + + SetDataWithPrincipal(NS_ConvertUTF8toUTF16(aFormat), nullptr, aIndex, + aPrincipal); } void DataTransfer::CacheExternalDragFormats() { // Called during the constructor to cache the formats available from an // external drag. The data associated with each format will be set to null. // This data will instead only be retrieved in FillInExternalDragData when // asked for, as it may be time consuming for the source application to // generate it. nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession(); - if (!dragSession) + if (!dragSession) { return; + } // make sure that the system principal is used for external drags nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); nsCOMPtr<nsIPrincipal> sysPrincipal; ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); // 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 @@ -1384,17 +1446,18 @@ DataTransfer::CacheExternalClipboardForm { NS_ASSERTION(mEventMessage == ePaste, "caching clipboard data for invalid event"); // Called during the constructor for paste events to cache the formats // available on the clipboard. As with CacheExternalDragFormats, the // data will only be retrieved when needed. - nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1"); + nsCOMPtr<nsIClipboard> clipboard = + do_GetService("@mozilla.org/widget/clipboard;1"); if (!clipboard || mClipboardType < 0) { return; } nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); nsCOMPtr<nsIPrincipal> sysPrincipal; ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); @@ -1402,17 +1465,18 @@ DataTransfer::CacheExternalClipboardForm // all platforms, so just check for the types that can actually be imported. // 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) { // check each format one at a time bool supported; - clipboard->HasDataMatchingFlavors(&(formats[f]), 1, mClipboardType, &supported); + clipboard->HasDataMatchingFlavors(&(formats[f]), 1, mClipboardType, + &supported); // if the format is supported, add an item to the array with null as // the data. When retrieved, GetRealData will read the data. if (supported) { if (f == 0) { FillInExternalCustomTypes(0, sysPrincipal); } else { CacheExternalData(formats[f], 0, sysPrincipal); } @@ -1430,33 +1494,36 @@ DataTransfer::FillInExternalData(Transfe } // only drag and paste events should be calling FillInExternalData NS_ASSERTION(mEventMessage != eCut && mEventMessage != eCopy, "clipboard event with empty data"); NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat); const char* format = utf8format.get(); - if (strcmp(format, "text/plain") == 0) + if (strcmp(format, "text/plain") == 0) { format = kUnicodeMime; - else if (strcmp(format, "text/uri-list") == 0) + } else if (strcmp(format, "text/uri-list") == 0) { format = kURLDataMime; + } nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1"); - if (!trans) + if (!trans) { return; + } trans->Init(nullptr); trans->AddDataFlavor(format); if (mEventMessage == ePaste) { MOZ_ASSERT(aIndex == 0, "index in clipboard must be 0"); - nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1"); + nsCOMPtr<nsIClipboard> clipboard = + do_GetService("@mozilla.org/widget/clipboard;1"); if (!clipboard || mClipboardType < 0) { return; } clipboard->GetData(trans, mClipboardType); } else { nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession(); if (!dragSession) { @@ -1512,68 +1579,73 @@ DataTransfer::FillAllExternalData() FillInExternalData(itemArray[j], i); } } } } } void -DataTransfer::FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal) +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) +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"); + 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)); + 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)); + 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); }
--- a/dom/events/DataTransfer.h +++ b/dom/events/DataTransfer.h @@ -63,17 +63,20 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIDOMDATATRANSFER NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DataTransfer) friend class mozilla::EventStateManager; - static DataTransfer* Cast(nsIDOMDataTransfer* aArg) { return static_cast<DataTransfer*>(aArg); } + static DataTransfer* Cast(nsIDOMDataTransfer* aArg) + { + return static_cast<DataTransfer*>(aArg); + } protected: // hide the default constructor DataTransfer(); // this constructor is used only by the Clone method to copy the fields as // needed to a new data transfer. @@ -98,23 +101,25 @@ public: // Constructor for DataTransfer. // // aIsExternal must only be true when used to create a dataTransfer for a // paste or a drag that was started without using a data transfer. The // latter will occur when an external drag occurs, that is, a drag where the // source is another application, or a drag is started by calling the drag // service directly. For clipboard operations, aClipboardType indicates - // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations, - // or if access to the system clipboard should not be allowed. + // which clipboard to use, from nsIClipboard, or -1 for non-clipboard + // operations, or if access to the system clipboard should not be allowed. DataTransfer(nsISupports* aParent, EventMessage aEventMessage, bool aIsExternal, int32_t aClipboardType); - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; - nsISupports* GetParentObject() + virtual JSObject* + WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; + + nsISupports* GetParentObject() const { return mParent; } void SetParentObject(nsISupports* aNewParent) { MOZ_ASSERT(aNewParent); // Setting the parent after we've been wrapped is pointless, so @@ -126,91 +131,109 @@ public: static already_AddRefed<DataTransfer> Constructor(const GlobalObject& aGlobal, const nsAString& aEventType, bool aIsExternal, ErrorResult& aRv); void GetDropEffect(nsString& aDropEffect) { aDropEffect.AssignASCII(sEffects[mDropEffect]); } + void GetEffectAllowed(nsString& aEffectAllowed) { if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) { aEffectAllowed.AssignLiteral("uninitialized"); } else { aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]); } } + void SetDragImage(Element& aElement, int32_t aX, int32_t aY, ErrorResult& aRv); - already_AddRefed<DOMStringList> Types(); + + already_AddRefed<DOMStringList> Types() const; + void GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv); + void SetData(const nsAString& aFormat, const nsAString& aData, ErrorResult& aRv); + void ClearData(const mozilla::dom::Optional<nsAString>& aFormat, mozilla::ErrorResult& aRv); + FileList* GetFiles(mozilla::ErrorResult& aRv); already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv); void AddElement(Element& aElement, mozilla::ErrorResult& aRv); - uint32_t MozItemCount() + + uint32_t MozItemCount() const { return mItems.Length(); } + void GetMozCursor(nsString& aCursor) { if (mCursorState) { aCursor.AssignLiteral("default"); } else { aCursor.AssignLiteral("auto"); } } + already_AddRefed<DOMStringList> MozTypesAt(uint32_t aIndex, mozilla::ErrorResult& aRv); + void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex, mozilla::ErrorResult& aRv); + void MozSetDataAt(JSContext* aCx, const nsAString& aFormat, JS::Handle<JS::Value> aData, uint32_t aIndex, mozilla::ErrorResult& aRv); + void MozGetDataAt(JSContext* aCx, const nsAString& aFormat, uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval, mozilla::ErrorResult& aRv); - bool MozUserCancelled() + + bool MozUserCancelled() const { return mUserCancelled; } + already_AddRefed<nsINode> GetMozSourceNode(); - mozilla::dom::Element* GetDragTarget() + mozilla::dom::Element* GetDragTarget() const { return mDragTarget; } nsresult GetDataAtNoSecurityCheck(const nsAString& aFormat, uint32_t aIndex, nsIVariant** aData); - // a readonly dataTransfer cannot have new data added or existing data removed. - // Only the dropEffect and effectAllowed may be modified. + // a readonly dataTransfer cannot have new data added or existing data + // removed. Only the dropEffect and effectAllowed may be modified. void SetReadOnly() { mReadOnly = true; } // converts the data into an array of nsITransferable objects to be used for // drag and drop or clipboard operations. already_AddRefed<nsISupportsArray> GetTransferables(nsIDOMNode* aDragTarget); - already_AddRefed<nsISupportsArray> GetTransferables(nsILoadContext* aLoadContext); + + already_AddRefed<nsISupportsArray> + GetTransferables(nsILoadContext* aLoadContext); - // converts the data for a single item at aIndex into an nsITransferable object. - already_AddRefed<nsITransferable> GetTransferable(uint32_t aIndex, - nsILoadContext* aLoadContext); + // converts the data for a single item at aIndex into an nsITransferable + // object. + already_AddRefed<nsITransferable> + GetTransferable(uint32_t aIndex, nsILoadContext* aLoadContext); // converts the data in the variant to an nsISupportString if possible or // an nsISupports or null otherwise. bool ConvertFromVariant(nsIVariant* aVariant, - nsISupports** aSupports, - uint32_t* aLength); + nsISupports** aSupports, + uint32_t* aLength) const; // clears all of the data void ClearAll(); // Similar to SetData except also specifies the principal to store. // aData may be null when called from CacheExternalDragFormats or // CacheExternalClipboardFormats. nsresult SetDataWithPrincipal(const nsAString& aFormat, @@ -221,67 +244,74 @@ public: // 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 - Element* GetDragImage(int32_t* aX, int32_t* aY) + Element* GetDragImage(int32_t* aX, int32_t* aY) const { *aX = mDragImageX; *aY = mDragImageY; return mDragImage; } nsresult Clone(nsISupports* aParent, EventMessage aEventMessage, bool aUserCancelled, bool aIsCrossDomainSubFrameDrop, DataTransfer** aResult); protected: // converts some formats used for compatibility in aInFormat into aOutFormat. // Text and text/unicode become text/plain, and URL becomes text/uri-list - void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat); + void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat) const; // caches text and uri-list data formats that exist in the drag service or // clipboard for retrieval later. - void CacheExternalData(const char* aFormat, uint32_t aIndex, nsIPrincipal* aPrincipal); + void CacheExternalData(const char* aFormat, uint32_t aIndex, + nsIPrincipal* aPrincipal); // caches the formats that exist in the drag service that were added by an // external drag void CacheExternalDragFormats(); // caches the formats that exist in the clipboard void CacheExternalClipboardFormats(); // fills in the data field of aItem with the data from the drag service or // clipboard for a given index. void FillInExternalData(TransferItem& aItem, uint32_t aIndex); - FileList* GetFileListInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal); + FileList* GetFileListInternal(ErrorResult& aRv, + nsIPrincipal* aSubjectPrincipal); + nsresult GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex, - nsIPrincipal* aSubjectPrincipal, nsIVariant** aData); - nsresult SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData, uint32_t aIndex, - nsIPrincipal* aSubjectPrincipal); + nsIPrincipal* aSubjectPrincipal, + nsIVariant** aData); + + nsresult SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData, + uint32_t aIndex, nsIPrincipal* aSubjectPrincipal); friend class ContentParent; + void FillAllExternalData(); void FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal); - void FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aPrincipal); + + void FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex, + nsIPrincipal* aPrincipal); void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex, mozilla::ErrorResult& aRv); nsCOMPtr<nsISupports> mParent; - // the drop effect and effect allowed uint32_t mDropEffect; uint32_t mEffectAllowed; // the event message this data transfer is for. This will correspond to an // event->mMessage value. EventMessage mEventMessage;