test-clipboard.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. require("sdk/clipboard");
  6. const { Cc, Ci } = require("chrome");
  7. const imageTools = Cc["@mozilla.org/image/tools;1"].
  8. getService(Ci.imgITools);
  9. const io = Cc["@mozilla.org/network/io-service;1"].
  10. getService(Ci.nsIIOService);
  11. const base64png = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA" +
  12. "AABzenr0AAAASUlEQVRYhe3O0QkAIAwD0eyqe3Q993AQ3cBSUKpygfsNTy" +
  13. "N5ugbQpK0BAADgP0BRDWXWlwEAAAAAgPsA3rzDaAAAAHgPcGrpgAnzQ2FG" +
  14. "bWRR9AAAAABJRU5ErkJggg%3D%3D";
  15. const base64jpeg = "data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQAAAQABAAD%2F" +
  16. "2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCg" +
  17. "sOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD%2F2wBDAQMDAwQDBAgEBAgQCw" +
  18. "kLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ" +
  19. "EBAQEBAQEBD%2FwAARCAAgACADAREAAhEBAxEB%2F8QAHwAAAQUBAQEBAQ" +
  20. "EAAAAAAAAAAAECAwQFBgcICQoL%2F8QAtRAAAgEDAwIEAwUFBAQAAAF9AQ" +
  21. "IDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRol" +
  22. "JicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eX" +
  23. "qDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJ" +
  24. "ytLT1NXW19jZ2uHi4%2BTl5ufo6erx8vP09fb3%2BPn6%2F8QAHwEAAwEB" +
  25. "AQEBAQEBAQAAAAAAAAECAwQFBgcICQoL%2F8QAtREAAgECBAQDBAcFBAQA" +
  26. "AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNO" +
  27. "El8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0" +
  28. "dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6ws" +
  29. "PExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3%2BPn6%2F9oADAMB" +
  30. "AAIRAxEAPwD5Kr8kP9CwoA5f4m%2F8iRqX%2FbH%2FANHJXr5F%2FwAjCn" +
  31. "8%2F%2FSWfnnir%2FwAkji%2F%2B4f8A6dgeD1%2BiH8bn1BX5If6FmFqW" +
  32. "pXtveyQwzbUXGBtB7D2r9l4U4UyjMsoo4rFUeacua75pLaUktFJLZH5NxN" +
  33. "xNmmX5pVw2Gq8sI8tlyxe8U3q03uzD8S3dxqOi3NneSeZDJs3LgDOHBHI5" +
  34. "6gV%2BkcG%2BH%2FDmJzuhSq4e8XzfbqfyS%2FvH5rx1xTm2MyDEUa1W8X" +
  35. "yXXLFbTi%2BkThv7B0r%2FAJ9f%2FH2%2Fxr90%2FwCIVcI%2F9An%2FAJ" +
  36. "Uq%2FwDyZ%2FO%2F16v%2FADfgv8j0r%2FhZvgj%2FAKDf%2FktN%2FwDE" +
  37. "V%2Fnr%2FYWYf8%2B%2Fxj%2Fmf3R%2FxFXhH%2FoL%2FwDKdX%2F5Azrv" +
  38. "xLouo3D3lne%2BZDJja3luM4GDwRnqDX9LeH%2FBud4nhzD1aVC8Xz%2Fa" +
  39. "h%2Fz8l%2FePx%2FinjrIMZm1WtRxF4vls%2BSa2jFdYlDUdRsp7OSKKbc" +
  40. "7YwNpHce1fqfCvCub5bm9HFYqjywjzXfNF7xklopN7s%2BC4l4lyvMMrq4" +
  41. "fD1bzfLZcsltJPqktkYlfsZ%2BUnBV%2FnufVnXaD%2FAMgqD%2FgX%2Fo" +
  42. "Rr%2BxvCr%2FkkcJ%2F3E%2F8ATsz5%2FHfx5fL8kX6%2FQjkCgD%2F%2F" +
  43. "2Q%3D%3D";
  44. const canvasHTML = "data:text/html," + encodeURIComponent(
  45. "<html>\
  46. <body>\
  47. <canvas width='32' height='32'></canvas>\
  48. </body>\
  49. </html>"
  50. );
  51. function comparePixelImages(imageA, imageB, callback) {
  52. let tabs = require("sdk/tabs");
  53. tabs.open({
  54. url: canvasHTML,
  55. onReady: function onReady(tab) {
  56. let worker = tab.attach({
  57. contentScript: "new " + function() {
  58. let canvas = document.querySelector("canvas");
  59. let context = canvas.getContext("2d");
  60. self.port.on("draw-image", function(imageURI) {
  61. let img = new Image();
  62. img.onload = function() {
  63. context.drawImage(this, 0, 0);
  64. let pixels = Array.join(context.getImageData(0, 0, 32, 32).data);
  65. self.port.emit("image-pixels", pixels);
  66. }
  67. img.src = imageURI;
  68. });
  69. }
  70. });
  71. let compared = "";
  72. worker.port.on("image-pixels", function (pixels) {
  73. if (!compared) {
  74. compared = pixels;
  75. this.emit("draw-image", imageB);
  76. } else {
  77. callback(compared === pixels);
  78. tab.close()
  79. }
  80. });
  81. worker.port.emit("draw-image", imageA);
  82. }
  83. });
  84. }
  85. // Test the typical use case, setting & getting with no flavors specified
  86. exports["test With No Flavor"] = function(assert) {
  87. var contents = "hello there";
  88. var flavor = "text";
  89. var fullFlavor = "text/unicode";
  90. var clip = require("sdk/clipboard");
  91. // Confirm we set the clipboard
  92. assert.ok(clip.set(contents));
  93. // Confirm flavor is set
  94. assert.equal(clip.currentFlavors[0], flavor);
  95. // Confirm we set the clipboard
  96. assert.equal(clip.get(), contents);
  97. // Confirm we can get the clipboard using the flavor
  98. assert.equal(clip.get(flavor), contents);
  99. // Confirm we can still get the clipboard using the full flavor
  100. assert.equal(clip.get(fullFlavor), contents);
  101. };
  102. // Test the slightly less common case where we specify the flavor
  103. exports["test With Flavor"] = function(assert) {
  104. var contents = "<b>hello there</b>";
  105. var contentsText = "hello there";
  106. var flavor = "html";
  107. var fullFlavor = "text/html";
  108. var unicodeFlavor = "text";
  109. var unicodeFullFlavor = "text/unicode";
  110. var clip = require("sdk/clipboard");
  111. assert.ok(clip.set(contents, flavor));
  112. assert.equal(clip.currentFlavors[0], unicodeFlavor);
  113. assert.equal(clip.currentFlavors[1], flavor);
  114. assert.equal(clip.get(), contentsText);
  115. assert.equal(clip.get(flavor), contents);
  116. assert.equal(clip.get(fullFlavor), contents);
  117. assert.equal(clip.get(unicodeFlavor), contentsText);
  118. assert.equal(clip.get(unicodeFullFlavor), contentsText);
  119. };
  120. // Test that the typical case still works when we specify the flavor to set
  121. exports["test With Redundant Flavor"] = function(assert) {
  122. var contents = "<b>hello there</b>";
  123. var flavor = "text";
  124. var fullFlavor = "text/unicode";
  125. var clip = require("sdk/clipboard");
  126. assert.ok(clip.set(contents, flavor));
  127. assert.equal(clip.currentFlavors[0], flavor);
  128. assert.equal(clip.get(), contents);
  129. assert.equal(clip.get(flavor), contents);
  130. assert.equal(clip.get(fullFlavor), contents);
  131. };
  132. exports["test Not In Flavor"] = function(assert) {
  133. var contents = "hello there";
  134. var flavor = "html";
  135. var clip = require("sdk/clipboard");
  136. assert.ok(clip.set(contents));
  137. // If there's nothing on the clipboard with this flavor, should return null
  138. assert.equal(clip.get(flavor), null);
  139. };
  140. exports["test Set Image"] = function(assert) {
  141. var clip = require("sdk/clipboard");
  142. var flavor = "image";
  143. var fullFlavor = "image/png";
  144. assert.ok(clip.set(base64png, flavor), "clipboard set");
  145. assert.equal(clip.currentFlavors[0], flavor, "flavor is set");
  146. };
  147. exports["test Get Image"] = function(assert, done) {
  148. var clip = require("sdk/clipboard");
  149. clip.set(base64png, "image");
  150. var contents = clip.get();
  151. comparePixelImages(base64png, contents, function (areEquals) {
  152. assert.ok(areEquals,
  153. "Image gets from clipboard equals to image sets to the clipboard");
  154. done();
  155. });
  156. }
  157. exports["test Set Image Type Not Supported"] = function(assert) {
  158. var clip = require("sdk/clipboard");
  159. var flavor = "image";
  160. assert.throws(function () {
  161. clip.set(base64jpeg, flavor);
  162. }, "Invalid flavor for image/jpeg");
  163. };
  164. // Notice that `imageTools.decodeImageData`, used by `clipboard.set` method for
  165. // images, write directly to the javascript console the error in case the image
  166. // is corrupt, even if the error is catched.
  167. //
  168. // See: http://mxr.mozilla.org/mozilla-central/source/image/src/Decoder.cpp#136
  169. exports["test Set Image Type Wrong Data"] = function(assert) {
  170. var clip = require("sdk/clipboard");
  171. var flavor = "image";
  172. var wrongPNG = "data:image/png" + base64jpeg.substr(15);
  173. assert.throws(function () {
  174. clip.set(wrongPNG, flavor);
  175. }, "Unable to decode data given in a valid image.");
  176. };
  177. require("test").run(exports)