Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / tests / clipboard_helper.js
blob76ed2aeb378a894f3a871f7e2cdb0304571fe6e7
1 /* Any copyright is dedicated to the Public Domain.
2    http://creativecommons.org/publicdomain/zero/1.0/ */
4 "use strict";
6 const Cc = SpecialPowers.Cc;
7 const Ci = SpecialPowers.Ci;
8 const Cr = SpecialPowers.Cr;
9 const clipboard = SpecialPowers.Services.clipboard;
10 const clipboardTypes = [
11   clipboard.kGlobalClipboard,
12   clipboard.kSelectionClipboard,
13   clipboard.kFindClipboard,
14   clipboard.kSelectionCache,
17 function emptyClipboardData(aType) {
18   // XXX gtk doesn't support emptying clipboard data which is stored from
19   // other application (bug 1853884). As a workaround, we set dummy data
20   // to the clipboard first to ensure the subsequent emptyClipboard call
21   // works.
22   if (navigator.platform.includes("Linux")) {
23     writeStringToClipboard("foo", "text/plain", aType);
24   }
26   clipboard.emptyClipboard(aType);
29 function cleanupAllClipboard() {
30   clipboardTypes.forEach(function (type) {
31     if (clipboard.isClipboardTypeSupported(type)) {
32       info(`cleanup clipboard ${type}`);
33       emptyClipboardData(type);
34     }
35   });
38 function generateRandomString() {
39   return "random number: " + Math.random();
42 function generateNewTransferable(aFlavor, aStr) {
43   let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
44     Ci.nsITransferable
45   );
46   trans.init(null);
47   trans.addDataFlavor(aFlavor);
49   let supportsStr = Cc["@mozilla.org/supports-string;1"].createInstance(
50     Ci.nsISupportsString
51   );
52   supportsStr.data = aStr;
53   trans.setTransferData(aFlavor, supportsStr);
55   return trans;
58 function addStringToTransferable(aFlavor, aStr, aTrans) {
59   aTrans.addDataFlavor(aFlavor);
61   let supportsStr = Cc["@mozilla.org/supports-string;1"].createInstance(
62     Ci.nsISupportsString
63   );
64   supportsStr.data = aStr;
65   aTrans.setTransferData(aFlavor, supportsStr);
68 function updateStringToTransferable(aFlavor, aStr, aTrans) {
69   let supportsStr = Cc["@mozilla.org/supports-string;1"].createInstance(
70     Ci.nsISupportsString
71   );
72   supportsStr.data = aStr;
73   aTrans.setTransferData(aFlavor, supportsStr);
76 function writeStringToClipboard(
77   aStr,
78   aFlavor,
79   aClipboardType,
80   aClipboardOwner = null,
81   aAsync = false
82 ) {
83   let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
84     Ci.nsITransferable
85   );
86   trans.init(null);
87   trans.addDataFlavor(aFlavor);
89   let supportsStr = Cc["@mozilla.org/supports-string;1"].createInstance(
90     Ci.nsISupportsString
91   );
92   supportsStr.data = aStr;
93   trans.setTransferData(aFlavor, supportsStr);
95   if (aAsync) {
96     let request = clipboard.asyncSetData(aClipboardType);
97     request.setData(trans, aClipboardOwner);
98     return;
99   }
101   clipboard.setData(trans, aClipboardOwner, aClipboardType);
102   // XXX gtk doesn't support get empty text data from clipboard, bug 1852983.
103   if (aStr == "" && navigator.platform.includes("Linux")) {
104     todo_is(
105       getClipboardData(aFlavor, aClipboardType),
106       "",
107       `Should get empty string on clipboard type ${aClipboardType}`
108     );
109   } else {
110     is(
111       getClipboardData(aFlavor, aClipboardType),
112       // On Windows, widget adds extra data into HTML clipboard.
113       aFlavor == "text/html" && navigator.platform.includes("Win")
114         ? `<html><body>\n<!--StartFragment-->${aStr}<!--EndFragment-->\n</body>\n</html>`
115         : aStr,
116       "ensure clipboard data is set"
117     );
118   }
121 function writeRandomStringToClipboard(
122   aFlavor,
123   aClipboardType,
124   aClipboardOwner = null,
125   aAsync = false
126 ) {
127   let randomString = generateRandomString();
128   writeStringToClipboard(
129     randomString,
130     aFlavor,
131     aClipboardType,
132     aClipboardOwner,
133     aAsync
134   );
135   return randomString;
138 function getClipboardData(aFlavor, aClipboardType) {
139   var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
140     Ci.nsITransferable
141   );
142   trans.init(null);
143   trans.addDataFlavor(aFlavor);
144   clipboard.getData(
145     trans,
146     aClipboardType,
147     SpecialPowers.wrap(window).browsingContext.currentWindowContext
148   );
150   try {
151     var data = SpecialPowers.createBlankObject();
152     trans.getTransferData(aFlavor, data);
153     return data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data;
154   } catch (ex) {
155     // If the clipboard is empty getTransferData will throw.
156     return null;
157   }
160 function getClipboardDataSnapshotSync(aClipboardType) {
161   return clipboard.getDataSnapshotSync(
162     ["text/plain", "text/html", "image/png"],
163     aClipboardType
164   );
167 function asyncGetClipboardData(
168   aClipboardType,
169   aFormats = ["text/plain", "text/html", "image/png"]
170 ) {
171   return new Promise((resolve, reject) => {
172     try {
173       clipboard.asyncGetData(
174         aFormats,
175         aClipboardType,
176         null,
177         SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(),
178         {
179           QueryInterface: SpecialPowers.ChromeUtils.generateQI([
180             "nsIAsyncClipboardGetCallback",
181           ]),
182           // nsIAsyncClipboardGetCallback
183           onSuccess: SpecialPowers.wrapCallback(function (
184             aAsyncGetClipboardData
185           ) {
186             resolve(aAsyncGetClipboardData);
187           }),
188           onError: SpecialPowers.wrapCallback(function (aResult) {
189             reject(aResult);
190           }),
191         }
192       );
193     } catch (e) {
194       ok(false, `asyncGetData should not throw`);
195       reject(e);
196     }
197   });
200 function asyncClipboardRequestGetData(aRequest, aFlavor, aThrows = false) {
201   return new Promise((resolve, reject) => {
202     var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
203       Ci.nsITransferable
204     );
205     trans.init(null);
206     trans.addDataFlavor(aFlavor);
207     try {
208       aRequest.getData(trans, aResult => {
209         if (aResult != Cr.NS_OK) {
210           reject(aResult);
211           return;
212         }
214         try {
215           var data = SpecialPowers.createBlankObject();
216           trans.getTransferData(aFlavor, data);
217           resolve(data.value.QueryInterface(Ci.nsISupportsString).data);
218         } catch (ex) {
219           // XXX: should widget set empty string to transferable when there no
220           // data in system clipboard?
221           resolve("");
222         }
223       });
224       ok(
225         !aThrows,
226         `nsIAsyncGetClipboardData.getData should ${
227           aThrows ? "throw" : "success"
228         }`
229       );
230     } catch (e) {
231       ok(
232         aThrows,
233         `nsIAsyncGetClipboardData.getData should ${
234           aThrows ? "throw" : "success"
235         }`
236       );
237       reject(e);
238     }
239   });