Conversation
Reviewer's GuideThis PR upgrades the embedded Plyr player to version 9.0.2 by modernizing its distributed JavaScript and CSS assets. It replaces shorthand boolean and negation patterns, normalizes function definitions, reorganizes utility sections, updates default settings (notably the icon URL and preview thumbnail credentials), and enhances the script loader to support ES module semantics. Core syntax cleanups include swapping innerText for textContent, simplifying catch blocks, and adopting Number.parseX for clarity. Class diagram for updated Plyr utility functionsclassDiagram
class Plyr {
+setup()
+destroy()
+togglePlay(input)
+rewind(seekTime)
+forward(seekTime)
+increaseVolume(step)
+decreaseVolume(step)
+toggleControls(toggle)
+on(event, callback)
+once(event, callback)
+off(event, callback)
+supports(type)
+toggleCaptions(input)
+currentTrack(input)
+language(input)
+quality(input)
+speed(input)
+volume(value)
+muted(mute)
+autoplay(input)
+poster(input)
+source(input)
+duration
+currentTime
}
class Utility {
+isElement(input)
+isEmpty(input)
+isUrl(input)
+cloneDeep(object)
+dedupe(array)
+supportsCSS(declaration)
+parseUrl(input, safe)
+parseVtt(vttDataString)
+fitRatio(ratio, outer)
+noop()
}
Plyr --> Utility
Class diagram for updated loadjs script loaderclassDiagram
class loadjs {
+ready(deps, args)
+done(bundleId)
+reset()
+isDefined(bundleId)
+loadjs(paths, arg1, arg2)
}
loadjs : Promise support for ES modules
loadjs : Handles module/nomodule semantics
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Pull Request Overview
This PR bumps the Plyr media player library from version 3.7.8 to 9.0.2, updating both the JavaScript and CSS files with significant code changes and modernization improvements.
- Updates the Plyr library to use more modern JavaScript syntax and improved code structure
- Fixes several browser compatibility issues and removes legacy code paths
- Updates default icon URL to point to the new version (3.8.3)
Reviewed Changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
plyr.js |
Major update with modernized JavaScript code, improved error handling, and cleaner syntax |
plyr.css |
Updated styles with minor improvements to CSS properties and layout |
BootstrapBlazor.Player.csproj |
Version bump from 9.0.1 to 9.0.2 |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| // ========================================================================== | ||
|
|
||
| const isIE = Boolean(window.document.documentMode); | ||
| const isEdge = /Edge/.test(navigator.userAgent); |
There was a problem hiding this comment.
The Edge browser detection using /Edge/ pattern may not work correctly with modern Edge browsers (Chromium-based) which use different user agent strings. Consider updating to detect modern Edge or removing legacy Edge-specific code.
| const isEdge = /Edge/.test(navigator.userAgent); | |
| const isEdge = /Edge\/|Edg\//.test(navigator.userAgent); |
| const isWebKit = 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent); | ||
| // navigator.platform may be deprecated but this check is still required | ||
| const isIPadOS = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1; | ||
| const isIos = /iPad|iPhone|iPod/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1; |
There was a problem hiding this comment.
iOS detection using user agent string is fragile and may not work reliably across all iOS devices and versions. Consider using feature detection instead of user agent sniffing where possible.
| const isIos = /iPad|iPhone|iPod/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1; | |
| const isIos = ( | |
| [ | |
| 'iPad', | |
| 'iPhone', | |
| 'iPod' | |
| ].includes(navigator.platform) | |
| || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) | |
| ); |
There was a problem hiding this comment.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/components/BootstrapBlazor.Player/wwwroot/plyr.js:5452` </location>
<code_context>
* If matched, the hash is available in capture group 4
*/
- const regex = /^.*(vimeo.com\/|video\/)(\d+)(\?.*&*h=|\/)+([\d,a-f]+)/;
+ const regex = /^.*(vimeo.com\/|video\/)(\d+)(\?.*h=|\/)+([\d,a-f]+)/;
const found = url.match(regex);
return found && found.length === 5 ? found[4] : null;
</code_context>
<issue_to_address>
Regex pattern may not match all valid Vimeo private video URLs.
The regex may fail if query parameters are ordered differently or if extra parameters are present. Please update the pattern for broader compatibility or clarify the expected URL structure.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
const regex = /^.*(vimeo.com\/|video\/)(\d+)(\?.*h=|\/)+([\d,a-f]+)/;
const found = url.match(regex);
return found && found.length === 5 ? found[4] : null;
=======
// Improved regex to match hash in various query parameter orders and allow extra parameters
const regex = /(?:vimeo\.com\/|video\/)(\d+)(?:\/([\d,a-f]+)|.*[?&]h=([\d,a-f]+))/i;
const found = url.match(regex);
// The hash may be in either capture group 2 (path) or 3 (query)
return found ? (found[2] || found[3] || null) : null;
>>>>>>> REPLACE
</suggested_fix>
### Comment 2
<location> `src/components/BootstrapBlazor.Player/wwwroot/plyr.js:5087` </location>
<code_context>
-
- function createCommonjsModule(fn, module) {
- return module = { exports: {} }, fn(module, module.exports), module.exports;
+ function getDefaultExportFromCjs (x) {
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
</code_context>
<issue_to_address>
Consider importing external dependencies and using concise arrow functions to reduce bundle size and improve maintainability.
```suggestion
Many of these changes bloat the bundle without adding features. Two quick wins:
1. Don’t inline the entire loadjs UMD – import it as a dependency
```js
// at top of file
import loadjs from 'loadjs';
function loadScript(url) {
return new Promise((resolve, reject) => {
loadjs(url, { success: resolve, error: reject });
});
}
```
Removing the 3.5 KLOC `createCommonjsModule`/`loadjs_umd` chunk will cut down the bundle drastically.
2. Restore terse arrow‐helpers for one‐liners instead of full named functions
```js
// before (expanded)
function isElement(input) {
return input !== null
&& typeof input === 'object'
&& input.nodeType === 1
&& typeof input.style === 'object'
&& typeof input.ownerDocument === 'object';
}
// after (concise)
const isElement = input =>
input != null &&
input.nodeType === 1 &&
typeof input.style === 'object' &&
typeof input.ownerDocument === 'object';
const isEmpty = input =>
input == null ||
((typeof input === 'string' || Array.isArray(input) || instanceOf(input, NodeList)) && !input.length) ||
(typeof input === 'object' && !Object.keys(input).length);
```
This removes dozens of lines of boilerplate and keeps everything just as readable.
If you need logical grouping, break the file into small modules (e.g. `utils/`, `loaders/`, `support/`) rather than injecting long “section headers.” That will preserve functionality and make maintenance far easier.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const regex = /^.*(vimeo.com\/|video\/)(\d+)(\?.*h=|\/)+([\d,a-f]+)/; | ||
| const found = url.match(regex); | ||
| return found && found.length === 5 ? found[4] : null; |
There was a problem hiding this comment.
suggestion: Regex pattern may not match all valid Vimeo private video URLs.
The regex may fail if query parameters are ordered differently or if extra parameters are present. Please update the pattern for broader compatibility or clarify the expected URL structure.
| const regex = /^.*(vimeo.com\/|video\/)(\d+)(\?.*h=|\/)+([\d,a-f]+)/; | |
| const found = url.match(regex); | |
| return found && found.length === 5 ? found[4] : null; | |
| // Improved regex to match hash in various query parameter orders and allow extra parameters | |
| const regex = /(?:vimeo\.com\/|video\/)(\d+)(?:\/([\d,a-f]+)|.*[?&]h=([\d,a-f]+))/i; | |
| const found = url.match(regex); | |
| // The hash may be in either capture group 2 (path) or 3 (query) | |
| return found ? (found[2] || found[3] || null) : null; |
|
|
||
| function createCommonjsModule(fn, module) { | ||
| return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
| function getDefaultExportFromCjs (x) { |
There was a problem hiding this comment.
issue (complexity): Consider importing external dependencies and using concise arrow functions to reduce bundle size and improve maintainability.
| function getDefaultExportFromCjs (x) { | |
| Many of these changes bloat the bundle without adding features. Two quick wins: | |
| 1. Don’t inline the entire loadjs UMD – import it as a dependency | |
| ```js | |
| // at top of file | |
| import loadjs from 'loadjs'; | |
| function loadScript(url) { | |
| return new Promise((resolve, reject) => { | |
| loadjs(url, { success: resolve, error: reject }); | |
| }); | |
| } |
Removing the 3.5 KLOC createCommonjsModule/loadjs_umd chunk will cut down the bundle drastically.
- Restore terse arrow‐helpers for one‐liners instead of full named functions
This removes dozens of lines of boilerplate and keeps everything just as readable.
// before (expanded) function isElement(input) { return input !== null && typeof input === 'object' && input.nodeType === 1 && typeof input.style === 'object' && typeof input.ownerDocument === 'object'; } // after (concise) const isElement = input => input != null && input.nodeType === 1 && typeof input.style === 'object' && typeof input.ownerDocument === 'object'; const isEmpty = input => input == null || ((typeof input === 'string' || Array.isArray(input) || instanceOf(input, NodeList)) && !input.length) || (typeof input === 'object' && !Object.keys(input).length);
If you need logical grouping, break the file into small modules (e.g. utils/, loaders/, support/) rather than injecting long “section headers.” That will preserve functionality and make maintenance far easier.
| function _defineProperty$1(e, r, t) { | ||
| return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { | ||
| value: t, | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true | ||
| }) : e[r] = t, e; | ||
| } |
There was a problem hiding this comment.
issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)
Explanation
Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers. Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you should use function expressions, which create functions in-scope.| } | ||
| return obj; | ||
| function _defineProperty$1(e, r, t) { | ||
| return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { |
There was a problem hiding this comment.
issue (code-quality): Don't reassign parameter - r (dont-reassign-parameters)
Explanation
Reassigning parameters can lead to unexpected behavior, especially when accessing the arguments object. It can also cause optimization issues, especially in V8.From the Airbnb JavaScript Style Guide
| function _toPrimitive(t, r) { | ||
| if ("object" != typeof t || !t) return t; | ||
| var e = t[Symbol.toPrimitive]; | ||
| if (void 0 !== e) { | ||
| var i = e.call(t, r); | ||
| if ("object" != typeof i) return i; | ||
| throw new TypeError("@@toPrimitive must return a primitive value."); | ||
| } | ||
| return (hint === "string" ? String : Number)(input); | ||
| return ("string" === r ? String : Number)(t); | ||
| } |
There was a problem hiding this comment.
issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)
Explanation
Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers. Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you should use function expressions, which create functions in-scope.| bundleIdCache = {}, | ||
| bundleResultCache = {}, | ||
| bundleCallbackQueue = {}; | ||
| var loadjs_umd$1 = {exports: {}}; |
There was a problem hiding this comment.
issue (code-quality): Use const or let instead of var. (avoid-using-var)
Explanation
`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code). `let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than function-scoped.From the Airbnb JavaScript Style Guide
| bundleCallbackQueue = {}; | ||
| var loadjs_umd$1 = {exports: {}}; | ||
|
|
||
| var loadjs_umd = loadjs_umd$1.exports; |
There was a problem hiding this comment.
issue (code-quality): Use const or let instead of var. (avoid-using-var)
Explanation
`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code). `let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than function-scoped.From the Airbnb JavaScript Style Guide
| var loadjs_umd$1 = {exports: {}}; | ||
|
|
||
| var loadjs_umd = loadjs_umd$1.exports; | ||
| var hasRequiredLoadjs_umd; |
There was a problem hiding this comment.
issue (code-quality): Use const or let instead of var. (avoid-using-var)
Explanation
`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code). `let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than function-scoped.From the Airbnb JavaScript Style Guide
| function requireLoadjs_umd() { | ||
| if (hasRequiredLoadjs_umd) return loadjs_umd$1.exports; | ||
| hasRequiredLoadjs_umd = 1; | ||
| (function (module, exports) { | ||
| (function (root, factory) { | ||
| { | ||
| module.exports = factory(); | ||
| } | ||
| })(loadjs_umd, function () { | ||
| /** | ||
| * Global dependencies. | ||
| * @global {Object} document - DOM | ||
| */ | ||
|
|
||
| var devnull = function () {}, | ||
| bundleIdCache = {}, | ||
| bundleResultCache = {}, | ||
| bundleCallbackQueue = {}; | ||
|
|
||
| /** | ||
| * Subscribe to bundle load event. | ||
| * @param {string[]} bundleIds - Bundle ids | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function subscribe(bundleIds, callbackFn) { | ||
| // listify | ||
| bundleIds = bundleIds.push ? bundleIds : [bundleIds]; | ||
| var depsNotFound = [], | ||
| i = bundleIds.length, | ||
| numWaiting = i, | ||
| fn, | ||
| bundleId, | ||
| r, | ||
| q; | ||
|
|
||
| // define callback function | ||
| fn = function (bundleId, pathsNotFound) { | ||
| if (pathsNotFound.length) depsNotFound.push(bundleId); | ||
| numWaiting--; | ||
| if (!numWaiting) callbackFn(depsNotFound); | ||
| }; | ||
|
|
||
| /** | ||
| * Subscribe to bundle load event. | ||
| * @param {string[]} bundleIds - Bundle ids | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function subscribe(bundleIds, callbackFn) { | ||
| // listify | ||
| bundleIds = bundleIds.push ? bundleIds : [bundleIds]; | ||
| var depsNotFound = [], | ||
| i = bundleIds.length, | ||
| numWaiting = i, | ||
| fn, | ||
| bundleId, | ||
| r, | ||
| q; | ||
|
|
||
| // define callback function | ||
| fn = function (bundleId, pathsNotFound) { | ||
| if (pathsNotFound.length) depsNotFound.push(bundleId); | ||
| numWaiting--; | ||
| if (!numWaiting) callbackFn(depsNotFound); | ||
| }; | ||
| // register callback | ||
| while (i--) { | ||
| bundleId = bundleIds[i]; | ||
|
|
||
| // register callback | ||
| while (i--) { | ||
| bundleId = bundleIds[i]; | ||
| // execute callback if in result cache | ||
| r = bundleResultCache[bundleId]; | ||
| if (r) { | ||
| fn(bundleId, r); | ||
| continue; | ||
| } | ||
|
|
||
| // execute callback if in result cache | ||
| r = bundleResultCache[bundleId]; | ||
| if (r) { | ||
| fn(bundleId, r); | ||
| continue; | ||
| // add to callback queue | ||
| q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || []; | ||
| q.push(fn); | ||
| } | ||
|
|
||
| // add to callback queue | ||
| q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || []; | ||
| q.push(fn); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Publish bundle load event. | ||
| * @param {string} bundleId - Bundle id | ||
| * @param {string[]} pathsNotFound - List of files not found | ||
| */ | ||
| function publish(bundleId, pathsNotFound) { | ||
| // exit if id isn't defined | ||
| if (!bundleId) return; | ||
| var q = bundleCallbackQueue[bundleId]; | ||
|
|
||
| // cache result | ||
| bundleResultCache[bundleId] = pathsNotFound; | ||
| /** | ||
| * Publish bundle load event. | ||
| * @param {string} bundleId - Bundle id | ||
| * @param {string[]} pathsNotFound - List of files not found | ||
| */ | ||
| function publish(bundleId, pathsNotFound) { | ||
| // exit if id isn't defined | ||
| if (!bundleId) return; | ||
| var q = bundleCallbackQueue[bundleId]; | ||
|
|
||
| // exit if queue is empty | ||
| if (!q) return; | ||
|
|
||
| // empty callback queue | ||
| while (q.length) { | ||
| q[0](bundleId, pathsNotFound); | ||
| q.splice(0, 1); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Execute callbacks. | ||
| * @param {Object or Function} args - The callback args | ||
| * @param {string[]} depsNotFound - List of dependencies not found | ||
| */ | ||
| function executeCallbacks(args, depsNotFound) { | ||
| // accept function as argument | ||
| if (args.call) args = { | ||
| success: args | ||
| }; | ||
| // cache result | ||
| bundleResultCache[bundleId] = pathsNotFound; | ||
|
|
||
| // success and error callbacks | ||
| if (depsNotFound.length) (args.error || devnull)(depsNotFound);else (args.success || devnull)(args); | ||
| } | ||
| // exit if queue is empty | ||
| if (!q) return; | ||
|
|
||
| /** | ||
| * Load individual file. | ||
| * @param {string} path - The file path | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function loadFile(path, callbackFn, args, numTries) { | ||
| var doc = document, | ||
| async = args.async, | ||
| maxTries = (args.numRetries || 0) + 1, | ||
| beforeCallbackFn = args.before || devnull, | ||
| pathname = path.replace(/[\?|#].*$/, ''), | ||
| pathStripped = path.replace(/^(css|img)!/, ''), | ||
| isLegacyIECss, | ||
| e; | ||
| numTries = numTries || 0; | ||
| if (/(^css!|\.css$)/.test(pathname)) { | ||
| // css | ||
| e = doc.createElement('link'); | ||
| e.rel = 'stylesheet'; | ||
| e.href = pathStripped; | ||
|
|
||
| // tag IE9+ | ||
| isLegacyIECss = 'hideFocus' in e; | ||
|
|
||
| // use preload in IE Edge (to detect load errors) | ||
| if (isLegacyIECss && e.relList) { | ||
| isLegacyIECss = 0; | ||
| e.rel = 'preload'; | ||
| e.as = 'style'; | ||
| // empty callback queue | ||
| while (q.length) { | ||
| q[0](bundleId, pathsNotFound); | ||
| q.splice(0, 1); | ||
| } | ||
| } else if (/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(pathname)) { | ||
| // image | ||
| e = doc.createElement('img'); | ||
| e.src = pathStripped; | ||
| } else { | ||
| // javascript | ||
| e = doc.createElement('script'); | ||
| e.src = path; | ||
| e.async = async === undefined ? true : async; | ||
| } | ||
| e.onload = e.onerror = e.onbeforeload = function (ev) { | ||
| var result = ev.type[0]; | ||
|
|
||
| // treat empty stylesheets as failures to get around lack of onerror | ||
| // support in IE9-11 | ||
| if (isLegacyIECss) { | ||
| try { | ||
| if (!e.sheet.cssText.length) result = 'e'; | ||
| } catch (x) { | ||
| // sheets objects created from load errors don't allow access to | ||
| // `cssText` (unless error is Code:18 SecurityError) | ||
| if (x.code != 18) result = 'e'; | ||
| /** | ||
| * Execute callbacks. | ||
| * @param {Object or Function} args - The callback args | ||
| * @param {string[]} depsNotFound - List of dependencies not found | ||
| */ | ||
| function executeCallbacks(args, depsNotFound) { | ||
| // accept function as argument | ||
| if (args.call) args = { | ||
| success: args | ||
| }; | ||
|
|
||
| // success and error callbacks | ||
| if (depsNotFound.length) (args.error || devnull)(depsNotFound);else (args.success || devnull)(args); | ||
| } | ||
|
|
||
| /** | ||
| * Load individual file. | ||
| * @param {string} path - The file path | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function loadFile(path, callbackFn, args, numTries) { | ||
| var doc = document, | ||
| async = args.async, | ||
| maxTries = (args.numRetries || 0) + 1, | ||
| beforeCallbackFn = args.before || devnull, | ||
| pathname = path.replace(/[\?|#].*$/, ''), | ||
| pathStripped = path.replace(/^(css|img|module|nomodule)!/, ''), | ||
| isLegacyIECss, | ||
| hasModuleSupport, | ||
| e; | ||
| numTries = numTries || 0; | ||
| if (/(^css!|\.css$)/.test(pathname)) { | ||
| // css | ||
| e = doc.createElement('link'); | ||
| e.rel = 'stylesheet'; | ||
| e.href = pathStripped; | ||
|
|
||
| // tag IE9+ | ||
| isLegacyIECss = 'hideFocus' in e; | ||
|
|
||
| // use preload in IE Edge (to detect load errors) | ||
| if (isLegacyIECss && e.relList) { | ||
| isLegacyIECss = 0; | ||
| e.rel = 'preload'; | ||
| e.as = 'style'; | ||
| } | ||
| } else if (/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(pathname)) { | ||
| // image | ||
| e = doc.createElement('img'); | ||
| e.src = pathStripped; | ||
| } else { | ||
| // javascript | ||
| e = doc.createElement('script'); | ||
| e.src = pathStripped; | ||
| e.async = async === undefined ? true : async; | ||
|
|
||
| // handle es modules | ||
| // modern browsers: | ||
| // module: add to dom with type="module" | ||
| // nomodule: call success() callback without adding to dom | ||
| // legacy browsers: | ||
| // module: call success() callback without adding to dom | ||
| // nomodule: add to dom with default type ("text/javascript") | ||
| hasModuleSupport = 'noModule' in e; | ||
| if (/^module!/.test(pathname)) { | ||
| if (!hasModuleSupport) return callbackFn(path, 'l'); | ||
| e.type = "module"; | ||
| } else if (/^nomodule!/.test(pathname) && hasModuleSupport) return callbackFn(path, 'l'); | ||
| } | ||
| e.onload = e.onerror = e.onbeforeload = function (ev) { | ||
| var result = ev.type[0]; | ||
|
|
||
| // treat empty stylesheets as failures to get around lack of onerror | ||
| // support in IE9-11 | ||
| if (isLegacyIECss) { | ||
| try { | ||
| if (!e.sheet.cssText.length) result = 'e'; | ||
| } catch (x) { | ||
| // sheets objects created from load errors don't allow access to | ||
| // `cssText` (unless error is Code:18 SecurityError) | ||
| if (x.code != 18) result = 'e'; | ||
| } | ||
| } | ||
|
|
||
| // handle retries in case of load failure | ||
| if (result == 'e') { | ||
| // increment counter | ||
| numTries += 1; | ||
| // handle retries in case of load failure | ||
| if (result == 'e') { | ||
| // increment counter | ||
| numTries += 1; | ||
|
|
||
| // exit function and try again | ||
| if (numTries < maxTries) { | ||
| return loadFile(path, callbackFn, args, numTries); | ||
| // exit function and try again | ||
| if (numTries < maxTries) { | ||
| return loadFile(path, callbackFn, args, numTries); | ||
| } | ||
| } else if (e.rel == 'preload' && e.as == 'style') { | ||
| // activate preloaded stylesheets | ||
| return e.rel = 'stylesheet'; // jshint ignore:line | ||
| } | ||
| } else if (e.rel == 'preload' && e.as == 'style') { | ||
| // activate preloaded stylesheets | ||
| return e.rel = 'stylesheet'; // jshint ignore:line | ||
| } | ||
|
|
||
| // execute callback | ||
| callbackFn(path, result, ev.defaultPrevented); | ||
| }; | ||
| // execute callback | ||
| callbackFn(path, result, ev.defaultPrevented); | ||
| }; | ||
|
|
||
| // add to document (unless callback returns `false`) | ||
| if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e); | ||
| } | ||
| // add to document (unless callback returns `false`) | ||
| if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e); | ||
| } | ||
|
|
||
| /** | ||
| * Load multiple files. | ||
| * @param {string[]} paths - The file paths | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function loadFiles(paths, callbackFn, args) { | ||
| // listify paths | ||
| paths = paths.push ? paths : [paths]; | ||
| var numWaiting = paths.length, | ||
| x = numWaiting, | ||
| pathsNotFound = [], | ||
| fn, | ||
| i; | ||
|
|
||
| // define callback function | ||
| fn = function (path, result, defaultPrevented) { | ||
| // handle error | ||
| if (result == 'e') pathsNotFound.push(path); | ||
|
|
||
| // handle beforeload event. If defaultPrevented then that means the load | ||
| // will be blocked (ex. Ghostery/ABP on Safari) | ||
| if (result == 'b') { | ||
| if (defaultPrevented) pathsNotFound.push(path);else return; | ||
| } | ||
| numWaiting--; | ||
| if (!numWaiting) callbackFn(pathsNotFound); | ||
| }; | ||
|
|
||
| /** | ||
| * Load multiple files. | ||
| * @param {string[]} paths - The file paths | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function loadFiles(paths, callbackFn, args) { | ||
| // listify paths | ||
| paths = paths.push ? paths : [paths]; | ||
| var numWaiting = paths.length, | ||
| x = numWaiting, | ||
| pathsNotFound = [], | ||
| fn, | ||
| i; | ||
|
|
||
| // define callback function | ||
| fn = function (path, result, defaultPrevented) { | ||
| // handle error | ||
| if (result == 'e') pathsNotFound.push(path); | ||
|
|
||
| // handle beforeload event. If defaultPrevented then that means the load | ||
| // will be blocked (ex. Ghostery/ABP on Safari) | ||
| if (result == 'b') { | ||
| if (defaultPrevented) pathsNotFound.push(path);else return; | ||
| } | ||
| numWaiting--; | ||
| if (!numWaiting) callbackFn(pathsNotFound); | ||
| }; | ||
| // load scripts | ||
| for (i = 0; i < x; i++) loadFile(paths[i], fn, args); | ||
| } | ||
|
|
||
| // load scripts | ||
| for (i = 0; i < x; i++) loadFile(paths[i], fn, args); | ||
| } | ||
| /** | ||
| * Initiate script load and register bundle. | ||
| * @param {(string|string[])} paths - The file paths | ||
| * @param {(string|Function|Object)} [arg1] - The (1) bundleId or (2) success | ||
| * callback or (3) object literal with success/error arguments, numRetries, | ||
| * etc. | ||
| * @param {(Function|Object)} [arg2] - The (1) success callback or (2) object | ||
| * literal with success/error arguments, numRetries, etc. | ||
| */ | ||
| function loadjs(paths, arg1, arg2) { | ||
| var bundleId, args; | ||
|
|
||
| /** | ||
| * Initiate script load and register bundle. | ||
| * @param {(string|string[])} paths - The file paths | ||
| * @param {(string|Function|Object)} [arg1] - The (1) bundleId or (2) success | ||
| * callback or (3) object literal with success/error arguments, numRetries, | ||
| * etc. | ||
| * @param {(Function|Object)} [arg2] - The (1) success callback or (2) object | ||
| * literal with success/error arguments, numRetries, etc. | ||
| */ | ||
| function loadjs(paths, arg1, arg2) { | ||
| var bundleId, args; | ||
| // bundleId (if string) | ||
| if (arg1 && arg1.trim) bundleId = arg1; | ||
|
|
||
| // bundleId (if string) | ||
| if (arg1 && arg1.trim) bundleId = arg1; | ||
| // args (default is {}) | ||
| args = (bundleId ? arg2 : arg1) || {}; | ||
|
|
||
| // args (default is {}) | ||
| args = (bundleId ? arg2 : arg1) || {}; | ||
| // throw error if bundle is already defined | ||
| if (bundleId) { | ||
| if (bundleId in bundleIdCache) { | ||
| throw "LoadJS"; | ||
| } else { | ||
| bundleIdCache[bundleId] = true; | ||
| } | ||
| } | ||
| function loadFn(resolve, reject) { | ||
| loadFiles(paths, function (pathsNotFound) { | ||
| // execute callbacks | ||
| executeCallbacks(args, pathsNotFound); | ||
|
|
||
| // resolve Promise | ||
| if (resolve) { | ||
| executeCallbacks({ | ||
| success: resolve, | ||
| error: reject | ||
| }, pathsNotFound); | ||
| } | ||
|
|
||
| // throw error if bundle is already defined | ||
| if (bundleId) { | ||
| if (bundleId in bundleIdCache) { | ||
| throw "LoadJS"; | ||
| } else { | ||
| bundleIdCache[bundleId] = true; | ||
| // publish bundle load event | ||
| publish(bundleId, pathsNotFound); | ||
| }, args); | ||
| } | ||
| if (args.returnPromise) return new Promise(loadFn);else loadFn(); | ||
| } | ||
| function loadFn(resolve, reject) { | ||
| loadFiles(paths, function (pathsNotFound) { | ||
| // execute callbacks | ||
| executeCallbacks(args, pathsNotFound); | ||
|
|
||
| // resolve Promise | ||
| if (resolve) { | ||
| executeCallbacks({ | ||
| success: resolve, | ||
| error: reject | ||
| }, pathsNotFound); | ||
| } | ||
|
|
||
| // publish bundle load event | ||
| publish(bundleId, pathsNotFound); | ||
| }, args); | ||
| } | ||
| if (args.returnPromise) return new Promise(loadFn);else loadFn(); | ||
| } | ||
| /** | ||
| * Execute callbacks when dependencies have been satisfied. | ||
| * @param {(string|string[])} deps - List of bundle ids | ||
| * @param {Object} args - success/error arguments | ||
| */ | ||
| loadjs.ready = function ready(deps, args) { | ||
| // subscribe to bundle load event | ||
| subscribe(deps, function (depsNotFound) { | ||
| // execute callbacks | ||
| executeCallbacks(args, depsNotFound); | ||
| }); | ||
| return loadjs; | ||
| }; | ||
|
|
||
| /** | ||
| * Execute callbacks when dependencies have been satisfied. | ||
| * @param {(string|string[])} deps - List of bundle ids | ||
| * @param {Object} args - success/error arguments | ||
| */ | ||
| loadjs.ready = function ready(deps, args) { | ||
| // subscribe to bundle load event | ||
| subscribe(deps, function (depsNotFound) { | ||
| // execute callbacks | ||
| executeCallbacks(args, depsNotFound); | ||
| }); | ||
| return loadjs; | ||
| }; | ||
| /** | ||
| * Manually satisfy bundle dependencies. | ||
| * @param {string} bundleId - The bundle id | ||
| */ | ||
| loadjs.done = function done(bundleId) { | ||
| publish(bundleId, []); | ||
| }; | ||
|
|
||
| /** | ||
| * Manually satisfy bundle dependencies. | ||
| * @param {string} bundleId - The bundle id | ||
| */ | ||
| loadjs.done = function done(bundleId) { | ||
| publish(bundleId, []); | ||
| }; | ||
| /** | ||
| * Reset loadjs dependencies statuses | ||
| */ | ||
| loadjs.reset = function reset() { | ||
| bundleIdCache = {}; | ||
| bundleResultCache = {}; | ||
| bundleCallbackQueue = {}; | ||
| }; | ||
|
|
||
| /** | ||
| * Reset loadjs dependencies statuses | ||
| */ | ||
| loadjs.reset = function reset() { | ||
| bundleIdCache = {}; | ||
| bundleResultCache = {}; | ||
| bundleCallbackQueue = {}; | ||
| }; | ||
| /** | ||
| * Determine if bundle has already been defined | ||
| * @param String} bundleId - The bundle id | ||
| */ | ||
| loadjs.isDefined = function isDefined(bundleId) { | ||
| return bundleId in bundleIdCache; | ||
| }; | ||
|
|
||
| /** | ||
| * Determine if bundle has already been defined | ||
| * @param String} bundleId - The bundle id | ||
| */ | ||
| loadjs.isDefined = function isDefined(bundleId) { | ||
| return bundleId in bundleIdCache; | ||
| }; | ||
| // export | ||
| return loadjs; | ||
| }); | ||
| })(loadjs_umd$1); | ||
| return loadjs_umd$1.exports; | ||
| } |
There was a problem hiding this comment.
issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)
Explanation
Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers. Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you should use function expressions, which create functions in-scope.| function subscribe(bundleIds, callbackFn) { | ||
| // listify | ||
| bundleIds = bundleIds.push ? bundleIds : [bundleIds]; | ||
| var depsNotFound = [], | ||
| i = bundleIds.length, | ||
| numWaiting = i, | ||
| fn, | ||
| bundleId, | ||
| r, | ||
| q; | ||
|
|
||
| // define callback function | ||
| fn = function (bundleId, pathsNotFound) { | ||
| if (pathsNotFound.length) depsNotFound.push(bundleId); | ||
| numWaiting--; | ||
| if (!numWaiting) callbackFn(depsNotFound); | ||
| }; | ||
|
|
||
| /** | ||
| * Subscribe to bundle load event. | ||
| * @param {string[]} bundleIds - Bundle ids | ||
| * @param {Function} callbackFn - The callback function | ||
| */ | ||
| function subscribe(bundleIds, callbackFn) { | ||
| // listify | ||
| bundleIds = bundleIds.push ? bundleIds : [bundleIds]; | ||
| var depsNotFound = [], | ||
| i = bundleIds.length, | ||
| numWaiting = i, | ||
| fn, | ||
| bundleId, | ||
| r, | ||
| q; | ||
|
|
||
| // define callback function | ||
| fn = function (bundleId, pathsNotFound) { | ||
| if (pathsNotFound.length) depsNotFound.push(bundleId); | ||
| numWaiting--; | ||
| if (!numWaiting) callbackFn(depsNotFound); | ||
| }; | ||
| // register callback | ||
| while (i--) { | ||
| bundleId = bundleIds[i]; | ||
|
|
||
| // register callback | ||
| while (i--) { | ||
| bundleId = bundleIds[i]; | ||
| // execute callback if in result cache | ||
| r = bundleResultCache[bundleId]; | ||
| if (r) { | ||
| fn(bundleId, r); | ||
| continue; | ||
| } | ||
|
|
||
| // execute callback if in result cache | ||
| r = bundleResultCache[bundleId]; | ||
| if (r) { | ||
| fn(bundleId, r); | ||
| continue; | ||
| // add to callback queue | ||
| q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || []; | ||
| q.push(fn); | ||
| } | ||
|
|
||
| // add to callback queue | ||
| q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || []; | ||
| q.push(fn); | ||
| } |
There was a problem hiding this comment.
issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)
Link issues
fixes #551
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Bump the bundled Plyr dependency in BootstrapBlazor.Player to version 9.0.2, replacing the plyr JavaScript and CSS assets with the updated upstream files and updating the project file accordingly.
Bug Fixes:
Enhancements:
Build: