OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This variable will be changed by iOS scripts. | 5 // This variable will be changed by iOS scripts. |
6 var distiller_on_ios = false; | 6 var distiller_on_ios = false; |
7 | 7 |
8 function addToPage(html) { | 8 function addToPage(html) { |
9 var div = document.createElement('div'); | 9 var div = document.createElement('div'); |
10 div.innerHTML = html; | 10 div.innerHTML = html; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 cssClass = "dark"; | 83 cssClass = "dark"; |
84 } else { | 84 } else { |
85 cssClass = "light"; | 85 cssClass = "light"; |
86 } | 86 } |
87 // Relies on the classname order of the body being Theme class, then Font | 87 // Relies on the classname order of the body being Theme class, then Font |
88 // Family class. | 88 // Family class. |
89 var fontFamilyClass = document.body.className.split(" ")[1]; | 89 var fontFamilyClass = document.body.className.split(" ")[1]; |
90 document.body.className = cssClass + " " + fontFamilyClass; | 90 document.body.className = cssClass + " " + fontFamilyClass; |
91 } | 91 } |
92 | 92 |
| 93 function useFontScaling(scaling) { |
| 94 pincher.useFontScaling(scaling); |
| 95 } |
| 96 |
93 var updateLoadingIndicator = function() { | 97 var updateLoadingIndicator = function() { |
94 var colors = ["red", "yellow", "green", "blue"]; | 98 var colors = ["red", "yellow", "green", "blue"]; |
95 return function(isLastPage) { | 99 return function(isLastPage) { |
96 if (!isLastPage && typeof this.colorShuffle == "undefined") { | 100 if (!isLastPage && typeof this.colorShuffle == "undefined") { |
97 var loader = document.getElementById("loader"); | 101 var loader = document.getElementById("loader"); |
98 if (loader) { | 102 if (loader) { |
99 var colorIndex = -1; | 103 var colorIndex = -1; |
100 this.colorShuffle = setInterval(function() { | 104 this.colorShuffle = setInterval(function() { |
101 colorIndex = (colorIndex + 1) % colors.length; | 105 colorIndex = (colorIndex + 1) % colors.length; |
102 loader.className = colors[colorIndex]; | 106 loader.className = colors[colorIndex]; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 209 |
206 var lastSpan; | 210 var lastSpan; |
207 var lastClientMid; | 211 var lastClientMid; |
208 | 212 |
209 var scale = 1; | 213 var scale = 1; |
210 var shiftX; | 214 var shiftX; |
211 var shiftY; | 215 var shiftY; |
212 | 216 |
213 // The zooming speed relative to pinching speed. | 217 // The zooming speed relative to pinching speed. |
214 var FONT_SCALE_MULTIPLIER = 0.5; | 218 var FONT_SCALE_MULTIPLIER = 0.5; |
| 219 |
215 var MIN_SPAN_LENGTH = 20; | 220 var MIN_SPAN_LENGTH = 20; |
216 | 221 |
217 // The font size is guaranteed to be in px. | 222 // The font size is guaranteed to be in px. |
218 var baseSize = | 223 var baseSize = |
219 parseFloat(getComputedStyle(document.documentElement).fontSize); | 224 parseFloat(getComputedStyle(document.documentElement).fontSize); |
220 | 225 |
221 var refreshTransform = function() { | 226 var refreshTransform = function() { |
222 var slowedScale = Math.exp(Math.log(scale) * FONT_SCALE_MULTIPLIER); | 227 var slowedScale = Math.exp(Math.log(scale) * FONT_SCALE_MULTIPLIER); |
223 clampedScale = Math.max(0.4, Math.min(2.5, fontSizeAnchor * slowedScale)); | 228 clampedScale = Math.max(0.4, Math.min(2.5, fontSizeAnchor * slowedScale)); |
224 | 229 |
225 // Use "fake" 3D transform so that the layer is not repainted. | 230 // Use "fake" 3D transform so that the layer is not repainted. |
226 // With 2D transform, the frame rate would be much lower. | 231 // With 2D transform, the frame rate would be much lower. |
227 document.body.style.transform = | 232 document.body.style.transform = |
228 'translate3d(' + shiftX + 'px,' + | 233 'translate3d(' + shiftX + 'px,' + |
229 shiftY + 'px, 0px)' + | 234 shiftY + 'px, 0px)' + |
230 'scale(' + clampedScale/fontSizeAnchor + ')'; | 235 'scale(' + clampedScale/fontSizeAnchor + ')'; |
231 }; | 236 }; |
232 | 237 |
| 238 function saveCenter(clientMid) { |
| 239 // Try to preserve the pinching center after text reflow. |
| 240 // This is accurate to the HTML element level. |
| 241 focusElement = document.elementFromPoint(clientMid.x, clientMid.y); |
| 242 var rect = focusElement.getBoundingClientRect(); |
| 243 initClientMid = clientMid; |
| 244 focusPos = (initClientMid.y - rect.top) / (rect.bottom - rect.top); |
| 245 } |
| 246 |
| 247 function restoreCenter() { |
| 248 var rect = focusElement.getBoundingClientRect(); |
| 249 var targetTop = focusPos * (rect.bottom - rect.top) + rect.top + |
| 250 document.body.scrollTop - (initClientMid.y + shiftY); |
| 251 document.body.scrollTop = targetTop; |
| 252 } |
| 253 |
233 function endPinch() { | 254 function endPinch() { |
234 pinching = false; | 255 pinching = false; |
235 | 256 |
236 document.body.style.transformOrigin = ''; | 257 document.body.style.transformOrigin = ''; |
237 document.body.style.transform = ''; | 258 document.body.style.transform = ''; |
238 document.documentElement.style.fontSize = clampedScale * baseSize + "px"; | 259 document.documentElement.style.fontSize = clampedScale * baseSize + "px"; |
239 | 260 |
240 var rect = focusElement.getBoundingClientRect(); | 261 restoreCenter(); |
241 var targetTop = focusPos * (rect.bottom - rect.top) + rect.top + | 262 |
242 document.body.scrollTop - (initClientMid.y + shiftY); | 263 var img = document.getElementById('fontscaling-img'); |
243 document.body.scrollTop = targetTop; | 264 if (!img) { |
| 265 img = document.createElement('img'); |
| 266 img.id = 'fontscaling-img'; |
| 267 img.style.display = 'none'; |
| 268 document.body.appendChild(img); |
| 269 } |
| 270 img.src = "/savefontscaling/" + clampedScale; |
244 } | 271 } |
245 | 272 |
246 function touchSpan(e) { | 273 function touchSpan(e) { |
247 var count = e.touches.length; | 274 var count = e.touches.length; |
248 var mid = touchClientMid(e); | 275 var mid = touchClientMid(e); |
249 var sum = 0; | 276 var sum = 0; |
250 for (var i = 0; i < count; i++) { | 277 for (var i = 0; i < count; i++) { |
251 var dx = (e.touches[i].clientX - mid.x); | 278 var dx = (e.touches[i].clientX - mid.x); |
252 var dy = (e.touches[i].clientY - mid.y); | 279 var dy = (e.touches[i].clientY - mid.y); |
253 sum += Math.hypot(dx, dy); | 280 sum += Math.hypot(dx, dy); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 | 321 |
295 pinching = true; | 322 pinching = true; |
296 fontSizeAnchor = | 323 fontSizeAnchor = |
297 parseFloat(getComputedStyle(document.documentElement).fontSize) / | 324 parseFloat(getComputedStyle(document.documentElement).fontSize) / |
298 baseSize; | 325 baseSize; |
299 | 326 |
300 var pinchOrigin = touchPageMid(e); | 327 var pinchOrigin = touchPageMid(e); |
301 document.body.style.transformOrigin = | 328 document.body.style.transformOrigin = |
302 pinchOrigin.x + 'px ' + pinchOrigin.y + 'px'; | 329 pinchOrigin.x + 'px ' + pinchOrigin.y + 'px'; |
303 | 330 |
304 // Try to preserve the pinching center after text reflow. | 331 saveCenter(clientMid); |
305 // This is accurate to the HTML element level. | |
306 focusElement = document.elementFromPoint(clientMid.x, clientMid.y); | |
307 var rect = focusElement.getBoundingClientRect(); | |
308 initClientMid = clientMid; | |
309 focusPos = (initClientMid.y - rect.top) / (rect.bottom - rect.top); | |
310 | 332 |
311 lastSpan = span; | 333 lastSpan = span; |
312 lastClientMid = clientMid; | 334 lastClientMid = clientMid; |
313 | 335 |
314 refreshTransform(); | 336 refreshTransform(); |
315 }, | 337 }, |
316 | 338 |
317 handleTouchMove: function(e) { | 339 handleTouchMove: function(e) { |
318 if (!pinching) return; | 340 if (!pinching) return; |
319 if (e.touches.length < 2) return; | 341 if (e.touches.length < 2) return; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 document.documentElement.style.fontSize = clampedScale * baseSize + "px"; | 383 document.documentElement.style.fontSize = clampedScale * baseSize + "px"; |
362 }, | 384 }, |
363 | 385 |
364 status: function() { | 386 status: function() { |
365 return { | 387 return { |
366 scale: scale, | 388 scale: scale, |
367 clampedScale: clampedScale, | 389 clampedScale: clampedScale, |
368 shiftX: shiftX, | 390 shiftX: shiftX, |
369 shiftY: shiftY | 391 shiftY: shiftY |
370 }; | 392 }; |
| 393 }, |
| 394 |
| 395 useFontScaling: function(scaling) { |
| 396 saveCenter({x: window.innerWidth/2, y: window.innerHeight/2}); |
| 397 shiftX = 0; |
| 398 shiftY = 0; |
| 399 document.documentElement.style.fontSize = scaling * baseSize + "px"; |
| 400 clampedScale = scaling; |
| 401 restoreCenter(); |
371 } | 402 } |
372 }; | 403 }; |
373 }()); | 404 }()); |
374 | 405 |
375 window.addEventListener('touchstart', pincher.handleTouchStart, false); | 406 window.addEventListener('touchstart', pincher.handleTouchStart, false); |
376 window.addEventListener('touchmove', pincher.handleTouchMove, false); | 407 window.addEventListener('touchmove', pincher.handleTouchMove, false); |
377 window.addEventListener('touchend', pincher.handleTouchEnd, false); | 408 window.addEventListener('touchend', pincher.handleTouchEnd, false); |
378 window.addEventListener('touchcancel', pincher.handleTouchCancel, false); | 409 window.addEventListener('touchcancel', pincher.handleTouchCancel, false); |
OLD | NEW |