'use strict';
/* global ScreenLayout */
/* global SettingsListener */
(function(exports) {
/**
* HomeGesture is used as an alternative to the software home button for
* devices without physical home buttons.
* HomeGesture will trigger a 'home' event for a single swipe from the bottom
* and a 'holdhome' event with a two-finger swipe from the bottom.
* @class HomeGesture
* @requires ScreenLayout
* @requires SettingsListener
*/
function HomeGesture() {
this.isTablet = !ScreenLayout.getCurrentLayout('tiny');
this.hasHardwareHomeButton =
ScreenLayout.getCurrentLayout('hardwareHomeButton');
this.homeBar = document.getElementById('bottom-panel');
}
HomeGesture.prototype = {
/**
* Whether or not the HomeGesture is enabled.
* @memberof HomeGesture.prototype
* @type {Boolean}
*/
enabled: false,
/**
* True when the user starts the home gesture.
* @memberof HomeGesture.prototype
* @type {Boolean}
*/
_moving: false,
/**
* True when the user is swiping with two or more fingers.
* @memberof HomeGesture.prototype
* @type {Boolean}
*/
_multiTouch: false,
/**
* The position of the touchstart event.
* @memberof HomeGesture.prototype
* @type {Integer}
*/
_startY1: 0,
/**
* Minimum moving distance to home in pixel of screen height
* @memberof HomeGesture.prototype
* @type {Integer}
*/
MINUMUM_DISTANCE: 50,
/**
* Starts the HomeGesture instance.
* @memberof HomeGesture.prototype
* @param {Boolean} enable Whether or not the HomeGesture is enabled.
*/
start: function() {
window.addEventListener('software-button-enabled', this);
window.addEventListener('software-button-disabled', this);
this.homeBar.addEventListener('touchstart', this, true);
this.homeBar.addEventListener('touchend', this, true);
// This 'click' listener can prevent other element which
// have click listener steal 'touchstart'.
this.homeBar.addEventListener('click', this, true);
if (!this.hasHardwareHomeButton && this.isTablet) {
// enable gesture for tablet without hardware home button
// as default
this.toggle(true);
} else {
SettingsListener.observe('homegesture.enabled', false,
function onObserve(value) {
this.toggle(value);
}.bind(this));
}
},
/**
* Toggles the state of the HomeGesture.
* @memberof HomeGesture.prototype
* @param {Boolean} enable Whether or not the HomeGesture is enabled.
*/
toggle: function(enable) {
if (enable === this.enabled) {
return;
}
if (enable) {
this.publish('homegesture-enabled');
window.addEventListener('lockscreen-appclose', this);
window.addEventListener('lockscreen-appopened', this);
window.addEventListener('utilitytrayshow', this);
window.addEventListener('utilitytrayhide', this);
this.homeBar.classList.add('visible');
} else {
this.publish('homegesture-disabled');
window.removeEventListener('lockscreen-appclose', this);
window.removeEventListener('lockscreen-appopened', this);
window.removeEventListener('utilitytrayshow', this);
window.removeEventListener('utilitytrayhide', this);
this.homeBar.classList.remove('visible');
}
this.enabled = enable;
},
/**
* General event handler interface.
* @memberof HomeGesture.prototype
* @param {DOMEvent} evt The event.
*/
handleEvent: function(evt) {
switch (evt.type) {
case 'touchstart':
evt.preventDefault();
this._moving = true;
this._startY1 = evt.changedTouches[0].pageY;
if (evt.touches.length > 1) {
this._multiTouch = true;
}
break;
case 'touchend':
var progress = Math.abs(this._startY1 - evt.changedTouches[0].pageY);
if (this._moving &&
(progress >= this.MINUMUM_DISTANCE)) {
if (this._multiTouch) {
window.dispatchEvent(new CustomEvent('holdhome'));
} else {
window.dispatchEvent(new CustomEvent('home'));
}
}
this._multiTouch = false;
this._moving = false;
break;
// hide gesture function when utilitytray/lockscreen display
case 'lockscreen-appopened':
case 'utilitytrayshow':
this.homeBar.classList.remove('visible');
break;
case 'lockscreen-appclose':
case 'utilitytrayhide':
this.homeBar.classList.add('visible');
break;
case 'software-button-disabled':
// at least one of software home button or gesture is enabled
// when no hardware home button
if (!this.hasHardwareHomeButton && !this.enabled) {
SettingsListener.getSettingsLock().set({
'homegesture.enabled': true});
}
break;
case 'software-button-enabled':
if (this.enabled) {
SettingsListener.getSettingsLock().set({
'homegesture.enabled': false});
}
break;
}
},
/**
* Shortcut to publish a custom event.
* @memberof HomeGesture.prototype
* @param {String} type The event type.
*/
publish: function(type) {
window.dispatchEvent(new CustomEvent(type));
}
};
exports.HomeGesture = HomeGesture;
}(window));