Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
183
gaia/tv_apps/remote-control/js/section.js
Executable file
183
gaia/tv_apps/remote-control/js/section.js
Executable file
|
|
@ -0,0 +1,183 @@
|
|||
/* global SpatialNavigator */
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
function Section(id) {
|
||||
this.id = id;
|
||||
this._dom = document.getElementById(this.id);
|
||||
|
||||
var focusables = this._dom.querySelectorAll('.focusable');
|
||||
Array.from(focusables).forEach(function(elem) {
|
||||
elem.setAttribute('tabindex', -1);
|
||||
});
|
||||
|
||||
this._spatialNav = new SpatialNavigator(
|
||||
focusables,
|
||||
{
|
||||
ignoreHiddenElement: true,
|
||||
rememberSource: true
|
||||
}
|
||||
);
|
||||
this._spatialNav.on('focus', (elem) => {
|
||||
elem.focus();
|
||||
});
|
||||
|
||||
this._childSections = {};
|
||||
this._activeChildSectionId = '';
|
||||
this._defaultFocusElement = undefined;
|
||||
this._focusableElementCount = focusables.length;
|
||||
}
|
||||
|
||||
Section.prototype = {
|
||||
uninit: function() {
|
||||
if (this._uninit) {
|
||||
this._uninit();
|
||||
}
|
||||
|
||||
this._defaultFocusElement = undefined;
|
||||
this._activeChildSectionId = '';
|
||||
this._childSections = {};
|
||||
this._parentSection = undefined;
|
||||
this._spatialNav = undefined;
|
||||
this._dom = undefined;
|
||||
},
|
||||
|
||||
addChild: function(id, section) {
|
||||
this._childSections[id] = section;
|
||||
section._parentSection = this;
|
||||
},
|
||||
|
||||
removeChild: function(id) {
|
||||
this._childSections[id]._parentSection = undefined;
|
||||
delete this._childSections[id];
|
||||
},
|
||||
|
||||
focus: function(elem) {
|
||||
if (typeof elem === 'string') {
|
||||
elem = document.getElementById(elem);
|
||||
}
|
||||
return this._spatialNav.focus(elem);
|
||||
},
|
||||
|
||||
unfocus: function() {
|
||||
return this._spatialNav.unfocus();
|
||||
},
|
||||
|
||||
handleMove: function(direction) {
|
||||
var activeChildSection = this.getActiveChildSection();
|
||||
if (activeChildSection) {
|
||||
activeChildSection.handleMove(direction);
|
||||
} else {
|
||||
if (this._handleMove) {
|
||||
var nextElement = this._handleMove(direction);
|
||||
if (nextElement) {
|
||||
if (this._spatialNav.focus(nextElement)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this._spatialNav.move(direction)) {
|
||||
// If failed to move, re-focus the current one.
|
||||
this._spatialNav.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleClick: function() {
|
||||
var activeChildSection = this.getActiveChildSection();
|
||||
if (activeChildSection) {
|
||||
activeChildSection.handleClick();
|
||||
} else if (this._handleClick) {
|
||||
this._handleClick();
|
||||
} else if (!this._focusableElementCount) {
|
||||
// If there is no focusable element in this section, just close it.
|
||||
this.backToParent();
|
||||
}
|
||||
},
|
||||
|
||||
handleBack: function() {
|
||||
var activeChildSection = this.getActiveChildSection();
|
||||
if (activeChildSection) {
|
||||
if (!activeChildSection.handleBack()) {
|
||||
// Hide the child section if it doesn't handle BACK key.
|
||||
this.hideChildSection();
|
||||
return true;
|
||||
}
|
||||
} else if (this._handleBack) {
|
||||
return this._handleBack();
|
||||
}
|
||||
// Returning false can let BACK key to be bubbled to its parent.
|
||||
return false;
|
||||
},
|
||||
|
||||
getFocusedElement: function() {
|
||||
return this._spatialNav.getFocusedElement();
|
||||
},
|
||||
|
||||
getActiveChildSection: function() {
|
||||
if (!this._activeChildSectionId) {
|
||||
return undefined;
|
||||
}
|
||||
return this._childSections[this._activeChildSectionId];
|
||||
},
|
||||
|
||||
backToParent: function() {
|
||||
if (this._parentSection) {
|
||||
this._parentSection.hideChildSection();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
show: function(previousId) {
|
||||
document.activeElement.blur();
|
||||
|
||||
if (this._readyToShow) {
|
||||
this._readyToShow(previousId);
|
||||
}
|
||||
|
||||
this._dom.classList.add('visible');
|
||||
this._dom.removeAttribute('aria-hidden');
|
||||
|
||||
this._spatialNav.focus(this._defaultFocusElement);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this._dom.classList.remove('visible');
|
||||
this._dom.setAttribute('aria-hidden', true);
|
||||
return this;
|
||||
},
|
||||
|
||||
showChildSection: function(id) {
|
||||
var child = this._childSections[id];
|
||||
if (child) {
|
||||
this.hide();
|
||||
this._childSections[id].show();
|
||||
this._activeChildSectionId = id;
|
||||
}
|
||||
},
|
||||
|
||||
hideChildSection: function() {
|
||||
var activeChildSection = this.getActiveChildSection();
|
||||
if (activeChildSection) {
|
||||
var previousId = this._activeChildSectionId;
|
||||
this._activeChildSectionId = '';
|
||||
activeChildSection.hide();
|
||||
this.show(previousId);
|
||||
}
|
||||
},
|
||||
|
||||
setDefaultFocusElement: function(elem) {
|
||||
if (typeof elem === 'string') {
|
||||
elem = document.getElementById(elem);
|
||||
}
|
||||
if (elem) {
|
||||
this._defaultFocusElement = elem;
|
||||
} else {
|
||||
this._defaultFocusElement = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.Section = Section;
|
||||
}(window));
|
||||
Loading…
Reference in a new issue