summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html')
-rw-r--r--dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html428
1 files changed, 428 insertions, 0 deletions
diff --git a/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html b/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html
new file mode 100644
index 0000000000..af3f46b81b
--- /dev/null
+++ b/dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html
@@ -0,0 +1,428 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>nsIContentViewer::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>