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

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

mercurial