<!-- NOTE if adding a new image here you need to adjust four other places: * add it to the gImgs array below * add it to the 4 arrays below that * add it to the condition in checkIfFinished if it's infinite * potentially update the starting index of finite imgs in addCallbacks observer.discard.
-->
<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="corruptinfinitegif" src="1835509.gif">
<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"> <!-- NOTE see above the steps you need to do if adding an img here -->
/** 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', 'corruptinfinitegif', '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, 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, null, null, null];
// Number of observed changes in the snapshot. var gNumSnapShotChanges = [0, 0, 0, 0, 0, 0, 0, 0, 0];
// If we've removed the observer. var gRemovedObserver = [false, false, false, false, false, false, false, false, false];
// 2 would probably be a good enough test, we arbitrarily choose 4. var kNumFrameUpdatesToExpect = 5;
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;
}
// 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 >= 5) {
// The last four 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) { varcanvas = 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");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.