diff options
Diffstat (limited to 'src/js/utils')
-rw-r--r-- | src/js/utils/animation.js | 16 | ||||
-rw-r--r-- | src/js/utils/elements.js | 29 | ||||
-rw-r--r-- | src/js/utils/events.js | 1 | ||||
-rw-r--r-- | src/js/utils/i18n.js | 4 | ||||
-rw-r--r-- | src/js/utils/load-image.js (renamed from src/js/utils/loadImage.js) | 0 | ||||
-rw-r--r-- | src/js/utils/load-script.js (renamed from src/js/utils/loadScript.js) | 0 | ||||
-rw-r--r-- | src/js/utils/load-sprite.js (renamed from src/js/utils/loadSprite.js) | 3 | ||||
-rw-r--r-- | src/js/utils/numbers.js | 17 | ||||
-rw-r--r-- | src/js/utils/style.js | 63 | ||||
-rw-r--r-- | src/js/utils/time.js | 1 | ||||
-rw-r--r-- | src/js/utils/urls.js | 4 |
11 files changed, 94 insertions, 44 deletions
diff --git a/src/js/utils/animation.js b/src/js/utils/animation.js index 6b950b61..3f721b5a 100644 --- a/src/js/utils/animation.js +++ b/src/js/utils/animation.js @@ -2,7 +2,6 @@ // Animation utils // ========================================================================== -import { toggleHidden } from './elements'; import is from './is'; export const transitionEndEvent = (() => { @@ -21,14 +20,19 @@ export const transitionEndEvent = (() => { })(); // Force repaint of element -export function repaint(element) { +export function repaint(element, delay) { setTimeout(() => { try { - toggleHidden(element, true); - element.offsetHeight; // eslint-disable-line - toggleHidden(element, false); + // eslint-disable-next-line no-param-reassign + element.hidden = true; + + // eslint-disable-next-line no-unused-expressions + element.offsetHeight; + + // eslint-disable-next-line no-param-reassign + element.hidden = false; } catch (e) { // Do nothing } - }, 0); + }, delay); } diff --git a/src/js/utils/elements.js b/src/js/utils/elements.js index 6be634e5..4f10938e 100644 --- a/src/js/utils/elements.js +++ b/src/js/utils/elements.js @@ -4,6 +4,7 @@ import { toggleListener } from './events'; import is from './is'; +import { extend } from './objects'; // Wrap an element export function wrap(elements, wrapper) { @@ -16,7 +17,6 @@ export function wrap(elements, wrapper) { .reverse() .forEach((element, index) => { const child = index > 0 ? wrapper.cloneNode(true) : wrapper; - // Cache the current parent and sibling. const parent = element.parentNode; const sibling = element.nextSibling; @@ -137,30 +137,28 @@ export function getAttributesFromSelector(sel, existingAttributes) { } const attributes = {}; - const existing = existingAttributes; + const existing = extend({}, existingAttributes); sel.split(',').forEach(s => { // Remove whitespace const selector = s.trim(); const className = selector.replace('.', ''); const stripped = selector.replace(/[[\]]/g, ''); - // Get the parts and value const parts = stripped.split('='); - const key = parts[0]; + const [key] = parts; const value = parts.length > 1 ? parts[1].replace(/["']/g, '') : ''; - // Get the first character const start = selector.charAt(0); switch (start) { case '.': // Add to existing classname - if (is.object(existing) && is.string(existing.class)) { - existing.class += ` ${className}`; + if (is.string(existing.class)) { + attributes.class = `${existing.class} ${className}`; + } else { + attributes.class = className; } - - attributes.class = className; break; case '#': @@ -179,7 +177,7 @@ export function getAttributesFromSelector(sel, existingAttributes) { } }); - return attributes; + return extend(existing, attributes); } // Toggle hidden @@ -194,11 +192,8 @@ export function toggleHidden(element, hidden) { hide = !element.hidden; } - if (hide) { - element.setAttribute('hidden', ''); - } else { - element.removeAttribute('hidden'); - } + // eslint-disable-next-line no-param-reassign + element.hidden = hide; } // Mirror Element.classList.toggle, with IE compatibility for "force" argument @@ -233,14 +228,14 @@ export function matches(element, selector) { return Array.from(document.querySelectorAll(selector)).includes(this); } - const matches = + const method = prototype.matches || prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || match; - return matches.call(element, selector); + return method.call(element, selector); } // Find all elements diff --git a/src/js/utils/events.js b/src/js/utils/events.js index d304c312..87c35d26 100644 --- a/src/js/utils/events.js +++ b/src/js/utils/events.js @@ -35,7 +35,6 @@ export function toggleListener(element, event, callback, toggle = false, passive // Allow multiple events const events = event.split(' '); - // Build options // Default to just the capture boolean for browsers with no passive listener support let options = capture; diff --git a/src/js/utils/i18n.js b/src/js/utils/i18n.js index 758ed695..5eee5829 100644 --- a/src/js/utils/i18n.js +++ b/src/js/utils/i18n.js @@ -36,8 +36,8 @@ const i18n = { '{title}': config.title, }; - Object.entries(replace).forEach(([key, value]) => { - string = replaceAll(string, key, value); + Object.entries(replace).forEach(([k, v]) => { + string = replaceAll(string, k, v); }); return string; diff --git a/src/js/utils/loadImage.js b/src/js/utils/load-image.js index 8acd2496..8acd2496 100644 --- a/src/js/utils/loadImage.js +++ b/src/js/utils/load-image.js diff --git a/src/js/utils/loadScript.js b/src/js/utils/load-script.js index 81ae36f4..81ae36f4 100644 --- a/src/js/utils/loadScript.js +++ b/src/js/utils/load-script.js diff --git a/src/js/utils/loadSprite.js b/src/js/utils/load-sprite.js index 917bd6ac..fe4add00 100644 --- a/src/js/utils/loadSprite.js +++ b/src/js/utils/load-sprite.js @@ -15,10 +15,10 @@ export default function loadSprite(url, id) { const prefix = 'cache'; const hasId = is.string(id); let isCached = false; - const exists = () => document.getElementById(id) !== null; const update = (container, data) => { + // eslint-disable-next-line no-param-reassign container.innerHTML = data; // Check again incase of race condition @@ -33,7 +33,6 @@ export default function loadSprite(url, id) { // Only load once if ID set if (!hasId || !exists()) { const useStorage = Storage.supported; - // Create container const container = document.createElement('div'); container.setAttribute('hidden', ''); diff --git a/src/js/utils/numbers.js b/src/js/utils/numbers.js new file mode 100644 index 00000000..f6eb65c8 --- /dev/null +++ b/src/js/utils/numbers.js @@ -0,0 +1,17 @@ +/** + * Returns a number whose value is limited to the given range. + * + * Example: limit the output of this computation to between 0 and 255 + * (x * 255).clamp(0, 255) + * + * @param {Number} input + * @param {Number} min The lower boundary of the output range + * @param {Number} max The upper boundary of the output range + * @returns A number in the range [min, max] + * @type Number + */ +export function clamp(input = 0, min = 0, max = 255) { + return Math.min(Math.max(input, min), max); +} + +export default { clamp }; diff --git a/src/js/utils/style.js b/src/js/utils/style.js index a8eb393b..941db8f2 100644 --- a/src/js/utils/style.js +++ b/src/js/utils/style.js @@ -4,26 +4,61 @@ import is from './is'; -/* function reduceAspectRatio(width, height) { - const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h)); - const ratio = getRatio(width, height); - return `${width / ratio}:${height / ratio}`; -} */ +export function validateRatio(input) { + if (!is.array(input) && (!is.string(input) || !input.includes(':'))) { + return false; + } -// Set aspect ratio for responsive container -export function setAspectRatio(input) { - let ratio = input; + const ratio = is.array(input) ? input : input.split(':'); + + return ratio.map(Number).every(is.number); +} + +export function reduceAspectRatio(ratio) { + if (!is.array(ratio) || !ratio.every(is.number)) { + return null; + } + + const [width, height] = ratio; + const getDivider = (w, h) => (h === 0 ? w : getDivider(h, w % h)); + const divider = getDivider(width, height); + + return [width / divider, height / divider]; +} - if (!is.string(ratio) && !is.nullOrUndefined(this.embed)) { +export function getAspectRatio(input) { + const parse = ratio => (validateRatio(ratio) ? ratio.split(':').map(Number) : null); + // Try provided ratio + let ratio = parse(input); + + // Get from config + if (ratio === null) { + ratio = parse(this.config.ratio); + } + + // Get from embed + if (ratio === null && !is.empty(this.embed) && is.array(this.embed.ratio)) { ({ ratio } = this.embed); } - if (!is.string(ratio)) { - ({ ratio } = this.config); + // Get from HTML5 video + if (ratio === null && this.isHTML5) { + const { videoWidth, videoHeight } = this.media; + ratio = reduceAspectRatio([videoWidth, videoHeight]); + } + + return ratio; +} + +// Set aspect ratio for responsive container +export function setAspectRatio(input) { + if (!this.isVideo) { + return {}; } - const [x, y] = ratio.split(':').map(Number); - const padding = (100 / x) * y; + const ratio = getAspectRatio.call(this, input); + const [w, h] = is.array(ratio) ? ratio : [0, 0]; + const padding = (100 / w) * h; this.elements.wrapper.style.paddingBottom = `${padding}%`; @@ -32,6 +67,8 @@ export function setAspectRatio(input) { const height = 240; const offset = (height - padding) / (height / 50); this.media.style.transform = `translateY(-${offset}%)`; + } else if (this.isHTML5) { + this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); } return { padding, ratio }; diff --git a/src/js/utils/time.js b/src/js/utils/time.js index 2deccf65..ffca88b2 100644 --- a/src/js/utils/time.js +++ b/src/js/utils/time.js @@ -18,7 +18,6 @@ export function formatTime(time = 0, displayHours = false, inverted = false) { // Format time component to add leading zero const format = value => `0${value}`.slice(-2); - // Breakdown to hours, mins, secs let hours = getHours(time); const mins = getMinutes(time); diff --git a/src/js/utils/urls.js b/src/js/utils/urls.js index 3ebe622e..843c6aa6 100644 --- a/src/js/utils/urls.js +++ b/src/js/utils/urls.js @@ -6,8 +6,8 @@ import is from './is'; /** * Parse a string to a URL object - * @param {string} input - the URL to be parsed - * @param {boolean} safe - failsafe parsing + * @param {String} input - the URL to be parsed + * @param {Boolean} safe - failsafe parsing */ export function parseUrl(input, safe = true) { let url = input; |