aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/utils')
-rw-r--r--src/js/utils/animation.js14
-rw-r--r--src/js/utils/elements.js69
-rw-r--r--src/js/utils/events.js81
3 files changed, 131 insertions, 33 deletions
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);
}
diff --git a/src/js/utils/elements.js b/src/js/utils/elements.js
index 69e4d46c..3a3dfcfd 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 <element>
+ 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) {
@@ -105,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;
}
@@ -192,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') {
@@ -202,7 +221,7 @@ export function toggleClass(element, className, force) {
return element.classList.contains(className);
}
- return null;
+ return false;
}
// Has class name
@@ -238,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];
@@ -268,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
@@ -281,5 +290,27 @@ 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
+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);
+ }
}
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(() => {});
}