Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

videojs-playlist

Package Overview
Dependencies
Maintainers
184
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

videojs-playlist - npm Package Compare versions

Comparing version 5.0.1 to 5.1.0

CHANGELOG.md

220

dist/videojs-playlist.cjs.js

@@ -1,2 +0,2 @@

/*! @name videojs-playlist @version 5.0.1 @license Apache-2.0 */
/*! @name videojs-playlist @version 5.1.0 @license Apache-2.0 */
'use strict';

@@ -147,21 +147,35 @@

let guid = 1;
/**
* Returns whether a playlist item is an object of any kind, excluding null.
* Transform any primitive playlist item value into an object.
*
* @private
* For non-object values, adds a property to the transformed item containing
* original value passed.
*
* @param {Object}
* value to be checked
* For all items, add a unique ID to each playlist item object. This id is
* used to determine the index of an item in the playlist array in cases where
* there are multiple otherwise identical items.
*
* @return {boolean}
* The result
* @param {Object} newItem
* An playlist item object, but accepts any value.
*
* @return {Object}
*/
const isItemObject = value => {
return !!value && typeof value === 'object';
const preparePlaylistItem = newItem => {
let item = newItem;
if (!newItem || typeof newItem !== 'object') {
// Casting to an Object in this way allows primitives to retain their
// primitiveness (i.e. they will be cast back to primitives as needed).
item = Object(newItem);
item.originalValue = newItem;
}
item.playlistItemId_ = guid++;
return item;
};
/**
* Look through an array of playlist items and transform any primitive
* as well as null values to objects. This method also adds a property
* to the transformed item containing original value passed in an input list.
* Look through an array of playlist items and passes them to
* preparePlaylistItem.
*

@@ -178,36 +192,4 @@ * @private

const transformPrimitiveItems = arr => {
const list = [];
let tempItem;
arr.forEach(item => {
if (!isItemObject(item)) {
tempItem = Object(item);
tempItem.originalValue = item;
} else {
tempItem = item;
}
list.push(tempItem);
});
return list;
};
const preparePlaylistItems = arr => arr.map(preparePlaylistItem);
/**
* Generate a unique id for each playlist item object. This id will be used to determine
* index of an item in the playlist array for cases where there are multiple items with
* the same source set.
*
* @private
*
* @param {Array} arr
* An array of playlist items
*/
const generatePlaylistItemId = arr => {
let guid = 1;
arr.forEach(item => {
item.playlistItemId_ = guid++;
});
};
/**
* Look through an array of playlist items for a specific playlist item id.

@@ -389,3 +371,3 @@ *

const playlist = player.playlist = (newList, newIndex = 0) => {
const playlist = player.playlist = (nextPlaylist, newIndex = 0) => {
if (changing) {

@@ -395,17 +377,7 @@ throw new Error('do not call playlist() during a playlist change');

if (Array.isArray(newList)) {
if (Array.isArray(nextPlaylist)) {
// @todo - Simplify this to `list.slice()` for v5.
const previousPlaylist = Array.isArray(list) ? list.slice() : null;
const nextPlaylist = newList.slice();
list = nextPlaylist.slice(); // Transform any primitive and null values in an input list to objects
list = preparePlaylistItems(nextPlaylist); // Mark the playlist as changing during the duringplaylistchange lifecycle.
if (list.filter(item => isItemObject(item)).length !== list.length) {
list = transformPrimitiveItems(list);
} // Add unique id to each playlist item. This id will be used
// to determine index in cases where there are more than one
// identical sources in the playlist.
generatePlaylistItemId(list); // Mark the playlist as changing during the duringplaylistchange lifecycle.
changing = true;

@@ -435,10 +407,13 @@ player.trigger({

player.setTimeout(() => {
player.trigger('playlistchange');
player.trigger({
type: 'playlistchange',
action: 'change'
});
}, 0);
}
} // Always return a shallow clone of the playlist list.
// We also want to return originalValue if any item in the list has it.
// We also want to return originalValue if any item in the list has it.
return list.map(item => item.originalValue || item).slice();
return list.map(item => item.originalValue || item);
}; // On a new source, if there is no current item, disable auto-advance.

@@ -518,2 +493,121 @@

/**
* A custom DOM event that is fired when new item(s) are added to the current
* playlist (rather than replacing the entire playlist).
*
* Unlike playlistchange, this is fired synchronously as it does not
* affect playback.
*
* @typedef {Object} PlaylistAddEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistadd"
*
* @property {number} count
* The number of items that were added.
*
* @property {number} index
* The starting index where item(s) were added.
*/
/**
* A custom DOM event that is fired when new item(s) are removed from the
* current playlist (rather than replacing the entire playlist).
*
* This is fired synchronously as it does not affect playback.
*
* @typedef {Object} PlaylistRemoveEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistremove"
*
* @property {number} count
* The number of items that were removed.
*
* @property {number} index
* The starting index where item(s) were removed.
*/
/**
* Add one or more items to the playlist.
*
* @fires {PlaylistAddEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {string|Object|Array} item
* An item - or array of items - to be added to the playlist.
*
* @param {number} [index]
* If given as a valid value, injects the new playlist item(s)
* starting from that index. Otherwise, the item(s) are appended.
*/
playlist.add = (items, index) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
index = list.length;
}
if (!Array.isArray(items)) {
items = [items];
}
list.splice(index, 0, ...preparePlaylistItems(items)); // playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({
type: 'playlistchange',
action: 'add'
});
player.trigger({
type: 'playlistadd',
count: items.length,
index
});
};
/**
* Remove one or more items from the playlist.
*
* @fires {PlaylistRemoveEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {number} index
* If a valid index in the current playlist, removes the item at that
* index from the playlist.
*
* If no valid index is given, nothing is removed from the playlist.
*
* @param {number} [count=1]
* The number of items to remove from the playlist.
*/
playlist.remove = (index, count = 1) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
return;
}
list.splice(index, count); // playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({
type: 'playlistchange',
action: 'remove'
});
player.trigger({
type: 'playlistremove',
count,
index
});
};
/**
* Checks if the playlist contains a value.

@@ -871,3 +965,3 @@ *

if (Array.isArray(initialList)) {
playlist(initialList.slice(), initialIndex); // If there is no initial list given, silently set an empty array.
playlist(initialList, initialIndex); // If there is no initial list given, silently set an empty array.
} else {

@@ -880,3 +974,3 @@ list = [];

var version = "5.0.1";
var version = "5.1.0";

@@ -883,0 +977,0 @@ const registerPlugin = videojs__default["default"].registerPlugin || videojs__default["default"].plugin;

@@ -1,2 +0,2 @@

/*! @name videojs-playlist @version 5.0.1 @license Apache-2.0 */
/*! @name videojs-playlist @version 5.1.0 @license Apache-2.0 */
import videojs from 'video.js';

