aboutsummaryrefslogtreecommitdiffstats
path: root/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js')
-rw-r--r--src/js/captions.js4
-rw-r--r--src/js/config/defaults.js3
-rw-r--r--src/js/controls.js3
-rw-r--r--src/js/fullscreen.js4
-rw-r--r--src/js/html5.js2
-rw-r--r--src/js/listeners.js4
-rw-r--r--src/js/plugins/ads.js4
-rw-r--r--src/js/plugins/vimeo.js37
-rw-r--r--src/js/plyr.d.ts21
-rw-r--r--src/js/plyr.js26
-rw-r--r--src/js/plyr.polyfilled.js2
-rw-r--r--src/js/storage.js8
-rw-r--r--src/js/support.js2
-rw-r--r--src/js/ui.js7
-rw-r--r--src/js/utils/animation.js2
-rw-r--r--src/js/utils/events.js2
-rw-r--r--src/js/utils/fetch.js6
-rw-r--r--src/js/utils/is.js2
-rw-r--r--src/js/utils/load-sprite.js16
-rw-r--r--src/js/utils/urls.js2
20 files changed, 115 insertions, 42 deletions
diff --git a/src/js/captions.js b/src/js/captions.js
index 98d7d613..856baccf 100644
--- a/src/js/captions.js
+++ b/src/js/captions.js
@@ -154,7 +154,9 @@ const captions = {
}
// Enable or disable captions based on track length
- toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));
+ if (this.elements) {
+ toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));
+ }
// Update available languages in list
if (
diff --git a/src/js/config/defaults.js b/src/js/config/defaults.js
index aa219bad..4d64d514 100644
--- a/src/js/config/defaults.js
+++ b/src/js/config/defaults.js
@@ -61,7 +61,7 @@ const defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
- iconUrl: 'https://cdn.plyr.io/3.6.8/plyr.svg',
+ iconUrl: 'https://cdn.plyr.io/3.6.12/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
@@ -398,6 +398,7 @@ const defaults = {
embed: {
provider: 'data-plyr-provider',
id: 'data-plyr-embed-id',
+ hash: 'data-plyr-embed-hash',
},
},
diff --git a/src/js/controls.js b/src/js/controls.js
index ff20982e..9fe74272 100644
--- a/src/js/controls.js
+++ b/src/js/controls.js
@@ -38,7 +38,8 @@ const controls = {
// Get icon URL
getIconUrl() {
const url = new URL(this.config.iconUrl, window.location);
- const cors = url.host !== window.location.host || (browser.isIE && !window.svg4everybody);
+ const host = window.location.host ? window.location.host : window.top.location.host;
+ const cors = url.host !== host || (browser.isIE && !window.svg4everybody);
return {
url: this.config.iconUrl,
diff --git a/src/js/fullscreen.js b/src/js/fullscreen.js
index 20e958fc..c1feadb5 100644
--- a/src/js/fullscreen.js
+++ b/src/js/fullscreen.js
@@ -124,7 +124,9 @@ class Fullscreen {
return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
}
- const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.property}Element`];
+ const element = !this.prefix
+ ? this.target.getRootNode().fullscreenElement
+ : this.target.getRootNode()[`${this.prefix}${this.property}Element`];
return element && element.shadowRoot ? element === this.target.getRootNode().host : element === this.target;
}
diff --git a/src/js/html5.js b/src/js/html5.js
index ab796234..9ec808c1 100644
--- a/src/js/html5.js
+++ b/src/js/html5.js
@@ -73,7 +73,7 @@ const html5 = {
return;
}
- // If we're using an an external handler...
+ // If we're using an external handler...
if (player.config.quality.forced && is.function(player.config.quality.onChange)) {
player.config.quality.onChange(input);
} else {
diff --git a/src/js/listeners.js b/src/js/listeners.js
index c490070c..dfe118b5 100644
--- a/src/js/listeners.js
+++ b/src/js/listeners.js
@@ -841,7 +841,9 @@ class Listeners {
.filter((c) => !c.contains(elements.container))
.forEach((child) => {
this.bind(child, 'mouseenter mouseleave', (event) => {
- elements.controls.hover = !player.touch && event.type === 'mouseenter';
+ if (elements.controls) {
+ elements.controls.hover = !player.touch && event.type === 'mouseenter';
+ }
});
});
}
diff --git a/src/js/plugins/ads.js b/src/js/plugins/ads.js
index 5d9406d1..515c4b97 100644
--- a/src/js/plugins/ads.js
+++ b/src/js/plugins/ads.js
@@ -213,8 +213,8 @@ class Ads {
request.setAdWillPlayMuted(!this.player.muted);
this.loader.requestAds(request);
- } catch (e) {
- this.onAdError(e);
+ } catch (error) {
+ this.onAdError(error);
}
};
diff --git a/src/js/plugins/vimeo.js b/src/js/plugins/vimeo.js
index 10246c66..f20159f9 100644
--- a/src/js/plugins/vimeo.js
+++ b/src/js/plugins/vimeo.js
@@ -28,6 +28,21 @@ function parseId(url) {
return url.match(regex) ? RegExp.$2 : url;
}
+// Try to extract a hash for private videos from the URL
+function parseHash(url) {
+ /* This regex matches a hexadecimal hash if given in any of these forms:
+ * - [https://player.]vimeo.com/video/{id}/{hash}[?params]
+ * - [https://player.]vimeo.com/video/{id}?h={hash}[&params]
+ * - [https://player.]vimeo.com/video/{id}?[params]&h={hash}
+ * - video/{id}/{hash}
+ * If matched, the hash is available in the named group `hash`
+ */
+ const regex = /^.*(?:vimeo.com\/|video\/)(?:\d+)(?:\?.*&*h=|\/)+(?<hash>[\d,a-f]+)/;
+ const found = url.match(regex);
+
+ return found ? found.groups.hash : null;
+}
+
// Set playback state and trigger change (only on actual change)
function assurePlaybackState(play) {
if (play && !this.embed.hasPlayed) {
@@ -71,6 +86,18 @@ const vimeo = {
const player = this;
const config = player.config.vimeo;
const { premium, referrerPolicy, ...frameParams } = config;
+ // Get the source URL or ID
+ let source = player.media.getAttribute('src');
+ let hash = '';
+ // Get from <div> if needed
+ if (is.empty(source)) {
+ source = player.media.getAttribute(player.config.attributes.embed.id);
+ // hash can also be set as attribute on the <div>
+ hash = player.media.getAttribute(player.config.attributes.embed.hash);
+ } else {
+ hash = parseHash(source);
+ }
+ const hashParam = hash ? { h: hash } : {};
// If the owner has a pro or premium account then we can hide controls etc
if (premium) {
@@ -87,17 +114,11 @@ const vimeo = {
muted: player.muted,
gesture: 'media',
playsinline: !this.config.fullscreen.iosNative,
+ // hash has to be added to iframe-URL
+ ...hashParam,
...frameParams,
});
- // Get the source URL or ID
- let source = player.media.getAttribute('src');
-
- // Get from <div> if needed
- if (is.empty(source)) {
- source = player.media.getAttribute(player.config.attributes.embed.id);
- }
-
const id = parseId(source);
// Build an iframe
const iframe = createElement('iframe');
diff --git a/src/js/plyr.d.ts b/src/js/plyr.d.ts
index 6eb2fa88..cf45f1ae 100644
--- a/src/js/plyr.d.ts
+++ b/src/js/plyr.d.ts
@@ -212,6 +212,11 @@ declare class Plyr {
airplay(): void;
/**
+ * Sets the preview thubmnails for the current source.
+ */
+ setPreviewThumbnails(source: Plyr.PreviewThumbnailsOptions): void;
+
+ /**
* Toggle the controls (video only). Takes optional truthy value to force it on/off.
*/
toggleControls(toggle: boolean): void;
@@ -238,8 +243,10 @@ declare class Plyr {
/**
* Destroy lib instance
+ * @param {Function} callback - Callback for when destroy is complete
+ * @param {Boolean} soft - Whether it's a soft destroy (for source changes etc)
*/
- destroy(): void;
+ destroy(callback?: (...args: any[]) => void, soft?: boolean): void;
}
declare namespace Plyr {
@@ -452,7 +459,7 @@ declare namespace Plyr {
* Allows binding of event listeners to the controls before the default handlers. See the defaults.js for available listeners.
* If your handler prevents default on the event (event.preventDefault()), the default handler will not fire.
*/
- listeners?: { [key: string]: (error: PlyrEvent) => void };
+ listeners?: {[key: string]: (error: PlyrEvent) => void};
/**
* active: Toggles if captions should be active by default. language: Sets the default language to load (if available). 'auto' uses the browser language.
@@ -526,7 +533,8 @@ declare namespace Plyr {
interface AdOptions {
enabled: boolean;
- publisherId: string;
+ publisherId?: string;
+ tagUrl?: string;
}
interface SpeedOptions {
@@ -616,6 +624,11 @@ declare namespace Plyr {
* Booleans are converted to HTML5 value-less attributes.
*/
tracks?: Track[];
+
+ /**
+ * Enable or disable preview thumbnails for current source
+ */
+ previewThumbnails?: Plyr.PreviewThumbnailsOptions;
}
interface Source {
@@ -654,7 +667,7 @@ declare namespace Plyr {
}
interface PlyrEvent extends CustomEvent {
- readonly detail: { readonly plyr: Plyr };
+ readonly detail: {readonly plyr: Plyr};
}
enum YoutubeState {
diff --git a/src/js/plyr.js b/src/js/plyr.js
index 7cfa5386..cad45d66 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
-// plyr.js v3.6.8
+// plyr.js v3.6.12
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
@@ -72,7 +72,7 @@ class Plyr {
(() => {
try {
return JSON.parse(this.media.getAttribute('data-plyr-config'));
- } catch (e) {
+ } catch (_) {
return {};
}
})(),
@@ -675,7 +675,9 @@ class Plyr {
// Set media speed
setTimeout(() => {
- this.media.playbackRate = speed;
+ if (this.media) {
+ this.media.playbackRate = speed;
+ }
}, 0);
}
@@ -956,6 +958,7 @@ class Plyr {
*/
set currentTrack(input) {
captions.set.call(this, input, false);
+ captions.setup();
}
/**
@@ -1030,6 +1033,23 @@ class Plyr {
}
/**
+ * Sets the preview thubmnails for the current source
+ */
+ setPreviewThumbnails(thumbnailSource) {
+ if (this.previewThumbnails && this.previewThumbnails.loaded) {
+ this.previewThumbnails.destroy();
+ this.previewThumbnails = null;
+ }
+
+ Object.assign(this.config.previewThumbnails, thumbnailSource);
+
+ // Create new instance if it is still enabled
+ if (this.config.previewThumbnails.enabled) {
+ this.previewThumbnails = new PreviewThumbnails(this);
+ }
+ }
+
+ /**
* Trigger the airplay dialog
* TODO: update player with state, support, enabled
*/
diff --git a/src/js/plyr.polyfilled.js b/src/js/plyr.polyfilled.js
index 3a515063..686d0693 100644
--- a/src/js/plyr.polyfilled.js
+++ b/src/js/plyr.polyfilled.js
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr Polyfilled Build
-// plyr.js v3.6.8
+// plyr.js v3.6.12
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
diff --git a/src/js/storage.js b/src/js/storage.js
index 323a6d25..6ba3b239 100644
--- a/src/js/storage.js
+++ b/src/js/storage.js
@@ -26,7 +26,7 @@ class Storage {
window.localStorage.removeItem(test);
return true;
- } catch (e) {
+ } catch (_) {
return false;
}
}
@@ -70,7 +70,11 @@ class Storage {
extend(storage, object);
// Update storage
- window.localStorage.setItem(this.key, JSON.stringify(storage));
+ try {
+ window.localStorage.setItem(this.key, JSON.stringify(storage));
+ } catch (_) {
+ // Do nothing
+ }
};
}
diff --git a/src/js/support.js b/src/js/support.js
index 99900210..9b5d2aa0 100644
--- a/src/js/support.js
+++ b/src/js/support.js
@@ -88,7 +88,7 @@ const support = {
try {
return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));
- } catch (e) {
+ } catch (_) {
return false;
}
},
diff --git a/src/js/ui.js b/src/js/ui.js
index c8b19677..b674c70d 100644
--- a/src/js/ui.js
+++ b/src/js/ui.js
@@ -82,6 +82,9 @@ const ui = {
// Reset time display
controls.timeUpdate.call(this);
+ // Reset duration display
+ controls.durationUpdate.call(this);
+
// Update the UI
ui.checkPlaying.call(this);
@@ -181,13 +184,13 @@ const ui = {
.call(this)
// Load image
.then(() => loadImage(poster))
- .catch((err) => {
+ .catch((error) => {
// Hide poster on error unless it's been set by another call
if (poster === this.poster) {
ui.togglePoster.call(this, false);
}
// Rethrow
- throw err;
+ throw error;
})
.then(() => {
// Prevent race conditions
diff --git a/src/js/utils/animation.js b/src/js/utils/animation.js
index b4ccf268..8cb37895 100644
--- a/src/js/utils/animation.js
+++ b/src/js/utils/animation.js
@@ -31,7 +31,7 @@ export function repaint(element, delay) {
// eslint-disable-next-line no-param-reassign
element.hidden = false;
- } catch (e) {
+ } catch (_) {
// Do nothing
}
}, delay);
diff --git a/src/js/utils/events.js b/src/js/utils/events.js
index 287129f1..d1c104ee 100644
--- a/src/js/utils/events.js
+++ b/src/js/utils/events.js
@@ -19,7 +19,7 @@ const supportsPassiveListeners = (() => {
});
window.addEventListener('test', null, options);
window.removeEventListener('test', null, options);
- } catch (e) {
+ } catch (_) {
// Do nothing
}
diff --git a/src/js/utils/fetch.js b/src/js/utils/fetch.js
index ef695193..1d0791ea 100644
--- a/src/js/utils/fetch.js
+++ b/src/js/utils/fetch.js
@@ -17,7 +17,7 @@ export default function fetch(url, responseType = 'text') {
if (responseType === 'text') {
try {
resolve(JSON.parse(request.responseText));
- } catch (e) {
+ } catch (_) {
resolve(request.responseText);
}
} else {
@@ -35,8 +35,8 @@ export default function fetch(url, responseType = 'text') {
request.responseType = responseType;
request.send();
- } catch (e) {
- reject(e);
+ } catch (error) {
+ reject(error);
}
});
}
diff --git a/src/js/utils/is.js b/src/js/utils/is.js
index 28f0c1a4..38317e3f 100644
--- a/src/js/utils/is.js
+++ b/src/js/utils/is.js
@@ -51,7 +51,7 @@ const isUrl = (input) => {
try {
return !isEmpty(new URL(string).hostname);
- } catch (e) {
+ } catch (_) {
return false;
}
};
diff --git a/src/js/utils/load-sprite.js b/src/js/utils/load-sprite.js
index 293163e5..b4a47f21 100644
--- a/src/js/utils/load-sprite.js
+++ b/src/js/utils/load-sprite.js
@@ -60,12 +60,16 @@ export default function loadSprite(url, id) {
}
if (useStorage) {
- window.localStorage.setItem(
- `${prefix}-${id}`,
- JSON.stringify({
- content: result,
- }),
- );
+ try {
+ window.localStorage.setItem(
+ `${prefix}-${id}`,
+ JSON.stringify({
+ content: result,
+ }),
+ );
+ } catch (_) {
+ // Do nothing
+ }
}
update(container, result);
diff --git a/src/js/utils/urls.js b/src/js/utils/urls.js
index ba264511..e0779dec 100644
--- a/src/js/utils/urls.js
+++ b/src/js/utils/urls.js
@@ -20,7 +20,7 @@ export function parseUrl(input, safe = true) {
try {
return new URL(url);
- } catch (e) {
+ } catch (_) {
return null;
}
}