Bug 1928997: Update tabs icon in Unified Search popup r=desktop-theme-reviewers,daleh...
[gecko.git] / dom / canvas / test / test_imagebitmap.html
blob3c7958242b1086c1645baeb5a8dcf84d0ede77f3
1 <!DOCTYPE HTML>
2 <title>Test ImageBitmap</title>
3 <meta charset="utf-8">
4 <script src="/tests/SimpleTest/SimpleTest.js"></script>
5 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
6 <body>
8 <img src="image_anim-gr.gif" id="image" class="resource">
9 <video width="320" height="240" src="http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.webm&type=video/webm&cors=anonymous" id="video" crossOrigin="anonymous" autoplay></video>
11 <canvas id="c1" class="output" width="128" height="128"></canvas>
12 <canvas id="c2" width="128" height="128"></canvas>
14 <script src="imagebitmap_bug1239300.js"></script>
15 <script src="imagebitmap_bug1239752.js"></script>
16 <script type="text/javascript">
18 SimpleTest.waitForExplicitFinish();
20 /**
21 * [isPixel description]
22 * @param {[type]} ctx : canvas context
23 * @param {[type]} x : pixel x coordinate
24 * @param {[type]} y : pixel y coordinate
25 * @param {[type]} c : a rgba color code
26 * @param {[type]} d : error duration
27 * @return {Promise}
29 function isPixel(ctx, x, y, c, d) {
30 var pos = x + "," + y;
31 var color = c[0] + "," + c[1] + "," + c[2] + "," + c[3];
32 var pixel = ctx.getImageData(x, y, 1, 1);
33 var pr = pixel.data[0],
34 pg = pixel.data[1],
35 pb = pixel.data[2],
36 pa = pixel.data[3];
37 ok(c[0]-d <= pr && pr <= c[0]+d &&
38 c[1]-d <= pg && pg <= c[1]+d &&
39 c[2]-d <= pb && pb <= c[2]+d &&
40 c[3]-d <= pa && pa <= c[3]+d,
41 "pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+"; expected "+color+" +/- "+d);
44 var TEST_BITMAPS = [
45 {'rect': [0, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [255, 0, 0, 255], 5]]},
46 {'rect': [128, 0, 128, 128], 'draw': [0, 0, 64, 64, 0, 0, 64, 64], 'test': [[0, 0, [0, 255, 0, 255], 5]]},
47 {'rect': [230, 230, 128, 128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5],
48 [100, 100, [0, 0, 0, 0], 5]]},
49 {'rect': [-64, -64, 512, 512], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 0, 0, 0], 5],
50 [100, 100, [255, 0, 0, 255], 5]]},
51 {'rect': [128, 128, -128, -128], 'draw': [0, 0, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [255, 0, 0, 255], 5]]},
52 {'rect': [0, 0, 256, 256], 'draw': [0, 128, 128, 128, 0, 0, 128, 128], 'test': [[0, 0, [0, 255, 0, 255], 5]]},
55 var canvas, ctx, ctx2, completedImage;
57 function failed(ex) {
58 ok(false, "Promise failure: " + ex);
61 function testDraw() {
62 var resolver, bitmaps = [], image = new Image();
64 image.src = 'image_rgrg-256x256.png';
65 var promise = new Promise(function (arg) { resolver = arg; });
67 function createBitmap(def) {
68 return createImageBitmap(image, def.rect[0], def.rect[1], def.rect[2], def.rect[3])
69 .then(function (bitmap) { def.bitmap = bitmap; }, failed);
72 image.onload = function() {
73 completedImage = image;
74 resolver(Promise.all(TEST_BITMAPS.map(createBitmap)));
77 function testPixel(test) {
78 isPixel(ctx, test[0], test[1], test[2], test[3]);
81 return promise.then(function() {
82 TEST_BITMAPS.forEach(function (test) {
83 if (!test.bitmap) { return; }
84 ctx.clearRect(0, 0, canvas.width, canvas.height);
85 ctx.drawImage(test.bitmap, test.draw[0], test.draw[1], test.draw[2], test.draw[3], test.draw[4], test.draw[5], test.draw[6], test.draw[7]);
86 test.test.forEach(testPixel);
87 is(test.bitmap.width, Math.abs(test.rect[2]), "Bitmap has correct width " + test.bitmap.width);
88 is(test.bitmap.height, Math.abs(test.rect[3]), "Bitmap has correct height " + test.bitmap.height);
89 });
90 });
93 function testSources() {
94 ctx.fillStyle="#00FF00";
95 ctx.fillRect(0, 0, 128, 128);
97 function check(bitmap) {
98 ctx2.clearRect(0, 0, 128, 128);
99 ctx2.drawImage(bitmap, 0, 0);
100 isPixel(ctx2, 0, 0, [0, 255, 0, 255], 5);
103 function getPNGBlobBitmapPromise() {
104 return new Promise(function(resolve, reject) {
105 canvas.toBlob(function(blob) {
106 resolve(createImageBitmap(blob));
111 function getJPGBlobBitmapPromise() {
112 return new Promise(function(resolve, reject) {
113 canvas.toBlob(function(blob) {
114 resolve(createImageBitmap(blob));
115 }, "image/jpeg", 0.95)
119 return Promise.all([
120 createImageBitmap(document.getElementById('image')).then(check, failed), // HTMLImageElement
121 createImageBitmap(ctx).then(check, failed), // CanvasRenderingContext2D
122 createImageBitmap(canvas).then(check, failed), // HTMLCanvasElement
123 createImageBitmap(ctx).then(function (bitmap) { return createImageBitmap(bitmap).then(check, failed); }, failed), // ImageBitmap
124 createImageBitmap(document.getElementById('video'), 140, 0, 20, 20).then(check, failed), // HTMLVideoElement
125 createImageBitmap(ctx.getImageData(0, 0, 128, 128)).then(check, failed), // ImageData
126 getPNGBlobBitmapPromise().then(check, failed), // PNG blob
127 getJPGBlobBitmapPromise().then(check, failed), // JPEG blob
131 function promiseThrows(p, name) {
132 var didThrow;
133 return p.then(function() { didThrow = false; },
134 function() { didThrow = true; })
135 .then(function() { ok(didThrow, name); });
138 function testExceptions() {
140 function createImageBitmapWithNeuturedImageData() {
141 return new Promise(function(resolve, reject) {
142 var tempImage = document.createElement('img');
143 tempImage.src = 'image_rgrg-256x256.png';
144 tempImage.onload = function() {
145 var tempCanvas = document.createElement('canvas');
146 var tempCtx = tempCanvas.getContext('2d');
147 tempCanvas.with = tempImage.naturalWidth;
148 tempCanvas.height = tempImage.naturalHeight;
149 tempCtx.drawImage(tempImage, 0, 0);
150 var tempWorker = new Worker("test_imagebitmap_on_worker.js");
151 var imageData = tempCtx.getImageData(0, 0, tempImage.naturalWidth, tempImage.naturalHeight);
152 tempWorker.postMessage(imageData.data.buffer, [imageData.data.buffer]);
153 tempWorker.terminate();
155 ok(!imageData.data.length, "Get a neutured ImageData.");
156 resolve(createImageBitmap(imageData));
161 function createImageBitmapWithCorruptedBlob() {
162 return new Promise(function(resolve, reject) {
163 var xhr = new XMLHttpRequest();
164 xhr.open("GET", "image_error-early.png");
165 xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
166 xhr.onload = function()
168 ok(xhr.response, "Get a corrupted blob");
169 resolve(createImageBitmap(xhr.response));
171 xhr.send();
175 function createImageBitmapWithNonImageFile() {
176 return new Promise(function(resolve, reject) {
177 var xhr = new XMLHttpRequest();
178 xhr.open("GET", "test_imagebitmap_on_worker.js");
179 xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
180 xhr.onload = function()
182 ok(xhr.response, "Get a non-image blob");
183 resolve(createImageBitmap(xhr.response));
185 xhr.send();
189 return Promise.all([
190 promiseThrows(createImageBitmap(new Image()), 'createImageBitmap should throw with unloaded image'),
191 promiseThrows(createImageBitmap(completedImage, 0, 0, 0, 0), 'createImageBitmap should throw with 0 width/height'),
192 promiseThrows(createImageBitmap(null), 'createImageBitmap should throw with null source'),
193 promiseThrows(createImageBitmapWithNeuturedImageData(), "createImageBitmap should throw with neutured ImageData"),
194 promiseThrows(createImageBitmapWithCorruptedBlob(), "createImageBitmap should throw with corrupted blob"),
195 promiseThrows(createImageBitmapWithNonImageFile(), "createImageBitmap should throw with non-image blob"),
199 function testSecurityErrors() {
201 function getUncleanImagePromise() {
202 return new Promise(function(resolve, reject) {
203 var uncleanImage = document.createElement('img');
205 uncleanImage.onload = function() {
206 resolve(createImageBitmap(uncleanImage));
209 uncleanImage.onerror = function() {
210 reject();
213 uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
217 function getUncleanVideoPromise() {
218 return new Promise(function(resolve, reject) {
219 var uncleanVideo = document.createElement('video');
221 uncleanVideo.onloadeddata = function() {
222 resolve(createImageBitmap(uncleanVideo));
225 uncleanVideo.onerror = function() {
226 reject();
229 uncleanVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.webm&type=video/webm";
230 uncleanVideo.play();
234 function getTaintedCanvasPromise() {
235 return new Promise(function(resolve, reject) {
236 var uncleanImage = document.createElement('img');
238 uncleanImage.onload = function() {
239 var taintedCanvas = document.createElement('canvas');
240 var taintedCtx = taintedCanvas.getContext('2d');
241 taintedCtx.drawImage(uncleanImage, 0, 0);
242 resolve(createImageBitmap(taintedCanvas));
245 uncleanImage.onerror = function() {
246 reject();
249 uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
253 function getTaintedCanvasRenderingContex2dPromise() {
254 return new Promise(function(resolve, reject) {
255 var uncleanImage = document.createElement('img');
257 uncleanImage.onload = function() {
258 var taintedCanvas = document.createElement('canvas');
259 var taintedCtx = taintedCanvas.getContext('2d');
260 taintedCtx.drawImage(uncleanImage, 0, 0);
261 resolve(createImageBitmap(taintedCtx));
264 uncleanImage.onerror = function() {
265 reject();
268 uncleanImage.src = "http://example.com/tests/dom/canvas/test/crossorigin/image.png";
272 function checkPromiseFailedWithSecurityError(p) {
273 return p.then(imageBitmap => {
274 ok(!!imageBitmap, "ImageBitmaps are always created");
275 const context = document.createElement("canvas").getContext("2d");
276 context.drawImage(imageBitmap, 0, 0);
277 try {
278 context.getImageData(0, 0, 1, 1);
279 ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully.");
280 } catch (ex) {
281 if (ex == "SecurityError: The operation is insecure.") {
282 ok(true, ex.message);
284 else {
285 ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex.message);
291 return Promise.all([
292 checkPromiseFailedWithSecurityError(getUncleanImagePromise()),
293 checkPromiseFailedWithSecurityError(getUncleanVideoPromise()),
294 checkPromiseFailedWithSecurityError(getTaintedCanvasPromise()),
295 checkPromiseFailedWithSecurityError(getTaintedCanvasRenderingContex2dPromise()),
299 function testCreatePattern() {
300 var resolve;
301 var promise = new Promise(function (arg) { resolve = arg; });
303 var TEST_PATTERN = [
304 [0, 0, [255, 0, 0, 255], 1],
305 [128, 128, [255, 0, 0, 255], 1],
306 [256, 256, [255, 0, 0, 255], 1],
307 [384, 0, [0, 255, 0, 255], 1],
308 [0, 384, [0, 255, 0, 255], 1],
311 var patternCanvas = document.createElement('canvas');
312 patternCanvas.width = "512";
313 patternCanvas.height = "512";
314 var patternCtx = patternCanvas.getContext('2d');
316 var image = new Image();
317 image.src = 'image_rgrg-256x256.png';
318 image.onload = function() {
319 var p = createImageBitmap(image);
320 p.then(function(bitmap) {
321 patternCtx.rect(0, 0, 512, 512);
322 patternCtx.fillStyle = patternCtx.createPattern(bitmap, "repeat");
323 patternCtx.fill();
324 document.body.appendChild(patternCanvas);
326 resolve(p);
329 return promise.then(function() {
330 TEST_PATTERN.forEach(function(test) {
331 isPixel(patternCtx, test[0], test[1], test[2], test[3]);
337 function runTests() {
338 canvas = document.getElementById('c1');
339 ctx = canvas.getContext('2d');
340 ctx2 = document.getElementById('c2').getContext('2d');
342 testDraw()
343 .then(testCreatePattern)
344 .then(testSources)
345 .then(testExceptions)
346 .then(testSecurityErrors)
347 .then(testBug1239300)
348 .then(testBug1239752)
349 .then(SimpleTest.finish, function(ev) { failed(ev); SimpleTest.finish(); });
352 addLoadEvent(runTests);
354 </script>
355 </body>