From ffd864ed39340c081adb9e4a45b3c9cfe4c139e3 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 18 Jun 2018 21:39:47 +1000 Subject: Work on controls --- src/js/utils/elements.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/js/utils') diff --git a/src/js/utils/elements.js b/src/js/utils/elements.js index 69e4d46c..7b58c9ff 100644 --- a/src/js/utils/elements.js +++ b/src/js/utils/elements.js @@ -70,12 +70,19 @@ export function createElement(type, attributes, text) { // Inaert an element after another export function insertAfter(element, target) { + if (!is.element(element) || !is.element(target)) { + return; + } + target.parentNode.insertBefore(element, target.nextSibling); } // Insert a DocumentFragment export function insertElement(type, parent, attributes, text) { - // Inject the new + if (!is.element(parent)) { + return; + } + parent.appendChild(createElement(type, attributes, text)); } @@ -95,6 +102,10 @@ export function removeElement(element) { // Remove all child elements export function emptyElement(element) { + if (!is.element(element)) { + return; + } + let { length } = element.childNodes; while (length > 0) { -- cgit v1.2.3 From 3bf1c59bd6a5beb32ee76ba46e37692c2b1c077f Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Thu, 28 Jun 2018 23:44:07 +1000 Subject: Work on key bindings for menu --- src/js/utils/elements.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/js/utils') diff --git a/src/js/utils/elements.js b/src/js/utils/elements.js index 7b58c9ff..e7e17041 100644 --- a/src/js/utils/elements.js +++ b/src/js/utils/elements.js @@ -294,3 +294,18 @@ export function trapFocus(element = null, toggle = false) { toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false); } + +// Set focus and tab focus class +export function setFocus(element = null, tabFocus = false) { + if (!is.element(element)) { + return; + } + + // Set regular focus + element.focus(); + + // If we want to mimic keyboard focus via tab + if (tabFocus) { + toggleClass(element, this.config.classNames.tabFocus); + } +} -- cgit v1.2.3 From e63ad7c74bd763043344fd2bd568a64e7ea18622 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 15 Jul 2018 19:23:28 +1000 Subject: Keyboard and focus improvements --- src/js/utils/elements.js | 41 +++++++++++++----------- src/js/utils/events.js | 81 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 94 insertions(+), 28 deletions(-) (limited to 'src/js/utils') diff --git a/src/js/utils/elements.js b/src/js/utils/elements.js index e7e17041..3a3dfcfd 100644 --- a/src/js/utils/elements.js +++ b/src/js/utils/elements.js @@ -116,7 +116,11 @@ export function emptyElement(element) { // Replace element export function replaceElement(newChild, oldChild) { - if (!is.element(oldChild) || !is.element(oldChild.parentNode) || !is.element(newChild)) { + if ( + !is.element(oldChild) || + !is.element(oldChild.parentNode) || + !is.element(newChild) + ) { return null; } @@ -203,6 +207,10 @@ export function toggleHidden(element, hidden) { // Mirror Element.classList.toggle, with IE compatibility for "force" argument export function toggleClass(element, className, force) { + if (is.nodeList(element)) { + return Array.from(element).map(e => toggleClass(e, className, force)); + } + if (is.element(element)) { let method = 'toggle'; if (typeof force !== 'undefined') { @@ -213,7 +221,7 @@ export function toggleClass(element, className, force) { return element.classList.contains(className); } - return null; + return false; } // Has class name @@ -249,26 +257,16 @@ export function getElement(selector) { return this.elements.container.querySelector(selector); } -// Get the focused element -export function getFocusElement() { - let focused = document.activeElement; - - if (!focused || focused === document.body) { - focused = null; - } else { - focused = document.querySelector(':focus'); - } - - return focused; -} - // Trap focus inside container export function trapFocus(element = null, toggle = false) { if (!is.element(element)) { return; } - const focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]'); + const focusable = getElements.call( + this, + 'button:not(:disabled), input:not(:disabled), [tabindex]', + ); const first = focusable[0]; const last = focusable[focusable.length - 1]; @@ -279,7 +277,7 @@ export function trapFocus(element = null, toggle = false) { } // Get the current focused element - const focused = getFocusElement(); + const focused = document.activeElement; if (focused === last && !event.shiftKey) { // Move focus to first element that can be tabbed if Shift isn't used @@ -292,7 +290,14 @@ export function trapFocus(element = null, toggle = false) { } }; - toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false); + toggleListener.call( + this, + this.elements.container, + 'keydown', + trap, + toggle, + false, + ); } // Set focus and tab focus class diff --git a/src/js/utils/events.js b/src/js/utils/events.js index 9f734f04..9820fcae 100644 --- a/src/js/utils/events.js +++ b/src/js/utils/events.js @@ -27,9 +27,21 @@ const supportsPassiveListeners = (() => { })(); // Toggle event listener -export function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) { +export function toggleListener( + element, + event, + callback, + toggle = false, + passive = true, + capture = false, +) { // Bail if no element, event, or callback - if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) { + if ( + !element || + !('addEventListener' in element) || + is.empty(event) || + !is.function(callback) + ) { return; } @@ -57,28 +69,74 @@ export function toggleListener(element, event, callback, toggle = false, passive this.eventListeners.push({ element, type, callback, options }); } - element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options); + element[toggle ? 'addEventListener' : 'removeEventListener']( + type, + callback, + options, + ); }); } // Bind event handler -export function on(element, events = '', callback, passive = true, capture = false) { - toggleListener.call(this, element, events, callback, true, passive, capture); +export function on( + element, + events = '', + callback, + passive = true, + capture = false, +) { + toggleListener.call( + this, + element, + events, + callback, + true, + passive, + capture, + ); } // Unbind event handler -export function off(element, events = '', callback, passive = true, capture = false) { - toggleListener.call(this, element, events, callback, false, passive, capture); +export function off( + element, + events = '', + callback, + passive = true, + capture = false, +) { + toggleListener.call( + this, + element, + events, + callback, + false, + passive, + capture, + ); } // Bind once-only event handler -export function once(element, events = '', callback, passive = true, capture = false) { +export function once( + element, + events = '', + callback, + passive = true, + capture = false, +) { function onceCallback(...args) { off(element, events, onceCallback, passive, capture); callback.apply(this, args); } - toggleListener.call(this, element, events, onceCallback, true, passive, capture); + toggleListener.call( + this, + element, + events, + onceCallback, + true, + passive, + capture, + ); } // Trigger event @@ -115,6 +173,9 @@ export function unbindListeners() { // Run method when / if player is ready export function ready() { return new Promise( - resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)), + resolve => + this.ready + ? setTimeout(resolve, 0) + : on.call(this, this.elements.container, 'ready', resolve), ).then(() => {}); } -- cgit v1.2.3 From 599b33e55fb4c0aec78cd0895bcd13f3fed12ad2 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Mon, 30 Jul 2018 01:13:12 +1000 Subject: Click to play fix, poster fix, iOS controls fixes --- src/js/utils/animation.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/js/utils') diff --git a/src/js/utils/animation.js b/src/js/utils/animation.js index 95e39f03..49bc0b8c 100644 --- a/src/js/utils/animation.js +++ b/src/js/utils/animation.js @@ -15,7 +15,9 @@ export const transitionEndEvent = (() => { transition: 'transitionend', }; - const type = Object.keys(events).find(event => element.style[event] !== undefined); + const type = Object.keys(events).find( + event => element.style[event] !== undefined, + ); return is.string(type) ? events[type] : false; })(); @@ -23,8 +25,12 @@ export const transitionEndEvent = (() => { // Force repaint of element export function repaint(element) { setTimeout(() => { - toggleHidden(element, true); - element.offsetHeight; // eslint-disable-line - toggleHidden(element, false); + try { + toggleHidden(element, true); + element.offsetHeight; // eslint-disable-line + toggleHidden(element, false); + } catch (e) { + // Do nothing + } }, 0); } -- cgit v1.2.3 From 2371619486dbbbfdb0350923684e53963141a7af Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 1 Aug 2018 00:56:44 +1000 Subject: Linting --- src/js/utils/events.js | 81 +++++++------------------------------------------- 1 file changed, 10 insertions(+), 71 deletions(-) (limited to 'src/js/utils') diff --git a/src/js/utils/events.js b/src/js/utils/events.js index 9820fcae..9f734f04 100644 --- a/src/js/utils/events.js +++ b/src/js/utils/events.js @@ -27,21 +27,9 @@ const supportsPassiveListeners = (() => { })(); // Toggle event listener -export function toggleListener( - element, - event, - callback, - toggle = false, - passive = true, - capture = false, -) { +export function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) { // Bail if no element, event, or callback - if ( - !element || - !('addEventListener' in element) || - is.empty(event) || - !is.function(callback) - ) { + if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) { return; } @@ -69,74 +57,28 @@ export function toggleListener( this.eventListeners.push({ element, type, callback, options }); } - element[toggle ? 'addEventListener' : 'removeEventListener']( - type, - callback, - options, - ); + element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options); }); } // Bind event handler -export function on( - element, - events = '', - callback, - passive = true, - capture = false, -) { - toggleListener.call( - this, - element, - events, - callback, - true, - passive, - capture, - ); +export function on(element, events = '', callback, passive = true, capture = false) { + toggleListener.call(this, element, events, callback, true, passive, capture); } // Unbind event handler -export function off( - element, - events = '', - callback, - passive = true, - capture = false, -) { - toggleListener.call( - this, - element, - events, - callback, - false, - passive, - capture, - ); +export function off(element, events = '', callback, passive = true, capture = false) { + toggleListener.call(this, element, events, callback, false, passive, capture); } // Bind once-only event handler -export function once( - element, - events = '', - callback, - passive = true, - capture = false, -) { +export function once(element, events = '', callback, passive = true, capture = false) { function onceCallback(...args) { off(element, events, onceCallback, passive, capture); callback.apply(this, args); } - toggleListener.call( - this, - element, - events, - onceCallback, - true, - passive, - capture, - ); + toggleListener.call(this, element, events, onceCallback, true, passive, capture); } // Trigger event @@ -173,9 +115,6 @@ export function unbindListeners() { // Run method when / if player is ready export function ready() { return new Promise( - resolve => - this.ready - ? setTimeout(resolve, 0) - : on.call(this, this.elements.container, 'ready', resolve), + resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)), ).then(() => {}); } -- cgit v1.2.3 From c8db1e55ddff51a1eb4ff08887cbed134116cd88 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 1 Aug 2018 01:26:15 +1000 Subject: Escape closes menu --- src/js/utils/is.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/js/utils') diff --git a/src/js/utils/is.js b/src/js/utils/is.js index b4760da4..2952d486 100644 --- a/src/js/utils/is.js +++ b/src/js/utils/is.js @@ -16,6 +16,7 @@ const isNodeList = input => instanceOf(input, NodeList); const isElement = input => instanceOf(input, Element); const isTextNode = input => getConstructor(input) === Text; const isEvent = input => instanceOf(input, Event); +const isKeyboardEvent = input => instanceOf(input, KeyboardEvent); const isCue = input => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue); const isTrack = input => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind)); @@ -56,6 +57,7 @@ export default { element: isElement, textNode: isTextNode, event: isEvent, + keyboardEvent: isKeyboardEvent, cue: isCue, track: isTrack, url: isUrl, -- cgit v1.2.3