browser/metro/base/content/apzc.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 let Cc = Components.classes;
     7 let Ci = Components.interfaces;
     8 let Cu = Components.utils;
     9 let Cr = Components.results;
    11 /**
    12  * Misc. front end utilities for apzc management.
    13  * the pref: layers.async-pan-zoom.enabled is true.
    14  */
    16 var APZCObserver = {
    17   _debugEvents: false,
    18   _enabled: false,
    20   get enabled() {
    21     return this._enabled;
    22   },
    24   init: function() {
    25     this._enabled = Services.prefs.getBoolPref(kAsyncPanZoomEnabled);
    26     if (!this._enabled) {
    27       return;
    28     }
    30     let os = Services.obs;
    31     os.addObserver(this, "apzc-transform-begin", false);
    33     Elements.tabList.addEventListener("TabSelect", this, true);
    34     Elements.browsers.addEventListener("pageshow", this, true);
    35     messageManager.addMessageListener("Content:ZoomToRect", this);
    36   },
    38   shutdown: function shutdown() {
    39     if (!this._enabled) {
    40       return;
    41     }
    43     let os = Services.obs;
    44     os.removeObserver(this, "apzc-transform-begin");
    46     Elements.tabList.removeEventListener("TabSelect", this, true);
    47     Elements.browsers.removeEventListener("pageshow", this, true);
    48     messageManager.removeMessageListener("Content:ZoomToRect", this);
    49   },
    51   handleEvent: function APZC_handleEvent(aEvent) {
    52     switch (aEvent.type) {
    53       case 'TabSelect':
    54         this._resetDisplayPort();
    55         break;
    57       case 'pageshow':
    58         if (aEvent.target != Browser.selectedBrowser.contentDocument) {
    59           break;
    60         }
    61         this._resetDisplayPort();
    62         break;
    63     }
    64   },
    66   observe: function ao_observe(aSubject, aTopic, aData) {
    67     if (aTopic == "apzc-transform-begin") {
    68       // When we're panning, hide the main scrollbars by setting imprecise
    69       // input (which sets a property on the browser which hides the scrollbar
    70       // via CSS).  This reduces jittering from left to right. We may be able
    71       // to get rid of this once we implement axis locking in /gfx APZC.
    72       if (InputSourceHelper.isPrecise) {
    73         InputSourceHelper._imprecise();
    74       }
    75     }
    76   },
    78   receiveMessage: function(aMessage) {
    79     let json = aMessage.json;
    80     let browser = aMessage.target;
    81     switch (aMessage.name) {
    82       case "Content:ZoomToRect": {
    83         let { presShellId, viewId } = json;
    84         let rect = Rect.fromRect(json.rect);
    85         if (this.isRectZoomedIn(rect, browser.contentViewportBounds)) {
    86           // If we're already zoomed in, zoom out instead.
    87           rect = new Rect(0,0,0,0);
    88         }
    89         let data = [rect.x, rect.y, rect.width, rect.height, presShellId, viewId].join(",");
    90         Services.obs.notifyObservers(null, "apzc-zoom-to-rect", data);
    91       }
    92     }
    93   },
    95   /**
    96    * Check to see if the area of the rect visible in the viewport is
    97    * approximately the max area of the rect we can show.
    98    * Based on code from BrowserElementPanning.js
    99    */
   100   isRectZoomedIn: function (aRect, aViewport) {
   101     let overlap = aViewport.intersect(aRect);
   102     let overlapArea = overlap.width * overlap.height;
   103     let availHeight = Math.min(aRect.width * aViewport.height / aViewport.width, aRect.height);
   104     let showing = overlapArea / (aRect.width * availHeight);
   105     let ratioW = (aRect.width / aViewport.width);
   106     let ratioH = (aRect.height / aViewport.height);
   108     return (showing > 0.9 && (ratioW > 0.9 || ratioH > 0.9));
   109   },
   111   _resetDisplayPort: function () {
   112     // Start off with something reasonable. The apzc will handle these
   113     // calculations once scrolling starts.
   114     let doc = Browser.selectedBrowser.contentDocument.documentElement;
   115     // While running tests, sometimes this can be null. If we don't have a
   116     // root document, there's no point in setting a scrollable display port.
   117     if (!doc) {
   118       return;
   119     }
   120     let win = Browser.selectedBrowser.contentWindow;
   121     let factor = 0.2;
   122     let portX = 0;
   123     let portY = 0;
   124     let portWidth = ContentAreaObserver.width;
   125     let portHeight = ContentAreaObserver.height;
   127     if (portWidth < doc.scrollWidth) {
   128       portWidth += ContentAreaObserver.width * factor;
   129       if (portWidth > doc.scrollWidth) {
   130         portWidth = doc.scrollWidth;
   131       }
   132     }
   133     if (portHeight < doc.scrollHeight) {
   134       portHeight += ContentAreaObserver.height * factor;
   135       if (portHeight > doc.scrollHeight) {
   136         portHeight = doc.scrollHeight;
   137       }
   138     }
   139     if (win.scrollX > 0) {
   140       portX -= ContentAreaObserver.width * factor;
   141     }
   142     if (win.scrollY > 0) {
   143       portY -= ContentAreaObserver.height * factor;
   144     }
   145     let cwu = Browser.selectedBrowser.contentWindow
   146                       .QueryInterface(Ci.nsIInterfaceRequestor)
   147                       .getInterface(Ci.nsIDOMWindowUtils);
   148     cwu.setDisplayPortForElement(portX, portY,
   149                                  portWidth, portHeight,
   150                                  Browser.selectedBrowser.contentDocument.documentElement,
   151                                  0);
   152   }
   153 };

mercurial