test_removal_ondecode.html (4422B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=841579 5 --> 6 <head> 7 <title>Test for Bug 841579</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <script src="/tests/SimpleTest/WindowSnapshot.js"></script> 10 <script type="application/javascript" src="imgutils.js"></script> 11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 12 </head> 13 <body> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841579">Mozilla Bug 841579</a> 15 <p id="display"></p> 16 <div id="content"> 17 </div> 18 <pre id="test"> 19 <script type="application/javascript"> 20 /** Test for Bug 841579*/ 21 22 SimpleTest.requestFlakyTimeout("Early failure timeout"); 23 SimpleTest.waitForExplicitFinish(); 24 25 const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) 26 27 const Cc = SpecialPowers.Cc; 28 const Ci = SpecialPowers.Ci; 29 const gContent = document.getElementById("content"); 30 31 var gImg; 32 var gMyDecoderObserver; 33 var gIsTestFinished = false; 34 var gFiles; 35 var gNotifications = 0; 36 var gLoads = 0; 37 var gRemovals = 0; 38 var gExpected = 5; 39 40 function* fileToLoad() { 41 yield "red.png"; 42 yield "invalid.jpg"; 43 yield "lime100x100.svg"; 44 yield "bad.jpg"; 45 yield "rillybad.jpg"; 46 } 47 48 function onSizeAvailable() { 49 ok(true, "AfterLoad.onSizeAvailable called for " + gImg.src); 50 } 51 function onLoadComplete(aRequest) { 52 ok(gExpected > gLoads, "AfterLoad.onLoadComplete called for " + gImg.src); 53 gLoads++; 54 55 // We aren't going to get a decode complete event if the metadata decoding 56 // failed (i.e. for invalid.jpg). By definition we should have the size or 57 // an error once we get a load complete event, so check if the size is valid 58 // and if not, trigger a decode complete event manually. 59 var hasSize = false; 60 try { 61 hasSize = aRequest.image.width > 0 && aRequest.image.height > 0; 62 } catch(e) {} 63 64 if (hasSize) { 65 maybeAdvance(); 66 } else { 67 onDecodeComplete(aRequest); 68 } 69 } 70 71 function onDecodeComplete() { 72 ok(gExpected > gRemovals, "AfterLoad.onDecodeComplete called for " + gImg.src); 73 SimpleTest.executeSoon(function() { 74 try { 75 gContent.removeChild(gImg); 76 } 77 catch (e) {} 78 gRemovals++; 79 maybeAdvance(); 80 }); 81 } 82 83 function failTest() { 84 ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " + 85 "currently displaying " + gImg.src); 86 cleanUpAndFinish(); 87 } 88 89 function onNotification() 90 { 91 ok(gExpected > gNotifications, "AfterLoad.onNotification called for " + gImg.src); 92 gNotifications++; 93 maybeAdvance(); 94 } 95 96 function maybeAdvance() 97 { 98 if (gNotifications != gLoads || gNotifications != gRemovals) { 99 return; 100 } 101 102 let {done, value} = gFiles.next(); 103 if (done) { 104 cleanUpAndFinish(); 105 return; 106 } 107 gImg.src = value; 108 gContent.appendChild(gImg); 109 } 110 111 function cleanUpAndFinish() { 112 // On the off chance that failTest and myOnStopFrame are triggered 113 // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. 114 if (gIsTestFinished) { 115 return; 116 } 117 let imgLoadingContent = SpecialPowers.wrap(gImg); 118 imgLoadingContent.removeObserver(gMyDecoderObserver); 119 // TODO - this isn't the case until post-bug 716140's refactorings 120 // ok(gNotifications == gLoads, "Should be notified the same number of times as loads"); 121 SimpleTest.finish(); 122 gIsTestFinished = true; 123 } 124 125 function main() { 126 gFiles = fileToLoad(); 127 gImg = new Image(); 128 gImg.onload = onNotification; 129 gImg.onerror = onNotification; 130 131 // Create, customize & attach decoder observer 132 var observer = new ImageDecoderObserverStub(); 133 observer.sizeAvailable = onSizeAvailable; 134 observer.loadComplete = onLoadComplete; 135 observer.decodeComplete = onDecodeComplete; 136 gMyDecoderObserver = 137 Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) 138 .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer)); 139 let imgLoadingContent = SpecialPowers.wrap(gImg); 140 imgLoadingContent.addObserver(gMyDecoderObserver); 141 142 // We want to test the cold loading behavior, so clear cache in case an 143 // earlier test got our image in there already. 144 clearAllImageCaches(); 145 146 // kick off image-loading! myOnStopFrame handles the rest. 147 gImg.setAttribute("src", gFiles.next().value); 148 gContent.appendChild(gImg); 149 150 // In case something goes wrong, fail earlier than mochitest timeout, 151 // and with more information. 152 setTimeout(failTest, FAILURE_TIMEOUT); 153 } 154 155 window.onload = main; 156 157 </script> 158 </pre> 159 </body> 160 </html>