Skip to content

feat(Plyr): bump version 9.0.2#552

Merged
ArgoZhang merged 3 commits intomasterfrom
refactor-plyr
Aug 28, 2025
Merged

feat(Plyr): bump version 9.0.2#552
ArgoZhang merged 3 commits intomasterfrom
refactor-plyr

Conversation

@ArgoZhang
Copy link
Copy Markdown
Member

@ArgoZhang ArgoZhang commented Aug 28, 2025

Link issues

fixes #551

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

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:

  • Refresh bundled plyr.js, plyr.min.js and plyr.css to the latest upstream release

Build:

  • Update BootstrapBlazor.Player.csproj to reference the new Plyr version

Copilot AI review requested due to automatic review settings August 28, 2025 00:54
@bb-auto bb-auto Bot added the enhancement New feature or request label Aug 28, 2025
@bb-auto bb-auto Bot added this to the v9.2.0 milestone Aug 28, 2025
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Aug 28, 2025

Reviewer's Guide

This 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 functions

classDiagram
  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
Loading

Class diagram for updated loadjs script loader

classDiagram
  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
Loading

File-Level Changes

Change Details Files
Normalize boolean literals and code style across the library
  • Replaced '!0'/'!1' and '!'/'+0' patterns with 'true'/'false'
  • Removed ESLint disable comments and simplified catch blocks to 'catch {}'
  • Converted many arrow functions back to named function declarations for consistency
wwwroot/plyr.js
Reorganized utility functions into clearly labeled sections
  • Introduced comments for Animation, Object, Element, Style, URL, and other utils
  • Moved browser-sniffing logic to a dedicated section near the end
  • Grouped related helpers (string, array, time, style) under distinct headers
wwwroot/plyr.js
Enhanced script loading and module support with loadjs improvements
  • Replaced inline CommonJS loader with a require/loadjs wrapper
  • Added 'module!' and 'nomodule!' path prefixes to handle ES modules vs legacy
  • Exposed loadjs.ready, .done, .reset, .isDefined methods
wwwroot/plyr.js
Updated default configuration values
  • Bumped default iconUrl from '3.7.8' to '3.8.3'
  • Added 'withCredentials' flag to previewThumbnails plugin
  • Left version references in project file for 9.0.2
wwwroot/plyr.js
BootstrapBlazor.Player.csproj
Improve DOM text handling and parsing routines
  • Replaced 'innerText' usages with 'textContent'
  • Adopted Number.parseInt/Number.parseFloat in place of parseInt/parseFloat
  • Simplified regular expressions and URL parsing logic
wwwroot/plyr.js

Assessment against linked issues

Issue Objective Addressed Explanation
#551 Update Plyr library to version 3.8.3 in the project.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link

Copilot AI Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
const isEdge = /Edge/.test(navigator.userAgent);
const isEdge = /Edge\/|Edg\//.test(navigator.userAgent);

Copilot uses AI. Check for mistakes.
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;
Copy link

Copilot AI Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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)
);

Copilot uses AI. Check for mistakes.
@ArgoZhang ArgoZhang merged commit 78cd988 into master Aug 28, 2025
1 check passed
@ArgoZhang ArgoZhang deleted the refactor-plyr branch August 28, 2025 00:57
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +5452 to 5454
const regex = /^.*(vimeo.com\/|video\/)(\d+)(\?.*h=|\/)+([\d,a-f]+)/;
const found = url.match(regex);
return found && found.length === 5 ? found[4] : null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider importing external dependencies and using concise arrow functions to reduce bundle size and improve maintainability.

Suggested change
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.

  1. Restore terse arrow‐helpers for one‐liners instead of full named functions
    // 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.

Comment on lines +7 to 14
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;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)

ExplanationFunction 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, {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Don't reassign parameter - r (dont-reassign-parameters)

ExplanationReassigning 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

Comment on lines +15 to 24
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);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)

ExplanationFunction 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: {}};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines +5095 to +5405
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;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)

ExplanationFunction 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.

Comment on lines +5119 to 5152
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);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Avoid function declarations, favouring function assignment expressions, inside blocks. (avoid-function-declarations-in-blocks)

ExplanationFunction 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(Plyr): bump version 9.0.2

2 participants