dist/bundle/navigation.js
require('./directionalnavigation.min.js');
/**
* The Navigation class provides utilities for dealing with user requests
* to nevigate around or away from the interactive controls.
*/
export class Navigation {
constructor(rpc) {
this.rpc = rpc;
this.escapeKeys = {
menu: false,
view: false,
};
this.handlingExit = false;
window.addEventListener('keydown', (ev) => {
this.handleKeydown(ev);
}, true);
window.addEventListener('keyup', (ev) => {
this.handleKeyup(ev);
}, true);
rpc.expose('keyboardShowing', () => {
window.TVJS.DirectionalNavigation.enabled = false;
});
rpc.expose('keyboardHiding', () => {
window.TVJS.DirectionalNavigation.enabled = true;
});
rpc.expose('focusIn', () => {
const firstFocus = document.querySelector('[tabindex="0"]') || document.body;
firstFocus.focus();
});
}
/**
* Should be called when the integration wants to intercept an event which
* would otherwise cause the Interactive integration to close, such as
* the "X" button on the user's controller when watching on their Xbox.
* Calling this will cause the next press of "X" to have no effect.
*/
handleExit() {
this.handlingExit = true;
}
/**
* Handle exiting via escape and Game.
* @private
* @param {KeyboardEvent} ev
*/
handleKeydown(ev) {
if (this.handlingExit && ev.keyCode === 196 /* GamepadB */) {
ev.preventDefault();
ev.stopPropagation();
this.handlingExit = false;
return;
}
if (ev.keyCode === 207 /* Menu */ || ev.keyCode === 208 /* View */) {
ev.keyCode === 207 /* Menu */ ? (this.escapeKeys.menu = true) : (this.escapeKeys.view = true);
}
else {
this.escapeKeys.menu = false;
this.escapeKeys.view = false;
}
if (ev.keyCode === 27 /* Escape */ ||
ev.keyCode === 196 /* GamepadB */ ||
(this.escapeKeys.menu && this.escapeKeys.view)) {
ev.preventDefault();
ev.stopPropagation();
this.escapeKeys.menu = false;
this.escapeKeys.view = false;
this.rpc.call('focusOut', {}, false);
return;
}
if (ev.keyCode === 13 /* Enter */ || ev.keyCode === 195 /* GamepadA */) {
this.handleSubmit();
return;
}
this.rpc.call('navigate', {}, false);
}
/**
* Handle exiting via escape and Game.
* @private
* @param {KeyboardEvent} ev
*/
handleKeyup(ev) {
if (ev.keyCode === 207 /* Menu */) {
this.escapeKeys.menu = false;
}
if (ev.keyCode === 208 /* View */) {
this.escapeKeys.view = false;
}
}
handleSubmit() {
const clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent('mousedown', true, true);
const currentEl = document.activeElement;
if (currentEl) {
currentEl.dispatchEvent(clickEvent);
}
}
}