diff options
Diffstat (limited to '')
161 files changed, 6336 insertions, 0 deletions
diff --git a/image/test/mochitest/12M-pixels-1.png b/image/test/mochitest/12M-pixels-1.png Binary files differnew file mode 100644 index 0000000000..f802dd5396 --- /dev/null +++ b/image/test/mochitest/12M-pixels-1.png diff --git a/image/test/mochitest/12M-pixels-2.png b/image/test/mochitest/12M-pixels-2.png Binary files differnew file mode 100644 index 0000000000..a6d430442e --- /dev/null +++ b/image/test/mochitest/12M-pixels-2.png diff --git a/image/test/mochitest/6M-pixels.png b/image/test/mochitest/6M-pixels.png Binary files differnew file mode 100644 index 0000000000..c813d8b569 --- /dev/null +++ b/image/test/mochitest/6M-pixels.png diff --git a/image/test/mochitest/INT32_MIN.bmp b/image/test/mochitest/INT32_MIN.bmp Binary files differnew file mode 100644 index 0000000000..d9a0016107 --- /dev/null +++ b/image/test/mochitest/INT32_MIN.bmp diff --git a/image/test/mochitest/animated-avif.avif b/image/test/mochitest/animated-avif.avif Binary files differnew file mode 100644 index 0000000000..f3cafef1e3 --- /dev/null +++ b/image/test/mochitest/animated-avif.avif diff --git a/image/test/mochitest/animated-gif-finalframe.gif b/image/test/mochitest/animated-gif-finalframe.gif Binary files differnew file mode 100644 index 0000000000..4e80d31a72 --- /dev/null +++ b/image/test/mochitest/animated-gif-finalframe.gif diff --git a/image/test/mochitest/animated-gif.gif b/image/test/mochitest/animated-gif.gif Binary files differnew file mode 100644 index 0000000000..001cbfb87a --- /dev/null +++ b/image/test/mochitest/animated-gif.gif diff --git a/image/test/mochitest/animated-gif2.gif b/image/test/mochitest/animated-gif2.gif Binary files differnew file mode 100644 index 0000000000..c66cc4b734 --- /dev/null +++ b/image/test/mochitest/animated-gif2.gif diff --git a/image/test/mochitest/animated-gif_trailing-garbage.gif b/image/test/mochitest/animated-gif_trailing-garbage.gif Binary files differnew file mode 100644 index 0000000000..02f4de2e31 --- /dev/null +++ b/image/test/mochitest/animated-gif_trailing-garbage.gif diff --git a/image/test/mochitest/animated1.gif b/image/test/mochitest/animated1.gif Binary files differnew file mode 100644 index 0000000000..2f9d8a512b --- /dev/null +++ b/image/test/mochitest/animated1.gif diff --git a/image/test/mochitest/animated1.svg b/image/test/mochitest/animated1.svg new file mode 100644 index 0000000000..87118c4ea0 --- /dev/null +++ b/image/test/mochitest/animated1.svg @@ -0,0 +1,12 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + style="animation: colorAnim 1s steps(2) infinite alternate" + width="40" height="40"> + <style> + @keyframes colorAnim { + from { background-color: green } + to { background-color: blue } + } + </style> +</svg> + diff --git a/image/test/mochitest/animated2.gif b/image/test/mochitest/animated2.gif Binary files differnew file mode 100644 index 0000000000..2f9d8a512b --- /dev/null +++ b/image/test/mochitest/animated2.gif diff --git a/image/test/mochitest/animatedMask.gif b/image/test/mochitest/animatedMask.gif Binary files differnew file mode 100644 index 0000000000..72a1c51ddc --- /dev/null +++ b/image/test/mochitest/animatedMask.gif diff --git a/image/test/mochitest/animation.svg b/image/test/mochitest/animation.svg new file mode 100644 index 0000000000..2141d86791 --- /dev/null +++ b/image/test/mochitest/animation.svg @@ -0,0 +1,5 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <image id="anim" xlink:href="animated-gif.gif" width="40" height="40"/> +</svg> + diff --git a/image/test/mochitest/animationPolling.js b/image/test/mochitest/animationPolling.js new file mode 100644 index 0000000000..f20377cf9d --- /dev/null +++ b/image/test/mochitest/animationPolling.js @@ -0,0 +1,469 @@ +// This file expects imgutils.js to be loaded as well. +/* import-globals-from imgutils.js */ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +var currentTest; +var gIsRefImageLoaded = false; +const gShouldOutputDebugInfo = false; + +function pollForSuccess() { + if (!currentTest.isTestFinished) { + if ( + !currentTest.reusingReferenceImage || + (currentTest.reusingReferenceImage && gIsRefImageLoaded) + ) { + currentTest.checkImage(); + } + + setTimeout(pollForSuccess, currentTest.pollFreq); + } +} + +function reuseImageCallback() { + gIsRefImageLoaded = true; +} + +function failTest() { + if (currentTest.isTestFinished || currentTest.closeFunc) { + return; + } + + ok( + false, + "timing out after " + + currentTest.timeout + + "ms. " + + "Animated image still doesn't look correct, after poll #" + + currentTest.pollCounter + ); + currentTest.wereFailures = true; + + if (currentTest.currentSnapshotDataURI) { + currentTest.outputDebugInfo( + "Snapshot #" + currentTest.pollCounter, + "snapNum" + currentTest.pollCounter, + currentTest.currentSnapshotDataURI + ); + } + + currentTest.enableDisplay( + document.getElementById(currentTest.debugElementId) + ); + + currentTest.cleanUpAndFinish(); +} + +/** + * Create a new AnimationTest object. + * + * @param pollFreq The amount of time (in ms) to wait between consecutive + * snapshots if the reference image and the test image don't match. + * @param timeout The total amount of time (in ms) to wait before declaring the + * test as failed. + * @param referenceElementId The id attribute of the reference image element, or + * the source of the image to change to, once the reference snapshot has + * been successfully taken. This latter option could be used if you don't + * want the image to become invisible at any time during the test. + * @param imageElementId The id attribute of the test image element. + * @param debugElementId The id attribute of the div where links should be + * appended if the test fails. + * @param cleanId The id attribute of the div or element to use as the 'clean' + * test. This element is only enabled when we are testing to verify that + * the reference image has been loaded. It can be undefined. + * @param srcAttr The location of the source of the image, for preloading. This + * is usually not required, but it useful for preloading reference + * images. + * @param xulTest A boolean value indicating whether or not this is a XUL test + * (uses hidden=true/false rather than display: none to hide/show + * elements). + * @param closeFunc A function that should be called when this test is finished. + * If null, then cleanUpAndFinish() will be called. This can be used to + * chain tests together, so they are all finished exactly once. + * @returns {AnimationTest} + */ +function AnimationTest( + pollFreq, + timeout, + referenceElementId, + imageElementId, + debugElementId, + cleanId, + srcAttr, + xulTest, + closeFunc +) { + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + this.wereFailures = false; + this.pollFreq = pollFreq; + this.timeout = timeout; + this.imageElementId = imageElementId; + this.referenceElementId = referenceElementId; + + if (!document.getElementById(referenceElementId)) { + // In this case, we're assuming the user passed in a string that + // indicates the source of the image they want to change to, + // after the reference image has been taken. + this.reusingImageAsReference = true; + } + + this.srcAttr = srcAttr; + this.debugElementId = debugElementId; + this.referenceSnapshot = ""; // value will be set in takeReferenceSnapshot() + this.pollCounter = 0; + this.isTestFinished = false; + this.numRefsTaken = 0; + this.blankWaitTime = 0; + + this.cleanId = cleanId ? cleanId : ""; + this.xulTest = xulTest ? xulTest : ""; + this.closeFunc = closeFunc ? closeFunc : ""; +} + +AnimationTest.prototype.preloadImage = function () { + if (this.srcAttr) { + this.myImage = new Image(); + this.myImage.onload = function () { + currentTest.continueTest(); + }; + this.myImage.src = this.srcAttr; + } else { + this.continueTest(); + } +}; + +AnimationTest.prototype.outputDebugInfo = function (message, id, dataUri) { + if (!gShouldOutputDebugInfo) { + return; + } + var debugElement = document.getElementById(this.debugElementId); + var newDataUriElement = document.createElement("a"); + newDataUriElement.setAttribute("id", id); + newDataUriElement.setAttribute("href", dataUri); + newDataUriElement.appendChild(document.createTextNode(message)); + debugElement.appendChild(newDataUriElement); + var brElement = document.createElement("br"); + debugElement.appendChild(brElement); + todo(false, "Debug (" + id + "): " + message + " " + dataUri); +}; + +AnimationTest.prototype.isFinished = function () { + return this.isTestFinished; +}; + +AnimationTest.prototype.takeCleanSnapshot = function () { + var cleanElement; + if (this.cleanId) { + cleanElement = document.getElementById(this.cleanId); + } + + // Enable clean page comparison element + if (cleanElement) { + this.enableDisplay(cleanElement); + } + + // Take a snapshot of the initial (clean) page + this.cleanSnapshot = snapshotWindow(window, false); + + // Disable the clean page comparison element + if (cleanElement) { + this.disableDisplay(cleanElement); + } + + var dataString1 = "Clean Snapshot"; + this.outputDebugInfo( + dataString1, + "cleanSnap", + this.cleanSnapshot.toDataURL() + ); +}; + +AnimationTest.prototype.takeBlankSnapshot = function () { + // Take a snapshot of the initial (essentially blank) page + this.blankSnapshot = snapshotWindow(window, false); + + var dataString1 = "Initial Blank Snapshot"; + this.outputDebugInfo( + dataString1, + "blank1Snap", + this.blankSnapshot.toDataURL() + ); +}; + +/** + * Begin the AnimationTest. This will utilize the information provided in the + * constructor to invoke a mochitest on animated images. It will automatically + * fail if allowed to run past the timeout. This will attempt to preload an + * image, if applicable, and then asynchronously call continueTest(), or if not + * applicable, synchronously trigger a call to continueTest(). + */ +AnimationTest.prototype.beginTest = function () { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("untriaged"); + + currentTest = this; + this.preloadImage(); +}; + +/** + * This is the second part of the test. It is triggered (eventually) from + * beginTest() either synchronously or asynchronously, as an image load + * callback. + */ +AnimationTest.prototype.continueTest = async function () { + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, this.timeout); + + if (!this.reusingImageAsReference) { + this.disableDisplay(document.getElementById(this.imageElementId)); + } + + let tookReference = new Promise(resolve => { + this.takeReferenceSnapshot(resolve); + }); + + tookReference.then(() => { + this.setupPolledImage(); + SimpleTest.executeSoon(pollForSuccess); + }); +}; + +AnimationTest.prototype.setupPolledImage = function () { + // Make sure the image is visible + if (!this.reusingImageAsReference) { + this.enableDisplay(document.getElementById(this.imageElementId)); + var currentSnapshot = snapshotWindow(window, false); + var result = compareSnapshots( + currentSnapshot, + this.referenceSnapshot, + true + ); + + this.currentSnapshotDataURI = currentSnapshot.toDataURL(); + + if (result[0]) { + // SUCCESS! + ok(true, "Animated image looks correct, at poll #" + this.pollCounter); + + this.outputDebugInfo( + "Animated image", + "animImage", + this.currentSnapshotDataURI + ); + + this.outputDebugInfo( + "Reference image", + "refImage", + this.referenceSnapshot.toDataURL() + ); + + this.cleanUpAndFinish(); + } + } else if (!gIsRefImageLoaded) { + this.myImage = new Image(); + this.myImage.onload = reuseImageCallback; + document + .getElementById(this.imageElementId) + .setAttribute("src", this.referenceElementId); + } +}; + +AnimationTest.prototype.checkImage = function () { + if (this.isTestFinished) { + return; + } + + this.pollCounter++; + + // We need this for some tests, because we need to force the + // test image to be visible. + if (!this.reusingImageAsReference) { + this.enableDisplay(document.getElementById(this.imageElementId)); + } + + var currentSnapshot = snapshotWindow(window, false); + var result = compareSnapshots(currentSnapshot, this.referenceSnapshot, true); + + this.currentSnapshotDataURI = currentSnapshot.toDataURL(); + + if (result[0]) { + // SUCCESS! + ok(true, "Animated image looks correct, at poll #" + this.pollCounter); + + this.outputDebugInfo("Animated image", "animImage", result[1]); + + this.outputDebugInfo("Reference image", "refImage", result[2]); + + this.cleanUpAndFinish(); + } +}; + +AnimationTest.prototype.takeReferenceSnapshot = function (resolve) { + this.numRefsTaken++; + + // Test to make sure the reference image doesn't match a clean snapshot + if (!this.cleanSnapshot) { + this.takeCleanSnapshot(); + } + + // Used later to verify that the reference div disappeared + if (!this.blankSnapshot) { + this.takeBlankSnapshot(); + } + + if (this.reusingImageAsReference) { + // Show reference elem (which is actually our image), & take a snapshot + var referenceElem = document.getElementById(this.imageElementId); + this.enableDisplay(referenceElem); + + this.referenceSnapshot = snapshotWindow(window, false); + + let snapResult = compareSnapshots( + this.cleanSnapshot, + this.referenceSnapshot, + false + ); + if (!snapResult[0]) { + if (this.blankWaitTime > 2000) { + // if it took longer than two seconds to load the image, we probably + // have a problem. + this.wereFailures = true; + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); + } else { + this.blankWaitTime += currentTest.pollFreq; + // let's wait a bit and see if it clears up + setTimeout( + () => this.takeReferenceSnapshot(resolve), + currentTest.pollFreq + ); + return; + } + } + + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); + + let dataString = "Reference Snapshot #" + this.numRefsTaken; + this.outputDebugInfo( + dataString, + "refSnapId", + this.referenceSnapshot.toDataURL() + ); + } else { + // Make sure the animation section is hidden + this.disableDisplay(document.getElementById(this.imageElementId)); + + // Show reference div, & take a snapshot + var referenceDiv = document.getElementById(this.referenceElementId); + this.enableDisplay(referenceDiv); + + this.referenceSnapshot = snapshotWindow(window, false); + let snapResult = compareSnapshots( + this.cleanSnapshot, + this.referenceSnapshot, + false + ); + if (!snapResult[0]) { + if (this.blankWaitTime > 2000) { + // if it took longer than two seconds to load the image, we probably + // have a problem. + this.wereFailures = true; + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); + } else { + this.blankWaitTime += 20; + // let's wait a bit and see if it clears up + setTimeout(() => this.takeReferenceSnapshot(resolve), 20); + return; + } + } + + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); + + let dataString = "Reference Snapshot #" + this.numRefsTaken; + this.outputDebugInfo( + dataString, + "refSnapId", + this.referenceSnapshot.toDataURL() + ); + + // Re-hide reference div, and take another snapshot to be sure it's gone + this.disableDisplay(referenceDiv); + this.testBlankCameBack(); + } + resolve(); +}; + +AnimationTest.prototype.enableDisplay = function (element) { + if (!element) { + return; + } + + if (!this.xulTest) { + element.style.display = ""; + } else { + element.setAttribute("hidden", "false"); + } +}; + +AnimationTest.prototype.disableDisplay = function (element) { + if (!element) { + return; + } + + if (!this.xulTest) { + element.style.display = "none"; + } else { + element.setAttribute("hidden", "true"); + } +}; + +AnimationTest.prototype.testBlankCameBack = function () { + var blankSnapshot2 = snapshotWindow(window, false); + var result = compareSnapshots(this.blankSnapshot, blankSnapshot2, true); + ok( + result[0], + "Reference image should disappear when it becomes display:none" + ); + + if (!result[0]) { + this.wereFailures = true; + var dataString = "Second Blank Snapshot"; + this.outputDebugInfo(dataString, "blank2SnapId", result[2]); + } +}; + +AnimationTest.prototype.cleanUpAndFinish = function () { + // On the off chance that failTest and checkImage are triggered + // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. + if (this.isTestFinished) { + return; + } + + this.isTestFinished = true; + + // Call our closing function, if one exists + if (this.closeFunc) { + this.closeFunc(); + return; + } + + if (this.wereFailures) { + document.getElementById(this.debugElementId).style.display = "block"; + } + + SimpleTest.finish(); + document.getElementById(this.debugElementId).style.display = ""; +}; diff --git a/image/test/mochitest/bad.jpg b/image/test/mochitest/bad.jpg Binary files differnew file mode 100644 index 0000000000..555a416d7d --- /dev/null +++ b/image/test/mochitest/bad.jpg diff --git a/image/test/mochitest/big.png b/image/test/mochitest/big.png Binary files differnew file mode 100644 index 0000000000..94e7eb6db2 --- /dev/null +++ b/image/test/mochitest/big.png diff --git a/image/test/mochitest/blue.gif b/image/test/mochitest/blue.gif Binary files differnew file mode 100644 index 0000000000..339f3702fb --- /dev/null +++ b/image/test/mochitest/blue.gif diff --git a/image/test/mochitest/blue.png b/image/test/mochitest/blue.png Binary files differnew file mode 100644 index 0000000000..8df58f3a5f --- /dev/null +++ b/image/test/mochitest/blue.png diff --git a/image/test/mochitest/bug1132427.gif b/image/test/mochitest/bug1132427.gif Binary files differnew file mode 100644 index 0000000000..39f49689a0 --- /dev/null +++ b/image/test/mochitest/bug1132427.gif diff --git a/image/test/mochitest/bug1132427.html b/image/test/mochitest/bug1132427.html new file mode 100644 index 0000000000..c765ce14ca --- /dev/null +++ b/image/test/mochitest/bug1132427.html @@ -0,0 +1,6 @@ +<html> +<body onload="opener.doTest();"> + <img id="left" style="width: 201px; height: 201px;" src="bug1132427.gif"> + <img id="right" src="bug1132427.gif"> +</body> +</html> diff --git a/image/test/mochitest/bug1180105-waiter.sjs b/image/test/mochitest/bug1180105-waiter.sjs new file mode 100644 index 0000000000..4e20cb9976 --- /dev/null +++ b/image/test/mochitest/bug1180105-waiter.sjs @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var timer = Cc["@mozilla.org/timer;1"]; +var waitTimer = timer.createInstance(Ci.nsITimer); + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.processAsync(); + waitForFinish(response); +} + +function waitForFinish(response) { + if (getSharedState("all-parts-done") === "1") { + response.write("done"); + response.finish(); + } else { + waitTimer.initWithCallback( + function () { + waitForFinish(response); + }, + 10, + Ci.nsITimer.TYPE_ONE_SHOT + ); + } +} diff --git a/image/test/mochitest/bug1180105.sjs b/image/test/mochitest/bug1180105.sjs new file mode 100644 index 0000000000..35c7025508 --- /dev/null +++ b/image/test/mochitest/bug1180105.sjs @@ -0,0 +1,68 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var counter = 100; +var timer = Cc["@mozilla.org/timer;1"]; +var partTimer = timer.createInstance(Ci.nsITimer); + +function getFileAsInputStream(aFilename) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + file.append(aFilename); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + return fileStream; +} + +function handleRequest(request, response) { + response.setHeader( + "Content-Type", + "multipart/x-mixed-replace;boundary=BOUNDARYOMG", + false + ); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + // We're sending parts off in a delayed fashion, to let the tests occur. + response.processAsync(); + response.write("--BOUNDARYOMG\r\n"); + sendParts(response); +} + +function sendParts(response) { + if (counter-- == 0) { + sendClose(response); + setSharedState("all-parts-done", "1"); + return; + } + sendNextPart(response); + partTimer.initWithCallback( + function () { + sendParts(response); + }, + 1, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} + +function sendClose(response) { + response.write("--BOUNDARYOMG--\r\n"); + response.finish(); +} + +function sendNextPart(response) { + var nextPartHead = "Content-Type: image/jpeg\r\n\r\n"; + var inputStream = getFileAsInputStream("damon.jpg"); + response.bodyOutputStream.write(nextPartHead, nextPartHead.length); + response.bodyOutputStream.writeFrom(inputStream, inputStream.available()); + inputStream.close(); + // Toss in the boundary, so the browser can know this part is complete + response.write("--BOUNDARYOMG\r\n"); +} diff --git a/image/test/mochitest/bug1217571-iframe.html b/image/test/mochitest/bug1217571-iframe.html new file mode 100644 index 0000000000..ab243d5cf5 --- /dev/null +++ b/image/test/mochitest/bug1217571-iframe.html @@ -0,0 +1,17 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1217571 +--> +<head> + <title>iframe for Bug 1217571</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + <img src="bug1217571.jpg"> +</div> +</body> +</html> diff --git a/image/test/mochitest/bug1217571.jpg b/image/test/mochitest/bug1217571.jpg Binary files differnew file mode 100644 index 0000000000..917b336607 --- /dev/null +++ b/image/test/mochitest/bug1217571.jpg diff --git a/image/test/mochitest/bug1319025-ref.png b/image/test/mochitest/bug1319025-ref.png Binary files differnew file mode 100644 index 0000000000..482d027a02 --- /dev/null +++ b/image/test/mochitest/bug1319025-ref.png diff --git a/image/test/mochitest/bug1319025.png b/image/test/mochitest/bug1319025.png Binary files differnew file mode 100644 index 0000000000..8023e77879 --- /dev/null +++ b/image/test/mochitest/bug1319025.png diff --git a/image/test/mochitest/bug399925.gif b/image/test/mochitest/bug399925.gif Binary files differnew file mode 100644 index 0000000000..fc1c8f3af0 --- /dev/null +++ b/image/test/mochitest/bug399925.gif diff --git a/image/test/mochitest/bug415761.ico b/image/test/mochitest/bug415761.ico Binary files differnew file mode 100644 index 0000000000..d3f65abc23 --- /dev/null +++ b/image/test/mochitest/bug415761.ico diff --git a/image/test/mochitest/bug468160.sjs b/image/test/mochitest/bug468160.sjs new file mode 100644 index 0000000000..6495482922 --- /dev/null +++ b/image/test/mochitest/bug468160.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "red.png", false); + response.setHeader("Cache-Control", "no-cache", false); +} diff --git a/image/test/mochitest/bug478398_ONLY.png b/image/test/mochitest/bug478398_ONLY.png Binary files differnew file mode 100644 index 0000000000..e094ae2cf4 --- /dev/null +++ b/image/test/mochitest/bug478398_ONLY.png diff --git a/image/test/mochitest/bug490949-iframe.html b/image/test/mochitest/bug490949-iframe.html new file mode 100644 index 0000000000..68f74b587e --- /dev/null +++ b/image/test/mochitest/bug490949-iframe.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 490949 iframe</title> +<body> +<img src="bug490949.sjs" width="100" height="100" id="image" /> +</body> +</html> diff --git a/image/test/mochitest/bug490949.sjs b/image/test/mochitest/bug490949.sjs new file mode 100644 index 0000000000..3b77dd9232 --- /dev/null +++ b/image/test/mochitest/bug490949.sjs @@ -0,0 +1,32 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + + var redirectstate = "/image/test/mochitest/bug490949.sjs"; + if (getState(redirectstate) == "") { + file.append("blue.png"); + setState(redirectstate, "red"); + } else { + file.append("red.png"); + setState(redirectstate, ""); + } + response.setHeader("Cache-Control", "no-cache", false); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + binaryStream.setInputStream(fileStream); + + response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available()); + + binaryStream.close(); + fileStream.close(); +} diff --git a/image/test/mochitest/bug496292-1.sjs b/image/test/mochitest/bug496292-1.sjs new file mode 100644 index 0000000000..2e842223d5 --- /dev/null +++ b/image/test/mochitest/bug496292-1.sjs @@ -0,0 +1,31 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + + if (request.getHeader("Accept") == "image/avif,image/webp,*/*") { + file.append("blue.png"); + } else { + file.append("red.png"); + } + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "image/png", false); + response.setHeader("Cache-Control", "no-cache", false); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + binaryStream.setInputStream(fileStream); + + response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available()); + + binaryStream.close(); + fileStream.close(); +} diff --git a/image/test/mochitest/bug496292-2.sjs b/image/test/mochitest/bug496292-2.sjs new file mode 100644 index 0000000000..af174e99c4 --- /dev/null +++ b/image/test/mochitest/bug496292-2.sjs @@ -0,0 +1,31 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + + if (request.getHeader("Accept") == "image/png") { + file.append("blue.png"); + } else { + file.append("red.png"); + } + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "image/png", false); + response.setHeader("Cache-Control", "no-cache", false); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + binaryStream.setInputStream(fileStream); + + response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available()); + + binaryStream.close(); + fileStream.close(); +} diff --git a/image/test/mochitest/bug496292-iframe-1.html b/image/test/mochitest/bug496292-iframe-1.html new file mode 100644 index 0000000000..00f0fbcfce --- /dev/null +++ b/image/test/mochitest/bug496292-iframe-1.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 496292 iframe 1</title> +<body> +<img src="bug496292-1.sjs" width="100" height="100" id="image" /> +</body> +</html> diff --git a/image/test/mochitest/bug496292-iframe-2.html b/image/test/mochitest/bug496292-iframe-2.html new file mode 100644 index 0000000000..67c1ecea16 --- /dev/null +++ b/image/test/mochitest/bug496292-iframe-2.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 496292 iframe 2</title> +<body> +<img src="bug496292-2.sjs" width="100" height="100" id="image" /> +</body> +</html> diff --git a/image/test/mochitest/bug496292-iframe-ref.html b/image/test/mochitest/bug496292-iframe-ref.html new file mode 100644 index 0000000000..2e804502e6 --- /dev/null +++ b/image/test/mochitest/bug496292-iframe-ref.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 496292 reference iframe</title> +<body> +<img src="blue.png" width="100" height="100" id="image" /> +</body> +</html> diff --git a/image/test/mochitest/bug497665-iframe.html b/image/test/mochitest/bug497665-iframe.html new file mode 100644 index 0000000000..a2b098e31b --- /dev/null +++ b/image/test/mochitest/bug497665-iframe.html @@ -0,0 +1,8 @@ +<html> +<head> +<title>Bug 497665 iframe</title> +<body> +<img src="bug497665.sjs" width="100" height="100" id="image1" /> +<img src="bug497665.sjs" width="100" height="100" id="image2" /> +</body> +</html> diff --git a/image/test/mochitest/bug497665.sjs b/image/test/mochitest/bug497665.sjs new file mode 100644 index 0000000000..cc6361d7c5 --- /dev/null +++ b/image/test/mochitest/bug497665.sjs @@ -0,0 +1,33 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + + var redirectstate = "/image/test/mochitest/bug497665.sjs"; + if (getState(redirectstate) == "") { + file.append("blue.png"); + setState(redirectstate, "red"); + } else { + file.append("red.png"); + setState(redirectstate, ""); + } + + response.setHeader("Cache-Control", "max-age=3600", false); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + binaryStream.setInputStream(fileStream); + + response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available()); + + binaryStream.close(); + fileStream.close(); +} diff --git a/image/test/mochitest/bug552605.sjs b/image/test/mochitest/bug552605.sjs new file mode 100644 index 0000000000..350ab729d5 --- /dev/null +++ b/image/test/mochitest/bug552605.sjs @@ -0,0 +1,12 @@ +function handleRequest(request, response) { + var redirectstate = "/image/test/mochitest/bug89419.sjs"; + response.setStatusLine("1.1", 302, "Found"); + if (getState(redirectstate) == "") { + response.setHeader("Location", "red.png", false); + setState(redirectstate, "red"); + } else { + response.setHeader("Location", "blue.png", false); + setState(redirectstate, ""); + } + response.setHeader("Cache-Control", "no-cache", false); +} diff --git a/image/test/mochitest/bug657191.sjs b/image/test/mochitest/bug657191.sjs new file mode 100644 index 0000000000..6a2c7924e1 --- /dev/null +++ b/image/test/mochitest/bug657191.sjs @@ -0,0 +1,26 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + file.append("lime100x100.svg"); + + response.setStatusLine("1.1", 500, "Internal Server Error"); + response.setHeader("Content-Type", "image/svg+xml", false); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + binaryStream.setInputStream(fileStream); + + response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available()); + + binaryStream.close(); + fileStream.close(); +} diff --git a/image/test/mochitest/bug671906-iframe.html b/image/test/mochitest/bug671906-iframe.html new file mode 100644 index 0000000000..87f8183a4d --- /dev/null +++ b/image/test/mochitest/bug671906-iframe.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 671906 iframe</title> +<body> +<img src="http://mochi.test:8888/tests/image/test/mochitest/bug671906.sjs" width="100" height="100" crossorigin="anonymous" /> +</body> +</html> diff --git a/image/test/mochitest/bug671906.sjs b/image/test/mochitest/bug671906.sjs new file mode 100644 index 0000000000..8473e87f3a --- /dev/null +++ b/image/test/mochitest/bug671906.sjs @@ -0,0 +1,34 @@ +function handleRequest(request, response) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + + var filestate = "/image/test/mochitest/bug671906.sjs"; + if (getState(filestate) == "") { + file.append("blue.png"); + setState(filestate, "red"); + } else { + file.append("red.png"); + setState(filestate, ""); + } + + // Set the expires date to some silly time in the future so we're sure to + // *want* to cache this image. + var date = new Date(); + date.setFullYear(date.getFullYear() + 1); + response.setHeader("Expires", date.toUTCString(), false); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + + response.bodyOutputStream.writeFrom(fileStream, fileStream.available()); + + fileStream.close(); + + response.setHeader("Access-Control-Allow-Origin", "*", false); +} diff --git a/image/test/mochitest/bug733553-informant.sjs b/image/test/mochitest/bug733553-informant.sjs new file mode 100644 index 0000000000..364830b636 --- /dev/null +++ b/image/test/mochitest/bug733553-informant.sjs @@ -0,0 +1,13 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/plain", false); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + // Tells bug733553.sjs that the consumer is ready for the next part + let partName = request.queryString; + setSharedState("next-part", partName); + response.write("OK!"); +} diff --git a/image/test/mochitest/bug733553.sjs b/image/test/mochitest/bug733553.sjs new file mode 100644 index 0000000000..869477b581 --- /dev/null +++ b/image/test/mochitest/bug733553.sjs @@ -0,0 +1,104 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var bodyPartIndex = -1; +var bodyParts = [ + ["red.png", "image/png"], + ["animated-gif2.gif", "image/gif"], + ["red.png", "image/png"], + ["lime100x100.svg", "image/svg+xml"], + ["lime100x100.svg", "image/svg+xml"], + ["animated-gif2.gif", "image/gif"], + ["red.png", "image/png"], + // Mime type intentionally wrong (test for bug 907575) + ["shaver.png", "image/gif"], + ["red.png", "image/png"], + ["damon.jpg", "image/jpeg"], + ["damon.jpg", "application/octet-stream"], + ["damon.jpg", "image/jpeg"], + ["rillybad.jpg", "application/x-unknown-content-type"], + ["damon.jpg", "image/jpeg"], + ["bad.jpg", "image/jpeg"], + ["red.png", "image/png"], + ["invalid.jpg", "image/jpeg"], + ["animated-gif2.gif", "image/gif"], +]; +var timer = Cc["@mozilla.org/timer;1"]; +var partTimer = timer.createInstance(Ci.nsITimer); + +function getFileAsInputStream(aFilename) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + file.append(aFilename); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + return fileStream; +} + +function handleRequest(request, response) { + if (!getSharedState("next-part")) { + setSharedState("next-part", "-1"); + } + response.setHeader( + "Content-Type", + "multipart/x-mixed-replace;boundary=BOUNDARYOMG", + false + ); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + // We're sending parts off in a delayed fashion, to let the tests occur. + response.processAsync(); + response.write("--BOUNDARYOMG\r\n"); + sendParts(response); +} + +function sendParts(response) { + let wait = false; + let nextPart = parseInt(getSharedState("next-part"), 10); + if (nextPart == bodyPartIndex) { + // Haven't been signaled yet, remain in holding pattern + wait = true; + } else { + bodyPartIndex = nextPart; + } + if (bodyParts.length > bodyPartIndex) { + let callback; + if (!wait) { + callback = getSendNextPart(response); + } else { + callback = function () { + sendParts(response); + }; + } + partTimer.initWithCallback(callback, 1000, Ci.nsITimer.TYPE_ONE_SHOT); + } else { + sendClose(response); + } +} + +function sendClose(response) { + response.write("--BOUNDARYOMG--\r\n"); + response.finish(); +} + +function getSendNextPart(response) { + var part = bodyParts[bodyPartIndex]; + var nextPartHead = "Content-Type: " + part[1] + "\r\n\r\n"; + var inputStream = getFileAsInputStream(part[0]); + return function () { + response.bodyOutputStream.write(nextPartHead, nextPartHead.length); + response.bodyOutputStream.writeFrom(inputStream, inputStream.available()); + inputStream.close(); + // Toss in the boundary, so the browser can know this part is complete + response.write("--BOUNDARYOMG\r\n"); + sendParts(response); + }; +} diff --git a/image/test/mochitest/bug767779.sjs b/image/test/mochitest/bug767779.sjs new file mode 100644 index 0000000000..b29b00cf1c --- /dev/null +++ b/image/test/mochitest/bug767779.sjs @@ -0,0 +1,56 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var timer = Cc["@mozilla.org/timer;1"]; +var partTimer = timer.createInstance(Ci.nsITimer); + +function getFileAsInputStream(aFilename) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + file.append(aFilename); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + return fileStream; +} + +function handleRequest(request, response) { + response.setHeader("Content-Type", "image/gif", false); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + // We're sending data off in a delayed fashion + response.processAsync(); + var inputStream = getFileAsInputStream("animated-gif_trailing-garbage.gif"); + // Should be 4029 bytes available. + // Send the good data at once + response.bodyOutputStream.writeFrom(inputStream, 285); + sendParts(inputStream, response); +} + +function sendParts(inputStream, response) { + // 3744 left, send in 8 chunks of 468 each + partTimer.initWithCallback( + getSendNextPart(inputStream, response), + 500, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} + +function getSendNextPart(inputStream, response) { + return function () { + response.bodyOutputStream.writeFrom(inputStream, 468); + if (!inputStream.available()) { + inputStream.close(); + response.finish(); + } else { + sendParts(inputStream, response); + } + }; +} diff --git a/image/test/mochitest/bug89419-iframe.html b/image/test/mochitest/bug89419-iframe.html new file mode 100644 index 0000000000..1915315633 --- /dev/null +++ b/image/test/mochitest/bug89419-iframe.html @@ -0,0 +1,7 @@ +<html> +<head> +<title>Bug 89419 iframe</title> +<body> +<img src="bug89419.sjs" width="100" height="100" /> +</body> +</html> diff --git a/image/test/mochitest/bug89419.sjs b/image/test/mochitest/bug89419.sjs new file mode 100644 index 0000000000..350ab729d5 --- /dev/null +++ b/image/test/mochitest/bug89419.sjs @@ -0,0 +1,12 @@ +function handleRequest(request, response) { + var redirectstate = "/image/test/mochitest/bug89419.sjs"; + response.setStatusLine("1.1", 302, "Found"); + if (getState(redirectstate) == "") { + response.setHeader("Location", "red.png", false); + setState(redirectstate, "red"); + } else { + response.setHeader("Location", "blue.png", false); + setState(redirectstate, ""); + } + response.setHeader("Cache-Control", "no-cache", false); +} diff --git a/image/test/mochitest/bug900200-ref.png b/image/test/mochitest/bug900200-ref.png Binary files differnew file mode 100644 index 0000000000..6360131325 --- /dev/null +++ b/image/test/mochitest/bug900200-ref.png diff --git a/image/test/mochitest/bug900200.png b/image/test/mochitest/bug900200.png Binary files differnew file mode 100644 index 0000000000..d7d87adce0 --- /dev/null +++ b/image/test/mochitest/bug900200.png diff --git a/image/test/mochitest/child.html b/image/test/mochitest/child.html new file mode 100644 index 0000000000..19f262ec3a --- /dev/null +++ b/image/test/mochitest/child.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<script src="imgutils.js"></script> +<img id="img" src="animated1.gif"> +<script> + let observer = new ImageDecoderObserverStub(); + observer.decodeComplete = () => { + parent.postMessage("decodeComplete", "*"); + }; + observer.loadComplete = () => { + parent.postMessage("loadComplete", "*"); + }; + observer = SpecialPowers.wrapCallbackObject(observer); + const gObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"] + .getService(SpecialPowers.Ci.imgITools) + .createScriptedObserver(observer); + const img = document.getElementById("img"); + SpecialPowers.wrap(img).addObserver(gObserver); + window.addEventListener("unload", () => { + SpecialPowers.wrap(img).removeObserver(gObserver); + }); +</script> diff --git a/image/test/mochitest/chrome.toml b/image/test/mochitest/chrome.toml new file mode 100644 index 0000000000..5859cc70fd --- /dev/null +++ b/image/test/mochitest/chrome.toml @@ -0,0 +1,6 @@ +[DEFAULT] +skip-if = ["os == 'android'"] + +["test_bug415761.html"] +skip-if = ["os != 'win'"] +support-files = ["bug415761.ico"] diff --git a/image/test/mochitest/clear.avif b/image/test/mochitest/clear.avif Binary files differnew file mode 100644 index 0000000000..b68e5729b4 --- /dev/null +++ b/image/test/mochitest/clear.avif diff --git a/image/test/mochitest/clear.gif b/image/test/mochitest/clear.gif Binary files differnew file mode 100644 index 0000000000..7ae79ba86e --- /dev/null +++ b/image/test/mochitest/clear.gif diff --git a/image/test/mochitest/clear.png b/image/test/mochitest/clear.png Binary files differnew file mode 100644 index 0000000000..b09aecaaa0 --- /dev/null +++ b/image/test/mochitest/clear.png diff --git a/image/test/mochitest/clear.webp b/image/test/mochitest/clear.webp Binary files differnew file mode 100644 index 0000000000..6db376d6e1 --- /dev/null +++ b/image/test/mochitest/clear.webp diff --git a/image/test/mochitest/clear2-results.gif b/image/test/mochitest/clear2-results.gif Binary files differnew file mode 100644 index 0000000000..965b650253 --- /dev/null +++ b/image/test/mochitest/clear2-results.gif diff --git a/image/test/mochitest/clear2.gif b/image/test/mochitest/clear2.gif Binary files differnew file mode 100644 index 0000000000..00ad873c65 --- /dev/null +++ b/image/test/mochitest/clear2.gif diff --git a/image/test/mochitest/clear2.webp b/image/test/mochitest/clear2.webp Binary files differnew file mode 100644 index 0000000000..e4a3e2efab --- /dev/null +++ b/image/test/mochitest/clear2.webp diff --git a/image/test/mochitest/damon.jpg b/image/test/mochitest/damon.jpg Binary files differnew file mode 100644 index 0000000000..917b336607 --- /dev/null +++ b/image/test/mochitest/damon.jpg diff --git a/image/test/mochitest/error-early.png b/image/test/mochitest/error-early.png new file mode 100644 index 0000000000..5df7507e2d --- /dev/null +++ b/image/test/mochitest/error-early.png @@ -0,0 +1 @@ +ERROR diff --git a/image/test/mochitest/filter-final.svg b/image/test/mochitest/filter-final.svg new file mode 100644 index 0000000000..b2b3dca008 --- /dev/null +++ b/image/test/mochitest/filter-final.svg @@ -0,0 +1,9 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<filter id="filter1" x="0%" y="0%" width="100%" height="100%"> + <feImage xlink:href="animated-gif-finalframe.gif"/> +</filter> +<g> + <rect x="0" y="0" width="100%" height="100%" filter="url(#filter1)"/> +</g> +</svg> diff --git a/image/test/mochitest/filter.svg b/image/test/mochitest/filter.svg new file mode 100644 index 0000000000..e185f15b69 --- /dev/null +++ b/image/test/mochitest/filter.svg @@ -0,0 +1,9 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + +<filter id="filter1" x="0%" y="0%" width="100%" height="100%"> + <feImage xlink:href="animated-gif.gif"/> +</filter> +<g> + <rect x="0" y="0" width="100%" height="100%" filter="url(#filter1)"/> +</g> +</svg> diff --git a/image/test/mochitest/finite-apng.png b/image/test/mochitest/finite-apng.png Binary files differnew file mode 100644 index 0000000000..778613d851 --- /dev/null +++ b/image/test/mochitest/finite-apng.png diff --git a/image/test/mochitest/first-frame-padding.gif b/image/test/mochitest/first-frame-padding.gif Binary files differnew file mode 100644 index 0000000000..e6d7c49322 --- /dev/null +++ b/image/test/mochitest/first-frame-padding.gif diff --git a/image/test/mochitest/green-background.html b/image/test/mochitest/green-background.html new file mode 100644 index 0000000000..731919f766 --- /dev/null +++ b/image/test/mochitest/green-background.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>Background color wrapper for clear image tests</title> +<style> +body { margin: 0; } +img { + background-color: rgb(0, 255, 0); +} +</style> +</head> +<body> +<!-- non-empty alt to avoid the broken image icon --> +<img id="image1" alt=" "> +<script> +// Loads an externally specified image and displays it +// with a green background. Intended for use with tests +// involving clear images. + +// Use as "green-background.html?image.png". + +// Get the image URL. +var imgURL = document.location.search.substr(1); + +// Load it. +var img = document.images[0]; +img.src = imgURL; +</script> +</body> +</html> diff --git a/image/test/mochitest/green.png b/image/test/mochitest/green.png Binary files differnew file mode 100644 index 0000000000..7df25f33bd --- /dev/null +++ b/image/test/mochitest/green.png diff --git a/image/test/mochitest/grey.png b/image/test/mochitest/grey.png Binary files differnew file mode 100644 index 0000000000..5c82cdeb10 --- /dev/null +++ b/image/test/mochitest/grey.png diff --git a/image/test/mochitest/ico-bmp-opaque.ico b/image/test/mochitest/ico-bmp-opaque.ico Binary files differnew file mode 100644 index 0000000000..3cf3320eae --- /dev/null +++ b/image/test/mochitest/ico-bmp-opaque.ico diff --git a/image/test/mochitest/ico-bmp-transparent.ico b/image/test/mochitest/ico-bmp-transparent.ico Binary files differnew file mode 100644 index 0000000000..151b7cb361 --- /dev/null +++ b/image/test/mochitest/ico-bmp-transparent.ico diff --git a/image/test/mochitest/iframe.html b/image/test/mochitest/iframe.html new file mode 100644 index 0000000000..6d66557ef8 --- /dev/null +++ b/image/test/mochitest/iframe.html @@ -0,0 +1,5 @@ +<html> +<body bgcolor="gray"> + <img src="animated-gif.gif"> +</body> +</html>
\ No newline at end of file diff --git a/image/test/mochitest/imgutils.js b/image/test/mochitest/imgutils.js new file mode 100644 index 0000000000..b16ad1d065 --- /dev/null +++ b/image/test/mochitest/imgutils.js @@ -0,0 +1,137 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Helper file for shared image functionality +// +// Note that this is use by tests elsewhere in the source tree. When in doubt, +// check mxr before removing or changing functionality. + +// Helper function to clear both the content and chrome image caches +function clearAllImageCaches() { + var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService( + SpecialPowers.Ci.imgITools + ); + var imageCache = tools.getImgCacheForDocument(window.document); + imageCache.clearCache(true); // true=chrome + imageCache.clearCache(false); // false=content +} + +// Helper function to clear the image cache of content images +function clearImageCache() { + var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService( + SpecialPowers.Ci.imgITools + ); + var imageCache = tools.getImgCacheForDocument(window.document); + imageCache.clearCache(false); // true=chrome, false=content +} + +// Helper function to determine if the frame is decoded for a given image id +function isFrameDecoded(id) { + return !!( + getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE + ); +} + +// Helper function to determine if the image is loaded for a given image id +function isImageLoaded(id) { + return !!( + getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE + ); +} + +// Helper function to get the status flags of an image +function getImageStatus(id) { + // Get the image + var img = SpecialPowers.wrap(document.getElementById(id)); + + // Get the request + var request = img.getRequest( + SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST + ); + + // Return the status + return request.imageStatus; +} + +// Forces a synchronous decode of an image by drawing it to a canvas. Only +// really meaningful if the image is fully loaded first +function forceDecode(id) { + // Get the image + var img = document.getElementById(id); + + // Make a new canvas + var canvas = document.createElement("canvas"); + + // Draw the image to the canvas. This forces a synchronous decode + var ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); +} + +// Functions to facilitate getting/setting various image-related prefs +// +// If you change a pref in a mochitest, Don't forget to reset it to its +// original value! +// +// Null indicates no pref set + +const DISCARD_ENABLED_PREF = { + name: "discardable", + branch: "image.mem.", + type: "bool", +}; +const DECODEONDRAW_ENABLED_PREF = { + name: "decodeondraw", + branch: "image.mem.", + type: "bool", +}; +const DISCARD_TIMEOUT_PREF = { + name: "min_discard_timeout_ms", + branch: "image.mem.", + type: "int", +}; + +function setImagePref(pref, val) { + var prefService = SpecialPowers.Services.prefs; + var branch = prefService.getBranch(pref.branch); + if (val != null) { + switch (pref.type) { + case "bool": + branch.setBoolPref(pref.name, val); + break; + case "int": + branch.setIntPref(pref.name, val); + break; + default: + throw new Error("Unknown pref type"); + } + } else if (branch.prefHasUserValue(pref.name)) { + branch.clearUserPref(pref.name); + } +} + +function getImagePref(pref) { + var prefService = SpecialPowers.Services.prefs; + var branch = prefService.getBranch(pref.branch); + if (branch.prefHasUserValue(pref.name)) { + switch (pref.type) { + case "bool": + return branch.getBoolPref(pref.name); + case "int": + return branch.getIntPref(pref.name); + default: + throw new Error("Unknown pref type"); + } + } else { + return null; + } +} + +// JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods. +function ImageDecoderObserverStub() { + this.sizeAvailable = function sizeAvailable(aRequest) {}; + this.frameComplete = function frameComplete(aRequest) {}; + this.decodeComplete = function decodeComplete(aRequest) {}; + this.loadComplete = function loadComplete(aRequest) {}; + this.frameUpdate = function frameUpdate(aRequest) {}; + this.discard = function discard(aRequest) {}; + this.isAnimated = function isAnimated(aRequest) {}; + this.hasTransparency = function hasTransparency(aRequest) {}; +} diff --git a/image/test/mochitest/infinite-apng.png b/image/test/mochitest/infinite-apng.png Binary files differnew file mode 100644 index 0000000000..637dafbc2b --- /dev/null +++ b/image/test/mochitest/infinite-apng.png diff --git a/image/test/mochitest/infinite.avif b/image/test/mochitest/infinite.avif Binary files differnew file mode 100644 index 0000000000..a5be1912a8 --- /dev/null +++ b/image/test/mochitest/infinite.avif diff --git a/image/test/mochitest/infinite.webp b/image/test/mochitest/infinite.webp Binary files differnew file mode 100644 index 0000000000..4219e179b0 --- /dev/null +++ b/image/test/mochitest/infinite.webp diff --git a/image/test/mochitest/invalid.jpg b/image/test/mochitest/invalid.jpg new file mode 100644 index 0000000000..c677a81e29 --- /dev/null +++ b/image/test/mochitest/invalid.jpg @@ -0,0 +1 @@ +notajpg diff --git a/image/test/mochitest/keep.gif b/image/test/mochitest/keep.gif Binary files differnew file mode 100644 index 0000000000..e967d6a6dc --- /dev/null +++ b/image/test/mochitest/keep.gif diff --git a/image/test/mochitest/keep.png b/image/test/mochitest/keep.png Binary files differnew file mode 100644 index 0000000000..aa3ff74450 --- /dev/null +++ b/image/test/mochitest/keep.png diff --git a/image/test/mochitest/keep.webp b/image/test/mochitest/keep.webp Binary files differnew file mode 100644 index 0000000000..342982be06 --- /dev/null +++ b/image/test/mochitest/keep.webp diff --git a/image/test/mochitest/lime-anim-100x100-2.svg b/image/test/mochitest/lime-anim-100x100-2.svg new file mode 100644 index 0000000000..d19d3b0e7e --- /dev/null +++ b/image/test/mochitest/lime-anim-100x100-2.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" + width="100" height="100"> + <rect width="100%" height="100%" fill="red"> + <animate attributeName="fill" to="lime" dur="0.1" fill="freeze"/> + </rect> +</svg> diff --git a/image/test/mochitest/lime-anim-100x100.svg b/image/test/mochitest/lime-anim-100x100.svg new file mode 100644 index 0000000000..c6584047d0 --- /dev/null +++ b/image/test/mochitest/lime-anim-100x100.svg @@ -0,0 +1,7 @@ +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" + width="100" height="100"> + <rect width="100%" height="100%" fill="red"/> + <rect x="-600" width="100%" height="100%" fill="lime"> + <animate attributeName="x" by="600" dur="0.1" fill="freeze"/> + </rect> +</svg> diff --git a/image/test/mochitest/lime-css-anim-100x100.svg b/image/test/mochitest/lime-css-anim-100x100.svg new file mode 100644 index 0000000000..3edbd3eaaf --- /dev/null +++ b/image/test/mochitest/lime-css-anim-100x100.svg @@ -0,0 +1,19 @@ +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" + width="100" height="100"> + <defs> + <style> + #myRect { + animation-duration: 0.1s; + animation-name: fade; + animation-fill-mode: forwards; + } + + @keyframes fade { + 0% { fill-opacity: 0 } + 100% { fill-opacity: 1 } + } + </style> + </defs> + <rect width="100%" height="100%" fill="red"/> + <rect id="myRect" width="100%" height="100%" fill="lime" fill-opacity="0"/> +</svg> diff --git a/image/test/mochitest/lime100x100.svg b/image/test/mochitest/lime100x100.svg new file mode 100644 index 0000000000..8bdec62c1f --- /dev/null +++ b/image/test/mochitest/lime100x100.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" + width="100" height="100"> + <rect width="100%" height="100%" fill="lime"/> +</svg> diff --git a/image/test/mochitest/mochitest.toml b/image/test/mochitest/mochitest.toml new file mode 100644 index 0000000000..96aaa8a0c3 --- /dev/null +++ b/image/test/mochitest/mochitest.toml @@ -0,0 +1,258 @@ +[DEFAULT] +support-files = [ + "INT32_MIN.bmp", + "animated1.gif", + "animated1.svg", + "animated2.gif", + "animatedMask.gif", + "animated-gif.gif", + "animated-gif2.gif", + "animated-gif_trailing-garbage.gif", + "animated-gif-finalframe.gif", + "animated-avif.avif", + "animation.svg", + "animationPolling.js", + "bad.jpg", + "big.png", + "blue.gif", + "blue.png", + "bug399925.gif", + "bug468160.sjs", + "bug478398_ONLY.png", + "bug490949-iframe.html", + "bug490949.sjs", + "bug496292-1.sjs", + "bug496292-2.sjs", + "bug496292-iframe-1.html", + "bug496292-iframe-2.html", + "bug496292-iframe-ref.html", + "bug497665-iframe.html", + "bug497665.sjs", + "bug552605.sjs", + "bug657191.sjs", + "bug671906-iframe.html", + "bug671906.sjs", + "bug733553-informant.sjs", + "bug733553.sjs", + "bug767779.sjs", + "bug89419-iframe.html", + "bug89419.sjs", + "bug900200.png", + "bug900200-ref.png", + "bug1132427.html", + "bug1132427.gif", + "bug1180105.sjs", + "bug1180105-waiter.sjs", + "bug1217571-iframe.html", + "bug1217571.jpg", + "bug1319025.png", + "bug1319025-ref.png", + "clear.gif", + "clear.png", + "clear.webp", + "clear.avif", + "clear2.gif", + "clear2.webp", + "clear2-results.gif", + "damon.jpg", + "error-early.png", + "filter-final.svg", + "filter.svg", + "finite-apng.png", + "first-frame-padding.gif", + "green.png", + "green-background.html", + "grey.png", + "ico-bmp-opaque.ico", + "ico-bmp-transparent.ico", + "iframe.html", + "imgutils.js", + "infinite.avif", + "infinite.webp", + "infinite-apng.png", + "invalid.jpg", + "keep.gif", + "keep.png", + "keep.webp", + "lime100x100.svg", + "lime-anim-100x100.svg", + "lime-anim-100x100-2.svg", + "lime-css-anim-100x100.svg", + "mq_dynamic_svg_test.html", + "mq_dynamic_svg_ref.html", + "opaque.bmp", + "purple.gif", + "rainbow.gif", + "red.gif", + "red.png", + "ref-iframe.html", + "restore-previous.gif", + "restore-previous.png", + "rillybad.jpg", + "schrep.png", + "shaver.png", + "short_header.gif", + "source.png", + "transparent.gif", + "transparent.png", + "over.png", + "webcam-simulacrum.sjs", + "6M-pixels.png", + "12M-pixels-1.png", + "12M-pixels-2.png", +] + +["test_animSVGImage.html"] +skip-if = [ + "os == 'android'", + "os == 'win'", + "os == 'mac' && os_version == '10.15'", # Bug 1370784, macosx due to bug 1549058 +] + +["test_animSVGImage2.html"] +skip-if = [ + "os == 'win'", # Bug 1354561 + "os == 'linux'", # Bug 1354561 + "os == 'android'", # Bug 1354561 +] + +["test_animated_css_image.html"] + +["test_animated_gif.html"] +support-files = ["child.html"] +skip-if = [ + "http3", + "http2", +] + +["test_animation.html"] + +["test_animation2.html"] + +["test_animation_operators.html"] + +["test_background_image_anim.html"] + +["test_bug89419-1.html"] + +["test_bug89419-2.html"] + +["test_bug399925.html"] + +["test_bug435296.html"] +skip-if = ["true"] # disabled - See bug 578591 + +["test_bug466586.html"] + +["test_bug468160.html"] + +["test_bug478398.html"] +skip-if = ["true"] # disabled - See bug 579139 + +["test_bug490949.html"] + +["test_bug496292.html"] +skip-if = ["verify"] + +["test_bug497665.html"] + +["test_bug552605-1.html"] + +["test_bug552605-2.html"] + +["test_bug553982.html"] + +["test_bug601470.html"] + +["test_bug614392.html"] + +["test_bug657191.html"] + +["test_bug671906.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug733553.html"] +skip-if = [ + "verify", + "http3", + "http2", +] + +["test_bug767779.html"] + +["test_bug865919.html"] + +["test_bug1132427.html"] +skip-if = ["display == 'wayland' && os_version == '22.04'"] # Bug 18570 + +["test_bug1180105.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1217571.html"] + +["test_bug1325080.html"] + +["test_bullet_animation.html"] + +["test_canvas_frame_animation.html"] + +["test_changeOfSource.html"] + +["test_changeOfSource2.html"] + +["test_discardAnimatedImage.html"] +skip-if = [ + "http3", + "http2", +] + +["test_discardFinishedAnimatedImage.html"] + +["test_discardFramesAnimatedImage.html"] + +["test_drawDiscardedImage.html"] + +["test_error_events.html"] + +["test_has_transparency.html"] + +["test_image_cache_notification.html"] + +["test_image_crossorigin_data_url.html"] + +["test_mq_dynamic_svg.html"] + +["test_net_failedtoprocess.html"] +skip-if = ["verify"] + +["test_removal_ondecode.html"] + +["test_removal_onload.html"] + +["test_short_gif_header.html"] + +["test_staticClone.html"] + +["test_svg_animatedGIF.html"] + +["test_svg_filter_animation.html"] + +["test_synchronized_animation.html"] +skip-if = ["true"] # bug 1295501 + +["test_undisplayed_iframe.html"] + +["test_webcam.html"] + +["test_xultree_animation.xhtml"] +allow_xul_xbl = true +skip-if = [ + "http3", + "http2", +] diff --git a/image/test/mochitest/mq_dynamic_svg_ref.html b/image/test/mochitest/mq_dynamic_svg_ref.html new file mode 100644 index 0000000000..bbd4a3e205 --- /dev/null +++ b/image/test/mochitest/mq_dynamic_svg_ref.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8> +<style> +iframe { border: none; } +</style> +<p>inline</p> +<svg width="50" height="50"> + <rect width="50" height="50" fill="green"/> +</svg> +<p>iframe</p> +<iframe src='data:image/svg+xml, + <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <rect width="50" height="50" fill="green"/> + </svg> +' width=50 height=50></iframe> +<p>img</p> +<img src='data:image/svg+xml, + <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <rect width="50" height="50" fill="green"/> + </svg> +' width=50 height=50> +<p>background-image</p> +<div style='background-image: url("data:image/svg+xml,\ + <svg xmlns='http://www.w3.org/2000/svg' width='50' height='50'>\ + <rect width='50' height='50' fill='green'/>\ + </svg>\ +"); width: 50px; height: 50px;'></div> +<p>img with nested document</p> +<img src='data:image/svg+xml, + <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <image href="data:image/svg+xml, + &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;50&quot; height=&quot;50&quot;> + &lt;rect width=&quot;50&quot; height=&quot;50&quot; fill=&quot;green&quot;/> + &lt;/svg> + " width="50" height="50"/> + </svg> +' width=50 height=50> diff --git a/image/test/mochitest/mq_dynamic_svg_test.html b/image/test/mochitest/mq_dynamic_svg_test.html new file mode 100644 index 0000000000..8acb6d3331 --- /dev/null +++ b/image/test/mochitest/mq_dynamic_svg_test.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html> +<meta charset=utf-8> +<style> +@media (prefers-color-scheme: dark) { + rect { fill: green; } +} +iframe { border: none; } +</style> +<p>inline</p> +<svg width="50" height="50"> + <rect width="50" height="50" fill="red"/> +</svg> +<p>iframe</p> +<iframe src='data:image/svg+xml, + <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <style> + @media (prefers-color-scheme: dark) { + rect { fill: green; } + } + </style> + <rect width="50" height="50" fill="red"/> + </svg> +' width=50 height=50></iframe> +<p>img</p> +<img src='data:image/svg+xml, + <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <style> + @media (prefers-color-scheme: dark) { + rect { fill: green; } + } + </style> + <rect width="50" height="50" fill="red"/> + </svg> +' width=50 height=50> +<p>background-image</p> +<div style='background-image: url("data:image/svg+xml,\ + <svg xmlns='http://www.w3.org/2000/svg' width='50' height='50'>\ + <style>\ + @media (prefers-color-scheme: dark) {\ + rect { fill: green; }\ + }\ + </style>\ + <rect width='50' height='50' fill='red'/>\ + </svg>\ +"); width: 50px; height: 50px;'></div> +<p>img with nested document</p> +<img src='data:image/svg+xml, + <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <image href="data:image/svg+xml, + &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;50&quot; height=&quot;50&quot;> + &lt;style> + @media (prefers-color-scheme: dark) { + rect { fill: green; } + } + &lt;/style> + &lt;rect width=&quot;50&quot; height=&quot;50&quot; fill=&quot;red&quot;/> + &lt;/svg> + " width="50" height="50"/> + </svg> +' width=50 height=50> diff --git a/image/test/mochitest/opaque.bmp b/image/test/mochitest/opaque.bmp Binary files differnew file mode 100644 index 0000000000..63d3f1c058 --- /dev/null +++ b/image/test/mochitest/opaque.bmp diff --git a/image/test/mochitest/over.png b/image/test/mochitest/over.png Binary files differnew file mode 100644 index 0000000000..9e957182f7 --- /dev/null +++ b/image/test/mochitest/over.png diff --git a/image/test/mochitest/purple.gif b/image/test/mochitest/purple.gif Binary files differnew file mode 100644 index 0000000000..79826af205 --- /dev/null +++ b/image/test/mochitest/purple.gif diff --git a/image/test/mochitest/rainbow.gif b/image/test/mochitest/rainbow.gif Binary files differnew file mode 100644 index 0000000000..a247a80df0 --- /dev/null +++ b/image/test/mochitest/rainbow.gif diff --git a/image/test/mochitest/red.gif b/image/test/mochitest/red.gif Binary files differnew file mode 100644 index 0000000000..d3c32bae25 --- /dev/null +++ b/image/test/mochitest/red.gif diff --git a/image/test/mochitest/red.png b/image/test/mochitest/red.png Binary files differnew file mode 100644 index 0000000000..aa9ce25263 --- /dev/null +++ b/image/test/mochitest/red.png diff --git a/image/test/mochitest/ref-iframe.html b/image/test/mochitest/ref-iframe.html new file mode 100644 index 0000000000..585772c8a9 --- /dev/null +++ b/image/test/mochitest/ref-iframe.html @@ -0,0 +1,6 @@ +<html> +<body bgcolor="gray"> + <div id="referenceImage" + style="height: 40px; width: 40px; background: #2aff00"></div> +</body> +</html> diff --git a/image/test/mochitest/restore-previous.gif b/image/test/mochitest/restore-previous.gif Binary files differnew file mode 100644 index 0000000000..15ba9ddc48 --- /dev/null +++ b/image/test/mochitest/restore-previous.gif diff --git a/image/test/mochitest/restore-previous.png b/image/test/mochitest/restore-previous.png Binary files differnew file mode 100644 index 0000000000..09dee63820 --- /dev/null +++ b/image/test/mochitest/restore-previous.png diff --git a/image/test/mochitest/rillybad.jpg b/image/test/mochitest/rillybad.jpg Binary files differnew file mode 100644 index 0000000000..e2fb1d303f --- /dev/null +++ b/image/test/mochitest/rillybad.jpg diff --git a/image/test/mochitest/schrep.png b/image/test/mochitest/schrep.png Binary files differnew file mode 100644 index 0000000000..bcb406387d --- /dev/null +++ b/image/test/mochitest/schrep.png diff --git a/image/test/mochitest/shaver.png b/image/test/mochitest/shaver.png Binary files differnew file mode 100644 index 0000000000..ab0b6c7b40 --- /dev/null +++ b/image/test/mochitest/shaver.png diff --git a/image/test/mochitest/short_header.gif b/image/test/mochitest/short_header.gif Binary files differnew file mode 100644 index 0000000000..70af95ac6d --- /dev/null +++ b/image/test/mochitest/short_header.gif diff --git a/image/test/mochitest/source.png b/image/test/mochitest/source.png Binary files differnew file mode 100644 index 0000000000..df1c76dae5 --- /dev/null +++ b/image/test/mochitest/source.png diff --git a/image/test/mochitest/test_animSVGImage.html b/image/test/mochitest/test_animSVGImage.html new file mode 100644 index 0000000000..a405cdd46b --- /dev/null +++ b/image/test/mochitest/test_animSVGImage.html @@ -0,0 +1,124 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=610419 +--> +<head> + <title>Test for Bug 610419</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=610419">Mozilla Bug 610419</a> +<p id="display"></p> +<div id="content"> + <div id="referenceDiv" style="height: 100px; width: 100px; + display: none; background: lime"></div> + <img> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 610419**/ + +SimpleTest.requestFlakyTimeout("Pre-existing timeouts when converting from mochitest-chrome"); +SimpleTest.requestCompleteLog(); +SimpleTest.waitForExplicitFinish(); + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +const gImg = document.getElementsByTagName("img")[0]; + +var gMyDecoderObserver; // value will be set in main() +var gReferenceSnapshot; // value will be set in takeReferenceSnapshot() +var gPollCounter = 0; +var gIsTestFinished = false; +var gSVGImages = [ + "lime-anim-100x100.svg", // SMIL animation + "lime-css-anim-100x100.svg" // CSS animation +] +var gSVGCurrentImage = 0; + +function takeReferenceSnapshot() { + // Take a snapshot of the initial (essentially blank) page + let blankSnapshot = snapshotWindow(window, false); + + // Show reference div, & take a snapshot + let referenceDiv = document.getElementById("referenceDiv"); + referenceDiv.style.display = "block"; + gReferenceSnapshot = snapshotWindow(window, false); + ok(compareSnapshots(blankSnapshot, gReferenceSnapshot, false)[0], + "reference snapshot shouldn't match blank page snapshot"); + + // Re-hide reference div, and take another snapshot to be sure it's gone + referenceDiv.style.display = "none"; + let blankSnapshot2 = snapshotWindow(window, false); + ok(compareSnapshots(blankSnapshot, blankSnapshot2, true)[0], + "reference div should disappear when it becomes display:none"); +} + +function loadNextImageAndPoll() +{ + setTimeout(myPoll, 1); + // kick off image-loading! myPoll handles the rest. + gImg.setAttribute("src", gSVGImages[gSVGCurrentImage]); +} + +function myPoll() { + gPollCounter++; + ok(true, "myPoll called"); + let currentSnapshot = snapshotWindow(window, false); + if (compareSnapshots(currentSnapshot, gReferenceSnapshot, true)[0]) { + // SUCCESS! + ok(true, "Animated image looks correct, " + + "at call #" + gPollCounter + " to myPoll"); + + if (++gSVGCurrentImage > gSVGImages.length) { + cleanUpAndFinish(); + } else { + loadNextImageAndPoll(); + } + } + else { + setTimeout(myPoll, 20); + } +} + +function failTest() { + ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " + + "Animated image still doesn't look correct, " + + "after call #" + gPollCounter + " to myPoll"); + cleanUpAndFinish(); +} + +function cleanUpAndFinish() { + // On the off chance that failTest and myPoll are triggered + // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. + if (gIsTestFinished) { + return; + } + SimpleTest.finish(); + gIsTestFinished = true; +} + +function main() { + takeReferenceSnapshot(); + + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + loadNextImageAndPoll(); + + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, FAILURE_TIMEOUT); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_animSVGImage2.html b/image/test/mochitest/test_animSVGImage2.html new file mode 100644 index 0000000000..0f3ae046c5 --- /dev/null +++ b/image/test/mochitest/test_animSVGImage2.html @@ -0,0 +1,124 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=907503 +--> +<head> + <title>Test for Bug 907503</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907503">Mozilla Bug 907503</a> +<p id="display"></p> +<div id="content"> + <div id="referenceDiv" style="height: 100px; width: 100px; + display: none; background: lime"></div> + <img> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 907503**/ + +SimpleTest.requestFlakyTimeout("Early failure timeout"); +SimpleTest.waitForExplicitFinish(); + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const gImg = document.getElementsByTagName("img")[0]; + +var gMyDecoderObserver; // value will be set in main() +var gReferenceSnapshot; // value will be set in takeReferenceSnapshot() +var gOnFrameUpdateCounter = 0; +var gIsTestFinished = false; + + +function takeReferenceSnapshot() { + // Take a snapshot of the initial (essentially blank) page + let blankSnapshot = snapshotWindow(window, false); + + // Show reference div, & take a snapshot + let referenceDiv = document.getElementById("referenceDiv"); + referenceDiv.style.display = "block"; + gReferenceSnapshot = snapshotWindow(window, false); + ok(compareSnapshots(blankSnapshot, gReferenceSnapshot, false)[0], + "reference snapshot shouldn't match blank page snapshot"); + + // Re-hide reference div, and take another snapshot to be sure it's gone + referenceDiv.style.display = "none"; + let blankSnapshot2 = snapshotWindow(window, false); + ok(compareSnapshots(blankSnapshot, blankSnapshot2, true)[0], + "reference div should disappear when it becomes display:none"); +} + +function myOnFrameUpdate(aRequest) { + if (gIsTestFinished) { + return; + } + gOnFrameUpdateCounter++; + ok(true, "myOnFrameUpdate called"); + let currentSnapshot = snapshotWindow(window, false); + if (compareSnapshots(currentSnapshot, gReferenceSnapshot, true)[0]) { + // SUCCESS! + ok(true, "Animated image looks correct, " + + "at call #" + gOnFrameUpdateCounter + " to myOnFrameUpdate"); + cleanUpAndFinish(); + } +} + +function failTest() { + if (gIsTestFinished) { + return; + } + ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " + + "Animated image still doesn't look correct, " + + "after call #" + gOnFrameUpdateCounter + " to myOnFrameUpdate"); + cleanUpAndFinish(); +} + +function cleanUpAndFinish() { + // On the off chance that failTest and myOnFrameUpdate are triggered + // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. + if (gIsTestFinished) { + return; + } + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.removeObserver(gMyDecoderObserver); + SimpleTest.finish(); + gIsTestFinished = true; +} + +function main() { + takeReferenceSnapshot(); + + // Create, customize & attach decoder observer + var observer = new ImageDecoderObserverStub(); + observer.frameUpdate = myOnFrameUpdate; + gMyDecoderObserver = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer)); + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.addObserver(gMyDecoderObserver); + + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + // kick off image-loading! myOnFrameUpdate handles the rest. + gImg.setAttribute("src", "lime-anim-100x100-2.svg"); + + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, FAILURE_TIMEOUT); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_animated_css_image.html b/image/test/mochitest/test_animated_css_image.html new file mode 100644 index 0000000000..ca4a47915f --- /dev/null +++ b/image/test/mochitest/test_animated_css_image.html @@ -0,0 +1,223 @@ +<!doctype html> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="/tests/SimpleTest/WindowSnapshot.js"></script> +<!-- + scrolling=no is just paranoia to ensure that we don't get invalidations + due to scrollbars +--> +<iframe scrolling="no" id="iframe"></iframe> +<script> +SimpleTest.waitForExplicitFinish(); + +// We hit an optimized path in WebRender that doesn't cause a repaint on the +// main thread: +// +// https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553 +// +// So our assertions and polling need to be a bit weaker on WR. +const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender"); + +let iframe = document.getElementById("iframe"); +let blankSnapshot; + +async function assertAnimates(html, getExpectedRepaintedElement) { + const kExpectEqual = true; + const kNumRetries = kUsingWebRender ? 600 : 30; + + info("testing: " + html); + + { + let load = new Promise(resolve => { + iframe.addEventListener("load", resolve, { once: true }); + }); + iframe.srcdoc = html; + await load; + } + + // This ensures the MozAfterPaint events come through as expected. + await SimpleTest.promiseFocus(iframe.contentWindow); + + let initial = await snapshotWindow(iframe.contentWindow); + + let repaintedElement = getExpectedRepaintedElement(iframe.contentDocument); + if (!kUsingWebRender) { + // Ensure the painted state is clear before we start polling. + SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement); + } + + { + let [equal, s1 /* , s2, differentPixels, maxDiff */] = compareSnapshots(initial, blankSnapshot, kExpectEqual); + ok(!equal, "Initial snapshot shouldn't be blank"); + info(s1); + } + + let foundDifferent = false; + let foundInitialAgain = false; + for (let i = 0; i < kNumRetries; ++i) { + let current = await snapshotWindow(iframe.contentWindow); + let [equal, /* s1 */, s2 /* , differentPixels, maxDiff */ ] = compareSnapshots(initial, current, kExpectEqual); + if (!foundDifferent && !equal) { + ok(true, `Found different image after ${i} retries`); + ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element"); + info(s2); + foundDifferent = true; + } + + // Ensure that we go back to the initial state (animated1.gif) is an + // infinite gif. + if (foundDifferent && equal) { + ok(true, `Found same image again after ${i} retries`); + ok(kUsingWebRender || SpecialPowers.DOMWindowUtils.checkAndClearPaintedState(repaintedElement), "Should've repainted the expected element"); + foundInitialAgain = true; + break; + } + + await new Promise(resolve => { + if (kUsingWebRender) { + requestAnimationFrame(() => { + requestAnimationFrame(resolve); + }); + } else { + iframe.contentWindow.addEventListener("MozAfterPaint", resolve, { once: true }); + } + }); + } + + ok(foundDifferent && foundInitialAgain, `Should've found a different snapshot and then an equal one, after ${kNumRetries} retries`); +} + +const kTests = [ + // Sanity test: background-image on a regular element. + { + html: ` + <!doctype html> + <style> + div { + width: 100px; + height: 100px; + background-image: url(animated1.gif); + } + </style> + <div></div> + `, + element(doc) { + return doc.querySelector("div"); + }, + }, + + // bug 1627585: content: url() + { + html: ` + <!doctype html> + <style> + div::before { + content: url(animated1.gif); + } + </style> + <div></div> + `, + element(doc) { + return doc.querySelector("div"); + }, + }, + + // bug 1627585: content: url() (on an element directly) + { + html: ` + <!doctype html> + <style> + div { + content: url(animated1.gif); + } + </style> + <div></div> + `, + element(doc) { + return doc.querySelector("div"); + }, + }, + + // bug 1625571: background propagated to canvas. + { + html: ` + <!doctype html> + <style> + body { + background-image: url(animated1.gif); + } + </style> + `, + element(doc) { + return doc.documentElement; + }, + }, + + // bug 1719375: CSS animation in SVG image. + { + html: ` + <!doctype html> + <style> + div { + width: 100px; + height: 100px; + background-image: url(animated1.svg); + } + </style> + <div></div> + `, + element(doc) { + return doc.querySelector("div"); + }, + }, + + // bug 1730834: stopped window. + { + html: ` + <!doctype html> + <style> + div { + width: 100px; + height: 100px; + } + </style> + <body onload="window.stop(); document.querySelector('div').style.backgroundImage = 'url(animated1.gif)';"> + <div></div> + </body> + `, + element(doc) { + return doc.querySelector("div"); + }, + }, + + // bug 1731138: Animated mask + { + html: ` + <!doctype html> + <style> + div { + width: 100px; + height: 100px; + background-color: lime; + mask-clip: border-box; + mask-size: 100% 100%; + mask-image: url(animatedMask.gif); + } + </style> + <div></div> + `, + element(doc) { + return doc.querySelector("div"); + }, + }, +]; + +onload = async function() { + // First snapshot the blank window. + blankSnapshot = await snapshotWindow(iframe.contentWindow); + + for (let { html, element } of kTests) + await assertAnimates(html, element); + + SimpleTest.finish(); +} +</script> diff --git a/image/test/mochitest/test_animated_gif.html b/image/test/mochitest/test_animated_gif.html new file mode 100644 index 0000000000..814749b7f0 --- /dev/null +++ b/image/test/mochitest/test_animated_gif.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>Images outside of display port are not decoded</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="imgutils.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<div id="scroller" style="height: 300px; overflow: scroll;"> + <div style="width: 100%; height: 12000px;"></div> + <iframe id="iframe"></iframe> + <div style="width: 100%; height: 5000px;"></div> +</div> +<pre id="test"></pre> +<script> + add_task(async () => { + window.addEventListener("message", event => { + isnot(event.data, "decodeComplete", + "decodeComplete should never be received"); + }); + + await new Promise(resolve => { + window.addEventListener("message", event => { + if (event.data == "loadComplete") { + ok(true, "Got loadComplete"); + resolve(); + } + }, { once: true }); + + const iframe = document.getElementById("iframe"); + iframe.src = "http://example.org/tests/image/test/mochitest/child.html"; + }); + + const start = Date.now(); + + // Waits a second; + await SimpleTest.promiseWaitForCondition(() => { + return 1000 < (Date.now() - start); + }); + + ok(true, "decodeComplete didn't receive within a second"); + }); + +</script> +</body> +</html> diff --git a/image/test/mochitest/test_animation.html b/image/test/mochitest/test_animation.html new file mode 100644 index 0000000000..725cd93e85 --- /dev/null +++ b/image/test/mochitest/test_animation.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - General Animated GIF Test</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> +Mozilla Bug 666446: lots of animated gifs swamp us with paint events +</a> +<p id="display"></p> + +<div id="content"> + <div id="referenceDiv" style="height: 40px; width: 40px; + display: none; background: #2aff00"></div> + <div id="animatedImage"> + <img id="animatedGif" src="animated-gif.gif" style="display: none;"> + <div id="text-descr"></div> + </div> + <div id="debug" style="display:none"> + </div> +</div> +<pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() +{ + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedGif', 'debug'); + animTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_animation2.html b/image/test/mochitest/test_animation2.html new file mode 100644 index 0000000000..1b4e0f94c7 --- /dev/null +++ b/image/test/mochitest/test_animation2.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=705580 +--> +<head> + <title>Test for Bug 705580 - General Animated GIF Test 2</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=705580"> +Mozilla Bug 705580: Test animated GIFs that are converted to ImageLayers +</a> +<p id="display"></p> + +<div id="content"> + <!-- + Use will-change: opacity to force a ContainerLayer, and the img as the sole item in the PaintedLayer. It should then + be promoted to an ImageLayer. + --> + <div id="referenceDiv" style="height: 40px; width: 40px; + display: none; background: #2aff00;"></div> + <div id="animatedImage" style="will-change: opacity;"> + <img id="animatedGif" src="animated-gif.gif" style="display: none;"> + <div id="text-descr"></div> + </div> + <div id="debug" style="display:none"> + </div> +</div> +<pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() +{ + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedGif', 'debug'); + animTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_animation_operators.html b/image/test/mochitest/test_animation_operators.html new file mode 100644 index 0000000000..2d3a6f6d67 --- /dev/null +++ b/image/test/mochitest/test_animation_operators.html @@ -0,0 +1,167 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=936720 +--> +<head> + <title>Test for Bug 936720</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=936720">Mozilla Bug 936720</a> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 936720 **/ + +// Because there is no event telling us when an animated image finishes +// animating, tests for the operators used by animated GIFs and PNGs +// require that we poll until we get the correct result. A fixed timeout +// can easily result in intermittent failures on tests running in VMs. + +// (Note that we do _not_ poll the reference, so it must not be animated.) + +var gTests = [ + // IMPORTANT NOTE: For these tests, the test and reference are not + // snapshotted in the same way. The REFERENCE (second file) is + // assumed to be complete when loaded, but we poll the TEST + // (first file) until the test passes. + + // Tests of the allowed disposal operators for GIF, APNG and WebP: keep, clear, + // and restore previous. + "== green-background.html?clear.gif green.png", + "== green-background.html?clear.png green.png", + "== green-background.html?clear.webp green.png", + "== green-background.html?clear.avif green.png", + "== keep.gif green.png", + "== keep.png green.png", + "== keep.webp green.png", + "== restore-previous.gif green.png", + "== restore-previous.png green.png", + + // Tests of the blending/compositing operators that only APNG supports. + "== over.png grey.png", + "!= source.png grey.png", + "== bug900200.png bug900200-ref.png", + "== bug1319025.png bug1319025-ref.png", + + // Test of subframe updates. + "== clear2.gif clear2-results.gif", + "== clear2.webp clear2-results.gif", +]; + +// Maintain a reference count of how many things we're waiting for until +// we can say the tests are done. +var gDelayCount = 0; +function AddFinishDependency() + { ++gDelayCount; } +function RemoveFinishDependency() + { if (--gDelayCount == 0) SimpleTest.finish(); } + +// We record the maximum number of times we had to look at a test before +// it switched to the passing state (though we assume it's 10 to start +// rather than 0 so that we have a reasonable default). Then we make a +// test "time out" if it takes more than gTimeoutFactor times that +// amount of time. This allows us to report a test failure rather than +// making a test failure just show up as a timeout. +var gMaxPassingTries = 10; +var gTimeoutFactor = 10; + +function takeSnapshot(iframe_element) +{ + return snapshotWindow(iframe_element.contentWindow, false); +} + +function passes(op, shot1, shot2) +{ + var values = compareSnapshots(shot1, shot2, op == "=="); + return values[0]; +} + +function startTest(i) +{ + var testLine = gTests[i]; + var splitData = testLine.split(" "); + var testData = + { op: splitData[0], test: splitData[1], reference: splitData[2] }; + var tries = 0; + + // Maintain state specific to this test in the closure exposed to all + // the functions nested inside this one. + + function startIframe(url) + { + var element = document.createElement("iframe"); + element.addEventListener("load", handleLoad); + // Smaller than normal reftests, but enough for these. + element.setAttribute("style", "width: 100px; height: 100px"); + element.setAttribute("frameborder", "0"); + element.setAttribute("scrolling", "no"); + element.src = url; + document.body.appendChild(element); + function handleLoad(event) + { + iframe.loaded = true; + if (iframe == reference) { + reference.snapshot = takeSnapshot(element); + } + var other = (iframe == test) ? reference : test; + if (other.loaded) { + setTimeout(checkTest, 100); + } + } + function checkTest() + { + var test_snapshot = takeSnapshot(test.element); + if (passes(testData.op, test_snapshot, reference.snapshot)) { + if (tries > gMaxPassingTries) { + gMaxPassingTries = tries; + } + report(true); + } else { + ++tries; + if (tries > gMaxPassingTries * gTimeoutFactor) { + info("Giving up after " + tries + " tries, " + + "maxp=" + gMaxPassingTries + + "fact=" + gTimeoutFactor); + report(false); + } else { + // The animation might not have finished. Try again in 100ms. + setTimeout(checkTest, 100); + } + } + } + function report(result) + { + ok(result, "(" + i + ") " + + testData.op + " " + testData.test + " " + testData.reference); + RemoveFinishDependency(); + } + var iframe = { element, loaded: false }; + + return iframe; + } + + AddFinishDependency(); + var test = startIframe(testData.test); + var reference = startIframe(testData.reference); +} + +function runTests() +{ + // Run the tests. + for (var i = 0; i < gTests.length; ++i) { + startTest(i); + } +} + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +runTests(); + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_background_image_anim.html b/image/test/mochitest/test_background_image_anim.html new file mode 100644 index 0000000000..f1aeb6288b --- /dev/null +++ b/image/test/mochitest/test_background_image_anim.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - Animated Background Images</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> +Mozilla Bug 666446: lots of animated gifs swamp us with paint events +</a> +<p id="display"></p> +<div id="content"> + <div id="referenceDiv" style="height: 140px; width: 140px; + display: none; background: #2aff00"></div> + <div id="bgImage" style="height: 140px; width: 140px; background-image: url(animated-gif.gif); display: none;"> + </div> +</div> +<div id="debug" style="display:none"></div> +<pre id="test"> +<script type="text/javascript"> + +/** Test for Bug 666446 nsImageLoader/RasterImage**/ + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() { + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'bgImage', 'debug'); + animTest.beginTest(); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug1132427.html b/image/test/mochitest/test_bug1132427.html new file mode 100644 index 0000000000..0ee2872fea --- /dev/null +++ b/image/test/mochitest/test_bug1132427.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for scrolling selection into view</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +// We open a window which contains two copies of the same gif. One at a scaled size, one at the +// natural image size. We rely on the bug only showing up in the scaled image. The gif has three +// frames and a delay of 100ms. The first is all white. The second has a very small update area +// in the upper left, it changes the pixels to slightly off white. The third changes all the +// pixels to blue. When the bug appears we only update the upper left pixels when looping around +// from the last frame to the first frame. We compare a middle pixel of the two images to make +// sure that they are the same at 100ms for a second. If the bug appears then the middle pixel +// on the scaled image will always be blue and so should not match the middle pixel on the +// unscaled image which should be white two thirds of the time. If the timers fire at bad times +// and only fire when both frames are displaying blue we won't be able to detect this bug and the +// test will pass without testing anything important, but that's not a big deal. That should be +// rare enough, and the next time the test is run will should do proper testing. + +SimpleTest.requestFlakyTimeout("Pre-existing timeouts when converting from mochitest-chrome"); +SimpleTest.waitForExplicitFinish(); +addLoadEvent(openWindow); + +var win = null; + +function openWindow() { + win = window.open("bug1132427.html", + "", "scrollbars=yes,toolbar,menubar,width=600,height=800"); + win.focus(); +} + +function doTest() { + setTimeout(continueTest, 1000); +} + +function checkPixel(canvas, context, x1, y1, x2, y2) { + var pix = context.getImageData(0, 0, canvas.width, canvas.height).data; + for (var i = 0; i < 4; i++) { + is(pix[4 * (y1 * canvas.width + x1) + i], pix[4 * (y2 * canvas.width + x2) + i], "pixels should match"); + } +} + +var iterationsLeft = 10; + +function continueTest() { + // we need to drawWindow the chrome window so we can get a dump of the retained widget layers + // if we have to repaint to fulfill this drawWindow request then it will be impossible to + // observe the bug + // XXX(kmag): This test has not had access to a chrome window since the dawn + // of e10s. I'm not sure how accurate the above comment was even before that + // point, but it certainly is not accurate now. + var topWin = SpecialPowers.wrap(win).top; + + var el = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); + el.width = topWin.innerWidth; + el.height = topWin.innerHeight; + var ctx = el.getContext("2d"); + // pass the correct flags so we don't have to flush the retained layers + SpecialPowers.wrap(ctx).drawWindow(topWin, 0, 0, topWin.innerWidth, topWin.innerHeight, "rgba(0,0,0,0)", + ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_DRAW_CARET); + + var leftbox = win.document.getElementById("left").getBoundingClientRect(); + var rightbox = win.document.getElementById("right").getBoundingClientRect(); + // this is actually chrome on left and right, but in practice we have none so it doesn't matter + var chromeleft = win.outerWidth - win.innerWidth; + // this is actually chrome on top and bottom, but bottom chrome is usually small to none and we have + // 100px to spare in hitting the middle of the image elements (they are 200x200) + var chrometop = win.outerHeight - win.innerHeight; + + // compare the middle of the two image elements + checkPixel(el, ctx, chromeleft + leftbox.left + Math.floor(leftbox.width/2), chrometop + leftbox.top + Math.floor(leftbox.height/2), + chromeleft + rightbox.left + Math.floor(rightbox.width/2), chrometop + rightbox.top + Math.floor(rightbox.height/2)); + + iterationsLeft--; + if (iterationsLeft > 0) { + // now test 100ms later, we should have the next frame of the gif then + setTimeout(continueTest, 100); + } else { + win.close(); + SimpleTest.finish(); + } +} +</script> +</pre> +</body> + +</html> diff --git a/image/test/mochitest/test_bug1180105.html b/image/test/mochitest/test_bug1180105.html new file mode 100644 index 0000000000..579c8db760 --- /dev/null +++ b/image/test/mochitest/test_bug1180105.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1180105 +--> +<head> + <title>Test for Bug 1180105</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="initializeOnload()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1180105">Mozilla Bug 1180105</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +const WAITER_URL = "bug1180105-waiter.sjs"; + +function initializeOnload() { + var firstimg = document.createElement('img'); + firstimg.src = "bug1180105.sjs"; + document.getElementById('content').appendChild(firstimg); + + waitForFinish(); +} + +function waitForFinish() { + var loader = document.getElementById("loader"); + loader.src = WAITER_URL; + loader.onload = function() { + var img = document.getElementsByTagName('img')[0]; + ok(img.width > 0, "Image should be loaded by now"); + SimpleTest.finish(); + }; +} + +</script> +</pre> +<div id="content">> +<iframe id="loader"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug1217571.html b/image/test/mochitest/test_bug1217571.html new file mode 100644 index 0000000000..f81fc7c51d --- /dev/null +++ b/image/test/mochitest/test_bug1217571.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1217571 +--> +<head> + <title>Test for Bug 1217571</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1217571">Mozilla Bug 1217571</a> +<p id="display"></p> +<iframe src="bug1217571-iframe.html"></iframe> +<iframe src="bug1217571-iframe.html"></iframe> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 614392**/ + +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + // Each iframe loads the same image. Both images should share the same + // container from the image cache. Check that this holds true. + var iframes = document.getElementsByTagName("iframe"); + var imgs = Array.from(iframes, function (f) { + return SpecialPowers.wrap(f.contentDocument.getElementsByTagName("img")[0]); + }); + var containers = imgs.map(function (img) { + return img.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST) + .image; + }); + + ok(SpecialPowers.compare(containers[0], containers[1]), + "containers for identical images in different iframes should be identical"); + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug1325080.html b/image/test/mochitest/test_bug1325080.html new file mode 100644 index 0000000000..91dea11173 --- /dev/null +++ b/image/test/mochitest/test_bug1325080.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1325080 +--> +<head> + <title>Test for Bug 1325080</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1325080">Mozilla Bug 1325080</a> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 1325080 **/ + +SimpleTest.waitForExplicitFinish(); + +function createImage() { + // This function's code comes from the Acid3 test #72 + document.open(); + document.write('<!DOCTYPE html><head><style>img { height: 10px; }</style></head><body><img src="data:image/gif;base64,R0lGODlhAQABAID%2FAMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D" alt="alt-text"></body>'); + document.close(); +} + +window.onload = function() { + createImage(); + SimpleTest.executeSoon(() => { + ok(document.images[0].height == 10, "Style should set height of image."); + SimpleTest.finish(); + }); +} + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug399925.html b/image/test/mochitest/test_bug399925.html new file mode 100644 index 0000000000..ae45479377 --- /dev/null +++ b/image/test/mochitest/test_bug399925.html @@ -0,0 +1,102 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=399925 +--> +<head> + <title>Test for Bug 399925</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=399925">Mozilla Bug 399925</a> +<p id="display"></p> +<div id="content" style="display: none"> +<canvas id="canvas" width="100" height="100"> </canvas> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 399925. **/ +var triggerDiscardingManually = false; +var pngResults = []; +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +window.onload = function() { + // It'd be nice to reduce the discard timer here, but unfortunately we only + // read that pref on startup. We instead manually trigger discarding on + // platforms where the discard timer is too long (which we'll somewhat + // arbitrarily define as 'longer than 60 seconds'). + var expirationMs = + SpecialPowers.getIntPref('image.mem.surfacecache.min_expiration_ms'); + if (expirationMs > 60000) { + ok(true, 'Triggering discarding manually because SurfaceCache expiration ' + + 'is ' + expirationMs + ' ms'); + triggerDiscardingManually = true; + } else { + ok(true, 'Using normal discarding because SurfaceCache expiration ' + + 'is ' + expirationMs + ' ms'); + } + + // Enable discarding for the test. + SpecialPowers.pushPrefEnv({ + 'set':[['image.mem.discardable',true]] + }, runTest); +} + +function runTest() { + var image = new Image(); + image.setAttribute("id", "gif"); + + // 1. Draw the canvas once on loadComplete + // 2. Redraw the canvas and compare the results right on discard + addCallbacks(image, drawCanvas, function() { + drawCanvas(); + is(pngResults[0], pngResults[1], "got different rendered results"); + SimpleTest.finish(); + }); + + image.src = "bug399925.gif"; + document.getElementById("content").appendChild(image); + + if (triggerDiscardingManually) { + var request = SpecialPowers.wrap(image) + .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST); + setTimeout(() => request.requestDiscard(), 1000); + } +} + +function addCallbacks(anImage, loadCompleteCallback, discardCallback) { + var observer = new ImageDecoderObserverStub(); + observer.discard = function () { + imgLoadingContent.removeObserver(scriptedObserver); + discardCallback(); + } + observer.loadComplete = loadCompleteCallback; + observer = SpecialPowers.wrapCallbackObject(observer); + + var scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"] + .getService(SpecialPowers.Ci.imgITools) + .createScriptedObserver(observer); + + var imgLoadingContent = SpecialPowers.wrap(anImage); + imgLoadingContent.addObserver(scriptedObserver); +} + +function drawCanvas() { + var canvas = document.getElementById('canvas'); + var context = canvas.getContext('2d'); + var gif = document.getElementById('gif'); + + context.drawImage(gif, 0, 0); + ok(true, "we got through the drawImage call without an exception being thrown"); + pngResults.push(canvas.toDataURL()); +} + +</script> +</pre> +</body> +</html> + diff --git a/image/test/mochitest/test_bug415761.html b/image/test/mochitest/test_bug415761.html new file mode 100644 index 0000000000..f3bf6c67a8 --- /dev/null +++ b/image/test/mochitest/test_bug415761.html @@ -0,0 +1,117 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for icon filenames</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +// We want to make sure that moz-icon URIs with non-ascii characters work. To that +// end, we compare the rendering of an icon without non-ascii characters to that +// of one that does include such characters. + +// First, obtain the file URI to the ourselves: +var chromeURI = location.href; +var io = Services.io; +chromeURI = io.newURI(chromeURI); +var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"] + .getService(Ci.nsIChromeRegistry); +var fileURI = chromeReg.convertChromeURL(chromeURI); +fileURI.QueryInterface(Ci.nsIFileURL); +var self = fileURI.file; + +// Check if the ref or test icon are still hanging around from a previous test +var testDest = self.parent; +var refDest = self.parent; +testDest.append("\u263a.ico"); +refDest.append("bug415761-ref.ico"); +if (testDest.exists()) { + testDest.remove(false); +} +if (refDest.exists()) { + refDest.remove(false); +} + +// Copy the source icon so that we have two identical icons with, one with +// non-ascii characters in its name. +var src = self.parent; +src.append("bug415761.ico"); +src.copyTo(null, testDest.leafName); +src.copyTo(null, refDest.leafName); + +// Now load both icons in an Image() with a moz-icon URI +var testImage = new Image(); +var refImage = new Image(); + +var loadedImages = 0; +testImage.onload = refImage.onload = function() { + loadedImages++; + if (loadedImages == 2) { + finishTest(); + } +}; +testImage.onerror = refImage.onerror = function() { + testImage.onload = refImage.onload = function() {}; + + ok(false, "Icon did not load successfully"); + SimpleTest.finish(); +}; + +function finishTest() { + ok(true, "Both icons loaded successfully"); + // Render the reference to a canvas + var refCanvas = document.createElement("canvas"); + refCanvas.setAttribute("height", 32); + refCanvas.setAttribute("width", 32); + refCanvas.getContext('2d').drawImage(refImage, 0, 0, 32, 32); + + // A blank canvas to compare to to make sure we don't draw nothing. + var blankCanvas = document.createElement("canvas"); + blankCanvas.setAttribute("height", 32); + blankCanvas.setAttribute("width", 32); + + // Assert that they should be the different. + if (!navigator.userAgent.includes("Windows NT 6.1")) { + // Fails on Windows 7 for some reason. + assertSnapshots(blankCanvas, refCanvas, false, 0, "blank", "reference icon"); + } + + // Render the icon with a non-ascii character in its name to a canvas + var testCanvas = document.createElement("canvas"); + testCanvas.setAttribute("height", 32); + testCanvas.setAttribute("width", 32); + testCanvas.getContext('2d').drawImage(testImage, 0, 0, 32, 32); + + // Assert that they should be the same. + assertSnapshots(testCanvas, refCanvas, true, 0, "icon", "reference icon"); + SimpleTest.finish(); +}; + +var testURI = io.newFileURI(testDest).spec; +var refURI = io.newFileURI(refDest).spec; +testImage.src = "moz-icon:" + testURI; +refImage.src = "moz-icon:" + refURI; + +SimpleTest.registerCleanupFunction(function() { + // Remove the copied files if they exist. + if (testDest.exists()) { + testDest.remove(false); + } + if (refDest.exists()) { + refDest.remove(false); + } +}); + +</script> +</pre> +</body> + +</html> + diff --git a/image/test/mochitest/test_bug435296.html b/image/test/mochitest/test_bug435296.html new file mode 100644 index 0000000000..1610410b16 --- /dev/null +++ b/image/test/mochitest/test_bug435296.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=435296 +--> +<head> + <title>Test for Bug 435296</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435296">Mozilla Bug 435296</a> +<img id="testimage" style="display: none;"> +<pre id="test"> +<script type="application/javascript"> + +// Boilerplate +SimpleTest.waitForExplicitFinish(); + +// Assert that discarding isn't enabled, which might make this test go orange. +ok(!getImagePref(DISCARD_ENABLED_PREF), "discarding should NOT be enabled here"); + +// We want to make sure d-o-d is enabled, since that's what we're testing +var oldDODPref = getImagePref(DECODEONDRAW_ENABLED_PREF); +setImagePref(DECODEONDRAW_ENABLED_PREF, true); + +// We're relying on very particular behavior for certain images - clear the +// image cache. +clearImageCache(); + +// In order to work around the effects introduced in bug 512435, we only load +// the image after window onload fires +function windowLoadHandler() +{ + // Set the source and an onload handler + var image = document.getElementById("testimage"); + image.src = "schrep.png"; + image.onload = imageLoadHandler; +} + +function imageLoadHandler() +{ + // The image is hidden, so it should not be decoded + ok(!isFrameDecoded("testimage"), "image should not be decoded"); + + // Make the image visible + var image = document.getElementById("testimage"); + image.style.display = "inline"; + + // Wait for the image to decode + setTimeout(function() { + tryToFinish(); + }, 500); +} + +function tryToFinish() +{ + // If it hasn't happened yet, wait longer. If it never happens, this test + // will timeout after 300 seconds... + if (!isFrameDecoded("testimage")) { + setTimeout(function() { + tryToFinish(); + }, 500); + return; + } + + // By definition, the image is decoded here. Give ourselves a pat on the back. + ok(isFrameDecoded("testimage"), "image should be decoded"); + + // Restore the decode-on-draw pref + setImagePref(DECODEONDRAW_ENABLED_PREF, oldDODPref); + + // All done + SimpleTest.finish(); +} + +// Set our onload handler, making sure we have focus +window.onload = SimpleTest.waitForFocus(windowLoadHandler); + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug466586.html b/image/test/mochitest/test_bug466586.html new file mode 100644 index 0000000000..fb900dc2b3 --- /dev/null +++ b/image/test/mochitest/test_bug466586.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=466586 +--> +<head> + <title>Test for Bug 466586</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body onload="loadSmall();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 466586</a> +<p id="display"></p> +<div id="content" style="display: none"> + <img id="big" src="big.png"/> +</div> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var jsBig = new Image(); + +// We have loaded the large png with id "big". We want to test if it will be +// kicked out of the cache and thus have to be reloaded, but to ensure that, we +// need to get the cache to look at what is there. So we load another image, +// this one small. +function loadSmall() +{ + // Trivial check, for reference. + is(document.getElementById("big").width, 3000, + "HTML 'big' image width after page onload()"); + + var small = new Image(); + small.onload = smallLoaded; + small.src = "red.png"; +} + +function smallLoaded() +{ + jsBig.src = document.getElementById("big").src; + // Check that it is not needed to wait for onload(). + is(jsBig.width, 3000, "JS 'big' image width before its onload()"); + // Check again after onload(), for reference. + jsBig.onload = jsBigLoaded; +} + +function jsBigLoaded() +{ + is(jsBig.width, 3000, "JS 'big' image width after its onload()"); + + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug468160.html b/image/test/mochitest/test_bug468160.html new file mode 100644 index 0000000000..cb33454e1b --- /dev/null +++ b/image/test/mochitest/test_bug468160.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=468160 +--> +<head> + <title>Test for Bug 468160</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=468160">Mozilla Bug 468160</a> +<p id="display"></p> +<div id="content" style="display: none"> +<!-- bug468160.sjs does a simple redirect to a PNG image. As long as this + doesn't leak, this test passes. --> + +<object data="bug468160.sjs"></object> + +</div> +<pre id="test"> +<script type="application/javascript"> + +ok(true, "test passed"); + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug478398.html b/image/test/mochitest/test_bug478398.html new file mode 100644 index 0000000000..45ab6acc2f --- /dev/null +++ b/image/test/mochitest/test_bug478398.html @@ -0,0 +1,87 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=478398 +--> +<head> + <title>Test for Bug 478398</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478398">Mozilla Bug 478398</a> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 399925. **/ +var oldTimeoutPref; +var oldDiscardPref; +SimpleTest.waitForExplicitFinish(); +window.onload = stage1; +var imageFilename = "bug478398_ONLY.png"; + +function stage1() +{ + // Get the current pref values + oldTimeoutPref = getImagePref(DISCARD_TIMEOUT_PREF); + oldDiscardPref = getImagePref(DISCARD_ENABLED_PREF); + + // We're testing discarding here + setImagePref(DISCARD_ENABLED_PREF, true); + + // Sets the discard timer to 500 ms (max timeout = 2*500ms = 1s) + setImagePref(DISCARD_TIMEOUT_PREF, 500); + + // Create the image _after_ setting the discard timer pref + // This image was carefully constructed to make it a "big win" for discarding, + // so any reasonable heuristic should still discard it. + var image = new Image(); + image.setAttribute("id", "testimage"); + image.style.display = "none"; + image.src = imageFilename; + + // Put the image into the document + document.body.appendChild(image); + + // Wait for load, then do stage2 + image.onload = stage2; +} + +function stage2() +{ + // Make sure we're loaded + ok(isImageLoaded("testimage"), "image should be loaded"); + + // We're loaded - force a synchronous decode + forceDecode("testimage"); + + // We should be decoded + ok(isFrameDecoded("testimage"), "image should be decoded"); + + // Wait 1.5 seconds, then finish the test + setTimeout(function() { + finishTest();; + }, 1500); + +} + +function finishTest() +{ + // The image should be discarded by now + ok(!isFrameDecoded("testimage"), "image should have been discarded!"); + + // Reset the prefs + setImagePref(DISCARD_TIMEOUT_PREF, oldTimeoutPref); + setImagePref(DISCARD_ENABLED_PREF, oldDiscardPref); + + // Finish the test + SimpleTest.finish(); +} + + +</script> +</pre> +</body> +</html> + diff --git a/image/test/mochitest/test_bug490949.html b/image/test/mochitest/test_bug490949.html new file mode 100644 index 0000000000..8f1b70c8f4 --- /dev/null +++ b/image/test/mochitest/test_bug490949.html @@ -0,0 +1,112 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=490949 +--> +<head> + <title>Test for Bug 490949</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490949">Mozilla Bug 490949</a> +<p id="display"></p> +<div id="content" style="display: none"> +<canvas id="canvas" width="100" height="100"> </canvas> +</div> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var canvas = document.getElementById('canvas'); +var first, second, third; + +var RemoteCanvas = function() { + this.url = "bug490949-iframe.html"; +}; + +RemoteCanvas.CANVAS_WIDTH = 100; +RemoteCanvas.CANVAS_HEIGHT = 100; + +RemoteCanvas.prototype.load = function(cb) { + this.cb = cb; + + var windowWidth = window.innerWidth - 25; + var iframe; + iframe = document.createElement("iframe"); + iframe.id = "test-iframe"; + iframe.height = "10px"; + iframe.width = windowWidth + "px"; + iframe.style.visibility = "hidden"; + iframe.src = this.url; + // Here is where the magic happens... add a listener to the + // frame's onload event - it will call handleEvent + iframe.addEventListener("load", this, true); + // append to the end of the page + window.document.body.appendChild(iframe); +}; + +RemoteCanvas.prototype.reload = function(cb, force) { + this.cb = cb; + window.frames[0].location.reload(force); +} + +RemoteCanvas.prototype.handleEvent = function() { + // Look back up the iframe by id + var ldrFrame = document.getElementById("test-iframe"); + // Get a reference to the window object you need for the + // SpecialPowers.snapshotRect method + var remoteWindow = ldrFrame.contentWindow; + + // Draw canvas + canvas.style.width = RemoteCanvas.CANVAS_WIDTH + "px"; + canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + "px"; + canvas.width = RemoteCanvas.CANVAS_WIDTH; + canvas.height = RemoteCanvas.CANVAS_HEIGHT; + var windowWidth = window.innerWidth - 25; + var windowHeight = window.innerHeight; + + var rect = { left: 0, top: 0, width: windowWidth, height: windowHeight }; + var snapshot = SpecialPowers.snapshotRect(remoteWindow, rect, "rgb(0,0,0)"); + + var ctx = canvas.getContext("2d"); + ctx.clearRect(0, 0, + RemoteCanvas.CANVAS_WIDTH, + RemoteCanvas.CANVAS_HEIGHT); + ctx.save(); + ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth, + RemoteCanvas.CANVAS_HEIGHT / windowHeight); + ctx.drawImage(snapshot, 0, 0); + ctx.restore(); + this.cb(); +}; + +function checkFirst() +{ + first = canvas.toDataURL(); + remoteCanvas.reload(checkForceReload, true); +} + +function checkForceReload() +{ + second = canvas.toDataURL(); + ok(first != second, "We got the wrong image."); + remoteCanvas.reload(checkLazyReload, false); +} + +function checkLazyReload() +{ + third = canvas.toDataURL(); + ok(second != third, "We got the wrong image."); + SimpleTest.finish(); +} + +var remoteCanvas = new RemoteCanvas(); +remoteCanvas.load(checkFirst); + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug496292.html b/image/test/mochitest/test_bug496292.html new file mode 100644 index 0000000000..7f91539bf3 --- /dev/null +++ b/image/test/mochitest/test_bug496292.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=496292 +--> +<head> + <title>Test for Bug 496292</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=496292">Mozilla Bug 496292</a> +<p id="display"></p> +<div id="content" style="display: none"> +<canvas id="canvas" width="100" height="100"> </canvas> +</div> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var canvas = document.getElementById('canvas'); +var first, second, third, ref; + +var RemoteCanvas = function(url) { + this.url = url; +}; + +RemoteCanvas.CANVAS_WIDTH = 100; +RemoteCanvas.CANVAS_HEIGHT = 100; + +RemoteCanvas.prototype.load = function(cb) { + this.cb = cb; + + var windowWidth = window.innerWidth - 25; + var iframe; + iframe = document.createElement("iframe"); + iframe.id = "test-iframe-" + this.url; + iframe.height = "10px"; + iframe.width = windowWidth + "px"; + iframe.style.visibility = "hidden"; + iframe.src = this.url; + // Here is where the magic happens... add a listener to the + // frame's onload event - it will call handleEvent + iframe.addEventListener("load", this, true); + // append to the end of the page + window.document.body.appendChild(iframe); +}; + +RemoteCanvas.prototype.reload = function(cb, force) { + this.cb = cb; + window.frames[0].location.reload(force); +} + +RemoteCanvas.prototype.handleEvent = function() { + // Look back up the iframe by id + var ldrFrame = document.getElementById("test-iframe-" + this.url); + // Get a reference to the window object you need for the canvas + // SpecialPowers.snapshotRect method + var remoteWindow = ldrFrame.contentWindow; + + // Draw canvas + canvas.style.width = RemoteCanvas.CANVAS_WIDTH + "px"; + canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + "px"; + canvas.width = RemoteCanvas.CANVAS_WIDTH; + canvas.height = RemoteCanvas.CANVAS_HEIGHT; + var windowWidth = window.innerWidth - 25; + var windowHeight = window.innerHeight; + + var rect = { left: 0, top: 0, width: windowWidth, height: windowHeight }; + var snapshot = SpecialPowers.snapshotRect(remoteWindow, rect, "rgb(0,0,0)"); + + var ctx = canvas.getContext("2d"); + ctx.clearRect(0, 0, + RemoteCanvas.CANVAS_WIDTH, + RemoteCanvas.CANVAS_HEIGHT); + ctx.save(); + ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth, + RemoteCanvas.CANVAS_HEIGHT / windowHeight); + ctx.drawImage(snapshot, 0, 0); + ctx.restore(); + this.cb(); +}; + +function loadFirst() +{ + ref = canvas.toDataURL(); + + var remoteCanvas = new RemoteCanvas("bug496292-iframe-1.html"); + remoteCanvas.load(checkFirst); +} + +function checkFirst() +{ + first = canvas.toDataURL(); + is(first, ref, "The default Accept header used by image loader is correct"); + + SpecialPowers.setCharPref("image.http.accept", "image/png"); + SpecialPowers.pushPrefEnv({"set": [["image.http.accept", "image/png"]]}, function() { + var remoteCanvas = new RemoteCanvas("bug496292-iframe-2.html"); + remoteCanvas.load(checkSecond); + }); +} + +function checkSecond() +{ + second = canvas.toDataURL(); + is(second, ref, "The modified Accept header used by image loader is correct"); + + SpecialPowers.pushPrefEnv({"clear": [["image.http.accept"]]}, function() { + var remoteCanvas = new RemoteCanvas("bug496292-iframe-1.html"); + remoteCanvas.load(checkThird); + }); +} + +function checkThird() { + third = canvas.toDataURL(); + is(third, ref, "The Accept header used by image loader should be correctly reset"); + + SimpleTest.finish(); +} + +var refCanvas = new RemoteCanvas("bug496292-iframe-ref.html"); +refCanvas.load(loadFirst); + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug497665.html b/image/test/mochitest/test_bug497665.html new file mode 100644 index 0000000000..3914e43c64 --- /dev/null +++ b/image/test/mochitest/test_bug497665.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=497665 +--> +<head> + <title>Test for Bug 497665</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=497665">Mozilla Bug 497665</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +var image1first, image2first, image1second, image2second, image1third, image2third; + +SimpleTest.waitForExplicitFinish(); + +function checkFirst() +{ + var iframeelem = document.getElementById('test-iframe'); + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + + var firstimg = iframeelem.contentDocument.getElementById('image1'); + var secondimg = iframeelem.contentDocument.getElementById('image2'); + ctx.drawImage(firstimg, 0, 0); + image1first = canvas.toDataURL(); + ctx.drawImage(secondimg, 0, 0); + image2first = canvas.toDataURL(); + + ok(image1first == image2first, "We got different images, but shouldn't have."); + + iframeelem.onload = checkForceReload; + iframeelem.contentWindow.location.reload(true); +} + +function checkForceReload() +{ + var iframeelem = document.getElementById('test-iframe'); + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + + var firstimg = iframeelem.contentDocument.getElementById('image1'); + var secondimg = iframeelem.contentDocument.getElementById('image2'); + ctx.drawImage(firstimg, 0, 0); + image1second = canvas.toDataURL(); + ctx.drawImage(secondimg, 0, 0); + image2second = canvas.toDataURL(); + + ok(image1second == image2second, "We got different images after a force-reload, but shouldn't have."); + + // Sanity check that we actually reloaded. + ok(image1first != image1second, "We got the same images after a force-reload."); + + iframeelem.onload = checkReload; + iframeelem.contentWindow.location.reload(false); +} + +function checkReload() +{ + var iframeelem = document.getElementById('test-iframe'); + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + + var firstimg = iframeelem.contentDocument.getElementById('image1'); + var secondimg = iframeelem.contentDocument.getElementById('image2'); + ctx.drawImage(firstimg, 0, 0); + image1third = canvas.toDataURL(); + ctx.drawImage(secondimg, 0, 0); + image2third = canvas.toDataURL(); + + ok(image1third == image2third, "We got different images after a reload, but shouldn't have."); + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<canvas id="canvas" width="100" height="100"> </canvas> +<iframe id="test-iframe" src="bug497665-iframe.html" onload="checkFirst()"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug552605-1.html b/image/test/mochitest/test_bug552605-1.html new file mode 100644 index 0000000000..271b3599ce --- /dev/null +++ b/image/test/mochitest/test_bug552605-1.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=552605 +--> +<head> + <title>Test for Bug 552605</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552605">Mozilla Bug 552605</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +var first, second; + +SimpleTest.waitForExplicitFinish(); + +function checkFirst() +{ + var testimage = document.getElementById('test-image'); + first = document.createElement('canvas') + var ctx = first.getContext('2d'); + ctx.drawImage(testimage, 0, 0); + + var newimg = new Image(); + newimg.onload = checkSecond; + newimg.src = "bug552605.sjs"; + document.body.appendChild(newimg); +} + +function checkSecond() +{ + var testimage = document.getElementById('test-image'); + second = document.createElement('canvas') + var ctx = second.getContext('2d'); + ctx.drawImage(testimage, 0, 0); + + // Check that the images are the same, since they're in the same document. + var values = compareSnapshots(first, second, true); + ok(values[0], "Image should be the same for all loads."); + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<img src="bug552605.sjs" onload="checkFirst()" id="test-image"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug552605-2.html b/image/test/mochitest/test_bug552605-2.html new file mode 100644 index 0000000000..7869a9e481 --- /dev/null +++ b/image/test/mochitest/test_bug552605-2.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=552605 +--> +<head> + <title>Test for Bug 552605</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552605">Mozilla Bug 552605</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +var count = 0; + +SimpleTest.waitForExplicitFinish(); + +function check() +{ + count++; + if (count != 2) + return; + + var image1 = document.getElementById('test-image1'); + var image2 = document.getElementById('test-image2'); + var first = document.createElement('canvas') + var ctx = first.getContext('2d'); + ctx.drawImage(image1, 0, 0); + + var second = document.createElement('canvas'); + ctx = second.getContext('2d'); + ctx.drawImage(image2, 0, 0); + + // Check that the images are the same, since they're in the same document. + var values = compareSnapshots(first, second, true); + ok(values[0], "Image should be the same for all loads."); + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<img src="bug552605.sjs" onload="check()" id="test-image1"></iframe> +<img src="bug552605.sjs" onload="check()" id="test-image2"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug553982.html b/image/test/mochitest/test_bug553982.html new file mode 100644 index 0000000000..f7fe58a0af --- /dev/null +++ b/image/test/mochitest/test_bug553982.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=553982 +--> +<head> + <title>Test for Bug 553982</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=553982">Mozilla Bug 553982</a> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); +var success = false; + +// This should fire +function doError() { + success = true; +} + +// This should not fire +function doLoad() { + ok(false, "onload should not fire"); +} + +window.onload = function() { + ok(success, "onerror should fire"); + SimpleTest.finish(); +} + +</script> +</pre> +<img src="data:text/html," onerror="doError()" onload="doLoad()" /> +</body> +</html> diff --git a/image/test/mochitest/test_bug601470.html b/image/test/mochitest/test_bug601470.html new file mode 100644 index 0000000000..fdf2d074f8 --- /dev/null +++ b/image/test/mochitest/test_bug601470.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=601470 +--> +<head> + <title>Test for Bug 601470</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=601470">Mozilla Bug 601470</a> +<p id="display"></p> +<div id="content" style="display: none"> + <img src="lime100x100.svg" style="width: 100px; height: 100px;"> + <img src="damon.jpg" style="width: 100px; height: 100px;"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 601470 **/ + +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"] + .getService(SpecialPowers.Ci.nsIMemoryReporterManager); + + var amount = 0; + var handleReport = function(aProcess, aPath, aKind, aUnits, aAmount, aDesc) { + amount += aAmount; + } + + var finished = function() { + ok(amount > 0, "we should be using a nonzero amount of memory"); + ok(true, "yay, didn't crash!"); + SimpleTest.finish(); + } + + mgr.getReports(handleReport, null, finished, null, /* anonymize = */ false); +} + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug614392.html b/image/test/mochitest/test_bug614392.html new file mode 100644 index 0000000000..94585ba35e --- /dev/null +++ b/image/test/mochitest/test_bug614392.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=614392 +--> +<head> + <title>Test for Bug 614392</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=614392">Mozilla Bug 614392</a> +<p id="display"></p> +<div id="content" style="display: none"> + <img src="damon.jpg"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 614392**/ + +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + var img = SpecialPowers.wrap(document.getElementsByTagName("img")[0]); + var container = img + .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST) + .image; + + container.animationMode = + SpecialPowers.Ci.imgIContainer.kDontAnimMode; + + is(container.animationMode, + SpecialPowers.Ci.imgIContainer.kDontAnimMode, + "yay, our animationMode tweak took effect (and we didn't crash!)"); + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug657191.html b/image/test/mochitest/test_bug657191.html new file mode 100644 index 0000000000..17fcae6c8a --- /dev/null +++ b/image/test/mochitest/test_bug657191.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=657191 +--> +<head> + <title>Test for Bug 657191</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=657191">Mozilla Bug 657191</a> +<p id="display"></p> +<div id="content" style="display: none"> +<!-- bug657191.sjs returns an SVG image with HTTP error code 500. + As long as this doesn't crash, this test passes. --> + <img src="bug657191.sjs"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 657191 **/ +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + ok(true, "test passed"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_bug671906.html b/image/test/mochitest/test_bug671906.html new file mode 100644 index 0000000000..82f70f19d6 --- /dev/null +++ b/image/test/mochitest/test_bug671906.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=671906 +--> +<head> + <title>Test for Bug 671906</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=671906">Mozilla Bug 671906</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +var first, second, third; +var correct, val1, val2; + +SimpleTest.waitForExplicitFinish(); + +async function snapshotFirst() +{ + var iframeelem = document.getElementById('test-iframe'); + first = await SpecialPowers.wrap(snapshotWindow(iframeelem, false)); + + iframeelem.onload = snapshotSecond; + iframeelem.src = "http://example.com/tests/image/test/mochitest/bug671906-iframe.html"; +} + +async function snapshotSecond() +{ + var iframeelem = document.getElementById('test-iframe'); + second = await SpecialPowers.wrap(snapshotWindow(iframeelem, false)); + + // We must have loaded the image again, because the principals for the + // loading document are different. + [correct, val1, val2] = compareSnapshots(first, second, false); + ok(correct, "Image should have changed after changing the iframe's src."); + + iframeelem.onload = snapshotThird; + iframeelem.src = "http://mochi.test:8888/tests/image/test/mochitest/bug671906-iframe.html"; +} + +async function snapshotThird() +{ + var iframeelem = document.getElementById('test-iframe'); + third = await SpecialPowers.wrap(snapshotWindow(iframeelem, false)); + + // We must have loaded the image again, because the principals for the + // loading document are different. + [correct, val1, val2] = compareSnapshots(second, third, false); + ok(correct, "Image should have changed after changing the iframe's src."); + + // We must have looped back to the first image, because the sjs only sends + // one of two images. + [correct, val1, val2] = compareSnapshots(first, third, true); + ok(correct, "Image should be the same on the third load."); + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<iframe id="test-iframe" src="http://mochi.test:8888/tests/image/test/mochitest/bug671906-iframe.html" onload="snapshotFirst()"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug733553.html b/image/test/mochitest/test_bug733553.html new file mode 100644 index 0000000000..6d7ed81019 --- /dev/null +++ b/image/test/mochitest/test_bug733553.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=733553 +--> +<head> + <title>Test for Bug 733553</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="initializeOnload()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=733553">Mozilla Bug 733553</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var testIndex = -1; +var testParts = [ + [1, "red.png"], + [40, "animated-gif2.gif"], + [1, "red.png"], + [100, "lime100x100.svg"], + [100, "lime100x100.svg"], + [40, "animated-gif2.gif"], + [1, "red.png"], + // Note a failure of the next 'red.png' may indicate failure of resniffing on + // this part ('shaver.png'); see bug 907575. + [177, "shaver.png"], + [1, "red.png"], + [80, "damon.jpg"], + [80, "damon.jpg"], + [80, "damon.jpg"], + // An invalid image (from bug 787899) that is further delivered with a + // "special" bad MIME type that indicates that the necko + // multipart/x-mixed-replace parser wasn't able to parse it. + // We use a width of 80 because MultipartImage will just drop rillybad.jpg + // and re-present damon.jpg. + [80, "rillybad.jpg"], + [80, "damon.jpg"], + // Similarly, we'll drop bad.jpg, so we use damon.jpg's width. + [80, "bad.jpg"], + [1, "red.png"], + // We also drop invalid.jpg, so we use red.png's width. + [1, "invalid.jpg"], + [40, "animated-gif2.gif"] +]; + +// We'll append the part number to this, and tell the informant +const BASE_URL = "bug733553-informant.sjs?"; + +function initializeOnload() { + var firstimg = document.createElement('img'); + firstimg.addEventListener("load", imageLoad); + firstimg.addEventListener("error", imageLoad); + firstimg.alt = ""; + firstimg.src = "bug733553.sjs"; + document.getElementById('content').appendChild(firstimg); + + // Really ready for first, but who's counting + readyForNext(); +} + +function readyForNext() { + var loader = document.getElementById("loader"); + loader.src = BASE_URL + ++testIndex; +} + +function imageLoad(aEvent) { + var [width, fileName] = testParts[testIndex]; + is(aEvent.target.width, width, + "Test " + testIndex + " " + fileName + " width correct"); + + // Always call readyForNext here, as it's the closest we have to a cleanup + readyForNext(); + if (testParts.length == testIndex) { + var firstimg = document.getElementsByTagName('img')[0]; + firstimg.removeEventListener("load", imageLoad); + firstimg.removeEventListener("error", imageLoad); + SimpleTest.finish(); + } +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<iframe id="loader"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug767779.html b/image/test/mochitest/test_bug767779.html new file mode 100644 index 0000000000..ae3fe492cf --- /dev/null +++ b/image/test/mochitest/test_bug767779.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=767779 +--> +<head> + <title>Test for Bug 767779</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=767779">Mozilla Bug 767779</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> +const FAILURE_TIMEOUT = 30000; // Fail early after 30 seconds + +function main() +{ + // referenceDiv's size and color correspond to the last frame of the GIF + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedGif', 'debug'); + animTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +<div id="content"> <!-- style="display: none" --> + <div id="referenceDiv" style="height: 40px; width: 40px; + display: none; background: #18ff00;"></div> + <div id="animatedImage"> + <img id="animatedGif" src="bug767779.sjs" style="display: none;"/> + <div id="text-descr"></div> + </div> + <div id="debug" style="display:none"> + </div> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug865919.html b/image/test/mochitest/test_bug865919.html new file mode 100644 index 0000000000..46686c67d7 --- /dev/null +++ b/image/test/mochitest/test_bug865919.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=865919 +--> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 865919</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script type="text/javascript"> +"use strict"; + +/* Test for Bug 865919: + * BMP with height of INT32_MIN should fail to decode. + */ + +SimpleTest.waitForExplicitFinish(); + +var req = new XMLHttpRequest(); +req.onload = function() { CallbackAssert(true, 'Request for file succeeded.'); }; +req.onerror = function() { CallbackAssert(false, 'Request for file failed! Failed to test non-existent file.'); }; +req.open('GET', 'INT32_MIN.bmp'); +req.send(null); + +var outstandingCallbacks = 2; + +function CallbackAssert(assertVal, failText) { + ok(assertVal, failText); + + outstandingCallbacks--; + ok(outstandingCallbacks >= 0, '`outstandingCallbacks` should be non-negative.'); + if (outstandingCallbacks) + return; + + // No outstanding callbacks remain, so we're done. + SimpleTest.finish(); +} + +</script> + +<div id='content'> + <img src='INT32_MIN.bmp' + onerror='CallbackAssert(true, "Got expected onerror for INT32_MIN.bmp")' + onload='CallbackAssert(false, "Got unexpected onload for INT32_MIN.bmp")'> +</div> + +</body> +</html> + diff --git a/image/test/mochitest/test_bug89419-1.html b/image/test/mochitest/test_bug89419-1.html new file mode 100644 index 0000000000..3364dacbfb --- /dev/null +++ b/image/test/mochitest/test_bug89419-1.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=89419 +--> +<head> + <title>Test for Bug 89419</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 89419</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +var first, second, third; +var correct, val1, val2; + +SimpleTest.waitForExplicitFinish(); + +function checkFirst() +{ + var iframeelem = document.getElementById('test-iframe'); + first = snapshotWindow(iframeelem.contentWindow, false); + + iframeelem.onload = checkSecond; + iframeelem.contentWindow.location.reload(false); +} + +function checkSecond() +{ + var iframeelem = document.getElementById('test-iframe'); + second = snapshotWindow(iframeelem.contentWindow, false); + + // Check that we actually reloaded. + [correct, val1, val2] = compareSnapshots(first, second, false); + ok(correct, "Image should have changed after the first reload."); + + iframeelem.onload = checkThird; + iframeelem.contentWindow.location.reload(false); +} + +function checkThird() +{ + var iframeelem = document.getElementById('test-iframe'); + third = snapshotWindow(iframeelem.contentWindow, false); + + // Check that we actually reloaded. + [correct, val1, val2] = compareSnapshots(second, third, false); + ok(correct, "Image should have changed after the second reload."); + + // Make sure we looped back to the first image. + [correct, val1, val2] = compareSnapshots(first, third, true); + ok(correct, "Third image should match first image."); + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<iframe id="test-iframe" src="bug89419-iframe.html" onload="checkFirst()"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bug89419-2.html b/image/test/mochitest/test_bug89419-2.html new file mode 100644 index 0000000000..25861b9179 --- /dev/null +++ b/image/test/mochitest/test_bug89419-2.html @@ -0,0 +1,70 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=89419 +--> +<head> + <title>Test for Bug 89419</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 89419</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +var first, second, third; +var correct, val1, val2; + +SimpleTest.waitForExplicitFinish(); + +function checkFirst() +{ + var iframeelem = document.getElementById('test-iframe'); + first = snapshotWindow(iframeelem.contentWindow, false); + + iframeelem.onload = checkSecond; + // eslint-disable-next-line no-self-assign + iframeelem.contentWindow.location.href = iframeelem.contentWindow.location.href; +} + +function checkSecond() +{ + var iframeelem = document.getElementById('test-iframe'); + second = snapshotWindow(iframeelem.contentWindow, false); + + // Check that we actually reloaded. + [correct, val1, val2] = compareSnapshots(first, second, false); + ok(correct, "Image should have changed after the first reload."); + + iframeelem.onload = checkThird; + // eslint-disable-next-line no-self-assign + iframeelem.contentWindow.location.href = iframeelem.contentWindow.location.href; +} + +function checkThird() +{ + var iframeelem = document.getElementById('test-iframe'); + third = snapshotWindow(iframeelem.contentWindow, false); + + // Check that we actually reloaded. + [correct, val1, val2] = compareSnapshots(second, third, false); + ok(correct, "Image should have changed after the second reload."); + + // Make sure we looped back to the first image. + [correct, val1, val2] = compareSnapshots(first, third, true); + ok(correct, "Third image should match first image."); + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content"> <!-- style="display: none" --> +<iframe id="test-iframe" src="bug89419-iframe.html" onload="checkFirst()"></iframe> +</div> +</body> +</html> diff --git a/image/test/mochitest/test_bullet_animation.html b/image/test/mochitest/test_bullet_animation.html new file mode 100644 index 0000000000..7e39898a4f --- /dev/null +++ b/image/test/mochitest/test_bullet_animation.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - Animated Bullets</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style> + li { color: transparent } + </style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> +Mozilla Bug 666446: lots of animated gifs swamp us with paint events +</a> +<p id="display"></p> + +<div id="content"> + <div id="cleanDiv" style="display: none;"> + <ul> + <li></li> + </ul> + </div> + <div id="referenceDiv" style="display: none;"> + <ul> + <li style="list-style-image: url(animated-gif-finalframe.gif);"></li> + </ul> + </div> + <div id="animatedImage" style="display: none;"> + <ul> + <li style="list-style-image: url(animated-gif.gif);"></li> + </ul> + </div> + <div id="text-descr"></div> + <div id="debug" style="display:none"> + </div> +</div> +<pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() +{ + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedImage', 'debug', 'cleanDiv', + 'animated-gif-finalframe.gif'); + animTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_canvas_frame_animation.html b/image/test/mochitest/test_canvas_frame_animation.html new file mode 100644 index 0000000000..c2820b3a66 --- /dev/null +++ b/image/test/mochitest/test_canvas_frame_animation.html @@ -0,0 +1,24 @@ +<!doctype html> +<title>Test for bug 1619245 - animated image as canvas background</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="/tests/SimpleTest/WindowSnapshot.js"></script> +<script src="imgutils.js"></script> +<script src="animationPolling.js"></script> +<!-- Intentionally not including SimpleTest.css as that sets the background of the root --> +<body id="body" style="background-image: url(animated-gif.gif); display: none; overflow: hidden;"> + <div id="reference" style="background-image: url(animated-gif-finalframe.gif); display: none; width: 100vw; height: 100vh;"></div> + <div id="clean" style="display: none; width: 100vw; height: 100vh;"></div> + <div id="debug" style="display: none"></div> +</body> +<script> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +window.onload = function() { + // first move the reference outside of the <body>, so that the test can properly show it. + document.documentElement.appendChild(document.getElementById("reference")); + document.documentElement.appendChild(document.getElementById("debug")); + document.documentElement.appendChild(document.getElementById("clean")); + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'reference', 'body', 'debug', 'clean', 'animated-gif.gif'); + animTest.beginTest(); +} +</script> diff --git a/image/test/mochitest/test_changeOfSource.html b/image/test/mochitest/test_changeOfSource.html new file mode 100644 index 0000000000..f557a3a140 --- /dev/null +++ b/image/test/mochitest/test_changeOfSource.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - Change of Source (1st Version)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> +Mozilla Bug 666446: lots of animated gifs swamp us with paint events +</a> +<p id="display"></p> + +<div id="content"> + <div id="referenceDiv" style="height: 40px; width: 40px; + display: none; background: #2aff00;"> + </div> + <div id="animatedImage"> + <img id='animatedGif' src="animated-gif.gif" style="display: none;"> + </div> + <div id="text-descr"></div> + <div id="debug" style="display:none"> + </div> +</div> +<pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +var gAnimTest; +var gIntervalId; + +function initSecondTest() { + document.getElementById('debug').style.display = 'none'; + document.getElementById('referenceDiv').style.background = "#9600ff"; + document.getElementById('animatedGif').setAttribute('src', + 'animated-gif2.gif'); + document.getElementById('animatedGif').style.display = 'none'; + var secondTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedGif', 'debug', '', '', false); + secondTest.beginTest(); +} + +function main() +{ + gAnimTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedGif', 'debug', '', '', false, + initSecondTest); + gAnimTest.beginTest(); + +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_changeOfSource2.html b/image/test/mochitest/test_changeOfSource2.html new file mode 100644 index 0000000000..e3db345470 --- /dev/null +++ b/image/test/mochitest/test_changeOfSource2.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 691792 - Change of Source (2nd Version)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=691792"> +Mozilla Bug 691792: Change of src attribute for animated gifs no longer works as expected +</a> +<p id="display"></p> + +<div id="content"> + <div id="animatedImage"> + <img id='animatedGif' src="purple.gif" style="display: none;"> + </div> + <div id="text-descr"></div> + <div id="debug" style="display:none"> + </div> +</div> +<pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +var gAnimTest; +var gIntervalId; + +function main() +{ + gAnimTest = new AnimationTest(20, FAILURE_TIMEOUT, 'animated-gif2.gif', + 'animatedGif', 'debug', '', 'animated-gif2.gif', + false); + gAnimTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_discardAnimatedImage.html b/image/test/mochitest/test_discardAnimatedImage.html new file mode 100644 index 0000000000..09bd9372c6 --- /dev/null +++ b/image/test/mochitest/test_discardAnimatedImage.html @@ -0,0 +1,217 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=686905 +--> +<head> + <title>Test that animated images can be discarded</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="text/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686905">Mozilla Bug 686905</a> +<p id="display"></p> +<div id="content"> + <div id="container"> + <canvas id="canvas" width="100" height="100"></canvas> + <img id="infinitepng" src="infinite-apng.png"> + <img id="infinitegif" src="animated1.gif"> + <img id="infinitewebp" src="infinite.webp"> + <img id="infiniteavif" src="infinite.avif"> + <img id="finitepng" src="restore-previous.png"> + <img id="finitegif" src="animated-gif.gif"> + <img id="finitewebp" src="keep.webp"> + <img id="finiteavif" src="animated-avif.avif"> + </div> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 686905. **/ +SimpleTest.waitForExplicitFinish(); + +var gFinished = false; + +var gNumDiscards = 0; + +window.onload = function() { + // Enable discarding for the test. + SpecialPowers.pushPrefEnv({ + 'set':[['image.mem.discardable',true], + ['image.avif.sequence.enabled',true]] + }, runTest); +} + +var gImgs = ['infinitepng', 'infinitegif', 'infinitewebp', 'infiniteavif', + 'finitepng', 'finitegif', 'finitewebp', 'finiteavif']; +// If we are currently counting frame updates. +var gCountingFrameUpdates = false; +// The number of frame update notifications for the images in gImgs that happen +// after discarding. (The last two images are finite looping so we don't expect +// them to get incremented but it's possible if they don't finish their +// animation before we discard them.) +var gNumFrameUpdates = [0, 0, 0, 0, 0, 0]; +// The last snapshot of the image. Used to check that the image actually changes. +var gLastSnapShot = [null, null, null, null, null, null]; +// Number of observed changes in the snapshot. +var gNumSnapShotChanges = [0, 0, 0, 0, 0, 0]; +// If we've removed the observer. +var gRemovedObserver = [false, false, false, false, false, false]; + +// 2 would probably be a good enough test, we arbitrarily choose 4. +var kNumFrameUpdatesToExpect = 4; + +function runTest() { + var animatedDiscardable = + SpecialPowers.getBoolPref('image.mem.animated.discardable'); + if (!animatedDiscardable) { + ok(true, "discarding of animated images is disabled, nothing to test"); + SimpleTest.finish(); + return; + } + + setTimeout(step2, 0); +} + +function step2() { + // Draw the images to canvas to force them to be decoded. + for (let i = 0; i < gImgs.length; i++) { + drawCanvas(document.getElementById(gImgs[i])); + } + + for (let i = 0; i < gImgs.length; i++) { + addCallbacks(document.getElementById(gImgs[i]), i); + } + + setTimeout(step3, 0); +} + +function step3() { + document.getElementById("container").style.display = "none"; + document.documentElement.offsetLeft; // force that style to take effect + + for (var i = 0; i < gImgs.length; i++) { + requestDiscard(document.getElementById(gImgs[i])); + } + + // the discard observers will call step4 +} + +function step4() { + gCountingFrameUpdates = true; + document.getElementById("container").style.display = ""; + + // Draw the images to canvas to force them to be decoded again. + for (var i = 0; i < gImgs.length; i++) { + drawCanvas(document.getElementById(gImgs[i])); + } +} + +function checkIfFinished() { + if (gFinished) { + return; + } + + if ((gNumFrameUpdates[0] >= kNumFrameUpdatesToExpect) && + (gNumFrameUpdates[1] >= kNumFrameUpdatesToExpect) && + (gNumFrameUpdates[2] >= kNumFrameUpdatesToExpect) && + (gNumSnapShotChanges[0] >= kNumFrameUpdatesToExpect) && + (gNumSnapShotChanges[1] >= kNumFrameUpdatesToExpect) && + (gNumSnapShotChanges[2] >= kNumFrameUpdatesToExpect)) { + ok(true, "got expected frame updates"); + gFinished = true; + SimpleTest.finish(); + } +} + +// arrayIndex is the index into the arrays gNumFrameUpdates and gNumDecodes +// to increment when a frame update notification is received. +function addCallbacks(anImage, arrayIndex) { + var observer = new ImageDecoderObserverStub(); + observer.discard = function () { + gNumDiscards++; + ok(true, "got image discard"); + if (arrayIndex >= 3) { + // The last two images are finite, so we don't expect any frame updates, + // this image is done the test, so remove the observer. + if (!gRemovedObserver[arrayIndex]) { + gRemovedObserver[arrayIndex] = true; + imgLoadingContent.removeObserver(scriptedObserver); + } + } + if (gNumDiscards == gImgs.length) { + step4(); + } + }; + observer.frameUpdate = function () { + if (!gCountingFrameUpdates) { + return; + } + + // Do this off a setTimeout since nsImageLoadingContent uses a scriptblocker + // when it notifies us and calling drawWindow can call will paint observers + // which can dispatch a scrollport event, and events assert if dispatched + // when there is a scriptblocker. + setTimeout(function () { + gNumFrameUpdates[arrayIndex]++; + + var r = document.getElementById(gImgs[arrayIndex]).getBoundingClientRect(); + var snapshot = snapshotRect(window, r, "rgba(0,0,0,0)"); + if (gLastSnapShot[arrayIndex] != null) { + if (snapshot.toDataURL() != gLastSnapShot[arrayIndex].toDataURL()) { + gNumSnapShotChanges[arrayIndex]++; + } + } + gLastSnapShot[arrayIndex] = snapshot; + + if (gNumFrameUpdates[arrayIndex] >= kNumFrameUpdatesToExpect && + gNumSnapShotChanges[arrayIndex] >= kNumFrameUpdatesToExpect) { + if (!gRemovedObserver[arrayIndex]) { + gRemovedObserver[arrayIndex] = true; + imgLoadingContent.removeObserver(scriptedObserver); + } + } + if (!gFinished) { + // because we do this in a setTimeout we can have several in flight + // so don't call ok if we've already finished. + ok(true, "got frame update"); + } + checkIfFinished(); + }, 0); + }; + observer = SpecialPowers.wrapCallbackObject(observer); + + var scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"] + .getService(SpecialPowers.Ci.imgITools) + .createScriptedObserver(observer); + + var imgLoadingContent = SpecialPowers.wrap(anImage); + imgLoadingContent.addObserver(scriptedObserver); +} + +function requestDiscard(anImage) { + var request = SpecialPowers.wrap(anImage) + .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST); + setTimeout(() => request.requestDiscard(), 0); +} + +function drawCanvas(anImage) { + var canvas = document.getElementById('canvas'); + var context = canvas.getContext('2d'); + + context.clearRect(0,0,100,100); + var cleared = canvas.toDataURL(); + + context.drawImage(anImage, 0, 0); + ok(true, "we got through the drawImage call without an exception being thrown"); + + ok(cleared != canvas.toDataURL(), "drawImage drew something"); +} + +</script> +</pre> +</body> +</html> + diff --git a/image/test/mochitest/test_discardFinishedAnimatedImage.html b/image/test/mochitest/test_discardFinishedAnimatedImage.html new file mode 100644 index 0000000000..190cb1d1a0 --- /dev/null +++ b/image/test/mochitest/test_discardFinishedAnimatedImage.html @@ -0,0 +1,144 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that img.decode works on finished, discarded animated images</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="text/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1629490">Mozilla Bug 1629490</a> +<div id="container"> + <img id="finitepng" src="finite-apng.png"> +</div> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +window.onload = runTest; + +let discardCallback = undefined; +let frameUpdateCallback = undefined; + +async function runTest() { + const kUsingWebRender = SpecialPowers.DOMWindowUtils.layerManagerType.startsWith("WebRender"); + + let img = document.getElementById("finitepng"); + + await img.decode(); + + while (!isItGreen(img)) { + // We hit an optimized path in WebRender that doesn't cause a repaint on the + // main thread and doesn't seem to send MozAfterPaints. + // + // https://searchfox.org/mozilla-central/rev/b7f3977978922d44c7d92ae01c0d4cc2baca7bc2/layout/style/ImageLoader.cpp#553 + await new Promise(resolve => { + if (kUsingWebRender) { + requestAnimationFrame(() => { + requestAnimationFrame(resolve); + }); + } else { + window.addEventListener("MozAfterPaint", resolve, { once: true }); + } + }); + } + + addCallbacks(img); + + let iterationsLeft = 26; + while (iterationsLeft > 0) { + + let discardPromise = new Promise(resolve => { + discardCallback = resolve; + }); + + document.getElementById("container").style.display = "none"; + document.documentElement.offsetLeft; // force that style to take effect + requestDiscard(img); + + await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); }); + + await discardPromise; + await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); }); + + let waitForFrameUpdate = new Promise(resolve => { + frameUpdateCallback = resolve; + }); + + document.getElementById("container").style.display = ""; + document.documentElement.offsetLeft; // force that style to take effect + + await img.decode(); + + await new Promise(resolve => requestAnimationFrame(resolve)); + + await waitForFrameUpdate; + + ok(isItGreen(img), "should be green"); + + iterationsLeft--; + await new Promise(resolve => {requestAnimationFrame(() => { requestAnimationFrame(resolve); }); }); + + } + + removeObserver(img); + SimpleTest.finish(); +} + +function isItGreen(img) { + let rect = img.getBoundingClientRect(); + let r = {left: rect.left + 5, top: rect.top + 5, width: 5, height: 5}; + let c = SpecialPowers.snapshotWindowWithOptions(window, r); + let d = c.getContext('2d').getImageData(0,0,5,5).data; + let isGreen = true; + for (let i = 0; i < 5*5; i++) { + if (d[4*i] != 0 || d[4*i + 1] != 128 || d[4*i + 2] != 0 || d[4*i + 3] != 255) { + isGreen = false; + } + } + return isGreen; +} + + +let scriptedObserver = undefined; +let imgLoadingContent = undefined; +function addCallbacks(anImage) { + var observer = new ImageDecoderObserverStub(); + observer.discard = function () { + if (discardCallback != undefined) { + let localDiscardCallback = discardCallback; + discardCallback = undefined; + setTimeout(localDiscardCallback, 0); + } + }; + observer.frameUpdate = function () { + if (frameUpdateCallback != undefined) { + let localFrameUpdateCallback = frameUpdateCallback; + frameUpdateCallback = undefined; + setTimeout(localFrameUpdateCallback, 0); + } + }; + observer = SpecialPowers.wrapCallbackObject(observer); + + scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"] + .getService(SpecialPowers.Ci.imgITools) + .createScriptedObserver(observer); + + imgLoadingContent = SpecialPowers.wrap(anImage); + imgLoadingContent.addObserver(scriptedObserver); +} + +function removeObserver(anImage) { + imgLoadingContent.removeObserver(scriptedObserver); +} + +function requestDiscard(anImage) { + var request = SpecialPowers.wrap(anImage) + .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST); + setTimeout(() => request.requestDiscard(), 0); +} + +</script> +</body> +</html> diff --git a/image/test/mochitest/test_discardFramesAnimatedImage.html b/image/test/mochitest/test_discardFramesAnimatedImage.html new file mode 100644 index 0000000000..2e95e6203b --- /dev/null +++ b/image/test/mochitest/test_discardFramesAnimatedImage.html @@ -0,0 +1,268 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=523950 +--> +<head> + <title>Test that animated images can discard frames and redecode</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="text/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=523950">Mozilla Bug 523950</a> +<p id="display"></p> +<div id="content"> + <div id="container"> + <canvas id="canvas" width="100" height="100"></canvas> + <img id="rainbow.gif"/> + </div> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 523950. **/ +SimpleTest.waitForExplicitFinish(); + +var gFinished = false; + +var gNumOnloads = 0; + +var gNumDiscards = 0; + +window.onload = function() { + // Enable minimal frame discard thresholds for the test. + SpecialPowers.pushPrefEnv({ + 'set':[['image.animated.decode-on-demand.threshold-kb',0], + ['image.animated.decode-on-demand.batch-size',1], + ['image.mem.discardable',true], + ['image.mem.animated.discardable',true]] + }, runTest); +} + +var gImgs = ['rainbow.gif']; +// If we are currently counting frame updates. +var gCountingFrameUpdates = false; +// The number of frame update notifications for the images in gImgs that happen +// after discarding. (The last two images are finite looping so we don't expect +// them to get incremented but it's possible if they don't finish their +// animation before we discard them.) +var gNumFrameUpdates = [0]; +// The last snapshot of the image. Used to check that the image actually changes. +var gLastSnapShot = [null]; +// Number of observed changes in the snapshot. +var gNumSnapShotChanges = [0]; +// If we've removed the observer. +var gRemovedObserver = [false]; + +// rainbow.gif has 9 frames, so we choose arbitrarily 22 to include two loops. +var kNumFrameUpdatesToExpect = 22; + +function runTest() { + var thresholdKb = + SpecialPowers.getIntPref('image.animated.decode-on-demand.threshold-kb'); + var batchSize = + SpecialPowers.getIntPref('image.animated.decode-on-demand.batch-size'); + var discardable = + SpecialPowers.getBoolPref('image.mem.discardable'); + var animDiscardable = + SpecialPowers.getBoolPref('image.mem.animated.discardable'); + if (thresholdKb > 0 || batchSize > 1 || !discardable || !animDiscardable) { + ok(true, "discarding frames of animated images is disabled, nothing to test"); + SimpleTest.finish(); + return; + } + + setTimeout(step2, 0); +} + +function step2() { + // Only set the src after setting the pref. + for (var i = 0; i < gImgs.length; i++) { + var elm = document.getElementById(gImgs[i]); + elm.src = gImgs[i]; + elm.onload = checkIfLoaded; + } +} + +function step3() { + // Draw the images to canvas to force them to be decoded. + for (let i = 0; i < gImgs.length; i++) { + drawCanvas(document.getElementById(gImgs[i])); + } + + for (let i = 0; i < gImgs.length; i++) { + addCallbacks(document.getElementById(gImgs[i]), i); + } + + setTimeout(step4, 0); +} + +function step4() { + ok(true, "now accepting frame updates"); + gCountingFrameUpdates = true; +} + +function step5() { + ok(true, "discarding images"); + + document.getElementById("container").style.display = "none"; + document.documentElement.offsetLeft; // force that style to take effect + + // Reset our state to let us do it all again after discarding. + resetState(); + + // Draw the images to canvas to force them to be decoded. + for (var i = 0; i < gImgs.length; i++) { + requestDiscard(document.getElementById(gImgs[i])); + } + + // the discard observers will call step6 +} + +function step6() { + // Repeat the cycle now that we discarded everything. + ok(gNumDiscards >= gImgs.length, "discard complete, restarting animations"); + document.getElementById("container").style.display = ""; + + // Draw the images to canvas to force them to be decoded. + for (var i = 0; i < gImgs.length; i++) { + drawCanvas(document.getElementById(gImgs[i])); + } + + setTimeout(step4, 0); +} + +function checkIfLoaded() { + ++gNumOnloads; + if (gNumOnloads != gImgs.length) { + return; + } + + ok(true, "got onloads"); + setTimeout(step3, 0); +} + +function resetState() { + gFinished = false; + gCountingFrameUpdates = false; + for (let i = 0; i < gNumFrameUpdates.length; ++i) { + gNumFrameUpdates[i] = 0; + } + for (let i = 0; i < gNumSnapShotChanges.length; ++i) { + gNumSnapShotChanges[i] = 0; + } + for (let i = 0; i < gLastSnapShot.length; ++i) { + gLastSnapShot[i] = null; + } +} + +function checkIfFinished() { + if (gFinished) { + return; + } + + for (var i = 0; i < gNumFrameUpdates.length; ++i) { + if (gNumFrameUpdates[i] < kNumFrameUpdatesToExpect || + gNumSnapShotChanges[i] < kNumFrameUpdatesToExpect) { + return; + } + } + + ok(true, "got expected frame updates"); + gFinished = true; + + if (gNumDiscards == 0) { + // If we haven't discarded any complete images, we should do so, and + // verify the animation again. + setTimeout(step5, 0); + return; + } + + SimpleTest.finish(); +} + +// arrayIndex is the index into the arrays gNumFrameUpdates and gNumDecodes +// to increment when a frame update notification is received. +function addCallbacks(anImage, arrayIndex) { + var observer = new ImageDecoderObserverStub(); + observer.discard = function () { + gNumDiscards++; + ok(true, "got image discard"); + if (gNumDiscards == gImgs.length) { + step6(); + } + }; + observer.frameUpdate = function () { + if (!gCountingFrameUpdates) { + return; + } + + // Do this off a setTimeout since nsImageLoadingContent uses a scriptblocker + // when it notifies us and calling drawWindow can call will paint observers + // which can dispatch a scrollport event, and events assert if dispatched + // when there is a scriptblocker. + setTimeout(function () { + gNumFrameUpdates[arrayIndex]++; + + var r = document.getElementById(gImgs[arrayIndex]).getBoundingClientRect(); + var snapshot = snapshotRect(window, r, "rgba(0,0,0,0)"); + if (gLastSnapShot[arrayIndex] != null) { + if (snapshot.toDataURL() != gLastSnapShot[arrayIndex].toDataURL()) { + gNumSnapShotChanges[arrayIndex]++; + } + } + gLastSnapShot[arrayIndex] = snapshot; + + if (gNumFrameUpdates[arrayIndex] >= kNumFrameUpdatesToExpect && + gNumSnapShotChanges[arrayIndex] >= kNumFrameUpdatesToExpect && + gNumDiscards >= gImgs.length) { + if (!gRemovedObserver[arrayIndex]) { + ok(true, "removing observer for " + arrayIndex); + gRemovedObserver[arrayIndex] = true; + imgLoadingContent.removeObserver(scriptedObserver); + } + } + if (!gFinished) { + // because we do this in a setTimeout we can have several in flight + // so don't call ok if we've already finished. + ok(true, "got frame update"); + } + checkIfFinished(); + }, 0); + }; + observer = SpecialPowers.wrapCallbackObject(observer); + + var scriptedObserver = SpecialPowers.Cc["@mozilla.org/image/tools;1"] + .getService(SpecialPowers.Ci.imgITools) + .createScriptedObserver(observer); + + var imgLoadingContent = SpecialPowers.wrap(anImage); + imgLoadingContent.addObserver(scriptedObserver); +} + +function requestDiscard(anImage) { + var request = SpecialPowers.wrap(anImage) + .getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST); + setTimeout(() => request.requestDiscard(), 0); +} + +function drawCanvas(anImage) { + var canvas = document.getElementById('canvas'); + var context = canvas.getContext('2d'); + + context.clearRect(0,0,100,100); + var cleared = canvas.toDataURL(); + + context.drawImage(anImage, 0, 0); + ok(true, "we got through the drawImage call without an exception being thrown"); + + ok(cleared != canvas.toDataURL(), "drawImage drew something"); +} + +</script> +</pre> +</body> +</html> + diff --git a/image/test/mochitest/test_drawDiscardedImage.html b/image/test/mochitest/test_drawDiscardedImage.html new file mode 100644 index 0000000000..f1a2dde89c --- /dev/null +++ b/image/test/mochitest/test_drawDiscardedImage.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=731419 +--> +<head> + <title>Test for Bug 731419 - Draw an ostensibly discarded image to a canvas</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body> + +<!-- + Load an image in an iframe, then draw that image to a canvas. Then set the + iframe to display:none (after bug 731419, this causes the image's decoded + data to be discarded) and draw the image to a canvas again. We should draw + the same image data both times. +--> + +<script> + +SimpleTest.waitForExplicitFinish(); + +var data1; + +function drawImage() +{ + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + var iframeDoc = document.getElementById('iframe').contentDocument; + + ctx.clearRect(0, 0, canvas.height, canvas.width); + ctx.drawImage(iframeDoc.getElementById('image'), 0, 0); + return canvas.toDataURL(); +} + +function iframeLoad() +{ + data1 = drawImage(); + document.getElementById('iframe').style.display = 'none'; + + // Spin the event loop a few times to give the image in the display:none + // iframe a chance to be discarded. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + step2(); + }); + }); + }); +} + +function step2() +{ + is(drawImage(), data1, "Same image before and after iframe display:none"); + SimpleTest.finish(); +} + +</script> + +<canvas id='canvas'></canvas> + +<iframe id='iframe' onload='iframeLoad()' srcdoc='<img id="image" +src="data:image/png;base64, +iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADRElEQVQ4EQXBTWgcZQCA4ff7ZmZ3 +NpvNZLObTWpCuoZGIxWJplAKbVUKavUiHrQHaRG1XrV4SNuD4MFcRDwUoR4qEq2gFUlBEWmtppYi +acSmMakxtfkx/5tNdmd35/8bn0cAzJ7IXwKGH/q8NDF48vy+7vk/3tzVXDs8nj9cAAiDcD70gwVi +vvvr4tsjAAAAAmD2RD4GOL34wge21XHsnHWh9/aUjX1pC4C1UpXrP08zN7vMvvujPx3P/PD+0VH3 +BoAcTspXAbK9iuGe78+csy70ZnsVvh+xWQ8p1QI8dNK7CiT9CmeO28/4ZsuVX9/IvQwgmzLaU9LS +AGh/3KJ5jw6A6ynyL7Xx7UCORiwQGRN0g7C4m4FX9poNV35681ShU6ZbxKDRLJVuZQl9RdSQRB4c +OtDGoQNtPGHBuh0SaAa+ZvLjHYt8fwfZrpTl2cFp2ZwVDyQzSgLgVIndGN/tIP/c61y/WWb14gaV +asTWioPSDabnfCqVkK7BHKHtPK0n06oFGQHgewJtbw8AujGNkYTNpTJxbYfaygqR0piYkaRkhMya +eI2oX9dTQRIFmtrmz7EGpS9vESZjAN7tfo/UL2PouoZwbfxIo9jaoLWlzI7jEPmhLjVEbXs5IPAE +jx5M0Z5RZDJwqjCENFN8XBtmOP0FXq1O6NR5snsRtsv4C+voCdHQpcfVtTn/xUKXTrMlyfck6BCC +a02fkDZDqirF5JVrRA8ewagu8NbADN6az9btMoTqjnasKDTHjp5PSM3I5DQy7UliZbCz7bCwFDD/ +b52h3BCviVHOHv2bvmydyvwOM5MSmch9Ji4/SxMNcaNJTw707zdJmBqeo+G5BuO/V6AzQ5Oo01MI +KBaTOOis3rPZrKeqrbn2hwXA10fY7zvicqeZKPQ8YpKxJCgIpEQXisBVhG6MYcQ0pGJp2XWnSpx8 +52o0ogF8c5/ltMlGIlYHo0qQrq9HxHWFvx3RqCoCFzwn4L+tiIVV5Y5MhWc/mlDnATQAgMkynbMb +opoN4z2hUAlPBdpO6FNp+JTtkPVaHE7NYX94K/xqrBT/BvwDIAAAgALQAfT1aWJwtyYea9VEXoAo +RfHGYhTfvRfF48BdYB3YAPgfnOuE39kFlREAAAAASUVORK5CYII=">'></iframe> + +</body> +</html> + diff --git a/image/test/mochitest/test_error_events.html b/image/test/mochitest/test_error_events.html new file mode 100644 index 0000000000..89ed9da528 --- /dev/null +++ b/image/test/mochitest/test_error_events.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=715308 +--> +<head> + <title>Test for Bug 715308 comment 93</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + +<!-- Test for Bug 715308 comment 93: + + - For a valid image, onload is fired and onerror is never fired. + - For an image with errors, onerror is fired, but onload is never fired. + - For any image, either onload or onerror is fired, but never both. + + --> +<script type="text/javascript"> +"use strict"; + +SimpleTest.waitForExplicitFinish(); + +var numCallbacks = 0; + +function image_error(name) +{ + numCallbacks++; + ok(name == 'error-early', "Got onerror for " + name); +} + +function image_load(name) +{ + numCallbacks++; + ok(name == 'shaver', "Got onload for " + name); +} + +function page_load() +{ + ok(numCallbacks == 2, 'Got page load before all onload/onerror callbacks?'); + + // Spin the event loop a few times to let image_error run if it's going to, + // then finish the test. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.finish(); + }); + }); + }); +} + +addEventListener('load', page_load); + +</script> + +<div id="content"> + <img src='shaver.png' onerror='image_error("shaver")' onload='image_load("shaver")'> + <img src='error-early.png' onerror='image_error("error-early")' onload='image_load("error-early")'> +</div> + +</pre> +</body> +</html> + diff --git a/image/test/mochitest/test_has_transparency.html b/image/test/mochitest/test_has_transparency.html new file mode 100644 index 0000000000..482aaf96b9 --- /dev/null +++ b/image/test/mochitest/test_has_transparency.html @@ -0,0 +1,169 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1089880 +--> +<head> + <title>Test for Bug 1089880</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1089880">Mozilla Bug 1089880</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 1089880 **/ + +SimpleTest.requestFlakyTimeout("Early failure timeout"); +SimpleTest.waitForExplicitFinish(); + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const gContent = document.getElementById("content"); + +var gCanvas; +var gCanvasCtx; +var gImg; +var gMyDecoderObserver; +var gIsTestFinished = false; +var gFiles; +var gCurrentFileIsTransparent = false; +var gHasTransparencyWasCalled = false; + +function* testFiles() { + // [A, B] where 'A' is the image and 'B' is whether it's transparent. + + // PNGs and GIFs may be transparent or not. + yield ["red.png", false]; + yield ["transparent.png", true]; + yield ["animated-gif-finalframe.gif", false]; + yield ["transparent.gif", true]; + + // GIFs with padding on the first frame are always transparent. + yield ["first-frame-padding.gif", true]; + + // JPEGs are never transparent. + yield ["damon.jpg", false]; + + // Most BMPs are not transparent. (The TestMetadata GTest, which will + // eventually replace this test totally, has coverage for the kinds that can be + // transparent.) + yield ["opaque.bmp", false]; + + // ICO files which contain BMPs have an additional type of transparency - the + // AND mask - that warrants separate testing. (Although, after bug 1201796, + // all ICOs are considered transparent.) + yield ["ico-bmp-opaque.ico", true]; + yield ["ico-bmp-transparent.ico", true]; + + // SVGs are always transparent. + yield ["lime100x100.svg", true]; +} + +function loadNext() { + var currentFile = ""; + gHasTransparencyWasCalled = false; + let {done, value} = gFiles.next(); + if (done) { + // We ran out of test files. + cleanUpAndFinish(); + return; + } + [currentFile, gCurrentFileIsTransparent] = value; + gImg.setAttribute("src", currentFile); +} + +function onHasTransparency(aRequest) { + gHasTransparencyWasCalled = true; +} + +function onDecodeComplete(aRequest) { + if (!gCurrentFileIsTransparent) { + ok(!gHasTransparencyWasCalled, + "onHasTransparency was not called for non-transparent file " + gImg.src); + } else { + ok(gHasTransparencyWasCalled, + "onHasTransparency was called for transparent file " + gImg.src); + } + loadNext(); +} + +function onError() { + if (gIsTestFinished) { + return; + } + ok(false, "Should successfully load " + gImg.src); + loadNext(); +} + +function onLoad() { + if (gIsTestFinished) { + return; + } + ok(true, "Should successfully load " + gImg.src); + + // Force decoding of the image. + SimpleTest.executeSoon(function() { + gCanvasCtx.drawImage(gImg, 0, 0); + }); +} + +function failTest() { + ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " + + "currently displaying " + gImg.src); + cleanUpAndFinish(); +} + +function cleanUpAndFinish() { + if (gIsTestFinished) { + return; + } + gIsTestFinished = true; + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.removeObserver(gMyDecoderObserver); + SimpleTest.finish(); +} + +function main() { + gFiles = testFiles(); + gCanvas = document.createElement('canvas'); + gCanvasCtx = gCanvas.getContext('2d'); + gImg = new Image(); + gImg.onload = onLoad; + gImg.onerror = onError; + + // Create, customize & attach decoder observer. + var observer = new ImageDecoderObserverStub(); + observer.hasTransparency = onHasTransparency; + observer.decodeComplete = onDecodeComplete; + gMyDecoderObserver = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer)); + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.addObserver(gMyDecoderObserver); + + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + // Load the first image. + loadNext(); + + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, FAILURE_TIMEOUT); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_image_cache_notification.html b/image/test/mochitest/test_image_cache_notification.html new file mode 100644 index 0000000000..73adac25ff --- /dev/null +++ b/image/test/mochitest/test_image_cache_notification.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> + <head> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + </head> + <body> + <button>Add Image</button> + <script> + /* Test to ensure http-on-image-cache-response should only be notified + * once per image + */ + + SimpleTest.waitForExplicitFinish(); + async function addImage() { + const newImage = document.createElement("img"); + + const imageLoaded = new Promise((r) => { + newImage.onload = r; + }); + + newImage.src = "./over.png"; + document.body.appendChild(newImage); + return imageLoaded; + } + + let imageCacheCallbackRunCount = 0; + const cb = SpecialPowers.wrapCallback(() => { + imageCacheCallbackRunCount += 1; + }); + SpecialPowers.addObserver(cb, "http-on-image-cache-response"); + + async function runTest() { + await addImage(); + SimpleTest.ok(imageCacheCallbackRunCount == 0, "first load of over.png shouldn't be cached"); + await addImage(); + SimpleTest.ok(imageCacheCallbackRunCount == 1, "second load of over.png should be cached"); + await addImage(); + await addImage(); + await addImage(); + SimpleTest.ok(imageCacheCallbackRunCount == 1, "further loads of over.png shouldn't be notified"); + SimpleTest.finish(); + } + + runTest(); + </script> + </body> +</html> diff --git a/image/test/mochitest/test_image_crossorigin_data_url.html b/image/test/mochitest/test_image_crossorigin_data_url.html new file mode 100644 index 0000000000..4465b5aab4 --- /dev/null +++ b/image/test/mochitest/test_image_crossorigin_data_url.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for handling of 'crossorigin' attribute on CSS link with data: URL</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<div id="someuniqueidhere"></div> +<img id="testimg" crossorigin src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"> +<script> + /* global async_test, assert_equals */ + var t = async_test("img@crossorigin with data: src"); + window.addEventListener("load", t.step_func_done(function() { + var img = document.getElementById("testimg"); + assert_equals(img.naturalWidth, 1, "Should have 1px width"); + assert_equals(img.naturalHeight, 1, "Should have 1px height"); + var c = document.createElement("canvas"); + c.width = c.height = 1; + var ctx = c.getContext("2d"); + ctx.drawImage(img, 0, 0); + var data = ctx.getImageData(0, 0, 1, 1); + assert_equals(data.width, 1, "Should have 1px data width"); + assert_equals(data.height, 1, "Should have 1px data height"); + assert_equals(data.data[0], 255, "Should have lots of red"); + assert_equals(data.data[1], 0, "Should have no green"); + assert_equals(data.data[2], 0, "Should have no blue"); + assert_equals(data.data[3], 255, "Should have no translucency"); + })); +</script> diff --git a/image/test/mochitest/test_mq_dynamic_svg.html b/image/test/mochitest/test_mq_dynamic_svg.html new file mode 100644 index 0000000000..25b708224e --- /dev/null +++ b/image/test/mochitest/test_mq_dynamic_svg.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Dynamic changes to prefers-color-scheme affecting SVG images</title> +<link rel=stylesheet type=text/css href=/tests/SimpleTest/test.css> +<script src=/tests/SimpleTest/SimpleTest.js></script> +<script src=/tests/SimpleTest/WindowSnapshot.js></script> +<body onload=run()> +<iframe id=f1 width=300 height=600></iframe> +<iframe id=f2 width=300 height=600></iframe> +<script> +SimpleTest.waitForExplicitFinish(); + +// Not strictly needed, but keeps eslint happy. +let f1 = window.f1; +let f2 = window.f2; + +function snapshotsEqual() { + let s1 = snapshotWindow(f1.contentWindow); + let s2 = snapshotWindow(f2.contentWindow); + return compareSnapshots(s1, s2, true)[0]; +} + +function waitForColorSchemeToBe(scheme) { + return new Promise(resolve => { + let mq = matchMedia(`(prefers-color-scheme: ${scheme})`); + if (mq.matches) { + resolve(); + } else { + mq.addEventListener("change", resolve, { once: true }); + } + }); +} + +async function run() { + let loadedFrame1 = new Promise(resolve => f1.onload = resolve); + let loadedFrame2 = new Promise(resolve => f2.onload = resolve); + await SpecialPowers.pushPrefEnv({ set: [["layout.css.prefers-color-scheme.content-override", 1]] }); + await waitForColorSchemeToBe("light"); + f1.src = "mq_dynamic_svg_test.html"; + f2.src = "mq_dynamic_svg_ref.html"; + await loadedFrame1; + await loadedFrame2; + ok(!snapshotsEqual(), "In light mode snapshot comparison should be false"); + await SpecialPowers.pushPrefEnv({ set: [["layout.css.prefers-color-scheme.content-override", 0]] }); + await waitForColorSchemeToBe("dark"); + ok(snapshotsEqual(), "In dark mode snapshot comparison should be true"); + SimpleTest.finish(); +} +</script> diff --git a/image/test/mochitest/test_net_failedtoprocess.html b/image/test/mochitest/test_net_failedtoprocess.html new file mode 100644 index 0000000000..95ab5c0cc3 --- /dev/null +++ b/image/test/mochitest/test_net_failedtoprocess.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test that a image decoding error producs a net:failed-to-process-uri-content +observer event with the nsIURI of the failed image as the subject +--> +<head> + <title>Test for image net:failed-to-process-uri-content</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<pre id="test"> +</pre> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +const Ci = SpecialPowers.Ci; +const Cc = SpecialPowers.Cc; +var obs = Cc["@mozilla.org/observer-service;1"].getService(); +obs = obs.QueryInterface(Ci.nsIObserverService); + +var observer = { + QueryInterface (aIID) { + if (aIID.equals(Ci.nsISupports) || + aIID.equals(Ci.nsIObserver)) + return this; + throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); + }, + + observe(subject, topic, data) { + ok(topic == "net:failed-to-process-uri-content", "wrong topic"); + subject = subject.QueryInterface(Ci.nsIURI); + is(subject.asciiSpec, `${location.origin}/tests/image/test/mochitest/invalid.jpg`, "wrong subject"); + + obs.removeObserver(this, "net:failed-to-process-uri-content"); + + SimpleTest.finish(); + } +}; + +obs.addObserver(SpecialPowers.wrapCallbackObject(observer), "net:failed-to-process-uri-content"); + +document.write('<img src="damon.jpg">'); +document.write('<img src="invalid.jpg">'); + +</script> +</body> +</html> diff --git a/image/test/mochitest/test_removal_ondecode.html b/image/test/mochitest/test_removal_ondecode.html new file mode 100644 index 0000000000..4ce7555757 --- /dev/null +++ b/image/test/mochitest/test_removal_ondecode.html @@ -0,0 +1,160 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=841579 +--> +<head> + <title>Test for Bug 841579</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841579">Mozilla Bug 841579</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 841579**/ + +SimpleTest.requestFlakyTimeout("Early failure timeout"); +SimpleTest.waitForExplicitFinish(); + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const gContent = document.getElementById("content"); + +var gImg; +var gMyDecoderObserver; +var gIsTestFinished = false; +var gFiles; +var gNotifications = 0; +var gLoads = 0; +var gRemovals = 0; +var gExpected = 5; + +function* fileToLoad() { + yield "red.png"; + yield "invalid.jpg"; + yield "lime100x100.svg"; + yield "bad.jpg"; + yield "rillybad.jpg"; +} + +function onSizeAvailable(aRequest) { + ok(true, "AfterLoad.onSizeAvailable called for " + gImg.src); +} +function onLoadComplete(aRequest) { + ok(gExpected > gLoads, "AfterLoad.onLoadComplete called for " + gImg.src); + gLoads++; + + // We aren't going to get a decode complete event if the metadata decoding + // failed (i.e. for invalid.jpg). By definition we should have the size or + // an error once we get a load complete event, so check if the size is valid + // and if not, trigger a decode complete event manually. + var hasSize = false; + try { + hasSize = aRequest.image.width > 0 && aRequest.image.height > 0; + } catch(e) {} + + if (hasSize) { + maybeAdvance(); + } else { + onDecodeComplete(aRequest); + } +} + +function onDecodeComplete(aRequest) { + ok(gExpected > gRemovals, "AfterLoad.onDecodeComplete called for " + gImg.src); + SimpleTest.executeSoon(function() { + try { + gContent.removeChild(gImg); + } + catch (e) {} + gRemovals++; + maybeAdvance(); + }); +} + +function failTest() { + ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " + + "currently displaying " + gImg.src); + cleanUpAndFinish(); +} + +function onNotification() +{ + ok(gExpected > gNotifications, "AfterLoad.onNotification called for " + gImg.src); + gNotifications++; + maybeAdvance(); +} + +function maybeAdvance() +{ + if (gNotifications != gLoads || gNotifications != gRemovals) { + return; + } + + let {done, value} = gFiles.next(); + if (done) { + cleanUpAndFinish(); + return; + } + gImg.src = value; + gContent.appendChild(gImg); +} + +function cleanUpAndFinish() { + // On the off chance that failTest and myOnStopFrame are triggered + // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. + if (gIsTestFinished) { + return; + } + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.removeObserver(gMyDecoderObserver); + // TODO - this isn't the case until post-bug 716140's refactorings + // ok(gNotifications == gLoads, "Should be notified the same number of times as loads"); + SimpleTest.finish(); + gIsTestFinished = true; +} + +function main() { + gFiles = fileToLoad(); + gImg = new Image(); + gImg.onload = onNotification; + gImg.onerror = onNotification; + + // Create, customize & attach decoder observer + var observer = new ImageDecoderObserverStub(); + observer.sizeAvailable = onSizeAvailable; + observer.loadComplete = onLoadComplete; + observer.decodeComplete = onDecodeComplete; + gMyDecoderObserver = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer)); + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.addObserver(gMyDecoderObserver); + + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + // kick off image-loading! myOnStopFrame handles the rest. + gImg.setAttribute("src", gFiles.next().value); + gContent.appendChild(gImg); + + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, FAILURE_TIMEOUT); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_removal_onload.html b/image/test/mochitest/test_removal_onload.html new file mode 100644 index 0000000000..0a060542f5 --- /dev/null +++ b/image/test/mochitest/test_removal_onload.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=841579 +--> +<head> + <title>Test for Bug 841579</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841579">Mozilla Bug 841579</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 841579**/ + +SimpleTest.requestFlakyTimeout("Early failure timeout"); +SimpleTest.waitForExplicitFinish(); + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const gContent = document.getElementById("content"); + +var gImg; +var gMyDecoderObserver; +var gIsTestFinished = false; +var gFiles; +var gNotifications = 0; +var gLoads = 0; +var gRemovals = 0; +var gExpected = 5; + +function* fileToLoad() { + yield "red.png"; + yield "invalid.jpg"; + yield "lime100x100.svg"; + yield "bad.jpg"; + yield "rillybad.jpg"; +} + +function onSizeAvailable(aRequest) { + ok(true, "AfterLoad.onSizeAvailable called for " + gImg.src); +} +function onLoadComplete(aRequest) { + ok(gExpected > gLoads, "AfterLoad.onLoadComplete called for " + gImg.src); + gLoads++; + SimpleTest.executeSoon(function() { + try { + gContent.removeChild(gImg); + } + catch (e) {} + gRemovals++; + maybeAdvance(); + }); +} +function onDecodeComplete(aRequest) { + ok(true, "AfterLoad.onDecodeComplete called for " + gImg.src); +} + +function failTest() { + ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. " + + "currently displaying " + gImg.src); + cleanUpAndFinish(); +} + +function onNotification() +{ + gNotifications++; + maybeAdvance(); +} + +function maybeAdvance() +{ + if (gRemovals != gNotifications) { + return; + } + + let {done, value} = gFiles.next(); + if (done) { + cleanUpAndFinish(); + return; + } + gImg.src = value; + gContent.appendChild(gImg); +} + +function cleanUpAndFinish() { + // On the off chance that failTest and myOnStopFrame are triggered + // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. + if (gIsTestFinished) { + return; + } + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.removeObserver(gMyDecoderObserver); + // TODO: this isn't the case until post-bug 716140's refactorings + // ok(gNotifications == gLoads, "Should be notified the same number of times as loads"); + SimpleTest.finish(); + gIsTestFinished = true; +} + +function main() { + gFiles = fileToLoad(); + gImg = new Image(); + gImg.onload = onNotification; + gImg.onerror = onNotification; + + // Create, customize & attach decoder observer + var observer = new ImageDecoderObserverStub(); + observer.sizeAvailable = onSizeAvailable; + observer.loadComplete = onLoadComplete; + observer.decodeComplete = onDecodeComplete; + gMyDecoderObserver = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .createScriptedObserver(SpecialPowers.wrapCallbackObject(observer)); + let imgLoadingContent = SpecialPowers.wrap(gImg); + imgLoadingContent.addObserver(gMyDecoderObserver); + + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + // kick off image-loading! myOnStopFrame handles the rest. + gImg.setAttribute("src", gFiles.next()); + + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, FAILURE_TIMEOUT); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_short_gif_header.html b/image/test/mochitest/test_short_gif_header.html new file mode 100644 index 0000000000..f8294825b5 --- /dev/null +++ b/image/test/mochitest/test_short_gif_header.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=844684 +--> +<head> + <title>Test for Bug 844684</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=844684">Mozilla Bug 844684</a> +<div id="content"> +<img id="testcontent" onload="success()" onerror="failure()"> +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +document.getElementById('testcontent').src = "short_header.gif"; + +function success() { + ok(true, "Image loaded."); + SimpleTest.finish(); +} + +function failure() { + ok(false, "Image didn't load."); + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_staticClone.html b/image/test/mochitest/test_staticClone.html new file mode 100644 index 0000000000..7400e064c6 --- /dev/null +++ b/image/test/mochitest/test_staticClone.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=878037 +--> +<head> + <title>Test for Bug 878037</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=878037">Mozilla Bug 878037</a> +<p id="display"></p> +<div> + <!-- transparent-animation.gif from the gif reftests. --> + <img id="animated" src="data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs="> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 878037**/ + +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + var img = document.getElementById("animated"); + var content = SpecialPowers.wrap(img); + + var request = content.getRequest(SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST); + + var staticReq = request.getStaticRequest(); + var clone = staticReq.clone(null); + + ok(clone, "hooray, we didn't crash!"); + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_svg_animatedGIF.html b/image/test/mochitest/test_svg_animatedGIF.html new file mode 100644 index 0000000000..04077676b7 --- /dev/null +++ b/image/test/mochitest/test_svg_animatedGIF.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - Animated Raster Images inside of SVG Frames</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<!-- Make sure embed element is snapped to an exact pixel. --> +<div class="bug-header" style="height: 100px;"> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> + Mozilla Bug 666446: lots of animated gifs swamp us with paint events + </a> +</div> + +<p id="display"></p> +<div id="content"> + <div id="referenceDiv" style="height: 40px; width: 40px; + display: none; background: #2aff00"></div> + <!-- + We use <embed> here instead of <img> because the <img> tag utilizes + the VectorImage class for SVG, whereas in this test, we are testing + RasterImage. + --> + <embed id="embeddedSVG" src="animation.svg" type="image/svg+xml" + style="height: 40px; width: 40px; display: none;"/> +</div> +<div id="debug" style="display:none"></div> +<pre id="test"> +<script type="text/javascript"> + +/** Test for Bug 666446 SVGImageFrame/RasterImage**/ + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() { + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'embeddedSVG', 'debug', ''); + animTest.beginTest(); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_svg_filter_animation.html b/image/test/mochitest/test_svg_filter_animation.html new file mode 100644 index 0000000000..b72aaa68c1 --- /dev/null +++ b/image/test/mochitest/test_svg_filter_animation.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - Animated Images within SVG Filters</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> +Mozilla Bug 666446: lots of animated gifs swamp us with paint events +</a> +<p id="display"></p> +<div id="content"> + <embed id="referenceImage" src="filter-final.svg" type="image/svg+xml" style="display: none;"/> + <embed id="embeddedSVGFilt" src="filter.svg" type="image/svg+xml" style="display: none;"/> +</div> +<div id="debug" style="display:none"></div> +<pre id="test"> +<script type="text/javascript"> + +/** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/ + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() { + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceImage', + 'embeddedSVGFilt', 'debug', ''); + animTest.beginTest(); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_synchronized_animation.html b/image/test/mochitest/test_synchronized_animation.html new file mode 100644 index 0000000000..3c2a874be1 --- /dev/null +++ b/image/test/mochitest/test_synchronized_animation.html @@ -0,0 +1,128 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=867758 +--> +<head> + <title>Test for Bug 867758</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=867758">Mozilla Bug 867758</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 867758**/ + +SimpleTest.requestFlakyTimeout("Early failure timeout"); +SimpleTest.waitForExplicitFinish(); + +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const gContent = document.getElementById("content"); + +var gDispatched = false; +var gRanEvent = false; +var gObserver; +var gImg1; +var gImg2; +var gFirstImageLoaded = false; +var gOuter; +var gFinished = false; +var gFirstRequest = null; + +function cleanUpAndFinish() { + if (gFinished) { + return; + } + var imgLoadingContent = SpecialPowers.wrap(gImg1); + imgLoadingContent.removeObserver(gOuter); + + imgLoadingContent = SpecialPowers.wrap(gImg2); + imgLoadingContent.removeObserver(gOuter); + + SimpleTest.finish(); + + gFinished = true; +} + +function frameUpdate(aRequest) { + if (!gDispatched) { + Promise.resolve().then(function() { + gRanEvent = true; + }); + gDispatched = true; + gFirstRequest = aRequest; + } else if (aRequest != gFirstRequest) { + ok(!gRanEvent, "Should not have run event before all frame update events occurred!"); + cleanUpAndFinish(); + } +} + +function failTest() { + ok(false, "timing out after " + FAILURE_TIMEOUT + "ms. "); + cleanUpAndFinish(); +} + +function waitForLoadAndTest(image) { + return () => { + // Draw the image into a canvas to ensure it's decoded. + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + context.drawImage(image, 0, 0); + + // Attach the observer. + var imgLoadingContent = SpecialPowers.wrap(image); + imgLoadingContent.addObserver(gOuter); + + // If the other image already loaded, add both images to the document, which + // begins the real test. + if (gFirstImageLoaded) { + gContent.appendChild(gImg1); + gContent.appendChild(gImg2); + } else { + gFirstImageLoaded = true; + } + }; +} + +function main() { + gImg1 = new Image(); + gImg2 = new Image(); + + // Create and customize decoder observer + var obs = new ImageDecoderObserverStub(); + obs.frameUpdate = frameUpdate; + + gOuter = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools).createScriptedObserver(SpecialPowers.wrapCallbackObject(obs)); + + // We want to test the cold loading behavior, so clear cache in case an + // earlier test got our image in there already. + clearAllImageCaches(); + + // These are two copies of the same image; hence, they have the same frame rate. + gImg1.src = "animated1.gif"; + gImg2.src = "animated2.gif"; + + // Wait for each image to load. + gImg1.addEventListener('load', waitForLoadAndTest(gImg1)); + gImg2.addEventListener('load', waitForLoadAndTest(gImg2)); + + // In case something goes wrong, fail earlier than mochitest timeout, + // and with more information. + setTimeout(failTest, FAILURE_TIMEOUT); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_undisplayed_iframe.html b/image/test/mochitest/test_undisplayed_iframe.html new file mode 100644 index 0000000000..695e4e5448 --- /dev/null +++ b/image/test/mochitest/test_undisplayed_iframe.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> +<title>Test for Bug 666446 - Test for Animated Gif within IFRAME</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="/tests/SimpleTest/WindowSnapshot.js"></script> +<script type="application/javascript" src="imgutils.js"></script> +<script type="application/javascript" src="animationPolling.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> + Mozilla Bug 666446: lots of animated gifs swamp us with paint events</a> + <p id="display"></p> + + <div id="content"> + <div id="referenceDiv" style="display:none;"> + <iframe id="referenceIFrame" src="ref-iframe.html" width="50%" height="100"> + Browser does not support iframes. + </iframe> + </div> + <div id="animatedImage"> + <iframe id="imageIFrame" src="iframe.html" width="50%" height="100" style="display: none;"> + Browser does not support iframes. + </iframe> + </div> + <div id="debug" style="display: none"></div> + </div> + <pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes) + +function main() +{ + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'imageIFrame', 'debug'); + animTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_webcam.html b/image/test/mochitest/test_webcam.html new file mode 100644 index 0000000000..8d6bf6b490 --- /dev/null +++ b/image/test/mochitest/test_webcam.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=641748 + +webcam-simulacrum.mgif is a hand-edited file containing red.gif and blue.gif, +concatenated together with the relevant headers for +multipart/x-mixed-replace. Specifically, with the headers in +webcam-simulacrum.mjpg^headers^, the web browser will get the following: + +HTTP 200 OK +Content-Type: multipart/x-mixed-replace;boundary=BOUNDARYOMG + +\-\-BOUNDARYOMG\r\n +Content-Type: image/gif\r\n +\r\n +<contents of red.gif> (no newline) +\-\-BOUNDARYOMG\r\n +Content-Type: image/gif\r\n +\r\n +<contents of blue.gif> (no newline) +\-\-BOUNDARYOMG\-\-\r\n + +(The boundary is arbitrary, and just has to be defined as something that +won't be in the text of the contents themselves. \-\-$(boundary)\r\n means +"Here is the beginning of a boundary," and \-\-$(boundary)\-\- means "All done +sending you parts.") +--> +<head> + <title>Test for Bug 641748 - WebCam Simulacrum</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=641748"> +Mozilla Bug 641748: GIF decoder doesn't support multipart/x-mixed-replace +</a> +<p id="display"></p> + +<div id="content"> + <div id="referenceDiv" style="height: 100px; width: 100px; + display: none; background: #0018ff;"></div> + <div id="animatedImage"> + <img id="animatedGif" src="webcam-simulacrum.sjs" style="display: none; height: 100px; width: 100px;"> + <div id="text-descr"></div> + </div> + <div id="debug" style="display:none"> + </div> +</div> +<pre id="test"> +<script type="text/javascript"> +const FAILURE_TIMEOUT = 60000; // Fail early after 60 seconds + +function main() +{ + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv', + 'animatedGif', 'debug'); + animTest.beginTest(); +} + +window.onload = main; +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/test_xultree_animation.xhtml b/image/test/mochitest/test_xultree_animation.xhtml new file mode 100644 index 0000000000..801117ed37 --- /dev/null +++ b/image/test/mochitest/test_xultree_animation.xhtml @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html +xmlns="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xml:lang="en" lang="en"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666446 +--> +<head> + <title>Test for Bug 666446 - Animated Images within SVG Filters</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="application/javascript" src="imgutils.js"></script> + <script type="application/javascript" src="animationPolling.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666446"> +Mozilla Bug 666446: lots of animated gifs swamp us with paint events +</a> +<p id="display"></p> +<div id="content"> + <xul:caption label="Bug 666446 - XULTree Test" /> + <xul:separator /> + <br /> + <xul:window id="main" title="Bug 666446: XUL Tree Testing" style="width: 100px; height: 100px"> + <xul:tree flex="1"> + <xul:treecols> + <xul:treecol id="icon" label="Icon" flex="1" /> + </xul:treecols> + + <xul:treechildren> + <xul:treeitem id="referenceItem" hidden="true"> + <xul:treerow> + <xul:treecell src="animated-gif-finalframe.gif" style="width: 40px; height: 40px;" /> + </xul:treerow> + </xul:treeitem> + <xul:treeitem id="imageItem" hidden="true"> + <xul:treerow> + <xul:treecell src="animated-gif.gif" style="width: 40px; height: 40px;" /> + </xul:treerow> + </xul:treeitem> + </xul:treechildren> + </xul:tree> + </xul:window> + </div> +<div id="debug" style="display:none"></div> +<pre id="test"> +<script type="text/javascript"> + +/** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/ + +const FAILURE_TIMEOUT = 5000; // Fail early after 120 seconds (2 minutes) + +function main() { + var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceItem', + 'imageItem', 'debug', '', + 'animated-gif-finalframe.gif', true); + animTest.beginTest(); +} + +window.onload = main; + +</script> +</pre> +</body> +</html> diff --git a/image/test/mochitest/transparent.gif b/image/test/mochitest/transparent.gif Binary files differnew file mode 100644 index 0000000000..48f5c7caf1 --- /dev/null +++ b/image/test/mochitest/transparent.gif diff --git a/image/test/mochitest/transparent.png b/image/test/mochitest/transparent.png Binary files differnew file mode 100644 index 0000000000..fc8002053a --- /dev/null +++ b/image/test/mochitest/transparent.png diff --git a/image/test/mochitest/webcam-simulacrum.sjs b/image/test/mochitest/webcam-simulacrum.sjs new file mode 100644 index 0000000000..6243329eac --- /dev/null +++ b/image/test/mochitest/webcam-simulacrum.sjs @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var counter = 2; +var frames = ["red.gif", "blue.gif"]; +var timer = Cc["@mozilla.org/timer;1"]; +var partTimer = timer.createInstance(Ci.nsITimer); + +function getFileAsInputStream(aFilename) { + var file = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + file.append(aFilename); + + var fileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + return fileStream; +} + +function handleRequest(request, response) { + response.setHeader( + "Content-Type", + "multipart/x-mixed-replace;boundary=BOUNDARYOMG", + false + ); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.processAsync(); + response.write("--BOUNDARYOMG\r\n"); + while (frames.length) { + sendNextPart(response); + } + response.write("--BOUNDARYOMG--\r\n"); + response.finish(); +} + +function sendNextPart(response) { + var nextPartHead = "Content-Type: image/gif\r\n\r\n"; + var inputStream = getFileAsInputStream(frames.shift()); + response.bodyOutputStream.write(nextPartHead, nextPartHead.length); + response.bodyOutputStream.writeFrom(inputStream, inputStream.available()); + inputStream.close(); + // Toss in the boundary, so the browser can know this part is complete + response.write("--BOUNDARYOMG\r\n"); +} |