diff options
Diffstat (limited to 'toolkit/components/extensions/parent/ext-clipboard.js')
-rw-r--r-- | toolkit/components/extensions/parent/ext-clipboard.js | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/toolkit/components/extensions/parent/ext-clipboard.js b/toolkit/components/extensions/parent/ext-clipboard.js new file mode 100644 index 0000000000..9916b14be7 --- /dev/null +++ b/toolkit/components/extensions/parent/ext-clipboard.js @@ -0,0 +1,87 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +/* 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/. */ + +"use strict"; + +XPCOMUtils.defineLazyServiceGetter( + this, + "imgTools", + "@mozilla.org/image/tools;1", + "imgITools" +); + +const Transferable = Components.Constructor( + "@mozilla.org/widget/transferable;1", + "nsITransferable" +); + +this.clipboard = class extends ExtensionAPI { + getAPI(context) { + return { + clipboard: { + async setImageData(imageData, imageType) { + if (AppConstants.platform == "android") { + return Promise.reject({ + message: + "Writing images to the clipboard is not supported on Android", + }); + } + let img; + try { + img = imgTools.decodeImageFromArrayBuffer( + imageData, + `image/${imageType}` + ); + } catch (e) { + return Promise.reject({ + message: `Data is not a valid ${imageType} image`, + }); + } + + // Other applications can only access the copied image once the data + // is exported via the platform-specific clipboard APIs: + // nsClipboard::SelectionGetEvent (widget/gtk/nsClipboard.cpp) + // nsClipboard::PasteDictFromTransferable (widget/cocoa/nsClipboard.mm) + // nsDataObj::GetDib (widget/windows/nsDataObj.cpp) + // + // The common protocol for exporting a nsITransferable as an image is: + // - Use nsITransferable::GetTransferData to fetch the stored data. + // - QI imgIContainer on the pointer. + // - Convert the image to the native clipboard format. + // + // Below we create a nsITransferable in the above format. + let transferable = new Transferable(); + transferable.init(null); + const kNativeImageMime = "application/x-moz-nativeimage"; + transferable.addDataFlavor(kNativeImageMime); + + // Internal consumers expect the image data to be stored as a + // nsIInputStream. On Linux and Windows, pasted data is directly + // retrieved from the system's native clipboard, and made available + // as a nsIInputStream. + // + // On macOS, nsClipboard::GetNativeClipboardData (nsClipboard.mm) uses + // a cached copy of nsITransferable if available, e.g. when the copy + // was initiated by the same browser instance. To make sure that a + // nsIInputStream is returned instead of the cached imgIContainer, + // the image is exported as as `kNativeImageMime`. Data associated + // with this type is converted to a platform-specific image format + // when written to the clipboard. The type is not used when images + // are read from the clipboard (on all platforms, not just macOS). + // This forces nsClipboard::GetNativeClipboardData to fall back to + // the native clipboard, and return the image as a nsITransferable. + transferable.setTransferData(kNativeImageMime, img); + + Services.clipboard.setData( + transferable, + null, + Services.clipboard.kGlobalClipboard + ); + }, + }, + }; + } +}; |