mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
218 lines
5.9 KiB
JavaScript
218 lines
5.9 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/*
|
|
* Handles nav overlay button positioning.
|
|
*/
|
|
|
|
// minimum amount of movement using the mouse after which we cancel the button click handlers
|
|
const kOnClickMargin = 3;
|
|
|
|
const kNavButtonPref = "browser.display.overlaynavbuttons";
|
|
|
|
var NavButtonSlider = {
|
|
_back: document.getElementById("overlay-back"),
|
|
_plus: document.getElementById("overlay-plus"),
|
|
_mouseMoveStarted: false,
|
|
_mouseDown: false,
|
|
_yPos: -1,
|
|
|
|
get back() {
|
|
return this._back;
|
|
},
|
|
|
|
get plus() {
|
|
return this._plus;
|
|
},
|
|
|
|
/*
|
|
* custom dragger, see input.js
|
|
*/
|
|
|
|
freeDrag: function freeDrag() {
|
|
return true;
|
|
},
|
|
|
|
isDraggable: function isDraggable(aTarget, aContent) {
|
|
return { x: false, y: true };
|
|
},
|
|
|
|
dragStart: function dragStart(aX, aY, aTarget, aScroller) {
|
|
return true;
|
|
},
|
|
|
|
dragStop: function dragStop(aDx, aDy, aScroller) {
|
|
return true;
|
|
},
|
|
|
|
dragMove: function dragMove(aDx, aDy, aScroller, aIsKenetic, aClientX, aClientY) {
|
|
// Note if aIsKenetic is true this is synthetic movement,
|
|
// we don't want that so return false.
|
|
if (aIsKenetic) {
|
|
return false;
|
|
}
|
|
|
|
this._updatePosition(aClientY);
|
|
|
|
// return true if we moved, false otherwise. The result
|
|
// is used in deciding if we should repaint between drags.
|
|
return true;
|
|
},
|
|
|
|
/*
|
|
* logic
|
|
*/
|
|
|
|
init: function init() {
|
|
// Touch drag support provided by input.js
|
|
this._back.customDragger = this;
|
|
this._plus.customDragger = this;
|
|
Elements.browsers.addEventListener("ContentSizeChanged", this, true);
|
|
let events = ["mousedown", "mouseup", "mousemove", "click", "touchstart", "touchmove", "touchend"];
|
|
events.forEach(function (value) {
|
|
this._back.addEventListener(value, this, true);
|
|
this._plus.addEventListener(value, this, true);
|
|
}, this);
|
|
|
|
this._updateStops();
|
|
this._updateVisibility();
|
|
Services.prefs.addObserver(kNavButtonPref, this, false);
|
|
},
|
|
|
|
observe: function (aSubject, aTopic, aData) {
|
|
if (aTopic == "nsPref:changed" && aData == kNavButtonPref) {
|
|
this._updateVisibility();
|
|
}
|
|
},
|
|
|
|
_updateVisibility: function () {
|
|
if (Services.prefs.getBoolPref(kNavButtonPref)) {
|
|
this._back.removeAttribute("hidden");
|
|
this._plus.removeAttribute("hidden");
|
|
} else {
|
|
this._back.setAttribute("hidden", true);
|
|
this._plus.setAttribute("hidden", true);
|
|
}
|
|
},
|
|
|
|
_updateStops: function () {
|
|
this._contentHeight = ContentAreaObserver.contentHeight;
|
|
this._imageHeight = 118;
|
|
this._topStop = this._imageHeight * .7;
|
|
this._bottomStop = this._contentHeight - (this._imageHeight * .7);
|
|
|
|
// Check to see if we need to move the slider into view
|
|
if (this._yPos != -1 &&
|
|
(this._topStop > this._yPos || this._bottomStop < this._yPos)) {
|
|
this._back.style.top = "50%";
|
|
this._plus.style.top = "50%";
|
|
}
|
|
},
|
|
|
|
_getPosition: function _getPosition() {
|
|
this._yPos = parseInt(getComputedStyle(this._back).top);
|
|
},
|
|
|
|
_setPosition: function _setPosition() {
|
|
this._back.style.top = this._yPos + "px";
|
|
this._plus.style.top = this._yPos + "px";
|
|
},
|
|
|
|
_updatePosition: function (aClientY) {
|
|
if (this._topStop > aClientY || this._bottomStop < aClientY)
|
|
return;
|
|
this._yPos = aClientY;
|
|
this._setPosition();
|
|
},
|
|
|
|
_updateOffset: function (aOffset) {
|
|
let newPos = this._yPos + aOffset;
|
|
if (this._topStop > newPos || this._bottomStop < newPos)
|
|
return;
|
|
this._yPos = newPos;
|
|
this._setPosition();
|
|
},
|
|
|
|
/*
|
|
* Events
|
|
*/
|
|
|
|
handleEvent: function handleEvent(aEvent) {
|
|
switch (aEvent.type) {
|
|
case "ContentSizeChanged":
|
|
this._updateStops();
|
|
break;
|
|
|
|
case "touchstart":
|
|
if (aEvent.touches.length != 1)
|
|
break;
|
|
aEvent.preventDefault();
|
|
aEvent = aEvent.touches[0];
|
|
case "mousedown":
|
|
this._getPosition();
|
|
this._mouseDown = true;
|
|
this._mouseMoveStarted = false;
|
|
this._mouseY = aEvent.clientY;
|
|
if (aEvent.originalTarget)
|
|
aEvent.originalTarget.setCapture();
|
|
this._back.setAttribute("mousedrag", true);
|
|
this._plus.setAttribute("mousedrag", true);
|
|
break;
|
|
|
|
case "touchend":
|
|
if (aEvent.touches.length != 0)
|
|
break;
|
|
this._mouseDown = false;
|
|
this._back.removeAttribute("mousedrag");
|
|
this._plus.removeAttribute("mousedrag");
|
|
if (!this._mouseMoveStarted) {
|
|
if (aEvent.originalTarget == this._back) {
|
|
CommandUpdater.doCommand('cmd_back');
|
|
} else {
|
|
CommandUpdater.doCommand('cmd_newTab');
|
|
}
|
|
}
|
|
break;
|
|
case "mouseup":
|
|
this._mouseDown = false;
|
|
this._back.removeAttribute("mousedrag");
|
|
this._plus.removeAttribute("mousedrag");
|
|
break;
|
|
|
|
case "touchmove":
|
|
if (aEvent.touches.length != 1)
|
|
break;
|
|
aEvent = aEvent.touches[0];
|
|
case "mousemove":
|
|
// Check to be sure this is a drag operation
|
|
if (!this._mouseDown) {
|
|
return;
|
|
}
|
|
// Don't start a drag until we've passed a threshold
|
|
let dy = aEvent.clientY - this._mouseY;
|
|
if (!this._mouseMoveStarted && Math.abs(dy) < kOnClickMargin) {
|
|
return;
|
|
}
|
|
// Start dragging via the mouse
|
|
this._mouseMoveStarted = true;
|
|
this._mouseY = aEvent.clientY;
|
|
this._updateOffset(dy);
|
|
break;
|
|
case "click":
|
|
// Don't invoke the click action if we've moved the buttons via the mouse.
|
|
if (this._mouseMoveStarted) {
|
|
return;
|
|
}
|
|
if (aEvent.originalTarget == this._back) {
|
|
CommandUpdater.doCommand('cmd_back');
|
|
} else {
|
|
CommandUpdater.doCommand('cmd_newTab');
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
};
|
|
|
|
|