diff options
author | wychen <wychen@chromium.org> | 2015-04-24 18:03:46 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-25 01:03:44 +0000 |
commit | 6349c066f2a16007c0fba1684dfe2a18d40a9e20 (patch) | |
tree | 2aec3faf322e1aa638229fc4a45bc8c40ece9860 /components/test | |
parent | 73dfc1c5a87b062a1432713dedb64db2c45dca7d (diff) | |
download | chromium_src-6349c066f2a16007c0fba1684dfe2a18d40a9e20.zip chromium_src-6349c066f2a16007c0fba1684dfe2a18d40a9e20.tar.gz chromium_src-6349c066f2a16007c0fba1684dfe2a18d40a9e20.tar.bz2 |
Changing font size with pinch gesture in Reader Mode
When users pinch in Reader Mode, the page would zoom in or out as if it
is a normal web page allowing user-zoom. At the end of pinch gesture, the
page would do text reflow. These pinch-to-zoom and text reflow effects
are not native, but are emulated using CSS and JavaScript.
In order to achieve near-native zooming and panning frame rate, fake 3D
transform is used so that the layer doesn't repaint for each frame.
After the text reflow, the web content shown in the viewport should
roughly be the same paragraph before zooming.
The control point of font size is the html element, so that both "em" and
"rem" are adjusted. Accordingly, font size of body is no longer specified
in CSS in unit of pixel.
Some CSS styles and animations are updated to fix issues specific to
resizing.
BUG=445632
Review URL: https://codereview.chromium.org/1009703002
Cr-Commit-Position: refs/heads/master@{#326945}
Diffstat (limited to 'components/test')
-rw-r--r-- | components/test/data/dom_distiller/pinch_tester.html | 14 | ||||
-rw-r--r-- | components/test/data/dom_distiller/pinch_tester.js | 388 |
2 files changed, 402 insertions, 0 deletions
diff --git a/components/test/data/dom_distiller/pinch_tester.html b/components/test/data/dom_distiller/pinch_tester.html new file mode 100644 index 0000000..9dbb48d --- /dev/null +++ b/components/test/data/dom_distiller/pinch_tester.html @@ -0,0 +1,14 @@ +<html> +<head><title>Test Page for Pinch to Zoom</title></head> +<body> +<div id="contentWrap"> +<p id="showOriginal">Original</p> +</div> +<div id="feedbackContainer"> + <div id="feedbackYes"></div> + <div id="feedbackNo"></div> +</div> +<script src="dom_distiller_viewer.js"></script> +<script src="pinch_tester.js"></script> +</body> +</html> diff --git a/components/test/data/dom_distiller/pinch_tester.js b/components/test/data/dom_distiller/pinch_tester.js new file mode 100644 index 0000000..e2c1df5 --- /dev/null +++ b/components/test/data/dom_distiller/pinch_tester.js @@ -0,0 +1,388 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var pinchtest = (function() { + 'use strict'; + + function assertTrue(condition, message) { + if (!condition) { + message = message || "Assertion failed"; + console.trace(); + throw new Error(message); + } + } + + function assertClose(a, b, message) { + if (Math.abs(a-b) > 1e-5) { + message = message || "Assertion failed"; + console.log('"', a, '" and "', b, '" are not close.'); + console.trace(); + throw new Error(message); + } + } + + function isEquivalent(a, b) { + // Create arrays of property names + var aProps = Object.getOwnPropertyNames(a); + var bProps = Object.getOwnPropertyNames(b); + + // If number of properties is different, + // objects are not equivalent + if (aProps.length != bProps.length) { + return false; + } + + for (var i = 0; i < aProps.length; i++) { + var propName = aProps[i]; + + // If values of same property are not equal, + // objects are not equivalent + if (a[propName] !== b[propName]) { + return false; + } + } + + // If we made it this far, objects + // are considered equivalent + return true; + } + + function assertEqual(a, b, message) { + if (!isEquivalent(a, b)) { + message = message || "Assertion failed"; + console.log('"', a, '" and "', b, '" are not equal'); + console.trace(); + throw new Error(message); + } + } + + var touch = (function() { + 'use strict'; + var points = {}; + function lowestID() { + var ans = -1; + for(var key in points) { + ans = Math.max(ans, key); + } + return ans + 1; + } + function changeTouchPoint (key, x, y, offsetX, offsetY) { + var e = { + clientX: x, + clientY: y, + pageX: x, + pageY: y + }; + if (typeof(offsetX) === 'number') { + e.clientX += offsetX; + } + if (typeof(offsetY) === 'number') { + e.clientY += offsetY; + } + points[key] = e; + } + return { + addTouchPoint: function(x, y, offsetX, offsetY) { + changeTouchPoint(lowestID(), x, y, offsetX, offsetY); + }, + updateTouchPoint: changeTouchPoint, + releaseTouchPoint: function(key) { + delete points[key]; + }, + events: function() { + var arr = []; + for(var key in points) { + arr.push(points[key]); + } + return { + touches: arr, + preventDefault: function(){} + }; + } + } + }); + + function testZoomOut() { + pincher.reset(); + var t = new touch(); + + // Make sure start event doesn't change state + var oldState = pincher.status(); + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.addTouchPoint(300, 300); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + + // Make sure extra move event doesn't change state + pincher.handleTouchMove(t.events()); + assertEqual(oldState, pincher.status()); + + t.updateTouchPoint(0, 150, 150); + t.updateTouchPoint(1, 250, 250); + pincher.handleTouchMove(t.events()); + assertTrue(pincher.status().clampedScale < 0.9); + + // Make sure end event doesn't change state + oldState = pincher.status(); + t.releaseTouchPoint(1); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + } + + function testZoomIn() { + pincher.reset(); + var t = new touch(); + + var oldState = pincher.status(); + t.addTouchPoint(150, 150); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.addTouchPoint(250, 250); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + + t.updateTouchPoint(0, 100, 100); + t.updateTouchPoint(1, 300, 300); + pincher.handleTouchMove(t.events()); + assertTrue(pincher.status().clampedScale > 1.1); + + oldState = pincher.status(); + t.releaseTouchPoint(1); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + } + + function testZoomOutAndPan() { + pincher.reset(); + var t = new touch(); + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(300, 300); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 150, 150); + t.updateTouchPoint(1, 250, 250); + pincher.handleTouchMove(t.events()); + t.updateTouchPoint(0, 150, 150, 10, -5); + t.updateTouchPoint(1, 250, 250, 10, -5); + pincher.handleTouchMove(t.events()); + t.releaseTouchPoint(1); + pincher.handleTouchEnd(t.events()); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + + assertClose(pincher.status().shiftX, 10); + assertClose(pincher.status().shiftY, -5); + assertTrue(pincher.status().clampedScale < 0.9); + } + + function testReversible() { + pincher.reset(); + var t = new touch(); + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(300, 300); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 0, 0); + t.updateTouchPoint(1, 400, 400); + pincher.handleTouchMove(t.events()); + t.releaseTouchPoint(1); + pincher.handleTouchEnd(t.events()); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + t.addTouchPoint(0, 0); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(400, 400); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 100, 100); + t.updateTouchPoint(1, 300, 300); + pincher.handleTouchMove(t.events()); + t.releaseTouchPoint(1); + pincher.handleTouchEnd(t.events()); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + assertClose(pincher.status().clampedScale, 1); + } + + function testMultitouchZoomOut() { + pincher.reset(); + var t = new touch(); + + var oldState = pincher.status(); + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.addTouchPoint(300, 300); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.addTouchPoint(100, 300); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.addTouchPoint(300, 100); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + + // Multi-touch zoom out. + t.updateTouchPoint(0, 150, 150); + t.updateTouchPoint(1, 250, 250); + t.updateTouchPoint(2, 150, 250); + t.updateTouchPoint(3, 250, 150); + pincher.handleTouchMove(t.events()); + + oldState = pincher.status(); + t.releaseTouchPoint(3); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + t.releaseTouchPoint(2); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + t.releaseTouchPoint(1); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + + assertTrue(pincher.status().clampedScale < 0.9); + } + + function testZoomOutThenMulti() { + pincher.reset(); + var t = new touch(); + + var oldState = pincher.status(); + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.addTouchPoint(300, 300); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + + // Zoom out. + t.updateTouchPoint(0, 150, 150); + t.updateTouchPoint(1, 250, 250); + pincher.handleTouchMove(t.events()); + assertTrue(pincher.status().clampedScale < 0.9); + + // Make sure adding and removing more point doesn't change state + oldState = pincher.status(); + t.addTouchPoint(600, 600); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + t.releaseTouchPoint(2); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + + // More than two fingers. + t.addTouchPoint(150, 250); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(250, 150); + pincher.handleTouchStart(t.events()); + assertEqual(oldState, pincher.status()); + + t.updateTouchPoint(0, 100, 100); + t.updateTouchPoint(1, 300, 300); + t.updateTouchPoint(2, 100, 300); + t.updateTouchPoint(3, 300, 100); + pincher.handleTouchMove(t.events()); + assertClose(pincher.status().scale, 1); + + oldState = pincher.status(); + t.releaseTouchPoint(3); + t.releaseTouchPoint(2); + t.releaseTouchPoint(1); + t.releaseTouchPoint(0); + pincher.handleTouchEnd(t.events()); + assertEqual(oldState, pincher.status()); + } + + function testCancel() { + pincher.reset(); + var t = new touch(); + + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(300, 300); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 150, 150); + t.updateTouchPoint(1, 250, 250); + pincher.handleTouchMove(t.events()); + assertTrue(pincher.status().clampedScale < 0.9); + + var oldState = pincher.status(); + t.releaseTouchPoint(1); + t.releaseTouchPoint(0); + pincher.handleTouchCancel(t.events()); + assertEqual(oldState, pincher.status()); + + t.addTouchPoint(150, 150); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(250, 250); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 100, 100); + t.updateTouchPoint(1, 300, 300); + pincher.handleTouchMove(t.events()); + assertClose(pincher.status().clampedScale, 1); + } + + function testSingularity() { + pincher.reset(); + var t = new touch(); + + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(100, 100); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 150, 150); + t.updateTouchPoint(1, 50, 50); + pincher.handleTouchMove(t.events()); + assertTrue(pincher.status().clampedScale > 1.1); + assertTrue(pincher.status().clampedScale < 100); + assertTrue(pincher.status().scale < 100); + + pincher.handleTouchCancel(); + } + + function testMinSpan() { + pincher.reset(); + var t = new touch(); + + t.addTouchPoint(50, 50); + pincher.handleTouchStart(t.events()); + t.addTouchPoint(150, 150); + pincher.handleTouchStart(t.events()); + t.updateTouchPoint(0, 100, 100); + t.updateTouchPoint(1, 100, 100); + pincher.handleTouchMove(t.events()); + assertTrue(pincher.status().clampedScale < 0.9); + assertTrue(pincher.status().clampedScale > 0); + assertTrue(pincher.status().scale > 0); + + pincher.handleTouchCancel(); + } + + return { + run: function(){ + testZoomOut(); + testZoomIn(); + testZoomOutAndPan(); + testReversible(); + testMultitouchZoomOut(); + testZoomOutThenMulti(); + testCancel(); + testSingularity(); + testMinSpan(); + pincher.reset(); + + return {success: true}; + } + }; +}()); |