site/node_modules/jsdom/lib/jsdom/utils.js

116 lines
2.9 KiB
JavaScript
Raw Normal View History

2024-10-14 08:09:33 +02:00
"use strict";
const whatwgURL = require("whatwg-url");
const { domSymbolTree } = require("./living/helpers/internal-constants");
const SYMBOL_TREE_POSITION = require("symbol-tree").TreePosition;
/**
* Define a set of properties on an object, by copying the property descriptors
* from the original object.
*
* - `object` {Object} the target object
* - `properties` {Object} the source from which to copy property descriptors
*/
exports.define = function define(object, properties) {
for (const name of Object.getOwnPropertyNames(properties)) {
const propDesc = Object.getOwnPropertyDescriptor(properties, name);
Object.defineProperty(object, name, propDesc);
}
};
exports.mixin = (target, source) => {
const keys = Reflect.ownKeys(source);
for (let i = 0; i < keys.length; ++i) {
if (keys[i] in target) {
continue;
}
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));
}
};
let memoizeQueryTypeCounter = 0;
/**
* Returns a version of a method that memoizes specific types of calls on the object
*
* - `fn` {Function} the method to be memozied
*/
exports.memoizeQuery = function memoizeQuery(fn) {
// Only memoize query functions with arity <= 2
if (fn.length > 2) {
return fn;
}
const type = memoizeQueryTypeCounter++;
return function (...args) {
if (!this._memoizedQueries) {
return fn.apply(this, args);
}
if (!this._memoizedQueries[type]) {
this._memoizedQueries[type] = Object.create(null);
}
let key;
if (args.length === 1 && typeof args[0] === "string") {
key = args[0];
} else if (args.length === 2 && typeof args[0] === "string" && typeof args[1] === "string") {
key = args[0] + "::" + args[1];
} else {
return fn.apply(this, args);
}
if (!(key in this._memoizedQueries[type])) {
this._memoizedQueries[type][key] = fn.apply(this, args);
}
return this._memoizedQueries[type][key];
};
};
function isValidAbsoluteURL(str) {
return whatwgURL.parseURL(str) !== null;
}
exports.isValidTargetOrigin = function (str) {
return str === "*" || str === "/" || isValidAbsoluteURL(str);
};
exports.simultaneousIterators = function* (first, second) {
for (;;) {
const firstResult = first.next();
const secondResult = second.next();
if (firstResult.done && secondResult.done) {
return;
}
yield [
firstResult.done ? null : firstResult.value,
secondResult.done ? null : secondResult.value
];
}
};
exports.treeOrderSorter = function (a, b) {
const compare = domSymbolTree.compareTreePosition(a, b);
if (compare & SYMBOL_TREE_POSITION.PRECEDING) { // b is preceding a
return 1;
}
if (compare & SYMBOL_TREE_POSITION.FOLLOWING) {
return -1;
}
// disconnected or equal:
return 0;
};
/* eslint-disable global-require */
try {
exports.Canvas = require("canvas");
} catch {
exports.Canvas = null;
}