428 lines
13 KiB
HTML
428 lines
13 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>nsIDocumentViewer::overrideDPPX test</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<iframe></iframe>
|
|
<img>
|
|
|
|
<script type="application/javascript">
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
|
|
const frameWindow = document.querySelector("iframe").contentWindow;
|
|
const image = document.querySelector("img");
|
|
|
|
const originalDPR = window.devicePixelRatio;
|
|
const originalZoom = SpecialPowers.getFullZoom(window);
|
|
const dppx = originalDPR * 1.5;
|
|
const zoom = originalZoom * 0.5;
|
|
|
|
const imageSets = {
|
|
"1x" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" +
|
|
"GUlEQVQ4jWP4z8DwnxLMMGrAqAGjBgwXAwAwxP4QWURl4wAAAABJRU5ErkJggg==",
|
|
"1.5x": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" +
|
|
"GElEQVQ4jWNgaGD4TxEeNWDUgFEDhosBAOsIfxAZ/CYXAAAAAElFTkSuQmCC",
|
|
"2x" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" +
|
|
"GElEQVQ4jWNgYPj/nzI8asCoAaMGDBMDADKm/hBZaHKGAAAAAElFTkSuQmCC",
|
|
"8x" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA" +
|
|
"GklEQVQ4jWP4f+D0f0oww6gBowaMGjBcDAAAskKJLhIvZvgAAAAASUVORK5CYII=",
|
|
};
|
|
|
|
const setOverrideDPPX = (value) => {
|
|
if (value > 0) {
|
|
info(`override window's dppx to ${value}`);
|
|
} else {
|
|
info(`restore window's dppx to default value`);
|
|
}
|
|
|
|
return SpecialPowers.spawnChrome([value], dppx => {
|
|
browsingContext.top.overrideDPPX = dppx;
|
|
});
|
|
};
|
|
|
|
const setFullZoom = (value) => {
|
|
info(`set window's fullZoom to ${value}`);
|
|
SpecialPowers.setFullZoom(window, value);
|
|
}
|
|
|
|
const createFontStyleForDPPX = (doc, value, size) => {
|
|
info(`adding a stylesheet that set font size to ${size}px for ${value}dppx`);
|
|
|
|
let style = doc.createElement("style");
|
|
|
|
style.setAttribute("media", `(resolution: ${value}dppx)`);
|
|
|
|
doc.head.appendChild(style);
|
|
|
|
style.sheet.insertRule(`body {font-size: ${size}px}`, 0);
|
|
|
|
return style;
|
|
}
|
|
|
|
const getBodyFontSize = (w) => w.getComputedStyle(w.document.body).fontSize;
|
|
|
|
const assertValuesAreInitial = () => {
|
|
is(window.devicePixelRatio, originalDPR,
|
|
"devicePixelRatio has the original value.");
|
|
is(SpecialPowers.getFullZoom(window), originalZoom,
|
|
"fullZoom has the original value.");
|
|
|
|
is(frameWindow.devicePixelRatio, originalDPR,
|
|
"devicePixelRatio has the original value.");
|
|
is(SpecialPowers.getFullZoom(frameWindow), originalZoom,
|
|
"fullZoom has the original value.");
|
|
}
|
|
|
|
const waitForMediaQueryListEvent = (mediaQueryList) => {
|
|
return new Promise(resolve => {
|
|
mediaQueryList.addListener(function listener() {
|
|
ok(true, "MediaQueryList's listener invoked for " + mediaQueryList.media);
|
|
mediaQueryList.removeListener(listener);
|
|
// We need to evacuate a media query list event to avoid changing any
|
|
// media features inside this callback (and microtasks for the callbacks),
|
|
// because we currently dispatch media query list events during flush
|
|
// pending styles, and we want to make sure there is no pending media
|
|
// feature changes after the event handling.
|
|
// This workaround should be dropped in bug 1437688.
|
|
setTimeout(resolve, 0);
|
|
});
|
|
});
|
|
}
|
|
|
|
const gTests = {
|
|
"test overrideDPPX with devicePixelRatio": async (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
await setOverrideDPPX(dppx);
|
|
|
|
is(window.devicePixelRatio, dppx,
|
|
"devicePixelRatio overridden.");
|
|
is(frameWindow.devicePixelRatio, dppx,
|
|
"frame's devicePixelRatio overridden.");
|
|
|
|
await setOverrideDPPX(0);
|
|
|
|
is(window.devicePixelRatio, originalDPR,
|
|
"devicePixelRatio back to default.");
|
|
is(frameWindow.devicePixelRatio, originalDPR,
|
|
"frame's devicePixelRatio back to default.");
|
|
|
|
done();
|
|
},
|
|
"test overrideDPPX with devicePixelRatio and fullZoom": async (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
setFullZoom(zoom);
|
|
await setOverrideDPPX(dppx);
|
|
|
|
is(window.devicePixelRatio, dppx,
|
|
"devicePixelRatio overridden; fullZoom ignored");
|
|
is(SpecialPowers.wrap(window).devicePixelRatio, originalDPR * zoom,
|
|
"devicePixelRatio is right for privileged code");
|
|
is(frameWindow.devicePixelRatio, dppx,
|
|
"frame's devicePixelRatio overridden; fullZoom ignored");
|
|
is(SpecialPowers.wrap(frameWindow).devicePixelRatio, originalDPR * zoom,
|
|
"frame's devicePixelRatio is right for privileged code");
|
|
|
|
await setOverrideDPPX(0);
|
|
|
|
is(window.devicePixelRatio, originalDPR * zoom,
|
|
"devicePixelRatio now is affected by fullZoom");
|
|
is(frameWindow.devicePixelRatio, originalDPR * zoom,
|
|
"frame's devicePixelRatio now is affected by fullZoom");
|
|
isnot(dppx, originalDPR * zoom,
|
|
"test is no longer testing what it should be");
|
|
|
|
setFullZoom(originalZoom);
|
|
|
|
is(window.devicePixelRatio, originalDPR,
|
|
"devicePixelRatio back to default.");
|
|
is(frameWindow.devicePixelRatio, originalDPR,
|
|
"frame's devicePixelRatio back to default.");
|
|
|
|
done();
|
|
|
|
},
|
|
"test overrideDPPX with media queries": async (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
let frameDoc = frameWindow.document;
|
|
|
|
let originalFontSize = getBodyFontSize(window);
|
|
let frameOriginalFontSize = getBodyFontSize(frameWindow);
|
|
|
|
let style = createFontStyleForDPPX(document, dppx, "32");
|
|
let frameStyle = createFontStyleForDPPX(frameDoc, dppx, "32");
|
|
|
|
let currentFontSize = getBodyFontSize(window);
|
|
let frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
|
|
is(currentFontSize, originalFontSize,
|
|
"media queries are not applied yet");
|
|
is(frameCurrentFontSize, frameOriginalFontSize,
|
|
"frame's media queries are not applied yet");
|
|
|
|
await setOverrideDPPX(dppx);
|
|
|
|
currentFontSize = getBodyFontSize(window);
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
|
|
isnot(currentFontSize, originalFontSize,
|
|
"media queries are applied.");
|
|
isnot(frameCurrentFontSize, frameOriginalFontSize,
|
|
"frame's media queries are applied.");
|
|
|
|
is(currentFontSize, "32px",
|
|
"font size has the expected value.");
|
|
is(frameCurrentFontSize, "32px",
|
|
"frame's font size has the expected value.");
|
|
|
|
await setOverrideDPPX(0);
|
|
|
|
currentFontSize = getBodyFontSize(window);
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
|
|
is(currentFontSize, originalFontSize,
|
|
"media queries are not applied anymore.");
|
|
is(frameCurrentFontSize, frameOriginalFontSize,
|
|
"media queries are not applied anymore.");
|
|
|
|
style.remove();
|
|
frameStyle.remove();
|
|
|
|
done();
|
|
},
|
|
"test overrideDPPX with media queries and fullZoom": async (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
let frameDoc = frameWindow.document;
|
|
|
|
let styles = [
|
|
createFontStyleForDPPX(document, originalDPR, "23"),
|
|
createFontStyleForDPPX(document, dppx, "32"),
|
|
createFontStyleForDPPX(document, originalDPR * zoom, "48"),
|
|
createFontStyleForDPPX(frameDoc, originalDPR, "23"),
|
|
createFontStyleForDPPX(frameDoc, dppx, "32"),
|
|
createFontStyleForDPPX(frameDoc, originalDPR * zoom, "48")
|
|
];
|
|
|
|
let currentFontSize = getBodyFontSize(window);
|
|
let frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
is(currentFontSize, "23px",
|
|
"media queries are not applied yet");
|
|
is(frameCurrentFontSize, "23px",
|
|
"frame's media queries are not applied yet");
|
|
|
|
setFullZoom(zoom);
|
|
await setOverrideDPPX(dppx);
|
|
|
|
currentFontSize = getBodyFontSize(window);
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
is(currentFontSize, "32px",
|
|
"media queries are applied for overridden DDPX; fullZoom ignored.");
|
|
is(frameCurrentFontSize, "32px",
|
|
"frame's media queries are applied for overridden DDPX; fullZoom ignored.");
|
|
|
|
await setOverrideDPPX(0);
|
|
|
|
currentFontSize = getBodyFontSize(window);
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
is(currentFontSize, "48px",
|
|
"media queries are applied for fullZoom.");
|
|
is(frameCurrentFontSize, "48px",
|
|
"frame's media queries are applied for fullZoom.");
|
|
|
|
setFullZoom(originalZoom);
|
|
|
|
currentFontSize = getBodyFontSize(window);
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
is(currentFontSize, "23px",
|
|
"media queries are not applied anymore.");
|
|
is(frameCurrentFontSize, "23px",
|
|
"frame's media queries are not applied anymore.");
|
|
|
|
styles.forEach(style => style.remove());
|
|
|
|
done();
|
|
},
|
|
"test OverrideDPPX with MediaQueryList": (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
let promises = [
|
|
waitForMediaQueryListEvent(
|
|
window.matchMedia(`(resolution: ${dppx}dppx)`)),
|
|
waitForMediaQueryListEvent(
|
|
frameWindow.matchMedia(`(resolution: ${dppx}dppx)`)),
|
|
];
|
|
|
|
Promise.all(promises)
|
|
.then(() => setOverrideDPPX(0))
|
|
.then(done, e => {throw e});
|
|
|
|
setOverrideDPPX(dppx);
|
|
},
|
|
"test OverrideDPPX with MediaQueryList and fullZoom": async (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
let promises = [
|
|
waitForMediaQueryListEvent(
|
|
window.matchMedia(`(resolution: ${dppx}dppx)`)),
|
|
waitForMediaQueryListEvent(
|
|
window.matchMedia(`(resolution: ${originalDPR * zoom}dppx)`)),
|
|
];
|
|
|
|
await setOverrideDPPX(dppx);
|
|
setFullZoom(zoom);
|
|
|
|
promises[0]
|
|
.then(() => setOverrideDPPX(0))
|
|
.then(promises[1])
|
|
.then(() => setFullZoom(originalZoom))
|
|
.then(done, e => {throw e});
|
|
},
|
|
"test OverrideDPPX is kept on document navigation": async (done) => {
|
|
assertValuesAreInitial();
|
|
|
|
let frameOriginalFontSize = getBodyFontSize(frameWindow);
|
|
let frameStyle = createFontStyleForDPPX(frameWindow.document, dppx, "32");
|
|
let frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
|
|
is(frameCurrentFontSize, frameOriginalFontSize,
|
|
"frame's media queries are not applied yet");
|
|
|
|
await setOverrideDPPX(dppx);
|
|
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
|
|
is(frameWindow.devicePixelRatio, dppx,
|
|
"frame's devicePixelRatio overridden.");
|
|
isnot(frameCurrentFontSize, frameOriginalFontSize,
|
|
"frame's media queries are applied.");
|
|
is(frameCurrentFontSize, "32px",
|
|
"frame's font size has the expected value.");
|
|
|
|
frameWindow.frameElement.addEventListener("load", async function() {
|
|
frameStyle = createFontStyleForDPPX(frameWindow.document, dppx, "32");
|
|
|
|
frameCurrentFontSize = getBodyFontSize(frameWindow);
|
|
|
|
is(frameWindow.devicePixelRatio, dppx,
|
|
"frame's devicePixelRatio is still overridden.");
|
|
isnot(frameCurrentFontSize, frameOriginalFontSize,
|
|
"frame's media queries are still applied.");
|
|
is(frameCurrentFontSize, "32px",
|
|
"frame's font size has still the expected value.");
|
|
|
|
frameStyle.remove();
|
|
|
|
await setOverrideDPPX(0);
|
|
|
|
done();
|
|
}, {once: true});
|
|
|
|
frameWindow.location.reload(true);
|
|
},
|
|
|
|
"test overrideDPPX with srcset": async function (done) {
|
|
assertValuesAreInitial();
|
|
|
|
let loaded;
|
|
|
|
// Set the image srcset and default src. This is delayed until this test so
|
|
// that dppx overrides in other test blocks don't trigger load event on the
|
|
// image.
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
image.srcset = Object.entries(imageSets).map(v => v[1] + " " + v[0]).join(", ");
|
|
image.src = imageSets["1x"];
|
|
await loaded;
|
|
|
|
let originalSrc = image.currentSrc;
|
|
|
|
// Make sure to test some very large value that can't be the default density
|
|
// so that the first override will always trigger a load.
|
|
isnot(originalDPR, 8, "originalDPR differs from final test value");
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
await setOverrideDPPX(8);
|
|
await loaded;
|
|
|
|
is(image.currentSrc, imageSets["8x"],
|
|
"Image is properly set for 8dppx.");
|
|
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
await setOverrideDPPX(1);
|
|
await loaded;
|
|
|
|
is(image.currentSrc, imageSets["1x"],
|
|
"Image url is properly set for 1dppx.");
|
|
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
await setOverrideDPPX(1.5);
|
|
await loaded;
|
|
|
|
is(image.currentSrc, imageSets["1.5x"],
|
|
"Image url is properly set for 1.5dppx.");
|
|
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
await setOverrideDPPX(2);
|
|
await loaded;
|
|
|
|
is(image.currentSrc, imageSets["2x"],
|
|
"Image is properly set for 2dppx.");
|
|
|
|
// Make sure to test some very large value that can't be the default density
|
|
// so that resetting to the default will always trigger a load.
|
|
isnot(originalDPR, 8, "originalDPR differs from final test value");
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
await setOverrideDPPX(8);
|
|
await loaded;
|
|
|
|
is(image.currentSrc, imageSets["8x"],
|
|
"Image is properly set for 8dppx.");
|
|
|
|
loaded = new Promise(resolve => image.onload = resolve);
|
|
await setOverrideDPPX(0);
|
|
await loaded;
|
|
|
|
is(image.currentSrc, originalSrc,
|
|
"Image is properly restored to the default value.");
|
|
|
|
// Clear sources so any future dppx test blocks don't trigger image loads.
|
|
image.srcset = "";
|
|
image.src = "";
|
|
|
|
done();
|
|
}
|
|
};
|
|
|
|
function* runner(tests) {
|
|
for (let name of Object.keys(tests)) {
|
|
info(name);
|
|
tests[name](next);
|
|
yield undefined;
|
|
}
|
|
};
|
|
|
|
const gTestRunner = runner(gTests);
|
|
|
|
function next() {
|
|
SimpleTest.executeSoon(function() {
|
|
if (gTestRunner.next().done) {
|
|
SimpleTest.finish();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Run the tests
|
|
addLoadEvent(next);
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|