aboutsummaryrefslogtreecommitdiff
path: root/ext/js/core.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/js/core.js')
-rw-r--r--ext/js/core.js130
1 files changed, 67 insertions, 63 deletions
diff --git a/ext/js/core.js b/ext/js/core.js
index c43d7828..09468be7 100644
--- a/ext/js/core.js
+++ b/ext/js/core.js
@@ -17,8 +17,8 @@
/**
* Converts an `Error` object to a serializable JSON object.
- * @param error An error object to convert.
- * @returns A simple object which can be serialized by `JSON.stringify()`.
+ * @param {*} error An error object to convert.
+ * @returns {{name: string, message: string, stack: string, data?: *}|{value: *, hasValue: boolean}} A simple object which can be serialized by `JSON.stringify()`.
*/
function serializeError(error) {
try {
@@ -44,8 +44,8 @@ function serializeError(error) {
/**
* Converts a serialized erorr into a standard `Error` object.
- * @param serializedError A simple object which was initially generated by serializeError.
- * @returns A new `Error` instance.
+ * @param {{name: string, message: string, stack: string, data?: *}|{value: *, hasValue: boolean}} serializedError A simple object which was initially generated by serializeError.
+ * @returns {Error|*} A new `Error` instance.
*/
function deserializeError(serializedError) {
if (serializedError.hasValue) {
@@ -62,8 +62,8 @@ function deserializeError(serializedError) {
/**
* Checks whether a given value is a non-array object.
- * @param value The value to check.
- * @returns `true` if the value is an object and not an array, `false` otherwise.
+ * @param {*} value The value to check.
+ * @returns {boolean} `true` if the value is an object and not an array, `false` otherwise.
*/
function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -72,8 +72,8 @@ function isObject(value) {
/**
* Converts any string into a form that can be passed into the RegExp constructor.
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
- * @param string The string to convert to a valid regular expression.
- * @returns The escaped string.
+ * @param {string} string The string to convert to a valid regular expression.
+ * @returns {string} The escaped string.
*/
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
@@ -81,8 +81,8 @@ function escapeRegExp(string) {
/**
* Reverses a string.
- * @param string The string to reverse.
- * @returns The returned string, which retains proper UTF-16 surrogate pair order.
+ * @param {string} string The string to reverse.
+ * @returns {string} The returned string, which retains proper UTF-16 surrogate pair order.
*/
function stringReverse(string) {
return [...string].reverse().join('');
@@ -90,8 +90,8 @@ function stringReverse(string) {
/**
* Creates a deep clone of an object or value. This is similar to `JSON.parse(JSON.stringify(value))`.
- * @param value The value to clone.
- * @returns A new clone of the value.
+ * @param {*} value The value to clone.
+ * @returns {*} A new clone of the value.
* @throws An error if the value is circular and cannot be cloned.
*/
const clone = (() => {
@@ -163,9 +163,9 @@ const clone = (() => {
/**
* Checks if an object or value is deeply equal to another object or value.
- * @param value1 The first value to check.
- * @param value2 The second value to check.
- * @returns `true` if the values are the same object, or deeply equal without cycles. `false` otherwise.
+ * @param {*} value1 The first value to check.
+ * @param {*} value2 The second value to check.
+ * @returns {boolean} `true` if the values are the same object, or deeply equal without cycles. `false` otherwise.
*/
const deepEqual = (() => {
// eslint-disable-next-line no-shadow
@@ -235,8 +235,8 @@ const deepEqual = (() => {
/**
* Creates a new base-16 (lower case) string of a sequence of random bytes of the given length.
- * @param length The number of bytes the string represents. The returned string's length will be twice as long.
- * @returns A string of random characters.
+ * @param {number} length The number of bytes the string represents. The returned string's length will be twice as long.
+ * @returns {string} A string of random characters.
*/
function generateId(length) {
const array = new Uint8Array(length);
@@ -250,7 +250,7 @@ function generateId(length) {
/**
* Creates an unresolved promise that can be resolved later, outside the promise's executor function.
- * @returns An object `{promise, resolve, reject}`, containing the promise and the resolve/reject functions.
+ * @returns {{promise: Promise, resolve: function, reject: function}} An object `{promise, resolve, reject}`, containing the promise and the resolve/reject functions.
*/
function deferPromise() {
let resolve;
@@ -264,9 +264,9 @@ function deferPromise() {
/**
* Creates a promise that is resolved after a set delay.
- * @param delay How many milliseconds until the promise should be resolved. If 0, the promise is immediately resolved.
- * @param resolveValue Optional; the value returned when the promise is resolved.
- * @returns A promise with two additional properties: `resolve` and `reject`, which can be used to complete the promise early.
+ * @param {number} delay How many milliseconds until the promise should be resolved. If 0, the promise is immediately resolved.
+ * @param {*} [resolveValue] The value returned when the promise is resolved.
+ * @returns {Promise} A promise with two additional properties: `resolve` and `reject`, which can be used to complete the promise early.
*/
function promiseTimeout(delay, resolveValue) {
if (delay <= 0) {
@@ -306,8 +306,8 @@ function promiseTimeout(delay, resolveValue) {
/**
* Creates a promise that will resolve after the next animation frame, using `requestAnimationFrame`.
- * @param timeout Optional; a maximum duration (in milliseconds) to wait until the promise resolves. If null or omitted, no timeout is used.
- * @returns A promise that is resolved with `{time, timeout}`, where `time` is the timestamp from `requestAnimationFrame`,
+ * @param {number} [timeout] A maximum duration (in milliseconds) to wait until the promise resolves. If null or omitted, no timeout is used.
+ * @returns {Promise<{time: number, timeout: number}>} A promise that is resolved with `{time, timeout}`, where `time` is the timestamp from `requestAnimationFrame`,
* and `timeout` is a boolean indicating whether the cause was a timeout or not.
* @throws The promise throws an error if animation is not supported in this context, such as in a service worker.
*/
@@ -349,16 +349,17 @@ function promiseAnimationFrame(timeout=null) {
/**
* Invokes a standard message handler. This function is used to react and respond
* to communication messages within the extension.
- * @param handler A handler function which is passed `params` and `...extraArgs` as arguments.
- * @param async Whether or not the handler is async or not. Values include `false`, `true`, or `'dynamic'`.
+ * @param {object} details
+ * @param {function} details.handler A handler function which is passed `params` and `...extraArgs` as arguments.
+ * @param {boolean|string} details.async Whether or not the handler is async or not. Values include `false`, `true`, or `'dynamic'`.
* When the value is `'dynamic'`, the handler should return an object of the format `{async: boolean, result: any}`.
- * @param params Information which was passed with the original message.
- * @param callback A callback function which is invoked after the handler has completed. The value passed
+ * @param {object} params Information which was passed with the original message.
+ * @param {function} callback A callback function which is invoked after the handler has completed. The value passed
* to the function is in the format:
* * `{result: any}` if the handler invoked successfully.
* * `{error: object}` if the handler thew an error. The error is serialized.
- * @param extraArgs Additional arguments which are passed to the `handler` function.
- * @returns `true` if the function is invoked asynchronously, `false` otherwise.
+ * @param {...*} extraArgs Additional arguments which are passed to the `handler` function.
+ * @returns {boolean} `true` if the function is invoked asynchronously, `false` otherwise.
*/
function invokeMessageHandler({handler, async}, params, callback, ...extraArgs) {
try {
@@ -395,9 +396,9 @@ class EventDispatcher {
/**
* Triggers an event with the given name and specified argument.
- * @param eventName The string representing the event's name.
- * @param details Optional; the argument passed to the callback functions.
- * @returns `true` if any callbacks were registered, `false` otherwise.
+ * @param {string} eventName The string representing the event's name.
+ * @param {*} [details] The argument passed to the callback functions.
+ * @returns {boolean} `true` if any callbacks were registered, `false` otherwise.
*/
trigger(eventName, details) {
const callbacks = this._eventMap.get(eventName);
@@ -411,8 +412,8 @@ class EventDispatcher {
/**
* Adds a single event listener to a specific event.
- * @param eventName The string representing the event's name.
- * @param callback The event listener callback to add.
+ * @param {string} eventName The string representing the event's name.
+ * @param {function} callback The event listener callback to add.
*/
on(eventName, callback) {
let callbacks = this._eventMap.get(eventName);
@@ -425,9 +426,9 @@ class EventDispatcher {
/**
* Removes a single event listener from a specific event.
- * @param eventName The string representing the event's name.
- * @param callback The event listener callback to add.
- * @returns `true` if the callback was removed, `false` otherwise.
+ * @param {string} eventName The string representing the event's name.
+ * @param {function} callback The event listener callback to add.
+ * @returns {boolean} `true` if the callback was removed, `false` otherwise.
*/
off(eventName, callback) {
const callbacks = this._eventMap.get(eventName);
@@ -448,8 +449,8 @@ class EventDispatcher {
/**
* Checks if an event has any listeners.
- * @param eventName The string representing the event's name.
- * @returns `true` if the event has listeners, `false` otherwise.
+ * @param {string} eventName The string representing the event's name.
+ * @returns {boolean} `true` if the event has listeners, `false` otherwise.
*/
hasListeners(eventName) {
const callbacks = this._eventMap.get(eventName);
@@ -470,7 +471,7 @@ class EventListenerCollection {
/**
* Returns the number of event listeners that are currently in the object.
- * @returns The number of event listeners that are currently in the object.
+ * @type {number}
*/
get size() {
return this._eventListeners.length;
@@ -478,9 +479,9 @@ class EventListenerCollection {
/**
* Adds an event listener of a generic type.
- * @param type The type of event listener, which can be 'addEventListener', 'addListener', or 'on'.
- * @param object The object to add the event listener to.
- * @param args The argument array passed to the object's event listener adding function.
+ * @param {string} type The type of event listener, which can be 'addEventListener', 'addListener', or 'on'.
+ * @param {object} object The object to add the event listener to.
+ * @param {...*} args The argument array passed to the object's event listener adding function.
* @throws An error if type is not an expected value.
*/
addGeneric(type, object, ...args) {
@@ -494,8 +495,8 @@ class EventListenerCollection {
/**
* Adds an event listener using `object.addEventListener`. The listener will later be removed using `object.removeEventListener`.
- * @param object The object to add the event listener to.
- * @param args The argument array passed to the `addEventListener`/`removeEventListener` functions.
+ * @param {object} object The object to add the event listener to.
+ * @param {...*} args The argument array passed to the `addEventListener`/`removeEventListener` functions.
*/
addEventListener(object, ...args) {
object.addEventListener(...args);
@@ -504,8 +505,8 @@ class EventListenerCollection {
/**
* Adds an event listener using `object.addListener`. The listener will later be removed using `object.removeListener`.
- * @param object The object to add the event listener to.
- * @param args The argument array passed to the `addListener`/`removeListener` function.
+ * @param {object} object The object to add the event listener to.
+ * @param {...*} args The argument array passed to the `addListener`/`removeListener` function.
*/
addListener(object, ...args) {
object.addListener(...args);
@@ -514,8 +515,8 @@ class EventListenerCollection {
/**
* Adds an event listener using `object.on`. The listener will later be removed using `object.off`.
- * @param object The object to add the event listener to.
- * @param args The argument array passed to the `on`/`off` function.
+ * @param {object} object The object to add the event listener to.
+ * @param {...*} args The argument array passed to the `on`/`off` function.
*/
on(object, ...args) {
object.on(...args);
@@ -553,7 +554,7 @@ class EventListenerCollection {
class DynamicProperty extends EventDispatcher {
/**
* Creates a new instance with the specified value.
- * @param value The value to assign.
+ * @param {*} value The value to assign.
*/
constructor(value) {
super();
@@ -565,6 +566,7 @@ class DynamicProperty extends EventDispatcher {
/**
* Gets the default value for the property, which is assigned to the
* public value property when no overrides are present.
+ * @type {*}
*/
get defaultValue() {
return this._defaultValue;
@@ -574,7 +576,7 @@ class DynamicProperty extends EventDispatcher {
* Assigns the default value for the property. If no overrides are present
* and if the value is different than the current default value,
* the 'change' event will be triggered.
- * @param value The value to assign.
+ * @param {*} value The value to assign.
*/
set defaultValue(value) {
this._defaultValue = value;
@@ -583,6 +585,7 @@ class DynamicProperty extends EventDispatcher {
/**
* Gets the current value for the property, taking any overrides into account.
+ * @type {*}
*/
get value() {
return this._value;
@@ -590,6 +593,7 @@ class DynamicProperty extends EventDispatcher {
/**
* Gets the number of overrides added to the property.
+ * @type {*}
*/
get overrideCount() {
return this._overrides.length;
@@ -602,9 +606,9 @@ class DynamicProperty extends EventDispatcher {
* If the newly added override has the highest priority of all overrides
* and if the override value is different from the current value,
* the 'change' event will be fired.
- * @param value The override value to assign.
- * @param priority The priority value to use, as a number.
- * @returns A string token which can be passed to the clearOverride function
+ * @param {*} value The override value to assign.
+ * @param {number} [priority] The priority value to use, as a number.
+ * @returns {string} A string token which can be passed to the clearOverride function
* to remove the override.
*/
setOverride(value, priority=0) {
@@ -623,8 +627,8 @@ class DynamicProperty extends EventDispatcher {
* Removes a specific override value. If the removed override
* had the highest priority, and the new value is different from
* the previous value, the 'change' event will be fired.
- * @param token The token for the corresponding override which is to be removed.
- * @returns true if an override was returned, false otherwise.
+ * @param {string} token The token for the corresponding override which is to be removed.
+ * @returns {boolean} `true` if an override was returned, `false` otherwise.
*/
clearOverride(token) {
for (let i = 0, ii = this._overrides.length; i < ii; ++i) {
@@ -670,10 +674,10 @@ class Logger extends EventDispatcher {
/**
* Logs a generic error. This will trigger the 'log' event with the same arguments as the function invocation.
- * @param error The error to log. This is typically an `Error` or `Error`-like object.
- * @param level The level to log at. Values include `'info'`, `'debug'`, `'warn'`, and `'error'`.
+ * @param {Error|object|*} error The error to log. This is typically an `Error` or `Error`-like object.
+ * @param {string} level The level to log at. Values include `'info'`, `'debug'`, `'warn'`, and `'error'`.
* Other values will be logged at a non-error level.
- * @param context An optional context object for the error which should typically include a `url` field.
+ * @param {?object} [context] An optional context object for the error which should typically include a `url` field.
*/
log(error, level, context=null) {
if (!isObject(context)) {
@@ -735,8 +739,8 @@ class Logger extends EventDispatcher {
/**
* Logs a warning. This function invokes `log` internally.
- * @param error The error to log. This is typically an `Error` or `Error`-like object.
- * @param context An optional context object for the error which should typically include a `url` field.
+ * @param {Error|object|*} error The error to log. This is typically an `Error` or `Error`-like object.
+ * @param {?object} context An optional context object for the error which should typically include a `url` field.
*/
warn(error, context=null) {
this.log(error, 'warn', context);
@@ -744,8 +748,8 @@ class Logger extends EventDispatcher {
/**
* Logs an error. This function invokes `log` internally.
- * @param error The error to log. This is typically an `Error` or `Error`-like object.
- * @param context An optional context object for the error which should typically include a `url` field.
+ * @param {Error|object|*} error The error to log. This is typically an `Error` or `Error`-like object.
+ * @param {?object} context An optional context object for the error which should typically include a `url` field.
*/
error(error, context=null) {
this.log(error, 'error', context);