summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_smooth.html
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/test/mochitest/helper_doubletap_zoom_smooth.html')
-rw-r--r--gfx/layers/apz/test/mochitest/helper_doubletap_zoom_smooth.html161
1 files changed, 161 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_smooth.html b/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_smooth.html
new file mode 100644
index 0000000000..65b4c6698f
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_smooth.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=2100"/>
+ <title>Check that double tapping zoom out animation is smooth</title>
+ <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+ <script type="application/javascript" src="apz_test_utils.js"></script>
+ <script src="/tests/SimpleTest/paint_listener.js"></script>
+ <script type="application/javascript">
+
+let hasPrev = false;
+let zoomingIn = true;
+let lastVVLeft = 0, lastVVTop = 0, lastVVWidth = 0, lastVVHeight = 0;
+let lastScrollX = 0, lastScrollY = 0;
+let lastResolution = 0;
+
+function within(a, b, tolerance) {
+ return (Math.abs(a-b) < tolerance);
+}
+
+async function afterpaint() {
+ info("vv pos " + visualViewport.pageLeft + "," + visualViewport.pageTop);
+ info("vv size " + visualViewport.width + "," + visualViewport.height);
+ info("win scroll " + window.scrollX + "," + window.scrollY);
+ info("res " + await getResolution());
+ if (hasPrev) {
+ ok(zoomingIn ?
+ lastVVLeft <= visualViewport.pageLeft :
+ lastVVLeft >= visualViewport.pageLeft,
+ "vvleft monotonic");
+ // When zooming in pageTop stays 0, when zooming out (at least on mac)
+ // the final value of pageTop is 2.5. Hence why the direction of these
+ // inequalities.
+ ok(zoomingIn ?
+ lastVVTop >= visualViewport.pageTop :
+ lastVVTop <= visualViewport.pageTop,
+ "vvtop monotonic");
+ ok(zoomingIn ?
+ lastVVWidth >= visualViewport.width :
+ lastVVWidth <= visualViewport.width,
+ "vvwidth monotonic");
+ ok(zoomingIn ?
+ lastVVHeight >= visualViewport.height :
+ lastVVHeight <= visualViewport.height,
+ "vvheight monotonic");
+ ok(zoomingIn ?
+ lastScrollX <= window.scrollX :
+ lastScrollX >= window.scrollX,
+ "scrollx monotonic");
+ if (!within(lastScrollY, window.scrollY, 2)) {
+ ok(zoomingIn ?
+ lastScrollY >= window.scrollY :
+ lastScrollY <= window.scrollY,
+ "scrolly monotonic");
+ }
+
+ // At the upper and lower limits of zoom constraints we can briefly go over
+ // the limit and then back because of floating point inaccuracies.
+ // In apzc callback helper we set the new content resolution to
+ // (last presshell resolution that apz knows about) * (apz async zoom)
+ // and (apz async zoom) is calculated as (apz zoom) / (last content resolution that apz knows about)
+ // and (last content resolution that apz knows about) = (dev pixels per css pixel) * (ps resolution) * (resolution induced by transforms)
+ // For simplicity we can assume that (dev pixels per css pixel) == (resolution induced by transforms) == 1
+ // and (ps resolution) == (last presshell resolution that apz knows about).
+ // The calculation then boils down to
+ // (ps resolution) * ((apz zoom) / (ps resolution))
+ // The fact that we divide by (ps resolution) first, and then multiply by
+ // it means the result is not quite equal to (apz zoom).
+ const deviceScale = window.devicePixelRatio;
+ const maxZoom = 10.0;
+ if (!within(lastResolution, maxZoom/deviceScale, 0.0001) &&
+ !within(await getResolution(), maxZoom/deviceScale, 0.0001) &&
+ !within(lastResolution, 1, 0.0001) &&
+ !within(await getResolution(), 1, 0.0001)) {
+ ok(zoomingIn ?
+ lastResolution <= await getResolution() :
+ lastResolution >= await getResolution(),
+ "resolution monotonic");
+ }
+
+ } else {
+ hasPrev = true;
+ }
+ lastVVLeft = visualViewport.pageLeft;
+ lastVVTop = visualViewport.pageTop;
+ lastVVWidth = visualViewport.width;
+ lastVVHeight = visualViewport.height;
+ lastScrollX = window.scrollX;
+ if (!within(lastScrollY, window.scrollY, 2)) {
+ lastScrollY = window.scrollY;
+ }
+ lastResolution = await getResolution();
+}
+
+async function test() {
+ let useTouchpad = (location.search == "?touchpad");
+
+ info("dpi: " + window.devicePixelRatio);
+
+ window.addEventListener("MozAfterPaint", afterpaint);
+ let intervalID = setInterval(afterpaint, 16);
+
+ let resolution = await getResolution();
+ ok(resolution > 0,
+ "The initial_resolution is " + resolution + ", which is some sane value");
+
+ // Check that double-tapping once on a small element zooms in
+ info("sending first double tap");
+ await doubleTapOn(document.getElementById("target2"), 10, 10, useTouchpad);
+ let prev_resolution = resolution;
+ resolution = await getResolution();
+ ok(resolution > prev_resolution, "The first double-tap has increased the resolution to " + resolution);
+
+ await promiseApzFlushedRepaints();
+
+ hasPrev = false;
+ zoomingIn = false;
+
+ // Double tap, this won't hit anything but the body/html, and so will zoom us out.
+ info("sending second double tap");
+ await doubleTapOn(document.getElementById("target2"), 5, 65, useTouchpad);
+ await promiseApzFlushedRepaints();
+ prev_resolution = resolution;
+ resolution = await getResolution();
+ ok(resolution < prev_resolution, "The second double-tap has decreased the resolution to " + resolution);
+
+ clearInterval(intervalID);
+ window.removeEventListener("MozAfterPaint", afterpaint);
+}
+
+waitUntilApzStable()
+.then(test)
+.then(subtestDone, subtestFailed);
+
+ </script>
+ <style>
+ .container {
+ background-color: #eee;
+ width: 95vw;
+ height: 400vh;
+ }
+ .smallcontainer {
+ background-color: #aaa;
+ width: 40px;
+ height: 40px;
+ position: absolute;
+ right: 0;
+ top: 20px;
+ }
+</style>
+</head>
+<body>
+
+<div id="target" class="container">
+</div>
+<div id="target2" class="smallcontainer">
+</div>
+
+</body>
+</html>