Utils broken down into seperate files and exports
This commit is contained in:
156
src/js/plyr.js
156
src/js/plyr.js
@ -6,9 +6,10 @@
|
||||
// ==========================================================================
|
||||
|
||||
import captions from './captions';
|
||||
import defaults from './config/defaults';
|
||||
import { getProviderByUrl, providers, types } from './config/types';
|
||||
import Console from './console';
|
||||
import controls from './controls';
|
||||
import defaults from './defaults';
|
||||
import Fullscreen from './fullscreen';
|
||||
import Listeners from './listeners';
|
||||
import media from './media';
|
||||
@ -16,9 +17,14 @@ import Ads from './plugins/ads';
|
||||
import source from './source';
|
||||
import Storage from './storage';
|
||||
import support from './support';
|
||||
import { providers, types } from './types';
|
||||
import ui from './ui';
|
||||
import utils from './utils';
|
||||
import { closest } from './utils/arrays';
|
||||
import { createElement, hasClass, removeElement, replaceElement, toggleClass, toggleState, wrap } from './utils/elements';
|
||||
import { off, on, trigger } from './utils/events';
|
||||
import is from './utils/is';
|
||||
import loadSprite from './utils/loadScript';
|
||||
import { cloneDeep, extend } from './utils/objects';
|
||||
import { parseUrl } from './utils/urls';
|
||||
|
||||
// Private properties
|
||||
// TODO: Use a WeakMap for private globals
|
||||
@ -41,18 +47,18 @@ class Plyr {
|
||||
this.media = target;
|
||||
|
||||
// String selector passed
|
||||
if (utils.is.string(this.media)) {
|
||||
if (is.string(this.media)) {
|
||||
this.media = document.querySelectorAll(this.media);
|
||||
}
|
||||
|
||||
// jQuery, NodeList or Array passed, use first element
|
||||
if ((window.jQuery && this.media instanceof jQuery) || utils.is.nodeList(this.media) || utils.is.array(this.media)) {
|
||||
if ((window.jQuery && this.media instanceof jQuery) || is.nodeList(this.media) || is.array(this.media)) {
|
||||
// eslint-disable-next-line
|
||||
this.media = this.media[0];
|
||||
}
|
||||
|
||||
// Set config
|
||||
this.config = utils.extend(
|
||||
this.config = extend(
|
||||
{},
|
||||
defaults,
|
||||
Plyr.defaults,
|
||||
@ -108,7 +114,7 @@ class Plyr {
|
||||
this.debug.log('Support', support);
|
||||
|
||||
// We need an element to setup
|
||||
if (utils.is.nullOrUndefined(this.media) || !utils.is.element(this.media)) {
|
||||
if (is.nullOrUndefined(this.media) || !is.element(this.media)) {
|
||||
this.debug.error('Setup failed: no suitable element passed');
|
||||
return;
|
||||
}
|
||||
@ -144,7 +150,6 @@ class Plyr {
|
||||
// Embed properties
|
||||
let iframe = null;
|
||||
let url = null;
|
||||
let params = null;
|
||||
|
||||
// Different setup based on type
|
||||
switch (type) {
|
||||
@ -153,10 +158,10 @@ class Plyr {
|
||||
iframe = this.media.querySelector('iframe');
|
||||
|
||||
// <iframe> type
|
||||
if (utils.is.element(iframe)) {
|
||||
if (is.element(iframe)) {
|
||||
// Detect provider
|
||||
url = iframe.getAttribute('src');
|
||||
this.provider = utils.getProviderByUrl(url);
|
||||
url = parseUrl(iframe.getAttribute('src'));
|
||||
this.provider = getProviderByUrl(url.toString());
|
||||
|
||||
// Rework elements
|
||||
this.elements.container = this.media;
|
||||
@ -166,24 +171,23 @@ class Plyr {
|
||||
this.elements.container.className = '';
|
||||
|
||||
// Get attributes from URL and set config
|
||||
params = utils.getUrlParams(url);
|
||||
if (!utils.is.empty(params)) {
|
||||
if (!url.searchParams) {
|
||||
const truthy = [
|
||||
'1',
|
||||
'true',
|
||||
];
|
||||
|
||||
if (truthy.includes(params.autoplay)) {
|
||||
if (truthy.includes(url.searchParams.get('autoplay'))) {
|
||||
this.config.autoplay = true;
|
||||
}
|
||||
if (truthy.includes(params.loop)) {
|
||||
if (truthy.includes(url.searchParams.get('loop'))) {
|
||||
this.config.loop.active = true;
|
||||
}
|
||||
|
||||
// TODO: replace fullscreen.iosNative with this playsinline config option
|
||||
// YouTube requires the playsinline in the URL
|
||||
if (this.isYouTube) {
|
||||
this.config.playsinline = truthy.includes(params.playsinline);
|
||||
this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));
|
||||
} else {
|
||||
this.config.playsinline = true;
|
||||
}
|
||||
@ -197,7 +201,7 @@ class Plyr {
|
||||
}
|
||||
|
||||
// Unsupported or missing provider
|
||||
if (utils.is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {
|
||||
if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {
|
||||
this.debug.error('Setup failed: Invalid provider');
|
||||
return;
|
||||
}
|
||||
@ -255,9 +259,9 @@ class Plyr {
|
||||
this.media.plyr = this;
|
||||
|
||||
// Wrap media
|
||||
if (!utils.is.element(this.elements.container)) {
|
||||
this.elements.container = utils.createElement('div');
|
||||
utils.wrap(this.media, this.elements.container);
|
||||
if (!is.element(this.elements.container)) {
|
||||
this.elements.container = createElement('div');
|
||||
wrap(this.media, this.elements.container);
|
||||
}
|
||||
|
||||
// Allow focus to be captured
|
||||
@ -271,7 +275,7 @@ class Plyr {
|
||||
|
||||
// Listen for events if debugging
|
||||
if (this.config.debug) {
|
||||
utils.on(this.elements.container, this.config.events.join(' '), event => {
|
||||
on(this.elements.container, this.config.events.join(' '), event => {
|
||||
this.debug.log(`event: ${event.type}`);
|
||||
});
|
||||
}
|
||||
@ -330,7 +334,7 @@ class Plyr {
|
||||
* Play the media, or play the advertisement (if they are not blocked)
|
||||
*/
|
||||
play() {
|
||||
if (!utils.is.function(this.media.play)) {
|
||||
if (!is.function(this.media.play)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -342,7 +346,7 @@ class Plyr {
|
||||
* Pause the media
|
||||
*/
|
||||
pause() {
|
||||
if (!this.playing || !utils.is.function(this.media.pause)) {
|
||||
if (!this.playing || !is.function(this.media.pause)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -383,7 +387,7 @@ class Plyr {
|
||||
*/
|
||||
togglePlay(input) {
|
||||
// Toggle based on current state if nothing passed
|
||||
const toggle = utils.is.boolean(input) ? input : !this.playing;
|
||||
const toggle = is.boolean(input) ? input : !this.playing;
|
||||
|
||||
if (toggle) {
|
||||
this.play();
|
||||
@ -399,7 +403,7 @@ class Plyr {
|
||||
if (this.isHTML5) {
|
||||
this.pause();
|
||||
this.restart();
|
||||
} else if (utils.is.function(this.media.stop)) {
|
||||
} else if (is.function(this.media.stop)) {
|
||||
this.media.stop();
|
||||
}
|
||||
}
|
||||
@ -416,7 +420,7 @@ class Plyr {
|
||||
* @param {number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime
|
||||
*/
|
||||
rewind(seekTime) {
|
||||
this.currentTime = this.currentTime - (utils.is.number(seekTime) ? seekTime : this.config.seekTime);
|
||||
this.currentTime = this.currentTime - (is.number(seekTime) ? seekTime : this.config.seekTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -424,7 +428,7 @@ class Plyr {
|
||||
* @param {number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime
|
||||
*/
|
||||
forward(seekTime) {
|
||||
this.currentTime = this.currentTime + (utils.is.number(seekTime) ? seekTime : this.config.seekTime);
|
||||
this.currentTime = this.currentTime + (is.number(seekTime) ? seekTime : this.config.seekTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -438,7 +442,7 @@ class Plyr {
|
||||
}
|
||||
|
||||
// Validate input
|
||||
const inputIsValid = utils.is.number(input) && input > 0;
|
||||
const inputIsValid = is.number(input) && input > 0;
|
||||
|
||||
// Set
|
||||
this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;
|
||||
@ -461,7 +465,7 @@ class Plyr {
|
||||
const { buffered } = this.media;
|
||||
|
||||
// YouTube / Vimeo return a float between 0-1
|
||||
if (utils.is.number(buffered)) {
|
||||
if (is.number(buffered)) {
|
||||
return buffered;
|
||||
}
|
||||
|
||||
@ -505,17 +509,17 @@ class Plyr {
|
||||
const max = 1;
|
||||
const min = 0;
|
||||
|
||||
if (utils.is.string(volume)) {
|
||||
if (is.string(volume)) {
|
||||
volume = Number(volume);
|
||||
}
|
||||
|
||||
// Load volume from storage if no value specified
|
||||
if (!utils.is.number(volume)) {
|
||||
if (!is.number(volume)) {
|
||||
volume = this.storage.get('volume');
|
||||
}
|
||||
|
||||
// Use config if all else fails
|
||||
if (!utils.is.number(volume)) {
|
||||
if (!is.number(volume)) {
|
||||
({ volume } = this.config);
|
||||
}
|
||||
|
||||
@ -535,7 +539,7 @@ class Plyr {
|
||||
this.media.volume = volume;
|
||||
|
||||
// If muted, and we're increasing volume manually, reset muted state
|
||||
if (!utils.is.empty(value) && this.muted && volume > 0) {
|
||||
if (!is.empty(value) && this.muted && volume > 0) {
|
||||
this.muted = false;
|
||||
}
|
||||
}
|
||||
@ -553,7 +557,7 @@ class Plyr {
|
||||
*/
|
||||
increaseVolume(step) {
|
||||
const volume = this.media.muted ? 0 : this.volume;
|
||||
this.volume = volume + (utils.is.number(step) ? step : 1);
|
||||
this.volume = volume + (is.number(step) ? step : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -562,7 +566,7 @@ class Plyr {
|
||||
*/
|
||||
decreaseVolume(step) {
|
||||
const volume = this.media.muted ? 0 : this.volume;
|
||||
this.volume = volume - (utils.is.number(step) ? step : 1);
|
||||
this.volume = volume - (is.number(step) ? step : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -573,12 +577,12 @@ class Plyr {
|
||||
let toggle = mute;
|
||||
|
||||
// Load muted state from storage
|
||||
if (!utils.is.boolean(toggle)) {
|
||||
if (!is.boolean(toggle)) {
|
||||
toggle = this.storage.get('muted');
|
||||
}
|
||||
|
||||
// Use config if all else fails
|
||||
if (!utils.is.boolean(toggle)) {
|
||||
if (!is.boolean(toggle)) {
|
||||
toggle = this.config.muted;
|
||||
}
|
||||
|
||||
@ -624,15 +628,15 @@ class Plyr {
|
||||
set speed(input) {
|
||||
let speed = null;
|
||||
|
||||
if (utils.is.number(input)) {
|
||||
if (is.number(input)) {
|
||||
speed = input;
|
||||
}
|
||||
|
||||
if (!utils.is.number(speed)) {
|
||||
if (!is.number(speed)) {
|
||||
speed = this.storage.get('speed');
|
||||
}
|
||||
|
||||
if (!utils.is.number(speed)) {
|
||||
if (!is.number(speed)) {
|
||||
speed = this.config.speed.selected;
|
||||
}
|
||||
|
||||
@ -671,19 +675,19 @@ class Plyr {
|
||||
set quality(input) {
|
||||
let quality = null;
|
||||
|
||||
if (!utils.is.empty(input)) {
|
||||
if (!is.empty(input)) {
|
||||
quality = Number(input);
|
||||
}
|
||||
|
||||
if (!utils.is.number(quality)) {
|
||||
if (!is.number(quality)) {
|
||||
quality = this.storage.get('quality');
|
||||
}
|
||||
|
||||
if (!utils.is.number(quality)) {
|
||||
if (!is.number(quality)) {
|
||||
quality = this.config.quality.selected;
|
||||
}
|
||||
|
||||
if (!utils.is.number(quality)) {
|
||||
if (!is.number(quality)) {
|
||||
quality = this.config.quality.default;
|
||||
}
|
||||
|
||||
@ -692,9 +696,9 @@ class Plyr {
|
||||
}
|
||||
|
||||
if (!this.options.quality.includes(quality)) {
|
||||
const closest = utils.closest(this.options.quality, quality);
|
||||
this.debug.warn(`Unsupported quality option: ${quality}, using ${closest} instead`);
|
||||
quality = closest;
|
||||
const value = closest(this.options.quality, quality);
|
||||
this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);
|
||||
quality = value;
|
||||
}
|
||||
|
||||
// Update config
|
||||
@ -717,7 +721,7 @@ class Plyr {
|
||||
* @param {boolean} input - Whether to loop or not
|
||||
*/
|
||||
set loop(input) {
|
||||
const toggle = utils.is.boolean(input) ? input : this.config.loop.active;
|
||||
const toggle = is.boolean(input) ? input : this.config.loop.active;
|
||||
this.config.loop.active = toggle;
|
||||
this.media.loop = toggle;
|
||||
|
||||
@ -816,7 +820,7 @@ class Plyr {
|
||||
* @param {boolean} input - Whether to autoplay or not
|
||||
*/
|
||||
set autoplay(input) {
|
||||
const toggle = utils.is.boolean(input) ? input : this.config.autoplay;
|
||||
const toggle = is.boolean(input) ? input : this.config.autoplay;
|
||||
this.config.autoplay = toggle;
|
||||
}
|
||||
|
||||
@ -838,18 +842,18 @@ class Plyr {
|
||||
}
|
||||
|
||||
// If the method is called without parameter, toggle based on current value
|
||||
const active = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
|
||||
const active = is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
|
||||
|
||||
// Toggle state
|
||||
utils.toggleState(this.elements.buttons.captions, active);
|
||||
toggleState(this.elements.buttons.captions, active);
|
||||
|
||||
// Add class hook
|
||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, active);
|
||||
toggleClass(this.elements.container, this.config.classNames.captions.active, active);
|
||||
|
||||
// Update state and trigger event
|
||||
if (active !== this.captions.active) {
|
||||
this.captions.active = active;
|
||||
utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
|
||||
trigger.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,7 +906,7 @@ class Plyr {
|
||||
}
|
||||
|
||||
// Toggle based on current state if not passed
|
||||
const toggle = utils.is.boolean(input) ? input : this.pip === states.inline;
|
||||
const toggle = is.boolean(input) ? input : this.pip === states.inline;
|
||||
|
||||
// Toggle based on current state
|
||||
this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);
|
||||
@ -938,22 +942,22 @@ class Plyr {
|
||||
// Don't toggle if missing UI support or if it's audio
|
||||
if (this.supported.ui && !this.isAudio) {
|
||||
// Get state before change
|
||||
const isHidden = utils.hasClass(this.elements.container, this.config.classNames.hideControls);
|
||||
const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);
|
||||
|
||||
// Negate the argument if not undefined since adding the class to hides the controls
|
||||
const force = typeof toggle === 'undefined' ? undefined : !toggle;
|
||||
|
||||
// Apply and get updated state
|
||||
const hiding = utils.toggleClass(this.elements.container, this.config.classNames.hideControls, force);
|
||||
const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);
|
||||
|
||||
// Close menu
|
||||
if (hiding && this.config.controls.includes('settings') && !utils.is.empty(this.config.settings)) {
|
||||
if (hiding && this.config.controls.includes('settings') && !is.empty(this.config.settings)) {
|
||||
controls.toggleMenu.call(this, false);
|
||||
}
|
||||
// Trigger event on change
|
||||
if (hiding !== isHidden) {
|
||||
const eventName = hiding ? 'controlshidden' : 'controlsshown';
|
||||
utils.dispatchEvent.call(this, this.media, eventName);
|
||||
trigger.call(this, this.media, eventName);
|
||||
}
|
||||
return !hiding;
|
||||
}
|
||||
@ -966,7 +970,7 @@ class Plyr {
|
||||
* @param {function} callback - Callback for when event occurs
|
||||
*/
|
||||
on(event, callback) {
|
||||
utils.on(this.elements.container, event, callback);
|
||||
on(this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -975,7 +979,7 @@ class Plyr {
|
||||
* @param {function} callback - Callback for when event occurs
|
||||
*/
|
||||
off(event, callback) {
|
||||
utils.off(this.elements.container, event, callback);
|
||||
off(this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1001,10 +1005,10 @@ class Plyr {
|
||||
if (soft) {
|
||||
if (Object.keys(this.elements).length) {
|
||||
// Remove elements
|
||||
utils.removeElement(this.elements.buttons.play);
|
||||
utils.removeElement(this.elements.captions);
|
||||
utils.removeElement(this.elements.controls);
|
||||
utils.removeElement(this.elements.wrapper);
|
||||
removeElement(this.elements.buttons.play);
|
||||
removeElement(this.elements.captions);
|
||||
removeElement(this.elements.controls);
|
||||
removeElement(this.elements.wrapper);
|
||||
|
||||
// Clear for GC
|
||||
this.elements.buttons.play = null;
|
||||
@ -1014,7 +1018,7 @@ class Plyr {
|
||||
}
|
||||
|
||||
// Callback
|
||||
if (utils.is.function(callback)) {
|
||||
if (is.function(callback)) {
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
@ -1022,13 +1026,13 @@ class Plyr {
|
||||
this.listeners.clear();
|
||||
|
||||
// Replace the container with the original element provided
|
||||
utils.replaceElement(this.elements.original, this.elements.container);
|
||||
replaceElement(this.elements.original, this.elements.container);
|
||||
|
||||
// Event
|
||||
utils.dispatchEvent.call(this, this.elements.original, 'destroyed', true);
|
||||
trigger.call(this, this.elements.original, 'destroyed', true);
|
||||
|
||||
// Callback
|
||||
if (utils.is.function(callback)) {
|
||||
if (is.function(callback)) {
|
||||
callback.call(this.elements.original);
|
||||
}
|
||||
|
||||
@ -1067,7 +1071,7 @@ class Plyr {
|
||||
clearInterval(this.timers.playing);
|
||||
|
||||
// Destroy YouTube API
|
||||
if (this.embed !== null && utils.is.function(this.embed.destroy)) {
|
||||
if (this.embed !== null && is.function(this.embed.destroy)) {
|
||||
this.embed.destroy();
|
||||
}
|
||||
|
||||
@ -1117,7 +1121,7 @@ class Plyr {
|
||||
* @param {string} [id] - Unique ID
|
||||
*/
|
||||
static loadSprite(url, id) {
|
||||
return utils.loadSprite(url, id);
|
||||
return loadSprite(url, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1128,15 +1132,15 @@ class Plyr {
|
||||
static setup(selector, options = {}) {
|
||||
let targets = null;
|
||||
|
||||
if (utils.is.string(selector)) {
|
||||
if (is.string(selector)) {
|
||||
targets = Array.from(document.querySelectorAll(selector));
|
||||
} else if (utils.is.nodeList(selector)) {
|
||||
} else if (is.nodeList(selector)) {
|
||||
targets = Array.from(selector);
|
||||
} else if (utils.is.array(selector)) {
|
||||
targets = selector.filter(utils.is.element);
|
||||
} else if (is.array(selector)) {
|
||||
targets = selector.filter(is.element);
|
||||
}
|
||||
|
||||
if (utils.is.empty(targets)) {
|
||||
if (is.empty(targets)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1144,6 +1148,6 @@ class Plyr {
|
||||
}
|
||||
}
|
||||
|
||||
Plyr.defaults = utils.cloneDeep(defaults);
|
||||
Plyr.defaults = cloneDeep(defaults);
|
||||
|
||||
export default Plyr;
|
||||
|
Reference in New Issue
Block a user