common.sub.js (6332B)
1 function makeCanvas() { 2 return new Promise(resolve => { 3 var testCanvas = document.createElement("canvas"); 4 testCanvas.width = 20; 5 testCanvas.height = 20; 6 var testCtx = testCanvas.getContext("2d"); 7 testCtx.fillStyle = "rgb(255, 0, 0)"; 8 testCtx.fillRect(0, 0, 10, 10); 9 testCtx.fillStyle = "rgb(0, 255, 0)"; 10 testCtx.fillRect(10, 0, 10, 10); 11 testCtx.fillStyle = "rgb(0, 0, 255)"; 12 testCtx.fillRect(0, 10, 10, 10); 13 testCtx.fillStyle = "rgb(0, 0, 0)"; 14 testCtx.fillRect(10, 10, 10, 10); 15 resolve(testCanvas); 16 }); 17 } 18 19 function makeOffscreenCanvas() { 20 return new Promise(resolve => { 21 let canvas = new OffscreenCanvas(20, 20); 22 var testCtx = canvas.getContext("2d"); 23 testCtx.fillStyle = "rgb(255, 0, 0)"; 24 testCtx.fillRect(0, 0, 10, 10); 25 testCtx.fillStyle = "rgb(0, 255, 0)"; 26 testCtx.fillRect(10, 0, 10, 10); 27 testCtx.fillStyle = "rgb(0, 0, 255)"; 28 testCtx.fillRect(0, 10, 10, 10); 29 testCtx.fillStyle = "rgb(0, 0, 0)"; 30 testCtx.fillRect(10, 10, 10, 10); 31 resolve(canvas); 32 }); 33 } 34 35 function makeMakeVideo(src) { 36 return function () { 37 return new Promise(function(resolve, reject) { 38 var video = document.createElement("video"); 39 video.oncanplaythrough = function() { 40 resolve(video); 41 }; 42 video.onerror = reject; 43 44 // preload=auto is required to ensure a frame is available once 45 // canplaythrough is fired. The default of preload=metadata does not 46 // gaurantee this. 47 video.preload = "auto"; 48 video.src = getVideoURI(src); 49 50 // Prevent WebKit from garbage collecting event handlers. 51 window._video = video; 52 }); 53 } 54 } 55 56 function makeVideo() { 57 return makeMakeVideo("/images/pattern")(); 58 } 59 60 var imageBitmapDataUrlVideoPromise = self.GLOBAL && self.GLOBAL.isWorker() 61 // /common/media.js can't load in a Worker so we don't have getVideoURI 62 ? null 63 : fetch(getVideoURI("/images/pattern")) 64 .then(response => Promise.all([response.headers.get("Content-Type"), response.arrayBuffer()])) 65 .then(([type, data]) => { 66 return new Promise(function(resolve, reject) { 67 var video = document.createElement("video"); 68 video.oncanplaythrough = function() { 69 resolve(video); 70 }; 71 video.onerror = reject; 72 73 var encoded = btoa(String.fromCodePoint(...new Uint8Array(data))); 74 var dataUrl = `data:${type};base64,${encoded}`; 75 76 // preload=auto is required to ensure a frame is available once 77 // canplaythrough is fired. The default of preload=metadata does not 78 // gaurantee this. 79 video.preload = "auto"; 80 video.src = dataUrl; 81 82 // Prevent WebKit from garbage collecting event handlers. 83 window._dataVideo = video; 84 }); 85 }); 86 87 function makeDataUrlVideo() { 88 return imageBitmapDataUrlVideoPromise; 89 } 90 91 function makeMakeHTMLImage(src) { 92 return function() { 93 return new Promise((resolve, reject) => { 94 var img = new Image(); 95 img.onload = function() { 96 resolve(img); 97 }; 98 img.onerror = reject; 99 img.src = src; 100 }); 101 } 102 } 103 104 function makeMakeSVGImage(src) { 105 return function() { 106 return new Promise((resolve, reject) => { 107 var image = document.createElementNS("http://www.w3.org/2000/svg", "image"); 108 image.onload = () => resolve(image); 109 image.onerror = reject; 110 image.setAttribute("externalResourcesRequired", "true"); 111 image.setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:href', src); 112 document.body.appendChild(image); 113 }); 114 } 115 } 116 117 function makeImageData() { 118 return new Promise(function(resolve, reject) { 119 var width = 20, height = 20; 120 var imgData = new ImageData(width, height); 121 for (var i = 0; i < width * height * 4; i += 4) { 122 imgData.data[i] = 0; 123 imgData.data[i + 1] = 0; 124 imgData.data[i + 2] = 0; 125 imgData.data[i + 3] = 255; //alpha channel: 255 126 } 127 var halfWidth = width / 2; 128 var halfHeight = height / 2; 129 // initialize to R, G, B, Black, with each one 10*10 pixels 130 for (var i = 0; i < halfHeight; i++) 131 for (var j = 0; j < halfWidth; j++) 132 imgData.data[i * width * 4 + j * 4] = 255; 133 for (var i = 0; i < halfHeight; i++) 134 for (var j = halfWidth; j < width; j++) 135 imgData.data[i * width * 4 + j * 4 + 1] = 255; 136 for (var i = halfHeight; i < height; i++) 137 for (var j = 0; j < halfWidth; j++) 138 imgData.data[i * width * 4 + j * 4 + 2] = 255; 139 resolve(imgData); 140 }); 141 } 142 143 function makeImageBitmap() { 144 return makeCanvas().then(canvas => { 145 return createImageBitmap(canvas); 146 }); 147 } 148 149 function makeBlob(src) { 150 return function () { 151 return new Promise(function(resolve, reject) { 152 var xhr = new XMLHttpRequest(); 153 xhr.open("GET", src); 154 xhr.responseType = 'blob'; 155 xhr.send(); 156 xhr.onload = function() { 157 resolve(xhr.response); 158 }; 159 }); 160 } 161 } 162 163 var imageSourceTypes = [ 164 { name: 'an HTMLCanvasElement', factory: makeCanvas }, 165 { name: 'an HTMLVideoElement', factory: makeVideo }, 166 { name: 'an HTMLVideoElement from a data URL', factory: makeDataUrlVideo }, 167 { name: 'a bitmap HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.png") }, 168 { name: 'a vector HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.svg") }, 169 { name: 'a bitmap SVGImageElement', factory: makeMakeSVGImage("/images/pattern.png") }, 170 { name: 'a vector SVGImageElement', factory: makeMakeSVGImage("/images/pattern.svg") }, 171 { name: 'an OffscreenCanvas', factory: makeOffscreenCanvas }, 172 { name: 'an ImageData', factory: makeImageData }, 173 { name: 'an ImageBitmap', factory: makeImageBitmap }, 174 { name: 'a Blob', factory: makeBlob("/images/pattern.png") }, 175 ];