browser/metro/base/content/NavButtonSlider.js

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     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
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * Handles nav overlay button positioning.
     7  */
     9 // minimum amount of movement using the mouse after which we cancel the button click handlers
    10 const kOnClickMargin = 3;
    12 const kNavButtonPref = "browser.display.overlaynavbuttons";
    14 var NavButtonSlider = {
    15   _back: document.getElementById("overlay-back"),
    16   _plus: document.getElementById("overlay-plus"),
    17   _mouseMoveStarted: false,
    18   _mouseDown: false,
    19   _yPos: -1,
    21   get back() {
    22     return this._back;
    23   },
    25   get plus() {
    26     return this._plus;
    27   },
    29   /*
    30    * custom dragger, see input.js
    31    */
    33   freeDrag: function freeDrag() {
    34     return true;
    35   },
    37   isDraggable: function isDraggable(aTarget, aContent) {
    38     return { x: false, y: true };
    39   },
    41   dragStart: function dragStart(aX, aY, aTarget, aScroller) {
    42     return true;
    43   },
    45   dragStop: function dragStop(aDx, aDy, aScroller) {
    46     return true;
    47   },
    49   dragMove: function dragMove(aDx, aDy, aScroller, aIsKenetic, aClientX, aClientY) {
    50     // Note if aIsKenetic is true this is synthetic movement,
    51     // we don't want that so return false.
    52     if (aIsKenetic) {
    53       return false;
    54     }
    56     this._updatePosition(aClientY);
    58     // return true if we moved, false otherwise. The result
    59     // is used in deciding if we should repaint between drags.
    60     return true;
    61   },
    63   /*
    64    * logic
    65    */
    67   init: function init() {
    68     // Touch drag support provided by input.js
    69     this._back.customDragger = this;
    70     this._plus.customDragger = this;
    71     Elements.browsers.addEventListener("ContentSizeChanged", this, true);
    72     let events = ["mousedown", "mouseup", "mousemove", "click", "touchstart", "touchmove", "touchend"];
    73     events.forEach(function (value) {
    74       this._back.addEventListener(value, this, true);
    75       this._plus.addEventListener(value, this, true);
    76     }, this);
    78     this._updateStops();
    79     this._updateVisibility();
    80     Services.prefs.addObserver(kNavButtonPref, this, false);
    81   },
    83   observe: function (aSubject, aTopic, aData) {
    84     if (aTopic == "nsPref:changed" && aData == kNavButtonPref) {
    85       this._updateVisibility();
    86     }
    87   },
    89   _updateVisibility: function () {
    90     if (Services.prefs.getBoolPref(kNavButtonPref)) {
    91       this._back.removeAttribute("hidden");
    92       this._plus.removeAttribute("hidden");
    93     } else {
    94       this._back.setAttribute("hidden", true);
    95       this._plus.setAttribute("hidden", true);
    96     }
    97   },
    99   _updateStops: function () {
   100     this._contentHeight = ContentAreaObserver.contentHeight;
   101     this._imageHeight = 118;
   102     this._topStop = this._imageHeight * .7;
   103     this._bottomStop = this._contentHeight - (this._imageHeight * .7);
   105     // Check to see if we need to move the slider into view
   106     if (this._yPos != -1 &&
   107         (this._topStop > this._yPos || this._bottomStop < this._yPos)) {
   108       this._back.style.top = "50%";
   109       this._plus.style.top = "50%";
   110     }
   111   },
   113   _getPosition: function _getPosition() {
   114     this._yPos = parseInt(getComputedStyle(this._back).top);
   115   },
   117   _setPosition: function _setPosition() {
   118     this._back.style.top = this._yPos + "px";
   119     this._plus.style.top = this._yPos + "px";
   120   },
   122   _updatePosition: function (aClientY) {
   123     if (this._topStop > aClientY || this._bottomStop < aClientY)
   124       return;
   125     this._yPos = aClientY;
   126     this._setPosition();
   127   },
   129   _updateOffset: function (aOffset) {
   130     let newPos = this._yPos + aOffset;
   131     if (this._topStop > newPos || this._bottomStop < newPos)
   132       return;
   133     this._yPos = newPos;
   134     this._setPosition();
   135   },
   137   /*
   138    * Events
   139    */
   141   handleEvent: function handleEvent(aEvent) {
   142     switch (aEvent.type) {
   143       case "ContentSizeChanged":
   144         this._updateStops();
   145         break;
   147       case "touchstart":
   148         if (aEvent.touches.length != 1)
   149           break;
   150         aEvent.preventDefault();
   151         aEvent = aEvent.touches[0];
   152       case "mousedown":
   153         this._getPosition();
   154         this._mouseDown = true;
   155         this._mouseMoveStarted = false;
   156         this._mouseY = aEvent.clientY;
   157         if (aEvent.originalTarget)
   158           aEvent.originalTarget.setCapture();
   159         this._back.setAttribute("mousedrag", true);
   160         this._plus.setAttribute("mousedrag", true);
   161         break;
   163       case "touchend":
   164         if (aEvent.touches.length != 0)
   165           break;
   166         this._mouseDown = false;
   167         this._back.removeAttribute("mousedrag");
   168         this._plus.removeAttribute("mousedrag");
   169         if (!this._mouseMoveStarted) {
   170           if (aEvent.originalTarget == this._back) {
   171             CommandUpdater.doCommand('cmd_back');
   172           } else {
   173             CommandUpdater.doCommand('cmd_newTab');
   174           }
   175         }
   176         break;
   177       case "mouseup":
   178         this._mouseDown = false;
   179         this._back.removeAttribute("mousedrag");
   180         this._plus.removeAttribute("mousedrag");
   181         break;
   183       case "touchmove":
   184         if (aEvent.touches.length != 1)
   185           break;
   186         aEvent = aEvent.touches[0];
   187       case "mousemove":
   188         // Check to be sure this is a drag operation
   189         if (!this._mouseDown) {
   190           return;
   191         }
   192         // Don't start a drag until we've passed a threshold
   193         let dy = aEvent.clientY - this._mouseY;
   194         if (!this._mouseMoveStarted && Math.abs(dy) < kOnClickMargin) {
   195           return;
   196         }
   197         // Start dragging via the mouse
   198         this._mouseMoveStarted = true;
   199         this._mouseY = aEvent.clientY;
   200         this._updateOffset(dy);
   201         break;
   202       case "click":
   203         // Don't invoke the click action if we've moved the buttons via the mouse.
   204         if (this._mouseMoveStarted) {
   205           return;
   206         }
   207         if (aEvent.originalTarget == this._back) {
   208            CommandUpdater.doCommand('cmd_back');
   209         } else {
   210            CommandUpdater.doCommand('cmd_newTab');
   211         }
   212         break;
   213     }
   214   },
   215 };

mercurial