mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-16 16:16:40 +03:00
9ece285b92
In v3.0, we changed our plugin interfaces so that all are factories that return objects. We no longer call those with "new" as we did in v2.5. We provided backward compatibility and a deprecation warning to alert applications to update their usage of those interfaces. However, this compatibility shim was broken for ES6 classes, which behaved differently than ES5 constructor functions. This fixes the shim and adds regression tests. The tests were tricky because we use Babel to transpile our tests, but we needed raw, untranspiled code to define a class to test these features. So we use eval and some associated trickery to get exactly the different kinds of plugin registrations we intend to support. These tests are skipped on non-ES6 browsers. Fixes #2958 Change-Id: Ife8b63c0d89f4ea0aff085d3a4c156c4eb657604
113 lines
2.9 KiB
JavaScript
113 lines
2.9 KiB
JavaScript
/*! @license
|
|
* Shaka Player
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
goog.provide('shaka.util.Functional');
|
|
|
|
goog.require('shaka.Deprecate');
|
|
|
|
|
|
/**
|
|
* @summary A set of functional utility functions.
|
|
*/
|
|
shaka.util.Functional = class {
|
|
/**
|
|
* Creates a promise chain that calls the given callback for each element in
|
|
* the array in a catch of a promise.
|
|
*
|
|
* e.g.:
|
|
* Promise.reject().catch(callback(array[0])).catch(callback(array[1]));
|
|
*
|
|
* @param {!Array.<ELEM>} array
|
|
* @param {function(ELEM):!Promise.<RESULT>} callback
|
|
* @return {!Promise.<RESULT>}
|
|
* @template ELEM,RESULT
|
|
*/
|
|
static createFallbackPromiseChain(array, callback) {
|
|
return array.reduce((promise, elem) => {
|
|
return promise.catch(() => callback(elem));
|
|
}, Promise.reject());
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the first array concatenated to the second; used to collapse an
|
|
* array of arrays into a single array.
|
|
*
|
|
* @param {!Array.<T>} all
|
|
* @param {!Array.<T>} part
|
|
* @return {!Array.<T>}
|
|
* @template T
|
|
*/
|
|
static collapseArrays(all, part) {
|
|
return all.concat(part);
|
|
}
|
|
|
|
/**
|
|
* A no-op function that ignores its arguments. This is used to suppress
|
|
* unused variable errors.
|
|
* @param {...*} args
|
|
*/
|
|
static ignored(...args) {}
|
|
|
|
|
|
/**
|
|
* A no-op function. Useful in promise chains.
|
|
*/
|
|
static noop() {}
|
|
|
|
|
|
/**
|
|
* Returns if the given value is not null; useful for filtering out null
|
|
* values.
|
|
*
|
|
* @param {T} value
|
|
* @return {boolean}
|
|
* @template T
|
|
*/
|
|
static isNotNull(value) {
|
|
return value != null;
|
|
}
|
|
|
|
/**
|
|
* Calls a factory function while allowing it to be a constructor for
|
|
* reverse-compatibility.
|
|
*
|
|
* @param {function():!T} factory
|
|
* @return {!T}
|
|
* @template T
|
|
*/
|
|
static callFactory(factory) {
|
|
// See https://stackoverflow.com/q/10428603/1208502
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
const obj = Object.create(factory.prototype || Object.prototype);
|
|
// If this is a constructor, call it with our newly created object to
|
|
// initialize it; if this isn't a constructor, the "this" shouldn't be used
|
|
// since it should be "undefined".
|
|
let ret;
|
|
try {
|
|
ret = factory.call(obj); // eslint-disable-line no-restricted-syntax
|
|
|
|
// If it didn't return anything, assume it is a constructor and return our
|
|
// "this" value instead.
|
|
if (!ret) {
|
|
shaka.Deprecate.deprecateFeature(4,
|
|
'Factories requiring new',
|
|
'Factories should be plain functions');
|
|
ret = obj;
|
|
}
|
|
} catch (e) {
|
|
// This was an ES6 class, so it threw a TypeError because we didn't use
|
|
// "new". Fall back to actually using "new".
|
|
shaka.Deprecate.deprecateFeature(4,
|
|
'Factories requiring new',
|
|
'Factories should be plain functions');
|
|
const FactoryAsClass = /** @type {function(new: T)} */(factory);
|
|
ret = new FactoryAsClass();
|
|
}
|
|
return ret;
|
|
}
|
|
};
|