mobile/android/chrome/content/ZoomHelper.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 "use strict";
     6 var ZoomHelper = {
     7   zoomInAndSnapToRange: function(aRange) {
     8     // aRange is always non-null here, since a check happened previously.
     9     let viewport = BrowserApp.selectedTab.getViewport();
    10     let fudge = 15; // Add a bit of fudge.
    11     let boundingElement = aRange.offsetNode;
    12     while (!boundingElement.getBoundingClientRect && boundingElement.parentNode) {
    13       boundingElement = boundingElement.parentNode;
    14     }
    16     let rect = ElementTouchHelper.getBoundingContentRect(boundingElement);
    17     let drRect = aRange.getClientRect();
    18     let scrollTop =
    19       BrowserApp.selectedBrowser.contentDocument.documentElement.scrollTop ||
    20       BrowserApp.selectedBrowser.contentDocument.body.scrollTop;
    22     // We subtract half the height of the viewport so that we can (ideally)
    23     // center the area of interest on the screen.
    24     let topPos = scrollTop + drRect.top - (viewport.cssHeight / 2.0);
    26     // Factor in the border and padding
    27     let boundingStyle = window.getComputedStyle(boundingElement);
    28     let leftAdjustment = parseInt(boundingStyle.paddingLeft) +
    29                          parseInt(boundingStyle.borderLeftWidth);
    31     BrowserApp.selectedTab._mReflozPositioned = true;
    33     rect.type = "Browser:ZoomToRect";
    34     rect.x = Math.max(viewport.cssPageLeft, rect.x  - fudge + leftAdjustment);
    35     rect.y = Math.max(topPos, viewport.cssPageTop);
    36     rect.w = viewport.cssWidth;
    37     rect.h = viewport.cssHeight;
    38     rect.animate = false;
    40     sendMessageToJava(rect);
    41     BrowserApp.selectedTab._mReflozPoint = null;
    42   },
    44   zoomOut: function() {
    45     BrowserEventHandler.resetMaxLineBoxWidth();
    46     sendMessageToJava({ type: "Browser:ZoomToPageWidth" });
    47   },
    49   isRectZoomedIn: function(aRect, aViewport) {
    50     // This function checks to see if the area of the rect visible in the
    51     // viewport (i.e. the "overlapArea" variable below) is approximately
    52     // the max area of the rect we can show. It also checks that the rect
    53     // is actually on-screen by testing the left and right edges of the rect.
    54     // In effect, this tells us whether or not zooming in to this rect
    55     // will significantly change what the user is seeing.
    56     const minDifference = -20;
    57     const maxDifference = 20;
    58     const maxZoomAllowed = 4; // keep this in sync with mobile/android/base/ui/PanZoomController.MAX_ZOOM
    60     let vRect = new Rect(aViewport.cssX, aViewport.cssY, aViewport.cssWidth, aViewport.cssHeight);
    61     let overlap = vRect.intersect(aRect);
    62     let overlapArea = overlap.width * overlap.height;
    63     let availHeight = Math.min(aRect.width * vRect.height / vRect.width, aRect.height);
    64     let showing = overlapArea / (aRect.width * availHeight);
    65     let dw = (aRect.width - vRect.width);
    66     let dx = (aRect.x - vRect.x);
    68     if (fuzzyEquals(aViewport.zoom, maxZoomAllowed) && overlap.width / aRect.width > 0.9) {
    69       // we're already at the max zoom and the block is not spilling off the side of the screen so that even
    70       // if the block isn't taking up most of the viewport we can't pan/zoom in any more. return true so that we zoom out
    71       return true;
    72     }
    74     return (showing > 0.9 &&
    75             dx > minDifference && dx < maxDifference &&
    76             dw > minDifference && dw < maxDifference);
    77   },
    79   /* Zoom to an element, optionally keeping a particular part of it
    80    * in view if it is really tall.
    81    */
    82   zoomToElement: function(aElement, aClickY = -1, aCanZoomOut = true, aCanScrollHorizontally = true) {
    83     let rect = ElementTouchHelper.getBoundingContentRect(aElement);
    84     ZoomHelper.zoomToRect(rect, aClickY, aCanZoomOut, aCanScrollHorizontally, aElement);
    85   },
    87   zoomToRect: function(aRect, aClickY = -1, aCanZoomOut = true, aCanScrollHorizontally = true, aElement) {
    88     const margin = 15;
    90     if(!aRect.h || !aRect.w) {
    91       aRect.h = aRect.height;
    92       aRect.w = aRect.width;
    93     }
    95     let viewport = BrowserApp.selectedTab.getViewport();
    96     let bRect = new Rect(aCanScrollHorizontally ? Math.max(viewport.cssPageLeft, aRect.x - margin) : viewport.cssX,
    97                          aRect.y,
    98                          aCanScrollHorizontally ? aRect.w + 2 * margin : viewport.cssWidth,
    99                          aRect.h);
   100     // constrict the rect to the screen's right edge
   101     bRect.width = Math.min(bRect.width, viewport.cssPageRight - bRect.x);
   103     // if the rect is already taking up most of the visible area and is stretching the
   104     // width of the page, then we want to zoom out instead.
   105     if (aElement) {
   106       if (BrowserEventHandler.mReflozPref) {
   107         let zoomFactor = BrowserApp.selectedTab.getZoomToMinFontSize(aElement);
   109         bRect.width = zoomFactor <= 1.0 ? bRect.width : gScreenWidth / zoomFactor;
   110         bRect.height = zoomFactor <= 1.0 ? bRect.height : bRect.height / zoomFactor;
   111         if (zoomFactor == 1.0 || ZoomHelper.isRectZoomedIn(bRect, viewport)) {
   112           if (aCanZoomOut) {
   113             ZoomHelper.zoomOut();
   114           }
   115           return;
   116         }
   117       } else if (ZoomHelper.isRectZoomedIn(bRect, viewport)) {
   118         if (aCanZoomOut) {
   119           ZoomHelper.zoomOut();
   120         }
   121         return;
   122       }
   123     }
   125     let rect = {};
   127     rect.type = "Browser:ZoomToRect";
   128     rect.x = bRect.x;
   129     rect.y = bRect.y;
   130     rect.w = bRect.width;
   131     rect.h = Math.min(bRect.width * viewport.cssHeight / viewport.cssWidth, bRect.height);
   133     if (aClickY >= 0) {
   134       // if the block we're zooming to is really tall, and we want to keep a particular
   135       // part of it in view, then adjust the y-coordinate of the target rect accordingly.
   136       // the 1.2 multiplier is just a little fuzz to compensate for bRect including horizontal
   137       // margins but not vertical ones.
   138       let cssTapY = viewport.cssY + aClickY;
   139       if ((bRect.height > rect.h) && (cssTapY > rect.y + (rect.h * 1.2))) {
   140         rect.y = cssTapY - (rect.h / 2);
   141       }
   142     }
   144     if (rect.w > viewport.cssWidth || rect.h > viewport.cssHeight) {
   145       BrowserEventHandler.resetMaxLineBoxWidth();
   146     }
   148     sendMessageToJava(rect);
   149   },
   150 };

mercurial