@@ -141,21 +141,35 @@

let guid = 1;
/**
* Returns whether a playlist item is an object of any kind, excluding null.
* Transform any primitive playlist item value into an object.
*
* @private
* For non-object values, adds a property to the transformed item containing
* original value passed.
*
* @param {Object}
* value to be checked
* For all items, add a unique ID to each playlist item object. This id is
* used to determine the index of an item in the playlist array in cases where
* there are multiple otherwise identical items.
*
* @return {boolean}
* The result
* @param {Object} newItem
* An playlist item object, but accepts any value.
*
* @return {Object}
*/
const isItemObject = value => {
return !!value && typeof value === 'object';
const preparePlaylistItem = newItem => {
let item = newItem;
if (!newItem || typeof newItem !== 'object') {
// Casting to an Object in this way allows primitives to retain their
// primitiveness (i.e. they will be cast back to primitives as needed).
item = Object(newItem);
item.originalValue = newItem;
}
item.playlistItemId_ = guid++;
return item;
};
/**
* Look through an array of playlist items and transform any primitive
* as well as null values to objects. This method also adds a property
* to the transformed item containing original value passed in an input list.
* Look through an array of playlist items and passes them to
* preparePlaylistItem.
*

@@ -172,36 +186,4 @@ * @private

const transformPrimitiveItems = arr => {
const list = [];
let tempItem;
arr.forEach(item => {
if (!isItemObject(item)) {
tempItem = Object(item);
tempItem.originalValue = item;
} else {
tempItem = item;
}
list.push(tempItem);
});
return list;
};
const preparePlaylistItems = arr => arr.map(preparePlaylistItem);
/**
* Generate a unique id for each playlist item object. This id will be used to determine
* index of an item in the playlist array for cases where there are multiple items with
* the same source set.
*
* @private
*
* @param {Array} arr
* An array of playlist items
*/
const generatePlaylistItemId = arr => {
let guid = 1;
arr.forEach(item => {
item.playlistItemId_ = guid++;
});
};
/**
* Look through an array of playlist items for a specific playlist item id.

@@ -383,3 +365,3 @@ *

const playlist = player.playlist = (newList, newIndex = 0) => {
const playlist = player.playlist = (nextPlaylist, newIndex = 0) => {
if (changing) {

@@ -389,17 +371,7 @@ throw new Error('do not call playlist() during a playlist change');

if (Array.isArray(newList)) {
if (Array.isArray(nextPlaylist)) {
// @todo - Simplify this to `list.slice()` for v5.
const previousPlaylist = Array.isArray(list) ? list.slice() : null;
const nextPlaylist = newList.slice();
list = nextPlaylist.slice(); // Transform any primitive and null values in an input list to objects
list = preparePlaylistItems(nextPlaylist); // Mark the playlist as changing during the duringplaylistchange lifecycle.
if (list.filter(item => isItemObject(item)).length !== list.length) {
list = transformPrimitiveItems(list);
} // Add unique id to each playlist item. This id will be used
// to determine index in cases where there are more than one
// identical sources in the playlist.
generatePlaylistItemId(list); // Mark the playlist as changing during the duringplaylistchange lifecycle.
changing = true;

@@ -429,10 +401,13 @@ player.trigger({

player.setTimeout(() => {
player.trigger('playlistchange');
player.trigger({
type: 'playlistchange',
action: 'change'
});
}, 0);
}
} // Always return a shallow clone of the playlist list.
// We also want to return originalValue if any item in the list has it.
// We also want to return originalValue if any item in the list has it.
return list.map(item => item.originalValue || item).slice();
return list.map(item => item.originalValue || item);
}; // On a new source, if there is no current item, disable auto-advance.

@@ -512,2 +487,121 @@

/**
* A custom DOM event that is fired when new item(s) are added to the current
* playlist (rather than replacing the entire playlist).
*
* Unlike playlistchange, this is fired synchronously as it does not
* affect playback.
*
* @typedef {Object} PlaylistAddEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistadd"
*
* @property {number} count
* The number of items that were added.
*
* @property {number} index
* The starting index where item(s) were added.
*/
/**
* A custom DOM event that is fired when new item(s) are removed from the
* current playlist (rather than replacing the entire playlist).
*
* This is fired synchronously as it does not affect playback.
*
* @typedef {Object} PlaylistRemoveEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistremove"
*
* @property {number} count
* The number of items that were removed.
*
* @property {number} index
* The starting index where item(s) were removed.
*/
/**
* Add one or more items to the playlist.
*
* @fires {PlaylistAddEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {string|Object|Array} item
* An item - or array of items - to be added to the playlist.
*
* @param {number} [index]
* If given as a valid value, injects the new playlist item(s)
* starting from that index. Otherwise, the item(s) are appended.
*/
playlist.add = (items, index) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
index = list.length;
}
if (!Array.isArray(items)) {
items = [items];
}
list.splice(index, 0, ...preparePlaylistItems(items)); // playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({
type: 'playlistchange',
action: 'add'
});
player.trigger({
type: 'playlistadd',
count: items.length,
index
});
};
/**
* Remove one or more items from the playlist.
*
* @fires {PlaylistRemoveEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {number} index
* If a valid index in the current playlist, removes the item at that
* index from the playlist.
*
* If no valid index is given, nothing is removed from the playlist.
*
* @param {number} [count=1]
* The number of items to remove from the playlist.
*/
playlist.remove = (index, count = 1) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
return;
}
list.splice(index, count); // playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({
type: 'playlistchange',
action: 'remove'
});
player.trigger({
type: 'playlistremove',
count,
index
});
};
/**
* Checks if the playlist contains a value.

@@ -865,3 +959,3 @@ *

if (Array.isArray(initialList)) {
playlist(initialList.slice(), initialIndex); // If there is no initial list given, silently set an empty array.
playlist(initialList, initialIndex); // If there is no initial list given, silently set an empty array.
} else {

@@ -874,3 +968,3 @@ list = [];

var version = "5.0.1";
var version = "5.1.0";

@@ -877,0 +971,0 @@ const registerPlugin = videojs.registerPlugin || videojs.plugin;

@@ -1,2 +0,2 @@

/*! @name videojs-playlist @version 5.0.1 @license Apache-2.0 */
/*! @name videojs-playlist @version 5.1.0 @license Apache-2.0 */
(function (global, factory) {

@@ -149,21 +149,35 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) :

let guid = 1;
/**
* Returns whether a playlist item is an object of any kind, excluding null.
* Transform any primitive playlist item value into an object.
*
* @private
* For non-object values, adds a property to the transformed item containing
* original value passed.
*
* @param {Object}
* value to be checked
* For all items, add a unique ID to each playlist item object. This id is
* used to determine the index of an item in the playlist array in cases where
* there are multiple otherwise identical items.
*
* @return {boolean}
* The result
* @param {Object} newItem
* An playlist item object, but accepts any value.
*
* @return {Object}
*/
const isItemObject = value => {
return !!value && typeof value === 'object';
const preparePlaylistItem = newItem => {
let item = newItem;
if (!newItem || typeof newItem !== 'object') {
// Casting to an Object in this way allows primitives to retain their
// primitiveness (i.e. they will be cast back to primitives as needed).
item = Object(newItem);
item.originalValue = newItem;
}
item.playlistItemId_ = guid++;
return item;
};
/**
* Look through an array of playlist items and transform any primitive
* as well as null values to objects. This method also adds a property
* to the transformed item containing original value passed in an input list.
* Look through an array of playlist items and passes them to
* preparePlaylistItem.
*

@@ -180,36 +194,4 @@ * @private

const transformPrimitiveItems = arr => {
const list = [];
let tempItem;
arr.forEach(item => {
if (!isItemObject(item)) {
tempItem = Object(item);
tempItem.originalValue = item;
} else {
tempItem = item;
}
list.push(tempItem);
});
return list;
};
const preparePlaylistItems = arr => arr.map(preparePlaylistItem);
/**
* Generate a unique id for each playlist item object. This id will be used to determine
* index of an item in the playlist array for cases where there are multiple items with
* the same source set.
*
* @private
*
* @param {Array} arr
* An array of playlist items
*/
const generatePlaylistItemId = arr => {
let guid = 1;
arr.forEach(item => {
item.playlistItemId_ = guid++;
});
};
/**
* Look through an array of playlist items for a specific playlist item id.

@@ -391,3 +373,3 @@ *

const playlist = player.playlist = (newList, newIndex = 0) => {
const playlist = player.playlist = (nextPlaylist, newIndex = 0) => {
if (changing) {

@@ -397,17 +379,7 @@ throw new Error('do not call playlist() during a playlist change');

if (Array.isArray(newList)) {
if (Array.isArray(nextPlaylist)) {
// @todo - Simplify this to `list.slice()` for v5.
const previousPlaylist = Array.isArray(list) ? list.slice() : null;
const nextPlaylist = newList.slice();
list = nextPlaylist.slice(); // Transform any primitive and null values in an input list to objects
list = preparePlaylistItems(nextPlaylist); // Mark the playlist as changing during the duringplaylistchange lifecycle.
if (list.filter(item => isItemObject(item)).length !== list.length) {
list = transformPrimitiveItems(list);
} // Add unique id to each playlist item. This id will be used
// to determine index in cases where there are more than one
// identical sources in the playlist.
generatePlaylistItemId(list); // Mark the playlist as changing during the duringplaylistchange lifecycle.
changing = true;

@@ -437,10 +409,13 @@ player.trigger({

player.setTimeout(() => {
player.trigger('playlistchange');
player.trigger({
type: 'playlistchange',
action: 'change'
});
}, 0);
}
} // Always return a shallow clone of the playlist list.
// We also want to return originalValue if any item in the list has it.
// We also want to return originalValue if any item in the list has it.
return list.map(item => item.originalValue || item).slice();
return list.map(item => item.originalValue || item);
}; // On a new source, if there is no current item, disable auto-advance.

@@ -520,2 +495,121 @@

/**
* A custom DOM event that is fired when new item(s) are added to the current
* playlist (rather than replacing the entire playlist).
*
* Unlike playlistchange, this is fired synchronously as it does not
* affect playback.
*
* @typedef {Object} PlaylistAddEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistadd"
*
* @property {number} count
* The number of items that were added.
*
* @property {number} index
* The starting index where item(s) were added.
*/
/**
* A custom DOM event that is fired when new item(s) are removed from the
* current playlist (rather than replacing the entire playlist).
*
* This is fired synchronously as it does not affect playback.
*
* @typedef {Object} PlaylistRemoveEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistremove"
*
* @property {number} count
* The number of items that were removed.
*
* @property {number} index
* The starting index where item(s) were removed.
*/
/**
* Add one or more items to the playlist.
*
* @fires {PlaylistAddEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {string|Object|Array} item
* An item - or array of items - to be added to the playlist.
*
* @param {number} [index]
* If given as a valid value, injects the new playlist item(s)
* starting from that index. Otherwise, the item(s) are appended.
*/
playlist.add = (items, index) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
index = list.length;
}
if (!Array.isArray(items)) {
items = [items];
}
list.splice(index, 0, ...preparePlaylistItems(items)); // playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({
type: 'playlistchange',
action: 'add'
});
player.trigger({
type: 'playlistadd',
count: items.length,
index
});
};
/**
* Remove one or more items from the playlist.
*
* @fires {PlaylistRemoveEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {number} index
* If a valid index in the current playlist, removes the item at that
* index from the playlist.
*
* If no valid index is given, nothing is removed from the playlist.
*
* @param {number} [count=1]
* The number of items to remove from the playlist.
*/
playlist.remove = (index, count = 1) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
return;
}
list.splice(index, count); // playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({
type: 'playlistchange',
action: 'remove'
});
player.trigger({
type: 'playlistremove',
count,
index
});
};
/**
* Checks if the playlist contains a value.

@@ -873,3 +967,3 @@ *

if (Array.isArray(initialList)) {
playlist(initialList.slice(), initialIndex); // If there is no initial list given, silently set an empty array.
playlist(initialList, initialIndex); // If there is no initial list given, silently set an empty array.
} else {

@@ -882,3 +976,3 @@ list = [];

var version = "5.0.1";
var version = "5.1.0";

@@ -885,0 +979,0 @@ const registerPlugin = videojs__default["default"].registerPlugin || videojs__default["default"].plugin;

@@ -1,2 +0,2 @@

/*! @name videojs-playlist @version 5.0.1 @license Apache-2.0 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojsPlaylist=t(e.videojs)}(this,(function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=t(e);let n=e=>{const t=e.playlist.autoadvance_;t.timeout&&e.clearTimeout(t.timeout),t.trigger&&e.off("ended",t.trigger),t.timeout=null,t.trigger=null};const l=(e,t)=>{var r;(n(e),"number"==typeof(r=t)&&!isNaN(r)&&r>=0&&r<1/0)?(e.playlist.autoadvance_.delay=t,e.playlist.autoadvance_.trigger=function(){const r=()=>l(e,t);e.one("play",r),e.playlist.autoadvance_.timeout=e.setTimeout((()=>{n(e),e.off("play",r),e.playlist.next()}),1e3*t)},e.one("ended",e.playlist.autoadvance_.trigger)):e.playlist.autoadvance_.delay=null},i=e=>!!e&&"object"==typeof e,a=(e,t)=>{let r=e,n=t;return"object"==typeof e&&(r=e.src),"object"==typeof t&&(n=t.src),/^\/\//.test(r)&&(n=n.slice(n.indexOf("//"))),/^\/\//.test(n)&&(r=r.slice(r.indexOf("//"))),r===n},o=(e,t)=>{for(let r=0;r<e.length;r++){const n=e[r].sources;if(Array.isArray(n))for(let e=0;e<n.length;e++){const l=n[e];if(l&&a(l,t))return r}}return-1};function s(e,t,a=0){let s=null,u=!1;const c=e.playlist=(t,r=0)=>{if(u)throw new Error("do not call playlist() during a playlist change");if(Array.isArray(t)){const n=Array.isArray(s)?s.slice():null,l=t.slice();s=l.slice(),s.filter((e=>i(e))).length!==s.length&&(s=(e=>{const t=[];let r;return e.forEach((e=>{i(e)?r=e:(r=Object(e),r.originalValue=e),t.push(r)})),t})(s)),(e=>{let t=1;e.forEach((e=>{e.playlistItemId_=t++}))})(s),u=!0,e.trigger({type:"duringplaylistchange",nextIndex:r,nextPlaylist:l,previousIndex:c.currentIndex_,previousPlaylist:n||[]}),u=!1,-1!==r&&c.currentItem(r),n&&e.setTimeout((()=>{e.trigger("playlistchange")}),0)}return s.map((e=>e.originalValue||e)).slice()};return e.on("loadstart",(()=>{-1===c.currentItem()&&n(e)})),c.currentIndex_=-1,c.player_=e,c.autoadvance_={},c.repeat_=!1,c.currentPlaylistItemId_=null,c.currentItem=t=>{if(u)return c.currentIndex_;if("number"==typeof t&&c.currentIndex_!==t&&t>=0&&t<s.length)return c.currentIndex_=t,((e,t)=>{const r=!e.paused()||e.ended();e.trigger("beforeplaylistitem",t.originalValue||t),t.playlistItemId_&&(e.playlist.currentPlaylistItemId_=t.playlistItemId_),e.poster(t.poster||""),e.src(t.sources),(e=>{const t=e.remoteTextTracks();let r=t&&t.length||0;for(;r--;)e.removeRemoteTextTrack(t[r])})(e),e.ready((()=>{if((t.textTracks||[]).forEach(e.addRemoteTextTrack.bind(e)),e.trigger("playlistitem",t.originalValue||t),r){const t=e.play();void 0!==t&&"function"==typeof t.then&&t.then(null,(e=>{}))}l(e,e.playlist.autoadvance_.delay)}))})(c.player_,s[c.currentIndex_]),t>0&&e.poster(""),c.currentIndex_;const r=c.player_.currentSrc()||"";if(c.currentPlaylistItemId_){const e=((e,t)=>{for(let r=0;r<e.length;r++)if(e[r].playlistItemId_===t)return r;return-1})(s,c.currentPlaylistItemId_),t=s[e];if(t&&Array.isArray(t.sources)&&o([t],r)>-1)return c.currentIndex_=e,c.currentIndex_;c.currentPlaylistItemId_=null}return c.currentIndex_=c.indexOf(r),c.currentIndex_},c.contains=e=>-1!==c.indexOf(e),c.indexOf=e=>{if("string"==typeof e)return o(s,e);const t=Array.isArray(e)?e:e.sources;for(let e=0;e<t.length;e++){const r=t[e];if("string"==typeof r)return o(s,r);if(r.src)return o(s,r.src)}return-1},c.currentIndex=()=>c.currentItem(),c.lastIndex=()=>s.length-1,c.nextIndex=()=>{const e=c.currentItem();if(-1===e)return-1;const t=c.lastIndex();return c.repeat_&&e===t?0:Math.min(e+1,t)},c.previousIndex=()=>{const e=c.currentItem();return-1===e?-1:c.repeat_&&0===e?c.lastIndex():Math.max(e-1,0)},c.first=()=>{if(u)return;const e=c.currentItem(0);if(s.length)return s[e].originalValue||s[e];c.currentIndex_=-1},c.last=()=>{if(u)return;const e=c.currentItem(c.lastIndex());if(s.length)return s[e].originalValue||s[e];c.currentIndex_=-1},c.next=()=>{if(u)return;const e=c.nextIndex();if(e!==c.currentIndex_){const t=c.currentItem(e);return s[t].originalValue||s[t]}},c.previous=()=>{if(u)return;const e=c.previousIndex();if(e!==c.currentIndex_){const t=c.currentItem(e);return s[t].originalValue||s[t]}},c.autoadvance=e=>{l(c.player_,e)},c.repeat=e=>void 0===e?c.repeat_:"boolean"==typeof e?(c.repeat_=!!e,c.repeat_):void r.default.log.error("videojs-playlist: Invalid value for repeat",e),c.sort=t=>{s.length&&(s.sort(t),u||e.trigger("playlistsorted"))},c.reverse=()=>{s.length&&(s.reverse(),u||e.trigger("playlistsorted"))},c.shuffle=({rest:t}={})=>{let r=0,n=s;t&&(r=c.currentIndex_+1,n=s.slice(r)),n.length<=1||((e=>{let t=-1;const r=e.length-1;for(;++t<e.length;){const n=t+Math.floor(Math.random()*(r-t+1)),l=e[n];e[n]=e[t],e[t]=l}})(n),t&&s.splice(...[r,n.length].concat(n)),u||e.trigger("playlistsorted"))},Array.isArray(t)?c(t.slice(),a):s=[],c}const u=function(e,t){s(this,e,t)};return(r.default.registerPlugin||r.default.plugin)("playlist",u),u.VERSION="5.0.1",u}));
/*! @name videojs-playlist @version 5.1.0 @license Apache-2.0 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojsPlaylist=t(e.videojs)}(this,(function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=t(e);let n=e=>{const t=e.playlist.autoadvance_;t.timeout&&e.clearTimeout(t.timeout),t.trigger&&e.off("ended",t.trigger),t.timeout=null,t.trigger=null};const l=(e,t)=>{var r;(n(e),"number"==typeof(r=t)&&!isNaN(r)&&r>=0&&r<1/0)?(e.playlist.autoadvance_.delay=t,e.playlist.autoadvance_.trigger=function(){const r=()=>l(e,t);e.one("play",r),e.playlist.autoadvance_.timeout=e.setTimeout((()=>{n(e),e.off("play",r),e.playlist.next()}),1e3*t)},e.one("ended",e.playlist.autoadvance_.trigger)):e.playlist.autoadvance_.delay=null};let i=1;const a=e=>{let t=e;return e&&"object"==typeof e||(t=Object(e),t.originalValue=e),t.playlistItemId_=i++,t},o=e=>e.map(a),s=(e,t)=>{let r=e,n=t;return"object"==typeof e&&(r=e.src),"object"==typeof t&&(n=t.src),/^\/\//.test(r)&&(n=n.slice(n.indexOf("//"))),/^\/\//.test(n)&&(r=r.slice(r.indexOf("//"))),r===n},u=(e,t)=>{for(let r=0;r<e.length;r++){const n=e[r].sources;if(Array.isArray(n))for(let e=0;e<n.length;e++){const l=n[e];if(l&&s(l,t))return r}}return-1};function c(e,t,i=0){let a=null,s=!1;const c=e.playlist=(t,r=0)=>{if(s)throw new Error("do not call playlist() during a playlist change");if(Array.isArray(t)){const n=Array.isArray(a)?a.slice():null;a=o(t),s=!0,e.trigger({type:"duringplaylistchange",nextIndex:r,nextPlaylist:t,previousIndex:c.currentIndex_,previousPlaylist:n||[]}),s=!1,-1!==r&&c.currentItem(r),n&&e.setTimeout((()=>{e.trigger({type:"playlistchange",action:"change"})}),0)}return a.map((e=>e.originalValue||e))};return e.on("loadstart",(()=>{-1===c.currentItem()&&n(e)})),c.currentIndex_=-1,c.player_=e,c.autoadvance_={},c.repeat_=!1,c.currentPlaylistItemId_=null,c.currentItem=t=>{if(s)return c.currentIndex_;if("number"==typeof t&&c.currentIndex_!==t&&t>=0&&t<a.length)return c.currentIndex_=t,((e,t)=>{const r=!e.paused()||e.ended();e.trigger("beforeplaylistitem",t.originalValue||t),t.playlistItemId_&&(e.playlist.currentPlaylistItemId_=t.playlistItemId_),e.poster(t.poster||""),e.src(t.sources),(e=>{const t=e.remoteTextTracks();let r=t&&t.length||0;for(;r--;)e.removeRemoteTextTrack(t[r])})(e),e.ready((()=>{if((t.textTracks||[]).forEach(e.addRemoteTextTrack.bind(e)),e.trigger("playlistitem",t.originalValue||t),r){const t=e.play();void 0!==t&&"function"==typeof t.then&&t.then(null,(e=>{}))}l(e,e.playlist.autoadvance_.delay)}))})(c.player_,a[c.currentIndex_]),t>0&&e.poster(""),c.currentIndex_;const r=c.player_.currentSrc()||"";if(c.currentPlaylistItemId_){const e=((e,t)=>{for(let r=0;r<e.length;r++)if(e[r].playlistItemId_===t)return r;return-1})(a,c.currentPlaylistItemId_),t=a[e];if(t&&Array.isArray(t.sources)&&u([t],r)>-1)return c.currentIndex_=e,c.currentIndex_;c.currentPlaylistItemId_=null}return c.currentIndex_=c.indexOf(r),c.currentIndex_},c.add=(t,r)=>{if(s)throw new Error("cannot modify a playlist that is currently changing");("number"!=typeof r||r<0||r>a.length)&&(r=a.length),Array.isArray(t)||(t=[t]),a.splice(r,0,...o(t)),e.trigger({type:"playlistchange",action:"add"}),e.trigger({type:"playlistadd",count:t.length,index:r})},c.remove=(t,r=1)=>{if(s)throw new Error("cannot modify a playlist that is currently changing");"number"!=typeof t||t<0||t>a.length||(a.splice(t,r),e.trigger({type:"playlistchange",action:"remove"}),e.trigger({type:"playlistremove",count:r,index:t}))},c.contains=e=>-1!==c.indexOf(e),c.indexOf=e=>{if("string"==typeof e)return u(a,e);const t=Array.isArray(e)?e:e.sources;for(let e=0;e<t.length;e++){const r=t[e];if("string"==typeof r)return u(a,r);if(r.src)return u(a,r.src)}return-1},c.currentIndex=()=>c.currentItem(),c.lastIndex=()=>a.length-1,c.nextIndex=()=>{const e=c.currentItem();if(-1===e)return-1;const t=c.lastIndex();return c.repeat_&&e===t?0:Math.min(e+1,t)},c.previousIndex=()=>{const e=c.currentItem();return-1===e?-1:c.repeat_&&0===e?c.lastIndex():Math.max(e-1,0)},c.first=()=>{if(s)return;const e=c.currentItem(0);if(a.length)return a[e].originalValue||a[e];c.currentIndex_=-1},c.last=()=>{if(s)return;const e=c.currentItem(c.lastIndex());if(a.length)return a[e].originalValue||a[e];c.currentIndex_=-1},c.next=()=>{if(s)return;const e=c.nextIndex();if(e!==c.currentIndex_){const t=c.currentItem(e);return a[t].originalValue||a[t]}},c.previous=()=>{if(s)return;const e=c.previousIndex();if(e!==c.currentIndex_){const t=c.currentItem(e);return a[t].originalValue||a[t]}},c.autoadvance=e=>{l(c.player_,e)},c.repeat=e=>void 0===e?c.repeat_:"boolean"==typeof e?(c.repeat_=!!e,c.repeat_):void r.default.log.error("videojs-playlist: Invalid value for repeat",e),c.sort=t=>{a.length&&(a.sort(t),s||e.trigger("playlistsorted"))},c.reverse=()=>{a.length&&(a.reverse(),s||e.trigger("playlistsorted"))},c.shuffle=({rest:t}={})=>{let r=0,n=a;t&&(r=c.currentIndex_+1,n=a.slice(r)),n.length<=1||((e=>{let t=-1;const r=e.length-1;for(;++t<e.length;){const n=t+Math.floor(Math.random()*(r-t+1)),l=e[n];e[n]=e[t],e[t]=l}})(n),t&&a.splice(...[r,n.length].concat(n)),s||e.trigger("playlistsorted"))},Array.isArray(t)?c(t,i):a=[],c}const d=function(e,t){c(this,e,t)};return(r.default.registerPlugin||r.default.plugin)("playlist",d),d.VERSION="5.1.0",d}));

@@ -5,10 +5,4 @@ # video.js Playlist API

A playlist is an array of playlist items. A playlist item is an object with the following properties:
A playlist is an array of playlist items. Usually, a playlist item is an object with an array of `sources`, but it could also be a primitive value like a string.
| Property | Type | Optional | Description |
| ------------ | ------ | -------- | -------------------------------------------------- |
| `sources` | Array | | An array of sources that video.js understands. |
| `poster` | String | ✓ | A poster image to display for these sources. |
| `textTracks` | Array | ✓ | An array of text tracks that Video.js understands. |
## Methods

@@ -24,30 +18,30 @@ ### `player.playlist([Array newList], [Number newIndex]) -> Array`

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}, {
sources: [{
src: 'http://vjs.zencdn.net/v/oceans.mp4',
src: '//vjs.zencdn.net/v/oceans.mp4',
type: 'video/mp4'
}],
poster: 'http://www.videojs.com/img/poster.jpg'
poster: '//www.videojs.com/img/poster.jpg'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/movie.mp4',
src: '//media.w3.org/2010/05/bunny/movie.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/video/movie_300.mp4',
src: '//media.w3.org/2010/05/video/movie_300.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/video/poster.png'
poster: '//media.w3.org/2010/05/video/poster.png'
}]);

@@ -58,6 +52,6 @@ // [{ ... }, ... ]

sources: [{
src: 'http://media.w3.org/2010/05/video/movie_300.mp4',
src: '//media.w3.org/2010/05/video/movie_300.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/video/poster.png'
poster: '//media.w3.org/2010/05/video/poster.png'
}]);

@@ -73,12 +67,12 @@ // [{ ... }]

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}], 1);

@@ -99,12 +93,12 @@ // [{ ... }]

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}];

@@ -120,3 +114,3 @@

player.src('http://example.com/video.mp4');
player.src('//example.com/video.mp4');
player.playlist.currentItem();

@@ -126,2 +120,82 @@ // -1

#### `player.playlist.add(String|Object|Array items, [Number index])`
Adds one or more items to the current playlist without replacing the playlist.
Fires the `playlistadd` event.
Calling this method during the `duringplaylistchange` event throws an error.
```js
var samplePlaylist = [{
sources: [{
src: 'sintel.mp4',
type: 'video/mp4'
}]
}];
player.playlist(samplePlaylist);
// Playlist will contain two items after this call: sintel.mp4, bbb.mp4
player.add({
sources: [{
src: 'bbb.mp4',
type: 'video/mp4'
}]
});
// Playlist will contain four items after this call: sintel.mp4, tears.mp4, test.mp4, and bbb.mp4
player.add([{
sources: [{
src: 'tears.mp4',
type: 'video/mp4'
}]
}, {
sources: [{
src: 'test.mp4',
type: 'video/mp4'
}]
}], 1);
```
#### `player.playlist.remove(Number index, [Number count=1])`
Removes one or more items from the current playlist without replacing the playlist. By default, if `count` is not provided, one item will be removed.
Fires the `playlistremove` event.
Calling this method during the `duringplaylistchange` event throws an error.
```js
var samplePlaylist = [{
sources: [{
src: 'sintel.mp4',
type: 'video/mp4'
}]
}, {
sources: [{
src: 'bbb.mp4',
type: 'video/mp4'
}]
}, {
sources: [{
src: 'tears.mp4',
type: 'video/mp4'
}]
}, {
sources: [{
src: 'test.mp4',
type: 'video/mp4'
}]
}];
player.playlist(samplePlaylist);
// Playlist will contain three items after this call: bbb.mp4, tears.mp4, and test.mp4
player.remove(0);
// Playlist will contain one item after this call: bbb.mp4
player.remove(1, 2);
```
#### `player.playlist.contains(String|Object|Array value) -> Boolean`

@@ -134,7 +208,7 @@

```js
player.playlist.contains('http://media.w3.org/2010/05/sintel/trailer.mp4');
player.playlist.contains('//media.w3.org/2010/05/sintel/trailer.mp4');
// true
player.playlist.contains([{
src: 'http://media.w3.org/2010/05/sintel/poster.png',
src: '//media.w3.org/2010/05/sintel/poster.png',
type: 'image/png'

@@ -146,3 +220,3 @@ }]);

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'

@@ -161,7 +235,7 @@ }]

```js
player.playlist.indexOf('http://media.w3.org/2010/05/bunny/trailer.mp4');
player.playlist.indexOf('//media.w3.org/2010/05/bunny/trailer.mp4');
// 1
player.playlist.indexOf([{
src: 'http://media.w3.org/2010/05/bunny/movie.mp4',
src: '//media.w3.org/2010/05/bunny/movie.mp4',
type: 'video/mp4'

@@ -173,3 +247,3 @@ }]);

sources: [{
src: 'http://media.w3.org/2010/05/video/movie_300.mp4',
src: '//media.w3.org/2010/05/video/movie_300.mp4',
type: 'video/mp4'

@@ -188,12 +262,12 @@ }]

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}];

@@ -216,12 +290,12 @@

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}];

@@ -242,3 +316,3 @@

player.src('http://example.com/video.mp4');
player.src('//example.com/video.mp4');
player.playlist.nextIndex();

@@ -259,12 +333,12 @@ // -1

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}];

@@ -285,3 +359,3 @@

player.src('http://example.com/video.mp4');
player.src('//example.com/video.mp4');
player.playlist.previousIndex();

@@ -298,12 +372,12 @@ // -1

sources: [{
src: 'http://media.w3.org/2010/05/sintel/trailer.mp4',
src: '//media.w3.org/2010/05/sintel/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/sintel/poster.png'
poster: '//media.w3.org/2010/05/sintel/poster.png'
}, {
sources: [{
src: 'http://media.w3.org/2010/05/bunny/trailer.mp4',
src: '//media.w3.org/2010/05/bunny/trailer.mp4',
type: 'video/mp4'
}],
poster: 'http://media.w3.org/2010/05/bunny/poster.png'
poster: '//media.w3.org/2010/05/bunny/poster.png'
}];

@@ -484,5 +558,5 @@

This event is fired _asynchronously_ whenever the contents of the playlist are changed (i.e., when `player.playlist()` is called with an argument) - except the first time.
This event is fired whenever the contents of the playlist are changed (i.e., when `player.playlist()` is called with an argument) - except the first time. Additionally, it is fired when item(s) are added or removed from the playlist.
It is fired asynchronously to let the browser start loading the first video in the new playlist.
In cases where a change to the playlist may result in a new video source being loaded, it is fired asynchronously to let the browser start loading the first video in the new playlist.

@@ -501,2 +575,12 @@ ```js

#### `action`
Each `playlistchange` event object has an additional `action` property. This can help you identify the action that caused the `playlistchange` event to be triggered. It will be one of:
* `add`: One or more items were added to the playlist
* `change`: The entire playlist was replaced
* `remove`: One or more items were removed from the playlist
This is considered temporary/deprecated behavior because future implementations should only fire the `playlistadd` and `playlistremove` events.
#### Backward Compatibility

@@ -516,2 +600,10 @@

### `playlistadd`
One or more items were added to the playlist via the `playlist.add()` method.
### `playlistremove`
One or more items were removed from the playlist via the `playlist.remove()` method.
### `beforeplaylistitem`

@@ -527,2 +619,2 @@

This event is fired when any method is called that changes the order of playlist items - `sort()`, `reverse()`, or `shuffle()`.
This event is fired when any method is called that changes the order of playlist items - `sort()`, `reverse()`, or `shuffle()`.
{
"name": "videojs-playlist",
"version": "5.0.1",
"version": "5.1.0",
"description": "Playlist plugin for Video.js",

@@ -48,3 +48,3 @@ "main": "dist/videojs-playlist.cjs.js",

"global": "^4.3.2",
"video.js": "^6 || ^7"
"video.js": "^6 || ^7 || ^8"
},

@@ -51,0 +51,0 @@ "devDependencies": {

@@ -5,52 +5,39 @@ import videojs from 'video.js';

// Shared incrementing GUID for playlist items.
let guid = 1;
/**
* Returns whether a playlist item is an object of any kind, excluding null.
* Transform any primitive playlist item value into an object.
*
* @private
* For non-object values, adds a property to the transformed item containing
* original value passed.
*
* @param {Object}
* value to be checked
* For all items, add a unique ID to each playlist item object. This id is
* used to determine the index of an item in the playlist array in cases where
* there are multiple otherwise identical items.
*
* @return {boolean}
* The result
*/
const isItemObject = (value) => {
return !!value && typeof value === 'object';
};
/**
* Look through an array of playlist items and transform any primitive
* as well as null values to objects. This method also adds a property
* to the transformed item containing original value passed in an input list.
* @param {Object} newItem
* An playlist item object, but accepts any value.
*
* @private
*
* @param {Array} arr
* An array of playlist items
*
* @return {Array}
* A new array with transformed items
* @return {Object}
*/
const transformPrimitiveItems = (arr) => {
const list = [];
let tempItem;
const preparePlaylistItem = (newItem) => {
let item = newItem;
arr.forEach(item => {
if (!isItemObject(item)) {
tempItem = Object(item);
tempItem.originalValue = item;
} else {
tempItem = item;
}
if (!newItem || typeof newItem !== 'object') {
list.push(tempItem);
});
// Casting to an Object in this way allows primitives to retain their
// primitiveness (i.e. they will be cast back to primitives as needed).
item = Object(newItem);
item.originalValue = newItem;
}
return list;
item.playlistItemId_ = guid++;
return item;
};
/**
* Generate a unique id for each playlist item object. This id will be used to determine
* index of an item in the playlist array for cases where there are multiple items with
* the same source set.
* Look through an array of playlist items and passes them to
* preparePlaylistItem.
*

@@ -61,11 +48,8 @@ * @private

* An array of playlist items
*
* @return {Array}
* A new array with transformed items
*/
const generatePlaylistItemId = (arr) => {
let guid = 1;
const preparePlaylistItems = (arr) => arr.map(preparePlaylistItem);
arr.forEach(item => {
item.playlistItemId_ = guid++;
});
};
/**

@@ -241,3 +225,3 @@ * Look through an array of playlist items for a specific playlist item id.

*/
const playlist = player.playlist = (newList, newIndex = 0) => {
const playlist = player.playlist = (nextPlaylist, newIndex = 0) => {
if (changing) {

@@ -247,20 +231,9 @@ throw new Error('do not call playlist() during a playlist change');

if (Array.isArray(newList)) {
if (Array.isArray(nextPlaylist)) {
// @todo - Simplify this to `list.slice()` for v5.
const previousPlaylist = Array.isArray(list) ? list.slice() : null;
const nextPlaylist = newList.slice();
list = nextPlaylist.slice();
list = preparePlaylistItems(nextPlaylist);
// Transform any primitive and null values in an input list to objects
if (list.filter(item => isItemObject(item)).length !== list.length) {
list = transformPrimitiveItems(list);
}
// Add unique id to each playlist item. This id will be used
// to determine index in cases where there are more than one
// identical sources in the playlist.
generatePlaylistItemId(list);
// Mark the playlist as changing during the duringplaylistchange lifecycle.

@@ -294,3 +267,3 @@ changing = true;

player.setTimeout(() => {
player.trigger('playlistchange');
player.trigger({type: 'playlistchange', action: 'change'});
}, 0);

@@ -301,4 +274,4 @@ }

// Always return a shallow clone of the playlist list.
// We also want to return originalValue if any item in the list has it.
return list.map((item) => item.originalValue || item).slice();
// We also want to return originalValue if any item in the list has it.
return list.map((item) => item.originalValue || item);
};

@@ -392,2 +365,102 @@

/**
* A custom DOM event that is fired when new item(s) are added to the current
* playlist (rather than replacing the entire playlist).
*
* Unlike playlistchange, this is fired synchronously as it does not
* affect playback.
*
* @typedef {Object} PlaylistAddEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistadd"
*
* @property {number} count
* The number of items that were added.
*
* @property {number} index
* The starting index where item(s) were added.
*/
/**
* A custom DOM event that is fired when new item(s) are removed from the
* current playlist (rather than replacing the entire playlist).
*
* This is fired synchronously as it does not affect playback.
*
* @typedef {Object} PlaylistRemoveEvent
* @see [CustomEvent Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
* @property {string} type
* Always "playlistremove"
*
* @property {number} count
* The number of items that were removed.
*
* @property {number} index
* The starting index where item(s) were removed.
*/
/**
* Add one or more items to the playlist.
*
* @fires {PlaylistAddEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {string|Object|Array} item
* An item - or array of items - to be added to the playlist.
*
* @param {number} [index]
* If given as a valid value, injects the new playlist item(s)
* starting from that index. Otherwise, the item(s) are appended.
*/
playlist.add = (items, index) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
index = list.length;
}
if (!Array.isArray(items)) {
items = [items];
}
list.splice(index, 0, ...preparePlaylistItems(items));
// playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({type: 'playlistchange', action: 'add'});
player.trigger({type: 'playlistadd', count: items.length, index});
};
/**
* Remove one or more items from the playlist.
*
* @fires {PlaylistRemoveEvent}
* @throws {Error}
* If called during the duringplaylistchange event, throws an error.
*
* @param {number} index
* If a valid index in the current playlist, removes the item at that
* index from the playlist.
*
* If no valid index is given, nothing is removed from the playlist.
*
* @param {number} [count=1]
* The number of items to remove from the playlist.
*/
playlist.remove = (index, count = 1) => {
if (changing) {
throw new Error('cannot modify a playlist that is currently changing');
}
if (typeof index !== 'number' || index < 0 || index > list.length) {
return;
}
list.splice(index, count);
// playlistchange is triggered synchronously in this case because it does
// not change the current media source
player.trigger({type: 'playlistchange', action: 'remove'});
player.trigger({type: 'playlistremove', count, index});
};
/**
* Checks if the playlist contains a value.

@@ -731,3 +804,3 @@ *

if (Array.isArray(initialList)) {
playlist(initialList.slice(), initialIndex);
playlist(initialList, initialIndex);

@@ -734,0 +807,0 @@ // If there is no initial list given, silently set an empty array.

@@ -733,2 +733,3 @@ import QUnit from 'qunit';

assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'change');
});

@@ -911,1 +912,158 @@

});
QUnit.test('playlist.add will append an item by default', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistadd'], spy);
playlist.add(4);
assert.deepEqual(playlist(), [1, 2, 3, 4]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'add');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistadd');
assert.strictEqual(spy.secondCall.args[0].index, 3);
assert.strictEqual(spy.secondCall.args[0].count, 1);
});
QUnit.test('playlist.add can insert an item at a specific index', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistadd'], spy);
playlist.add(4, 1);
assert.deepEqual(playlist(), [1, 4, 2, 3]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'add');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistadd');
assert.strictEqual(spy.secondCall.args[0].index, 1);
assert.strictEqual(spy.secondCall.args[0].count, 1);
});
QUnit.test('playlist.add appends when specified index is out of bounds', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistadd'], spy);
playlist.add(4, 10);
assert.deepEqual(playlist(), [1, 2, 3, 4]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'add');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistadd');
assert.strictEqual(spy.secondCall.args[0].index, 3);
assert.strictEqual(spy.secondCall.args[0].count, 1);
});
QUnit.test('playlist.add can append multiple items', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistadd'], spy);
playlist.add([4, 5, 6]);
assert.deepEqual(playlist(), [1, 2, 3, 4, 5, 6]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'add');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistadd');
assert.strictEqual(spy.secondCall.args[0].index, 3);
assert.strictEqual(spy.secondCall.args[0].count, 3);
});
QUnit.test('playlist.add can insert multiple items at a specific index', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistadd'], spy);
playlist.add([4, 5, 6, 7], 1);
assert.deepEqual(playlist(), [1, 4, 5, 6, 7, 2, 3]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'add');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistadd');
assert.strictEqual(spy.secondCall.args[0].index, 1);
assert.strictEqual(spy.secondCall.args[0].count, 4);
});
QUnit.test('playlist.add throws an error duringplaylistchange', function(assert) {
const done = assert.async();
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
player.on('duringplaylistchange', (e) => {
assert.throws(() => playlist.add(4));
done();
});
playlist([4, 5, 6]);
});
QUnit.test('playlist.remove can remove an item at an index', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistremove'], spy);
playlist.remove(1);
assert.deepEqual(playlist(), [1, 3]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'remove');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistremove');
assert.strictEqual(spy.secondCall.args[0].index, 1);
assert.strictEqual(spy.secondCall.args[0].count, 1);
});
QUnit.test('playlist.remove does nothing when index is out of range', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistremove'], spy);
playlist.remove(4);
assert.deepEqual(playlist(), [1, 2, 3]);
assert.strictEqual(spy.callCount, 0);
});
QUnit.test('playlist.remove can remove multiple items at an index', function(assert) {
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
const spy = sinon.spy();
this.clock.tick(1);
player.on(['playlistchange', 'playlistremove'], spy);
playlist.remove(1, 2);
assert.deepEqual(playlist(), [1]);
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(spy.firstCall.args[0].type, 'playlistchange');
assert.strictEqual(spy.firstCall.args[0].action, 'remove');
assert.strictEqual(spy.secondCall.args[0].type, 'playlistremove');
assert.strictEqual(spy.secondCall.args[0].index, 1);
assert.strictEqual(spy.secondCall.args[0].count, 2);
});
QUnit.test('playlist.remove throws an error duringplaylistchange', function(assert) {
const done = assert.async();
const player = playerProxyMaker();
const playlist = playlistMaker(player, [1, 2, 3]);
player.on('duringplaylistchange', (e) => {
assert.throws(() => playlist.remove(0));
done();
});
playlist([4, 5, 6]);
});

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc