$
This commit is contained in:
22
node_modules/jsdom/LICENSE.txt
generated
vendored
Normal file
22
node_modules/jsdom/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2010 Elijah Insua
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
522
node_modules/jsdom/README.md
generated
vendored
Normal file
522
node_modules/jsdom/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
333
node_modules/jsdom/lib/api.js
generated
vendored
Normal file
333
node_modules/jsdom/lib/api.js
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("fs").promises;
|
||||
const vm = require("vm");
|
||||
const toughCookie = require("tough-cookie");
|
||||
const sniffHTMLEncoding = require("html-encoding-sniffer");
|
||||
const whatwgURL = require("whatwg-url");
|
||||
const whatwgEncoding = require("whatwg-encoding");
|
||||
const { URL } = require("whatwg-url");
|
||||
const MIMEType = require("whatwg-mimetype");
|
||||
const idlUtils = require("./jsdom/living/generated/utils.js");
|
||||
const VirtualConsole = require("./jsdom/virtual-console.js");
|
||||
const { createWindow } = require("./jsdom/browser/Window.js");
|
||||
const { parseIntoDocument } = require("./jsdom/browser/parser");
|
||||
const { fragmentSerialization } = require("./jsdom/living/domparsing/serialization.js");
|
||||
const ResourceLoader = require("./jsdom/browser/resources/resource-loader.js");
|
||||
const NoOpResourceLoader = require("./jsdom/browser/resources/no-op-resource-loader.js");
|
||||
|
||||
class CookieJar extends toughCookie.CookieJar {
|
||||
constructor(store, options) {
|
||||
// jsdom cookie jars must be loose by default
|
||||
super(store, { looseMode: true, ...options });
|
||||
}
|
||||
}
|
||||
|
||||
const window = Symbol("window");
|
||||
let sharedFragmentDocument = null;
|
||||
|
||||
class JSDOM {
|
||||
constructor(input = "", options = {}) {
|
||||
const mimeType = new MIMEType(options.contentType === undefined ? "text/html" : options.contentType);
|
||||
const { html, encoding } = normalizeHTML(input, mimeType);
|
||||
|
||||
options = transformOptions(options, encoding, mimeType);
|
||||
|
||||
this[window] = createWindow(options.windowOptions);
|
||||
|
||||
const documentImpl = idlUtils.implForWrapper(this[window]._document);
|
||||
|
||||
options.beforeParse(this[window]._globalProxy);
|
||||
|
||||
parseIntoDocument(html, documentImpl);
|
||||
|
||||
documentImpl.close();
|
||||
}
|
||||
|
||||
get window() {
|
||||
// It's important to grab the global proxy, instead of just the result of `createWindow(...)`, since otherwise
|
||||
// things like `window.eval` don't exist.
|
||||
return this[window]._globalProxy;
|
||||
}
|
||||
|
||||
get virtualConsole() {
|
||||
return this[window]._virtualConsole;
|
||||
}
|
||||
|
||||
get cookieJar() {
|
||||
// TODO NEWAPI move _cookieJar to window probably
|
||||
return idlUtils.implForWrapper(this[window]._document)._cookieJar;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return fragmentSerialization(idlUtils.implForWrapper(this[window]._document), { requireWellFormed: false });
|
||||
}
|
||||
|
||||
nodeLocation(node) {
|
||||
if (!idlUtils.implForWrapper(this[window]._document)._parseOptions.sourceCodeLocationInfo) {
|
||||
throw new Error("Location information was not saved for this jsdom. Use includeNodeLocations during creation.");
|
||||
}
|
||||
|
||||
return idlUtils.implForWrapper(node).sourceCodeLocation;
|
||||
}
|
||||
|
||||
getInternalVMContext() {
|
||||
if (!vm.isContext(this[window])) {
|
||||
throw new TypeError("This jsdom was not configured to allow script running. " +
|
||||
"Use the runScripts option during creation.");
|
||||
}
|
||||
|
||||
return this[window];
|
||||
}
|
||||
|
||||
reconfigure(settings) {
|
||||
if ("windowTop" in settings) {
|
||||
this[window]._top = settings.windowTop;
|
||||
}
|
||||
|
||||
if ("url" in settings) {
|
||||
const document = idlUtils.implForWrapper(this[window]._document);
|
||||
|
||||
const url = whatwgURL.parseURL(settings.url);
|
||||
if (url === null) {
|
||||
throw new TypeError(`Could not parse "${settings.url}" as a URL`);
|
||||
}
|
||||
|
||||
document._URL = url;
|
||||
document._origin = whatwgURL.serializeURLOrigin(document._URL);
|
||||
}
|
||||
}
|
||||
|
||||
static fragment(string = "") {
|
||||
if (!sharedFragmentDocument) {
|
||||
sharedFragmentDocument = (new JSDOM()).window.document;
|
||||
}
|
||||
|
||||
const template = sharedFragmentDocument.createElement("template");
|
||||
template.innerHTML = string;
|
||||
return template.content;
|
||||
}
|
||||
|
||||
static fromURL(url, options = {}) {
|
||||
return Promise.resolve().then(() => {
|
||||
// Remove the hash while sending this through the research loader fetch().
|
||||
// It gets added back a few lines down when constructing the JSDOM object.
|
||||
const parsedURL = new URL(url);
|
||||
const originalHash = parsedURL.hash;
|
||||
parsedURL.hash = "";
|
||||
url = parsedURL.href;
|
||||
|
||||
options = normalizeFromURLOptions(options);
|
||||
|
||||
const resourceLoader = resourcesToResourceLoader(options.resources);
|
||||
const resourceLoaderForInitialRequest = resourceLoader.constructor === NoOpResourceLoader ?
|
||||
new ResourceLoader() :
|
||||
resourceLoader;
|
||||
|
||||
const req = resourceLoaderForInitialRequest.fetch(url, {
|
||||
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
cookieJar: options.cookieJar,
|
||||
referrer: options.referrer
|
||||
});
|
||||
|
||||
return req.then(body => {
|
||||
const res = req.response;
|
||||
|
||||
options = Object.assign(options, {
|
||||
url: req.href + originalHash,
|
||||
contentType: res.headers["content-type"],
|
||||
referrer: req.getHeader("referer")
|
||||
});
|
||||
|
||||
return new JSDOM(body, options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static async fromFile(filename, options = {}) {
|
||||
options = normalizeFromFileOptions(filename, options);
|
||||
const buffer = await fs.readFile(filename);
|
||||
|
||||
return new JSDOM(buffer, options);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeFromURLOptions(options) {
|
||||
// Checks on options that are invalid for `fromURL`
|
||||
if (options.url !== undefined) {
|
||||
throw new TypeError("Cannot supply a url option when using fromURL");
|
||||
}
|
||||
if (options.contentType !== undefined) {
|
||||
throw new TypeError("Cannot supply a contentType option when using fromURL");
|
||||
}
|
||||
|
||||
// Normalization of options which must be done before the rest of the fromURL code can use them, because they are
|
||||
// given to request()
|
||||
const normalized = { ...options };
|
||||
|
||||
if (options.referrer !== undefined) {
|
||||
normalized.referrer = (new URL(options.referrer)).href;
|
||||
}
|
||||
|
||||
if (options.cookieJar === undefined) {
|
||||
normalized.cookieJar = new CookieJar();
|
||||
}
|
||||
|
||||
return normalized;
|
||||
|
||||
// All other options don't need to be processed yet, and can be taken care of in the normal course of things when
|
||||
// `fromURL` calls `new JSDOM(html, options)`.
|
||||
}
|
||||
|
||||
function normalizeFromFileOptions(filename, options) {
|
||||
const normalized = { ...options };
|
||||
|
||||
if (normalized.contentType === undefined) {
|
||||
const extname = path.extname(filename);
|
||||
if (extname === ".xhtml" || extname === ".xht" || extname === ".xml") {
|
||||
normalized.contentType = "application/xhtml+xml";
|
||||
}
|
||||
}
|
||||
|
||||
if (normalized.url === undefined) {
|
||||
normalized.url = new URL("file:" + path.resolve(filename));
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function transformOptions(options, encoding, mimeType) {
|
||||
const transformed = {
|
||||
windowOptions: {
|
||||
// Defaults
|
||||
url: "about:blank",
|
||||
referrer: "",
|
||||
contentType: "text/html",
|
||||
parsingMode: "html",
|
||||
parseOptions: {
|
||||
sourceCodeLocationInfo: false,
|
||||
scriptingEnabled: false
|
||||
},
|
||||
runScripts: undefined,
|
||||
encoding,
|
||||
pretendToBeVisual: false,
|
||||
storageQuota: 5000000,
|
||||
|
||||
// Defaults filled in later
|
||||
resourceLoader: undefined,
|
||||
virtualConsole: undefined,
|
||||
cookieJar: undefined
|
||||
},
|
||||
|
||||
// Defaults
|
||||
beforeParse() { }
|
||||
};
|
||||
|
||||
// options.contentType was parsed into mimeType by the caller.
|
||||
if (!mimeType.isHTML() && !mimeType.isXML()) {
|
||||
throw new RangeError(`The given content type of "${options.contentType}" was not a HTML or XML content type`);
|
||||
}
|
||||
|
||||
transformed.windowOptions.contentType = mimeType.essence;
|
||||
transformed.windowOptions.parsingMode = mimeType.isHTML() ? "html" : "xml";
|
||||
|
||||
if (options.url !== undefined) {
|
||||
transformed.windowOptions.url = (new URL(options.url)).href;
|
||||
}
|
||||
|
||||
if (options.referrer !== undefined) {
|
||||
transformed.windowOptions.referrer = (new URL(options.referrer)).href;
|
||||
}
|
||||
|
||||
if (options.includeNodeLocations) {
|
||||
if (transformed.windowOptions.parsingMode === "xml") {
|
||||
throw new TypeError("Cannot set includeNodeLocations to true with an XML content type");
|
||||
}
|
||||
|
||||
transformed.windowOptions.parseOptions = { sourceCodeLocationInfo: true };
|
||||
}
|
||||
|
||||
transformed.windowOptions.cookieJar = options.cookieJar === undefined ?
|
||||
new CookieJar() :
|
||||
options.cookieJar;
|
||||
|
||||
transformed.windowOptions.virtualConsole = options.virtualConsole === undefined ?
|
||||
(new VirtualConsole()).sendTo(console) :
|
||||
options.virtualConsole;
|
||||
|
||||
if (!(transformed.windowOptions.virtualConsole instanceof VirtualConsole)) {
|
||||
throw new TypeError("virtualConsole must be an instance of VirtualConsole");
|
||||
}
|
||||
|
||||
transformed.windowOptions.resourceLoader = resourcesToResourceLoader(options.resources);
|
||||
|
||||
if (options.runScripts !== undefined) {
|
||||
transformed.windowOptions.runScripts = String(options.runScripts);
|
||||
if (transformed.windowOptions.runScripts === "dangerously") {
|
||||
transformed.windowOptions.parseOptions.scriptingEnabled = true;
|
||||
} else if (transformed.windowOptions.runScripts !== "outside-only") {
|
||||
throw new RangeError(`runScripts must be undefined, "dangerously", or "outside-only"`);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.beforeParse !== undefined) {
|
||||
transformed.beforeParse = options.beforeParse;
|
||||
}
|
||||
|
||||
if (options.pretendToBeVisual !== undefined) {
|
||||
transformed.windowOptions.pretendToBeVisual = Boolean(options.pretendToBeVisual);
|
||||
}
|
||||
|
||||
if (options.storageQuota !== undefined) {
|
||||
transformed.windowOptions.storageQuota = Number(options.storageQuota);
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
|
||||
function normalizeHTML(html, mimeType) {
|
||||
let encoding = "UTF-8";
|
||||
|
||||
if (ArrayBuffer.isView(html)) {
|
||||
html = Buffer.from(html.buffer, html.byteOffset, html.byteLength);
|
||||
} else if (html instanceof ArrayBuffer) {
|
||||
html = Buffer.from(html);
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(html)) {
|
||||
encoding = sniffHTMLEncoding(html, {
|
||||
defaultEncoding: mimeType.isXML() ? "UTF-8" : "windows-1252",
|
||||
transportLayerEncodingLabel: mimeType.parameters.get("charset")
|
||||
});
|
||||
html = whatwgEncoding.decode(html, encoding);
|
||||
} else {
|
||||
html = String(html);
|
||||
}
|
||||
|
||||
return { html, encoding };
|
||||
}
|
||||
|
||||
function resourcesToResourceLoader(resources) {
|
||||
switch (resources) {
|
||||
case undefined: {
|
||||
return new NoOpResourceLoader();
|
||||
}
|
||||
case "usable": {
|
||||
return new ResourceLoader();
|
||||
}
|
||||
default: {
|
||||
if (!(resources instanceof ResourceLoader)) {
|
||||
throw new TypeError("resources must be an instance of ResourceLoader");
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.JSDOM = JSDOM;
|
||||
|
||||
exports.VirtualConsole = VirtualConsole;
|
||||
exports.CookieJar = CookieJar;
|
||||
exports.ResourceLoader = ResourceLoader;
|
||||
|
||||
exports.toughCookie = toughCookie;
|
938
node_modules/jsdom/lib/jsdom/browser/Window.js
generated
vendored
Normal file
938
node_modules/jsdom/lib/jsdom/browser/Window.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
789
node_modules/jsdom/lib/jsdom/browser/default-stylesheet.js
generated
vendored
Normal file
789
node_modules/jsdom/lib/jsdom/browser/default-stylesheet.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
307
node_modules/jsdom/lib/jsdom/browser/js-globals.json
generated
vendored
Normal file
307
node_modules/jsdom/lib/jsdom/browser/js-globals.json
generated
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
{
|
||||
"Object": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Function": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Number": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"parseFloat": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"parseInt": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Infinity": {
|
||||
"writable": false,
|
||||
"enumerable": false,
|
||||
"configurable": false
|
||||
},
|
||||
"NaN": {
|
||||
"writable": false,
|
||||
"enumerable": false,
|
||||
"configurable": false
|
||||
},
|
||||
"undefined": {
|
||||
"writable": false,
|
||||
"enumerable": false,
|
||||
"configurable": false
|
||||
},
|
||||
"Boolean": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"String": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Symbol": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Date": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Promise": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"RegExp": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Error": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"AggregateError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"EvalError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"RangeError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"ReferenceError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"SyntaxError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"TypeError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"URIError": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"globalThis": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"JSON": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Math": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Intl": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"ArrayBuffer": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Uint8Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Int8Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Uint16Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Int16Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Uint32Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Int32Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Float32Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Float64Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Uint8ClampedArray": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"BigUint64Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"BigInt64Array": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"DataView": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Map": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"BigInt": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Set": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"WeakMap": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"WeakSet": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Proxy": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Reflect": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"FinalizationRegistry": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"WeakRef": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"decodeURI": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"decodeURIComponent": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"encodeURI": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"encodeURIComponent": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"escape": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"unescape": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"eval": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"isFinite": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"isNaN": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"SharedArrayBuffer": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"Atomics": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
},
|
||||
"WebAssembly": {
|
||||
"writable": true,
|
||||
"enumerable": false,
|
||||
"configurable": true
|
||||
}
|
||||
}
|
13
node_modules/jsdom/lib/jsdom/browser/not-implemented.js
generated
vendored
Normal file
13
node_modules/jsdom/lib/jsdom/browser/not-implemented.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function (nameForErrorMessage, window) {
|
||||
if (!window) {
|
||||
// Do nothing for window-less documents.
|
||||
return;
|
||||
}
|
||||
|
||||
const error = new Error(`Not implemented: ${nameForErrorMessage}`);
|
||||
error.type = "not implemented";
|
||||
|
||||
window._virtualConsole.emit("jsdomError", error);
|
||||
};
|
208
node_modules/jsdom/lib/jsdom/browser/parser/html.js
generated
vendored
Normal file
208
node_modules/jsdom/lib/jsdom/browser/parser/html.js
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
"use strict";
|
||||
|
||||
const parse5 = require("parse5");
|
||||
|
||||
const { createElement } = require("../../living/helpers/create-element");
|
||||
const { HTML_NS } = require("../../living/helpers/namespaces");
|
||||
|
||||
const DocumentType = require("../../living/generated/DocumentType");
|
||||
const DocumentFragment = require("../../living/generated/DocumentFragment");
|
||||
const Text = require("../../living/generated/Text");
|
||||
const Comment = require("../../living/generated/Comment");
|
||||
|
||||
const attributes = require("../../living/attributes");
|
||||
const nodeTypes = require("../../living/node-type");
|
||||
|
||||
const serializationAdapter = require("../../living/domparsing/parse5-adapter-serialization");
|
||||
const {
|
||||
customElementReactionsStack, invokeCEReactions, lookupCEDefinition
|
||||
} = require("../../living/helpers/custom-elements");
|
||||
|
||||
|
||||
class JSDOMParse5Adapter {
|
||||
constructor(documentImpl, options = {}) {
|
||||
this._documentImpl = documentImpl;
|
||||
this._globalObject = documentImpl._globalObject;
|
||||
this._fragment = options.fragment || false;
|
||||
|
||||
// Since the createElement hook doesn't provide the parent element, we keep track of this using _currentElement:
|
||||
// https://github.com/inikulin/parse5/issues/285.
|
||||
this._currentElement = undefined;
|
||||
}
|
||||
|
||||
_ownerDocument() {
|
||||
const { _currentElement } = this;
|
||||
|
||||
// The _currentElement is undefined when parsing elements at the root of the document.
|
||||
if (_currentElement) {
|
||||
return _currentElement.localName === "template" && _currentElement.namespaceURI === HTML_NS ?
|
||||
_currentElement.content._ownerDocument :
|
||||
_currentElement._ownerDocument;
|
||||
}
|
||||
|
||||
return this._documentImpl;
|
||||
}
|
||||
|
||||
createDocument() {
|
||||
// parse5's model assumes that parse(html) will call into here to create the new Document, then return it. However,
|
||||
// jsdom's model assumes we can create a Window (and through that create an empty Document), do some other setup
|
||||
// stuff, and then parse, stuffing nodes into that Document as we go. So to adapt between these two models, we just
|
||||
// return the already-created Document when asked by parse5 to "create" a Document.
|
||||
return this._documentImpl;
|
||||
}
|
||||
|
||||
createDocumentFragment() {
|
||||
const ownerDocument = this._ownerDocument();
|
||||
return DocumentFragment.createImpl(this._globalObject, [], { ownerDocument });
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#create-an-element-for-the-token
|
||||
createElement(localName, namespace, attrs) {
|
||||
const ownerDocument = this._ownerDocument();
|
||||
|
||||
const isAttribute = attrs.find(attr => attr.name === "is");
|
||||
const isValue = isAttribute ? isAttribute.value : null;
|
||||
|
||||
const definition = lookupCEDefinition(ownerDocument, namespace, localName);
|
||||
|
||||
let willExecuteScript = false;
|
||||
if (definition !== null && !this._fragment) {
|
||||
willExecuteScript = true;
|
||||
}
|
||||
|
||||
if (willExecuteScript) {
|
||||
ownerDocument._throwOnDynamicMarkupInsertionCounter++;
|
||||
customElementReactionsStack.push([]);
|
||||
}
|
||||
|
||||
const element = createElement(ownerDocument, localName, namespace, null, isValue, willExecuteScript);
|
||||
this.adoptAttributes(element, attrs);
|
||||
|
||||
if (willExecuteScript) {
|
||||
const queue = customElementReactionsStack.pop();
|
||||
invokeCEReactions(queue);
|
||||
ownerDocument._throwOnDynamicMarkupInsertionCounter--;
|
||||
}
|
||||
|
||||
if ("_parserInserted" in element) {
|
||||
element._parserInserted = true;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
createCommentNode(data) {
|
||||
const ownerDocument = this._ownerDocument();
|
||||
return Comment.createImpl(this._globalObject, [], { data, ownerDocument });
|
||||
}
|
||||
|
||||
appendChild(parentNode, newNode) {
|
||||
parentNode._append(newNode);
|
||||
}
|
||||
|
||||
insertBefore(parentNode, newNode, referenceNode) {
|
||||
parentNode._insert(newNode, referenceNode);
|
||||
}
|
||||
|
||||
setTemplateContent(templateElement, contentFragment) {
|
||||
// This code makes the glue between jsdom and parse5 HTMLTemplateElement parsing:
|
||||
//
|
||||
// * jsdom during the construction of the HTMLTemplateElement (for example when create via
|
||||
// `document.createElement("template")`), creates a DocumentFragment and set it into _templateContents.
|
||||
// * parse5 when parsing a <template> tag creates an HTMLTemplateElement (`createElement` adapter hook) and also
|
||||
// create a DocumentFragment (`createDocumentFragment` adapter hook).
|
||||
//
|
||||
// At this point we now have to replace the one created in jsdom with one created by parse5.
|
||||
const { _ownerDocument, _host } = templateElement._templateContents;
|
||||
contentFragment._ownerDocument = _ownerDocument;
|
||||
contentFragment._host = _host;
|
||||
|
||||
templateElement._templateContents = contentFragment;
|
||||
}
|
||||
|
||||
setDocumentType(document, name, publicId, systemId) {
|
||||
const ownerDocument = this._ownerDocument();
|
||||
const documentType = DocumentType.createImpl(this._globalObject, [], { name, publicId, systemId, ownerDocument });
|
||||
|
||||
document._append(documentType);
|
||||
}
|
||||
|
||||
setDocumentMode(document, mode) {
|
||||
// TODO: the rest of jsdom ignores this
|
||||
document._mode = mode;
|
||||
}
|
||||
|
||||
detachNode(node) {
|
||||
node.remove();
|
||||
}
|
||||
|
||||
insertText(parentNode, text) {
|
||||
const { lastChild } = parentNode;
|
||||
if (lastChild && lastChild.nodeType === nodeTypes.TEXT_NODE) {
|
||||
lastChild.data += text;
|
||||
} else {
|
||||
const ownerDocument = this._ownerDocument();
|
||||
const textNode = Text.createImpl(this._globalObject, [], { data: text, ownerDocument });
|
||||
parentNode._append(textNode);
|
||||
}
|
||||
}
|
||||
|
||||
insertTextBefore(parentNode, text, referenceNode) {
|
||||
const { previousSibling } = referenceNode;
|
||||
if (previousSibling && previousSibling.nodeType === nodeTypes.TEXT_NODE) {
|
||||
previousSibling.data += text;
|
||||
} else {
|
||||
const ownerDocument = this._ownerDocument();
|
||||
const textNode = Text.createImpl(this._globalObject, [], { data: text, ownerDocument });
|
||||
parentNode._append(textNode, referenceNode);
|
||||
}
|
||||
}
|
||||
|
||||
adoptAttributes(element, attrs) {
|
||||
for (const attr of attrs) {
|
||||
const prefix = attr.prefix === "" ? null : attr.prefix;
|
||||
attributes.setAttributeValue(element, attr.name, attr.value, prefix, attr.namespace);
|
||||
}
|
||||
}
|
||||
|
||||
onItemPush(after) {
|
||||
this._currentElement = after;
|
||||
after._pushedOnStackOfOpenElements?.();
|
||||
}
|
||||
|
||||
onItemPop(before, newTop) {
|
||||
this._currentElement = newTop;
|
||||
before._poppedOffStackOfOpenElements?.();
|
||||
}
|
||||
}
|
||||
|
||||
// Assign shared adapters with serializer.
|
||||
Object.assign(JSDOMParse5Adapter.prototype, serializationAdapter);
|
||||
|
||||
function parseFragment(markup, contextElement) {
|
||||
const ownerDocument = contextElement.localName === "template" && contextElement.namespaceURI === HTML_NS ?
|
||||
contextElement.content._ownerDocument :
|
||||
contextElement._ownerDocument;
|
||||
|
||||
const config = {
|
||||
...ownerDocument._parseOptions,
|
||||
sourceCodeLocationInfo: false,
|
||||
treeAdapter: new JSDOMParse5Adapter(ownerDocument, { fragment: true })
|
||||
};
|
||||
|
||||
return parse5.parseFragment(contextElement, markup, config);
|
||||
}
|
||||
|
||||
function parseIntoDocument(markup, ownerDocument) {
|
||||
const config = {
|
||||
...ownerDocument._parseOptions,
|
||||
treeAdapter: new JSDOMParse5Adapter(ownerDocument)
|
||||
};
|
||||
|
||||
return parse5.parse(markup, config);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseFragment,
|
||||
parseIntoDocument
|
||||
};
|
37
node_modules/jsdom/lib/jsdom/browser/parser/index.js
generated
vendored
Normal file
37
node_modules/jsdom/lib/jsdom/browser/parser/index.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
|
||||
const xmlParser = require("./xml");
|
||||
const htmlParser = require("./html");
|
||||
|
||||
// https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm
|
||||
function parseFragment(markup, contextElement) {
|
||||
const { _parsingMode } = contextElement._ownerDocument;
|
||||
|
||||
let parseAlgorithm;
|
||||
if (_parsingMode === "html") {
|
||||
parseAlgorithm = htmlParser.parseFragment;
|
||||
} else if (_parsingMode === "xml") {
|
||||
parseAlgorithm = xmlParser.parseFragment;
|
||||
}
|
||||
|
||||
// Note: HTML and XML fragment parsing algorithm already return a document fragments; no need to do steps 3 and 4
|
||||
return parseAlgorithm(markup, contextElement);
|
||||
}
|
||||
|
||||
function parseIntoDocument(markup, ownerDocument) {
|
||||
const { _parsingMode } = ownerDocument;
|
||||
|
||||
let parseAlgorithm;
|
||||
if (_parsingMode === "html") {
|
||||
parseAlgorithm = htmlParser.parseIntoDocument;
|
||||
} else if (_parsingMode === "xml") {
|
||||
parseAlgorithm = xmlParser.parseIntoDocument;
|
||||
}
|
||||
|
||||
return parseAlgorithm(markup, ownerDocument);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseFragment,
|
||||
parseIntoDocument
|
||||
};
|
202
node_modules/jsdom/lib/jsdom/browser/parser/xml.js
generated
vendored
Normal file
202
node_modules/jsdom/lib/jsdom/browser/parser/xml.js
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
"use strict";
|
||||
|
||||
const { SaxesParser } = require("saxes");
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
const { createElement } = require("../../living/helpers/create-element");
|
||||
|
||||
const DocumentFragment = require("../../living/generated/DocumentFragment");
|
||||
const DocumentType = require("../../living/generated/DocumentType");
|
||||
const CDATASection = require("../../living/generated/CDATASection");
|
||||
const Comment = require("../../living/generated/Comment");
|
||||
const ProcessingInstruction = require("../../living/generated/ProcessingInstruction");
|
||||
const Text = require("../../living/generated/Text");
|
||||
|
||||
const attributes = require("../../living/attributes");
|
||||
const { HTML_NS } = require("../../living/helpers/namespaces");
|
||||
|
||||
const HTML5_DOCTYPE = /<!doctype html>/i;
|
||||
const PUBLIC_DOCTYPE = /<!doctype\s+([^\s]+)\s+public\s+"([^"]+)"\s+"([^"]+)"/i;
|
||||
const SYSTEM_DOCTYPE = /<!doctype\s+([^\s]+)\s+system\s+"([^"]+)"/i;
|
||||
const CUSTOM_NAME_DOCTYPE = /<!doctype\s+([^\s>]+)/i;
|
||||
|
||||
function parseDocType(globalObject, ownerDocument, html) {
|
||||
if (HTML5_DOCTYPE.test(html)) {
|
||||
return createDocumentType(globalObject, ownerDocument, "html", "", "");
|
||||
}
|
||||
|
||||
const publicPieces = PUBLIC_DOCTYPE.exec(html);
|
||||
if (publicPieces) {
|
||||
return createDocumentType(globalObject, ownerDocument, publicPieces[1], publicPieces[2], publicPieces[3]);
|
||||
}
|
||||
|
||||
const systemPieces = SYSTEM_DOCTYPE.exec(html);
|
||||
if (systemPieces) {
|
||||
return createDocumentType(globalObject, ownerDocument, systemPieces[1], "", systemPieces[2]);
|
||||
}
|
||||
|
||||
const namePiece = CUSTOM_NAME_DOCTYPE.exec(html)[1] || "html";
|
||||
return createDocumentType(globalObject, ownerDocument, namePiece, "", "");
|
||||
}
|
||||
|
||||
function createDocumentType(globalObject, ownerDocument, name, publicId, systemId) {
|
||||
return DocumentType.createImpl(globalObject, [], { ownerDocument, name, publicId, systemId });
|
||||
}
|
||||
|
||||
function isHTMLTemplateElement(element) {
|
||||
return element.tagName === "template" && element.namespaceURI === HTML_NS;
|
||||
}
|
||||
|
||||
|
||||
function createParser(rootNode, globalObject, saxesOptions) {
|
||||
const parser = new SaxesParser({
|
||||
...saxesOptions,
|
||||
// Browsers always have namespace support.
|
||||
xmlns: true,
|
||||
// We force the parser to treat all documents (even documents declaring themselves to be XML 1.1 documents) as XML
|
||||
// 1.0 documents. See https://github.com/jsdom/jsdom/issues/2677 for a discussion of the stakes.
|
||||
defaultXMLVersion: "1.0",
|
||||
forceXMLVersion: true
|
||||
});
|
||||
const openStack = [rootNode];
|
||||
|
||||
function getOwnerDocument() {
|
||||
const currentElement = openStack[openStack.length - 1];
|
||||
|
||||
return isHTMLTemplateElement(currentElement) ?
|
||||
currentElement._templateContents._ownerDocument :
|
||||
currentElement._ownerDocument;
|
||||
}
|
||||
|
||||
function appendChild(child) {
|
||||
const parentElement = openStack[openStack.length - 1];
|
||||
|
||||
if (isHTMLTemplateElement(parentElement)) {
|
||||
parentElement._templateContents._insert(child, null);
|
||||
} else {
|
||||
parentElement._insert(child, null);
|
||||
}
|
||||
}
|
||||
|
||||
parser.on("text", saxesOptions.fragment ?
|
||||
// In a fragment, all text events produced by saxes must result in a text
|
||||
// node.
|
||||
data => {
|
||||
const ownerDocument = getOwnerDocument();
|
||||
appendChild(Text.createImpl(globalObject, [], { data, ownerDocument }));
|
||||
} :
|
||||
// When parsing a whole document, we must ignore those text nodes that are
|
||||
// produced outside the root element. Saxes produces events for them,
|
||||
// but DOM trees do not record text outside the root element.
|
||||
data => {
|
||||
if (openStack.length > 1) {
|
||||
const ownerDocument = getOwnerDocument();
|
||||
appendChild(Text.createImpl(globalObject, [], { data, ownerDocument }));
|
||||
}
|
||||
});
|
||||
|
||||
parser.on("cdata", data => {
|
||||
const ownerDocument = getOwnerDocument();
|
||||
appendChild(CDATASection.createImpl(globalObject, [], { data, ownerDocument }));
|
||||
});
|
||||
|
||||
parser.on("opentag", tag => {
|
||||
const { local: tagLocal, attributes: tagAttributes } = tag;
|
||||
|
||||
const ownerDocument = getOwnerDocument();
|
||||
const tagNamespace = tag.uri === "" ? null : tag.uri;
|
||||
const tagPrefix = tag.prefix === "" ? null : tag.prefix;
|
||||
const isValue = tagAttributes.is === undefined ? null : tagAttributes.is.value;
|
||||
|
||||
const elem = createElement(ownerDocument, tagLocal, tagNamespace, tagPrefix, isValue, true);
|
||||
|
||||
// We mark a script element as "parser-inserted", which prevents it from
|
||||
// being immediately executed.
|
||||
if (tagLocal === "script" && tagNamespace === HTML_NS) {
|
||||
elem._parserInserted = true;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(tagAttributes)) {
|
||||
const { prefix, local, uri, value } = tagAttributes[key];
|
||||
attributes.setAttributeValue(elem, local, value, prefix === "" ? null : prefix, uri === "" ? null : uri);
|
||||
}
|
||||
|
||||
appendChild(elem);
|
||||
openStack.push(elem);
|
||||
});
|
||||
|
||||
parser.on("closetag", () => {
|
||||
const elem = openStack.pop();
|
||||
// Once a script is populated, we can execute it.
|
||||
if (elem.localName === "script" && elem.namespaceURI === HTML_NS) {
|
||||
elem._eval();
|
||||
}
|
||||
});
|
||||
|
||||
parser.on("comment", data => {
|
||||
const ownerDocument = getOwnerDocument();
|
||||
appendChild(Comment.createImpl(globalObject, [], { data, ownerDocument }));
|
||||
});
|
||||
|
||||
parser.on("processinginstruction", ({ target, body }) => {
|
||||
const ownerDocument = getOwnerDocument();
|
||||
appendChild(ProcessingInstruction.createImpl(globalObject, [], { target, data: body, ownerDocument }));
|
||||
});
|
||||
|
||||
parser.on("doctype", dt => {
|
||||
const ownerDocument = getOwnerDocument();
|
||||
appendChild(parseDocType(globalObject, ownerDocument, `<!doctype ${dt}>`));
|
||||
|
||||
const entityMatcher = /<!ENTITY ([^ ]+) "([^"]+)">/g;
|
||||
let result;
|
||||
while ((result = entityMatcher.exec(dt))) {
|
||||
const [, name, value] = result;
|
||||
if (!(name in parser.ENTITIES)) {
|
||||
parser.ENTITIES[name] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
parser.on("error", err => {
|
||||
throw DOMException.create(globalObject, [err.message, "SyntaxError"]);
|
||||
});
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
function parseFragment(markup, contextElement) {
|
||||
const { _globalObject, _ownerDocument } = contextElement;
|
||||
|
||||
const fragment = DocumentFragment.createImpl(_globalObject, [], { ownerDocument: _ownerDocument });
|
||||
|
||||
// Only parseFragment needs resolvePrefix per the saxes documentation:
|
||||
// https://github.com/lddubeau/saxes#parsing-xml-fragments
|
||||
const parser = createParser(fragment, _globalObject, {
|
||||
fragment: true,
|
||||
resolvePrefix(prefix) {
|
||||
// saxes wants undefined as the return value if the prefix is not defined, not null.
|
||||
return contextElement.lookupNamespaceURI(prefix) || undefined;
|
||||
}
|
||||
});
|
||||
|
||||
parser.write(markup).close();
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
function parseIntoDocument(markup, ownerDocument) {
|
||||
const { _globalObject } = ownerDocument;
|
||||
|
||||
const parser = createParser(ownerDocument, _globalObject, {
|
||||
fileName: ownerDocument.location && ownerDocument.location.href
|
||||
});
|
||||
|
||||
parser.write(markup).close();
|
||||
|
||||
return ownerDocument;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseFragment,
|
||||
parseIntoDocument
|
||||
};
|
114
node_modules/jsdom/lib/jsdom/browser/resources/async-resource-queue.js
generated
vendored
Normal file
114
node_modules/jsdom/lib/jsdom/browser/resources/async-resource-queue.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
|
||||
class QueueItem {
|
||||
constructor(onLoad, onError, dependentItem) {
|
||||
this.onLoad = onLoad;
|
||||
this.onError = onError;
|
||||
this.data = null;
|
||||
this.error = null;
|
||||
this.dependentItem = dependentItem;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AsyncResourceQueue is the queue in charge of run the async scripts
|
||||
* and notify when they finish.
|
||||
*/
|
||||
module.exports = class AsyncResourceQueue {
|
||||
constructor() {
|
||||
this.items = new Set();
|
||||
this.dependentItems = new Set();
|
||||
}
|
||||
|
||||
count() {
|
||||
return this.items.size + this.dependentItems.size;
|
||||
}
|
||||
|
||||
_notify() {
|
||||
if (this._listener) {
|
||||
this._listener();
|
||||
}
|
||||
}
|
||||
|
||||
_check(item) {
|
||||
let promise;
|
||||
|
||||
if (item.onError && item.error) {
|
||||
promise = item.onError(item.error);
|
||||
} else if (item.onLoad && item.data) {
|
||||
promise = item.onLoad(item.data);
|
||||
}
|
||||
|
||||
promise
|
||||
.then(() => {
|
||||
this.items.delete(item);
|
||||
this.dependentItems.delete(item);
|
||||
|
||||
if (this.count() === 0) {
|
||||
this._notify();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setListener(listener) {
|
||||
this._listener = listener;
|
||||
}
|
||||
|
||||
push(request, onLoad, onError, dependentItem) {
|
||||
const q = this;
|
||||
|
||||
const item = new QueueItem(onLoad, onError, dependentItem);
|
||||
|
||||
q.items.add(item);
|
||||
|
||||
return request
|
||||
.then(data => {
|
||||
item.data = data;
|
||||
|
||||
if (dependentItem && !dependentItem.finished) {
|
||||
q.dependentItems.add(item);
|
||||
return q.items.delete(item);
|
||||
}
|
||||
|
||||
if (onLoad) {
|
||||
return q._check(item);
|
||||
}
|
||||
|
||||
q.items.delete(item);
|
||||
|
||||
if (q.count() === 0) {
|
||||
q._notify();
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.catch(err => {
|
||||
item.error = err;
|
||||
|
||||
if (dependentItem && !dependentItem.finished) {
|
||||
q.dependentItems.add(item);
|
||||
return q.items.delete(item);
|
||||
}
|
||||
|
||||
if (onError) {
|
||||
return q._check(item);
|
||||
}
|
||||
|
||||
q.items.delete(item);
|
||||
|
||||
if (q.count() === 0) {
|
||||
q._notify();
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
notifyItem(syncItem) {
|
||||
for (const item of this.dependentItems) {
|
||||
if (item.dependentItem === syncItem) {
|
||||
this._check(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
8
node_modules/jsdom/lib/jsdom/browser/resources/no-op-resource-loader.js
generated
vendored
Normal file
8
node_modules/jsdom/lib/jsdom/browser/resources/no-op-resource-loader.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
const ResourceLoader = require("./resource-loader.js");
|
||||
|
||||
module.exports = class NoOpResourceLoader extends ResourceLoader {
|
||||
fetch() {
|
||||
return null;
|
||||
}
|
||||
};
|
95
node_modules/jsdom/lib/jsdom/browser/resources/per-document-resource-loader.js
generated
vendored
Normal file
95
node_modules/jsdom/lib/jsdom/browser/resources/per-document-resource-loader.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
"use strict";
|
||||
const idlUtils = require("../../living/generated/utils");
|
||||
const { fireAnEvent } = require("../../living/helpers/events");
|
||||
|
||||
module.exports = class PerDocumentResourceLoader {
|
||||
constructor(document) {
|
||||
this._document = document;
|
||||
this._defaultEncoding = document._encoding;
|
||||
this._resourceLoader = document._defaultView ? document._defaultView._resourceLoader : null;
|
||||
this._requestManager = document._requestManager;
|
||||
this._queue = document._queue;
|
||||
this._deferQueue = document._deferQueue;
|
||||
this._asyncQueue = document._asyncQueue;
|
||||
}
|
||||
|
||||
fetch(url, { element, onLoad, onError }) {
|
||||
const request = this._resourceLoader.fetch(url, {
|
||||
cookieJar: this._document._cookieJar,
|
||||
element: idlUtils.wrapperForImpl(element),
|
||||
referrer: this._document.URL
|
||||
});
|
||||
|
||||
if (request === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this._requestManager.add(request);
|
||||
|
||||
const onErrorWrapped = error => {
|
||||
this._requestManager.remove(request);
|
||||
|
||||
if (onError) {
|
||||
onError(error);
|
||||
}
|
||||
|
||||
fireAnEvent("error", element);
|
||||
|
||||
const err = new Error(`Could not load ${element.localName}: "${url}"`);
|
||||
err.type = "resource loading";
|
||||
err.detail = error;
|
||||
|
||||
this._document._defaultView._virtualConsole.emit("jsdomError", err);
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
const onLoadWrapped = data => {
|
||||
this._requestManager.remove(request);
|
||||
|
||||
this._addCookies(url, request.response ? request.response.headers : {});
|
||||
|
||||
try {
|
||||
const result = onLoad ? onLoad(data) : undefined;
|
||||
|
||||
return Promise.resolve(result)
|
||||
.then(() => {
|
||||
fireAnEvent("load", element);
|
||||
|
||||
return Promise.resolve();
|
||||
})
|
||||
.catch(err => {
|
||||
return onErrorWrapped(err);
|
||||
});
|
||||
} catch (err) {
|
||||
return onErrorWrapped(err);
|
||||
}
|
||||
};
|
||||
|
||||
if (element.localName === "script" && element.hasAttributeNS(null, "async")) {
|
||||
this._asyncQueue.push(request, onLoadWrapped, onErrorWrapped, this._queue.getLastScript());
|
||||
} else if (element.localName === "script" && element.hasAttributeNS(null, "defer")) {
|
||||
this._deferQueue.push(request, onLoadWrapped, onErrorWrapped, false, element);
|
||||
} else {
|
||||
this._queue.push(request, onLoadWrapped, onErrorWrapped, false, element);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
_addCookies(url, headers) {
|
||||
let cookies = headers["set-cookie"];
|
||||
|
||||
if (!cookies) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(cookies)) {
|
||||
cookies = [cookies];
|
||||
}
|
||||
|
||||
cookies.forEach(cookie => {
|
||||
this._document._cookieJar.setCookieSync(cookie, url, { http: true, ignoreError: true });
|
||||
});
|
||||
}
|
||||
};
|
33
node_modules/jsdom/lib/jsdom/browser/resources/request-manager.js
generated
vendored
Normal file
33
node_modules/jsdom/lib/jsdom/browser/resources/request-manager.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Manage all the request and it is able to abort
|
||||
* all pending request.
|
||||
*/
|
||||
module.exports = class RequestManager {
|
||||
constructor() {
|
||||
this.openedRequests = [];
|
||||
}
|
||||
|
||||
add(req) {
|
||||
this.openedRequests.push(req);
|
||||
}
|
||||
|
||||
remove(req) {
|
||||
const idx = this.openedRequests.indexOf(req);
|
||||
if (idx !== -1) {
|
||||
this.openedRequests.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
for (const openedRequest of this.openedRequests) {
|
||||
openedRequest.abort();
|
||||
}
|
||||
this.openedRequests = [];
|
||||
}
|
||||
|
||||
size() {
|
||||
return this.openedRequests.length;
|
||||
}
|
||||
};
|
142
node_modules/jsdom/lib/jsdom/browser/resources/resource-loader.js
generated
vendored
Normal file
142
node_modules/jsdom/lib/jsdom/browser/resources/resource-loader.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
const fs = require("fs");
|
||||
const { fileURLToPath } = require("url");
|
||||
const { parseURL } = require("whatwg-url");
|
||||
const dataURLFromRecord = require("data-urls").fromURLRecord;
|
||||
const packageVersion = require("../../../../package.json").version;
|
||||
const agentFactory = require("../../living/helpers/agent-factory");
|
||||
const Request = require("../../living/helpers/http-request");
|
||||
|
||||
const IS_BROWSER = Object.prototype.toString.call(process) !== "[object process]";
|
||||
|
||||
module.exports = class ResourceLoader {
|
||||
constructor({
|
||||
strictSSL = true,
|
||||
proxy = undefined,
|
||||
userAgent = `Mozilla/5.0 (${process.platform || "unknown OS"}) AppleWebKit/537.36 ` +
|
||||
`(KHTML, like Gecko) jsdom/${packageVersion}`
|
||||
} = {}) {
|
||||
this._strictSSL = strictSSL;
|
||||
this._proxy = proxy;
|
||||
this._userAgent = userAgent;
|
||||
}
|
||||
|
||||
_readDataURL(urlRecord) {
|
||||
const dataURL = dataURLFromRecord(urlRecord);
|
||||
let timeoutId;
|
||||
const promise = new Promise(resolve => {
|
||||
timeoutId = setTimeout(resolve, 0, Buffer.from(dataURL.body));
|
||||
});
|
||||
promise.abort = () => {
|
||||
if (timeoutId !== undefined) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
return promise;
|
||||
}
|
||||
|
||||
_readFile(filePath) {
|
||||
let readableStream, abort; // Native Promises doesn't have an "abort" method.
|
||||
|
||||
// Creating a promise for two reason:
|
||||
// 1. fetch always return a promise.
|
||||
// 2. We need to add an abort handler.
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
readableStream = fs.createReadStream(filePath);
|
||||
let data = Buffer.alloc(0);
|
||||
|
||||
abort = reject;
|
||||
|
||||
readableStream.on("error", reject);
|
||||
|
||||
readableStream.on("data", chunk => {
|
||||
data = Buffer.concat([data, chunk]);
|
||||
});
|
||||
|
||||
readableStream.on("end", () => {
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
|
||||
promise.abort = () => {
|
||||
readableStream.destroy();
|
||||
const error = new Error("request canceled by user");
|
||||
error.isAbortError = true;
|
||||
abort(error);
|
||||
};
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
fetch(urlString, { accept, cookieJar, referrer } = {}) {
|
||||
const url = parseURL(urlString);
|
||||
|
||||
if (!url) {
|
||||
return Promise.reject(new Error(`Tried to fetch invalid URL ${urlString}`));
|
||||
}
|
||||
|
||||
switch (url.scheme) {
|
||||
case "data": {
|
||||
return this._readDataURL(url);
|
||||
}
|
||||
|
||||
case "http":
|
||||
case "https": {
|
||||
const agents = agentFactory(this._proxy, this._strictSSL);
|
||||
const headers = {
|
||||
"User-Agent": this._userAgent,
|
||||
"Accept-Language": "en",
|
||||
"Accept-Encoding": "gzip",
|
||||
"Accept": accept || "*/*"
|
||||
};
|
||||
if (referrer && !IS_BROWSER) {
|
||||
headers.Referer = referrer;
|
||||
}
|
||||
const requestClient = new Request(
|
||||
urlString,
|
||||
{ followRedirects: true, cookieJar, agents },
|
||||
{ headers }
|
||||
);
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const accumulated = [];
|
||||
requestClient.once("response", res => {
|
||||
promise.response = res;
|
||||
const { statusCode } = res;
|
||||
// TODO This deviates from the spec when it comes to
|
||||
// loading resources such as images
|
||||
if (statusCode < 200 || statusCode > 299) {
|
||||
requestClient.abort();
|
||||
reject(new Error(`Resource was not loaded. Status: ${statusCode}`));
|
||||
}
|
||||
});
|
||||
requestClient.on("data", chunk => {
|
||||
accumulated.push(chunk);
|
||||
});
|
||||
requestClient.on("end", () => resolve(Buffer.concat(accumulated)));
|
||||
requestClient.on("error", reject);
|
||||
});
|
||||
// The method fromURL in lib/api.js crashes without the following four
|
||||
// properties defined on the Promise instance, causing the test suite to halt
|
||||
requestClient.on("end", () => {
|
||||
promise.href = requestClient.currentURL;
|
||||
});
|
||||
promise.abort = requestClient.abort.bind(requestClient);
|
||||
promise.getHeader = name => headers[name] || requestClient.getHeader(name);
|
||||
requestClient.end();
|
||||
return promise;
|
||||
}
|
||||
|
||||
case "file": {
|
||||
try {
|
||||
return this._readFile(fileURLToPath(urlString));
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
return Promise.reject(new Error(`Tried to fetch URL ${urlString} with invalid scheme ${url.scheme}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
142
node_modules/jsdom/lib/jsdom/browser/resources/resource-queue.js
generated
vendored
Normal file
142
node_modules/jsdom/lib/jsdom/browser/resources/resource-queue.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Queue for all the resources to be download except async scripts.
|
||||
* Async scripts have their own queue AsyncResourceQueue.
|
||||
*/
|
||||
module.exports = class ResourceQueue {
|
||||
constructor({ paused, asyncQueue } = {}) {
|
||||
this.paused = Boolean(paused);
|
||||
this._asyncQueue = asyncQueue;
|
||||
}
|
||||
|
||||
getLastScript() {
|
||||
let head = this.tail;
|
||||
|
||||
while (head) {
|
||||
if (head.isScript) {
|
||||
return head;
|
||||
}
|
||||
head = head.prev;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_moreScripts() {
|
||||
let found = false;
|
||||
|
||||
let head = this.tail;
|
||||
while (head && !found) {
|
||||
found = head.isScript;
|
||||
head = head.prev;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
_notify() {
|
||||
if (this._listener) {
|
||||
this._listener();
|
||||
}
|
||||
}
|
||||
|
||||
setListener(listener) {
|
||||
this._listener = listener;
|
||||
}
|
||||
|
||||
push(request, onLoad, onError, keepLast, element) {
|
||||
const isScript = element ? element.localName === "script" : false;
|
||||
|
||||
if (!request) {
|
||||
if (isScript && !this._moreScripts()) {
|
||||
return onLoad();
|
||||
}
|
||||
|
||||
request = Promise.resolve();
|
||||
}
|
||||
const q = this;
|
||||
const item = {
|
||||
isScript,
|
||||
err: null,
|
||||
element,
|
||||
fired: false,
|
||||
data: null,
|
||||
keepLast,
|
||||
prev: q.tail,
|
||||
check() {
|
||||
if (!q.paused && !this.prev && this.fired) {
|
||||
let promise;
|
||||
|
||||
if (this.err && onError) {
|
||||
promise = onError(this.err);
|
||||
}
|
||||
|
||||
if (!this.err && onLoad) {
|
||||
promise = onLoad(this.data);
|
||||
}
|
||||
|
||||
Promise.resolve(promise)
|
||||
.then(() => {
|
||||
if (this.next) {
|
||||
this.next.prev = null;
|
||||
this.next.check();
|
||||
} else { // q.tail===this
|
||||
q.tail = null;
|
||||
q._notify();
|
||||
}
|
||||
|
||||
this.finished = true;
|
||||
|
||||
if (q._asyncQueue) {
|
||||
q._asyncQueue.notifyItem(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
if (q.tail) {
|
||||
if (q.tail.keepLast) {
|
||||
// if the tail is the load event in document and we receive a new element to load
|
||||
// we should add this new request before the load event.
|
||||
if (q.tail.prev) {
|
||||
q.tail.prev.next = item;
|
||||
}
|
||||
item.prev = q.tail.prev;
|
||||
q.tail.prev = item;
|
||||
item.next = q.tail;
|
||||
} else {
|
||||
q.tail.next = item;
|
||||
q.tail = item;
|
||||
}
|
||||
} else {
|
||||
q.tail = item;
|
||||
}
|
||||
return request
|
||||
.then(data => {
|
||||
item.fired = 1;
|
||||
item.data = data;
|
||||
item.check();
|
||||
})
|
||||
.catch(err => {
|
||||
item.fired = true;
|
||||
item.err = err;
|
||||
item.check();
|
||||
});
|
||||
}
|
||||
|
||||
resume() {
|
||||
if (!this.paused) {
|
||||
return;
|
||||
}
|
||||
this.paused = false;
|
||||
|
||||
let head = this.tail;
|
||||
while (head && head.prev) {
|
||||
head = head.prev;
|
||||
}
|
||||
if (head) {
|
||||
head.check();
|
||||
}
|
||||
}
|
||||
};
|
57
node_modules/jsdom/lib/jsdom/level2/style.js
generated
vendored
Normal file
57
node_modules/jsdom/lib/jsdom/level2/style.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
const cssom = require("cssom");
|
||||
const cssstyle = require("cssstyle");
|
||||
|
||||
exports.addToCore = core => {
|
||||
// What works now:
|
||||
// - Accessing the rules defined in individual stylesheets
|
||||
// - Modifications to style content attribute are reflected in style property
|
||||
// - Modifications to style property are reflected in style content attribute
|
||||
// TODO
|
||||
// - Modifications to style element's textContent are reflected in sheet property.
|
||||
// - Modifications to style element's sheet property are reflected in textContent.
|
||||
// - Modifications to link.href property are reflected in sheet property.
|
||||
// - Less-used features of link: disabled
|
||||
// - Less-used features of style: disabled, scoped, title
|
||||
// - CSSOM-View
|
||||
// - getComputedStyle(): requires default stylesheet, cascading, inheritance,
|
||||
// filtering by @media (screen? print?), layout for widths/heights
|
||||
// - Load events are not in the specs, but apparently some browsers
|
||||
// implement something. Should onload only fire after all @imports have been
|
||||
// loaded, or only the primary sheet?
|
||||
|
||||
core.StyleSheet = cssom.StyleSheet;
|
||||
core.MediaList = cssom.MediaList;
|
||||
core.CSSStyleSheet = cssom.CSSStyleSheet;
|
||||
core.CSSRule = cssom.CSSRule;
|
||||
core.CSSStyleRule = cssom.CSSStyleRule;
|
||||
core.CSSMediaRule = cssom.CSSMediaRule;
|
||||
core.CSSImportRule = cssom.CSSImportRule;
|
||||
core.CSSStyleDeclaration = cssstyle.CSSStyleDeclaration;
|
||||
|
||||
// Relevant specs
|
||||
// http://www.w3.org/TR/DOM-Level-2-Style (2000)
|
||||
// http://www.w3.org/TR/cssom-view/ (2008)
|
||||
// http://dev.w3.org/csswg/cssom/ (2010) Meant to replace DOM Level 2 Style
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/ HTML5, of course
|
||||
// http://dev.w3.org/csswg/css-style-attr/ not sure what's new here
|
||||
|
||||
// Objects that aren't in cssom library but should be:
|
||||
// CSSRuleList (cssom just uses array)
|
||||
// CSSFontFaceRule
|
||||
// CSSPageRule
|
||||
|
||||
// These rules don't really make sense to implement, so CSSOM draft makes them
|
||||
// obsolete.
|
||||
// CSSCharsetRule
|
||||
// CSSUnknownRule
|
||||
|
||||
// These objects are considered obsolete by CSSOM draft, although modern
|
||||
// browsers implement them.
|
||||
// CSSValue
|
||||
// CSSPrimitiveValue
|
||||
// CSSValueList
|
||||
// RGBColor
|
||||
// Rect
|
||||
// Counter
|
||||
};
|
1874
node_modules/jsdom/lib/jsdom/level3/xpath.js
generated
vendored
Normal file
1874
node_modules/jsdom/lib/jsdom/level3/xpath.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
node_modules/jsdom/lib/jsdom/living/aborting/AbortController-impl.js
generated
vendored
Normal file
17
node_modules/jsdom/lib/jsdom/living/aborting/AbortController-impl.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
const AbortSignal = require("../generated/AbortSignal");
|
||||
|
||||
class AbortControllerImpl {
|
||||
constructor(globalObject) {
|
||||
this.signal = AbortSignal.createImpl(globalObject, []);
|
||||
}
|
||||
|
||||
abort(reason) {
|
||||
this.signal._signalAbort(reason);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
implementation: AbortControllerImpl
|
||||
};
|
69
node_modules/jsdom/lib/jsdom/living/aborting/AbortSignal-impl.js
generated
vendored
Normal file
69
node_modules/jsdom/lib/jsdom/living/aborting/AbortSignal-impl.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
|
||||
const { setupForSimpleEventAccessors } = require("../helpers/create-event-accessor");
|
||||
const { fireAnEvent } = require("../helpers/events");
|
||||
const EventTargetImpl = require("../events/EventTarget-impl").implementation;
|
||||
const AbortSignal = require("../generated/AbortSignal");
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
class AbortSignalImpl extends EventTargetImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
super(globalObject, args, privateData);
|
||||
|
||||
// make event firing possible
|
||||
this._ownerDocument = globalObject.document;
|
||||
|
||||
this.reason = undefined;
|
||||
this.abortAlgorithms = new Set();
|
||||
}
|
||||
|
||||
get aborted() {
|
||||
return this.reason !== undefined;
|
||||
}
|
||||
|
||||
static abort(globalObject, reason) {
|
||||
const abortSignal = AbortSignal.createImpl(globalObject, []);
|
||||
if (reason !== undefined) {
|
||||
abortSignal.reason = reason;
|
||||
} else {
|
||||
abortSignal.reason = DOMException.create(globalObject, ["The operation was aborted.", "AbortError"]);
|
||||
}
|
||||
return abortSignal;
|
||||
}
|
||||
|
||||
_signalAbort(reason) {
|
||||
if (this.aborted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reason !== undefined) {
|
||||
this.reason = reason;
|
||||
} else {
|
||||
this.reason = DOMException.create(this._globalObject, ["The operation was aborted.", "AbortError"]);
|
||||
}
|
||||
|
||||
for (const algorithm of this.abortAlgorithms) {
|
||||
algorithm();
|
||||
}
|
||||
this.abortAlgorithms.clear();
|
||||
|
||||
fireAnEvent("abort", this);
|
||||
}
|
||||
|
||||
_addAlgorithm(algorithm) {
|
||||
if (this.aborted) {
|
||||
return;
|
||||
}
|
||||
this.abortAlgorithms.add(algorithm);
|
||||
}
|
||||
|
||||
_removeAlgorithm(algorithm) {
|
||||
this.abortAlgorithms.delete(algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
setupForSimpleEventAccessors(AbortSignalImpl.prototype, ["abort"]);
|
||||
|
||||
module.exports = {
|
||||
implementation: AbortSignalImpl
|
||||
};
|
312
node_modules/jsdom/lib/jsdom/living/attributes.js
generated
vendored
Normal file
312
node_modules/jsdom/lib/jsdom/living/attributes.js
generated
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
"use strict";
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
const { HTML_NS } = require("./helpers/namespaces");
|
||||
const { asciiLowercase } = require("./helpers/strings");
|
||||
const { queueAttributeMutationRecord } = require("./helpers/mutation-observers");
|
||||
const { enqueueCECallbackReaction } = require("./helpers/custom-elements");
|
||||
|
||||
// The following three are for https://dom.spec.whatwg.org/#concept-element-attribute-has. We don't just have a
|
||||
// predicate tester since removing that kind of flexibility gives us the potential for better future optimizations.
|
||||
|
||||
/* eslint-disable no-restricted-properties */
|
||||
|
||||
exports.hasAttribute = function (element, A) {
|
||||
return element._attributeList.includes(A);
|
||||
};
|
||||
|
||||
exports.hasAttributeByName = function (element, name) {
|
||||
return element._attributesByNameMap.has(name);
|
||||
};
|
||||
|
||||
exports.hasAttributeByNameNS = function (element, namespace, localName) {
|
||||
return element._attributeList.some(attribute => {
|
||||
return attribute._localName === localName && attribute._namespace === namespace;
|
||||
});
|
||||
};
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-change
|
||||
exports.changeAttribute = (element, attribute, value) => {
|
||||
const { _localName, _namespace, _value } = attribute;
|
||||
|
||||
queueAttributeMutationRecord(element, _localName, _namespace, _value);
|
||||
|
||||
if (element._ceState === "custom") {
|
||||
enqueueCECallbackReaction(element, "attributeChangedCallback", [
|
||||
_localName,
|
||||
_value,
|
||||
value,
|
||||
_namespace
|
||||
]);
|
||||
}
|
||||
|
||||
attribute._value = value;
|
||||
|
||||
// Run jsdom hooks; roughly correspond to spec's "An attribute is set and an attribute is changed."
|
||||
element._attrModified(attribute._qualifiedName, value, _value);
|
||||
};
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-append
|
||||
exports.appendAttribute = function (element, attribute) {
|
||||
const { _localName, _namespace, _value } = attribute;
|
||||
queueAttributeMutationRecord(element, _localName, _namespace, null);
|
||||
|
||||
if (element._ceState === "custom") {
|
||||
enqueueCECallbackReaction(element, "attributeChangedCallback", [
|
||||
_localName,
|
||||
null,
|
||||
_value,
|
||||
_namespace
|
||||
]);
|
||||
}
|
||||
|
||||
const attributeList = element._attributeList;
|
||||
|
||||
attributeList.push(attribute);
|
||||
attribute._element = element;
|
||||
|
||||
// Sync name cache
|
||||
const name = attribute._qualifiedName;
|
||||
const cache = element._attributesByNameMap;
|
||||
let entry = cache.get(name);
|
||||
if (!entry) {
|
||||
entry = [];
|
||||
cache.set(name, entry);
|
||||
}
|
||||
entry.push(attribute);
|
||||
|
||||
// Run jsdom hooks; roughly correspond to spec's "An attribute is set and an attribute is added."
|
||||
element._attrModified(name, _value, null);
|
||||
};
|
||||
|
||||
exports.removeAttribute = function (element, attribute) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-remove
|
||||
|
||||
const { _localName, _namespace, _value } = attribute;
|
||||
|
||||
queueAttributeMutationRecord(element, _localName, _namespace, _value);
|
||||
|
||||
if (element._ceState === "custom") {
|
||||
enqueueCECallbackReaction(element, "attributeChangedCallback", [
|
||||
_localName,
|
||||
_value,
|
||||
null,
|
||||
_namespace
|
||||
]);
|
||||
}
|
||||
|
||||
const attributeList = element._attributeList;
|
||||
|
||||
for (let i = 0; i < attributeList.length; ++i) {
|
||||
if (attributeList[i] === attribute) {
|
||||
attributeList.splice(i, 1);
|
||||
attribute._element = null;
|
||||
|
||||
// Sync name cache
|
||||
const name = attribute._qualifiedName;
|
||||
const cache = element._attributesByNameMap;
|
||||
const entry = cache.get(name);
|
||||
entry.splice(entry.indexOf(attribute), 1);
|
||||
if (entry.length === 0) {
|
||||
cache.delete(name);
|
||||
}
|
||||
|
||||
// Run jsdom hooks; roughly correspond to spec's "An attribute is removed."
|
||||
element._attrModified(name, null, attribute._value);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.replaceAttribute = function (element, oldAttr, newAttr) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-replace
|
||||
|
||||
const { _localName, _namespace, _value } = oldAttr;
|
||||
|
||||
queueAttributeMutationRecord(element, _localName, _namespace, _value);
|
||||
|
||||
if (element._ceState === "custom") {
|
||||
enqueueCECallbackReaction(element, "attributeChangedCallback", [
|
||||
_localName,
|
||||
_value,
|
||||
newAttr._value,
|
||||
_namespace
|
||||
]);
|
||||
}
|
||||
|
||||
const attributeList = element._attributeList;
|
||||
|
||||
for (let i = 0; i < attributeList.length; ++i) {
|
||||
if (attributeList[i] === oldAttr) {
|
||||
attributeList.splice(i, 1, newAttr);
|
||||
oldAttr._element = null;
|
||||
newAttr._element = element;
|
||||
|
||||
// Sync name cache
|
||||
const name = newAttr._qualifiedName;
|
||||
const cache = element._attributesByNameMap;
|
||||
let entry = cache.get(name);
|
||||
if (!entry) {
|
||||
entry = [];
|
||||
cache.set(name, entry);
|
||||
}
|
||||
entry.splice(entry.indexOf(oldAttr), 1, newAttr);
|
||||
|
||||
// Run jsdom hooks; roughly correspond to spec's "An attribute is set and an attribute is changed."
|
||||
element._attrModified(name, newAttr._value, oldAttr._value);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.getAttributeByName = function (element, name) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
||||
|
||||
if (element._namespaceURI === HTML_NS &&
|
||||
element._ownerDocument._parsingMode === "html") {
|
||||
name = asciiLowercase(name);
|
||||
}
|
||||
|
||||
const cache = element._attributesByNameMap;
|
||||
const entry = cache.get(name);
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entry[0];
|
||||
};
|
||||
|
||||
exports.getAttributeByNameNS = function (element, namespace, localName) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
|
||||
|
||||
if (namespace === "") {
|
||||
namespace = null;
|
||||
}
|
||||
|
||||
const attributeList = element._attributeList;
|
||||
for (let i = 0; i < attributeList.length; ++i) {
|
||||
const attr = attributeList[i];
|
||||
if (attr._namespace === namespace && attr._localName === localName) {
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
// Both of the following functions implement https://dom.spec.whatwg.org/#concept-element-attributes-get-value.
|
||||
// Separated them into two to keep symmetry with other functions.
|
||||
exports.getAttributeValue = function (element, localName) {
|
||||
const attr = exports.getAttributeByNameNS(element, null, localName);
|
||||
|
||||
if (!attr) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return attr._value;
|
||||
};
|
||||
|
||||
exports.getAttributeValueNS = function (element, namespace, localName) {
|
||||
const attr = exports.getAttributeByNameNS(element, namespace, localName);
|
||||
|
||||
if (!attr) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return attr._value;
|
||||
};
|
||||
|
||||
exports.setAttribute = function (element, attr) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-set
|
||||
|
||||
if (attr._element !== null && attr._element !== element) {
|
||||
throw DOMException.create(element._globalObject, ["The attribute is in use.", "InUseAttributeError"]);
|
||||
}
|
||||
|
||||
const oldAttr = exports.getAttributeByNameNS(element, attr._namespace, attr._localName);
|
||||
if (oldAttr === attr) {
|
||||
return attr;
|
||||
}
|
||||
|
||||
if (oldAttr !== null) {
|
||||
exports.replaceAttribute(element, oldAttr, attr);
|
||||
} else {
|
||||
exports.appendAttribute(element, attr);
|
||||
}
|
||||
|
||||
return oldAttr;
|
||||
};
|
||||
|
||||
exports.setAttributeValue = function (element, localName, value, prefix, namespace) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-set-value
|
||||
|
||||
if (prefix === undefined) {
|
||||
prefix = null;
|
||||
}
|
||||
if (namespace === undefined) {
|
||||
namespace = null;
|
||||
}
|
||||
|
||||
const attribute = exports.getAttributeByNameNS(element, namespace, localName);
|
||||
if (attribute === null) {
|
||||
const newAttribute = element._ownerDocument._createAttribute({
|
||||
namespace,
|
||||
namespacePrefix: prefix,
|
||||
localName,
|
||||
value
|
||||
});
|
||||
exports.appendAttribute(element, newAttribute);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
exports.changeAttribute(element, attribute, value);
|
||||
};
|
||||
|
||||
// https://dom.spec.whatwg.org/#set-an-existing-attribute-value
|
||||
exports.setAnExistingAttributeValue = (attribute, value) => {
|
||||
const element = attribute._element;
|
||||
if (element === null) {
|
||||
attribute._value = value;
|
||||
} else {
|
||||
exports.changeAttribute(element, attribute, value);
|
||||
}
|
||||
};
|
||||
|
||||
exports.removeAttributeByName = function (element, name) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
|
||||
|
||||
const attr = exports.getAttributeByName(element, name);
|
||||
|
||||
if (attr !== null) {
|
||||
exports.removeAttribute(element, attr);
|
||||
}
|
||||
|
||||
return attr;
|
||||
};
|
||||
|
||||
exports.removeAttributeByNameNS = function (element, namespace, localName) {
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
|
||||
|
||||
const attr = exports.getAttributeByNameNS(element, namespace, localName);
|
||||
|
||||
if (attr !== null) {
|
||||
exports.removeAttribute(element, attr);
|
||||
}
|
||||
|
||||
return attr;
|
||||
};
|
||||
|
||||
exports.attributeNames = function (element) {
|
||||
// Needed by https://dom.spec.whatwg.org/#dom-element-getattributenames
|
||||
|
||||
return element._attributeList.map(a => a._qualifiedName);
|
||||
};
|
||||
|
||||
exports.hasAttributes = function (element) {
|
||||
// Needed by https://dom.spec.whatwg.org/#dom-element-hasattributes
|
||||
|
||||
return element._attributeList.length > 0;
|
||||
};
|
60
node_modules/jsdom/lib/jsdom/living/attributes/Attr-impl.js
generated
vendored
Normal file
60
node_modules/jsdom/lib/jsdom/living/attributes/Attr-impl.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
|
||||
const { setAnExistingAttributeValue } = require("../attributes.js");
|
||||
const NodeImpl = require("../nodes/Node-impl.js").implementation;
|
||||
const { ATTRIBUTE_NODE } = require("../node-type.js");
|
||||
|
||||
exports.implementation = class AttrImpl extends NodeImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
super(globalObject, args, privateData);
|
||||
|
||||
this._namespace = privateData.namespace !== undefined ? privateData.namespace : null;
|
||||
this._namespacePrefix = privateData.namespacePrefix !== undefined ? privateData.namespacePrefix : null;
|
||||
this._localName = privateData.localName;
|
||||
this._value = privateData.value !== undefined ? privateData.value : "";
|
||||
this._element = privateData.element !== undefined ? privateData.element : null;
|
||||
|
||||
this.nodeType = ATTRIBUTE_NODE;
|
||||
this.specified = true;
|
||||
}
|
||||
|
||||
get namespaceURI() {
|
||||
return this._namespace;
|
||||
}
|
||||
|
||||
get prefix() {
|
||||
return this._namespacePrefix;
|
||||
}
|
||||
|
||||
get localName() {
|
||||
return this._localName;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._qualifiedName;
|
||||
}
|
||||
|
||||
get nodeName() {
|
||||
return this._qualifiedName;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
set value(value) {
|
||||
setAnExistingAttributeValue(this, value);
|
||||
}
|
||||
|
||||
get ownerElement() {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
get _qualifiedName() {
|
||||
// https://dom.spec.whatwg.org/#concept-attribute-qualified-name
|
||||
if (this._namespacePrefix === null) {
|
||||
return this._localName;
|
||||
}
|
||||
|
||||
return this._namespacePrefix + ":" + this._localName;
|
||||
}
|
||||
};
|
78
node_modules/jsdom/lib/jsdom/living/attributes/NamedNodeMap-impl.js
generated
vendored
Normal file
78
node_modules/jsdom/lib/jsdom/living/attributes/NamedNodeMap-impl.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
const idlUtils = require("../generated/utils.js");
|
||||
const attributes = require("../attributes.js");
|
||||
const { HTML_NS } = require("../helpers/namespaces");
|
||||
|
||||
exports.implementation = class NamedNodeMapImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
this._element = privateData.element;
|
||||
|
||||
this._globalObject = globalObject;
|
||||
}
|
||||
get _attributeList() {
|
||||
return this._element._attributeList;
|
||||
}
|
||||
|
||||
get [idlUtils.supportedPropertyIndices]() {
|
||||
return this._attributeList.keys();
|
||||
}
|
||||
get length() {
|
||||
return this._attributeList.length;
|
||||
}
|
||||
item(index) {
|
||||
if (index >= this._attributeList.length) {
|
||||
return null;
|
||||
}
|
||||
return this._attributeList[index];
|
||||
}
|
||||
|
||||
get [idlUtils.supportedPropertyNames]() {
|
||||
const names = new Set(this._attributeList.map(a => a._qualifiedName));
|
||||
const el = this._element;
|
||||
if (el._namespaceURI === HTML_NS && el._ownerDocument._parsingMode === "html") {
|
||||
for (const name of names) {
|
||||
const lowercaseName = name.toLowerCase();
|
||||
if (lowercaseName !== name) {
|
||||
names.delete(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
getNamedItem(qualifiedName) {
|
||||
return attributes.getAttributeByName(this._element, qualifiedName);
|
||||
}
|
||||
getNamedItemNS(namespace, localName) {
|
||||
return attributes.getAttributeByNameNS(this._element, namespace, localName);
|
||||
}
|
||||
setNamedItem(attr) {
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
return attributes.setAttribute(this._element, attr);
|
||||
}
|
||||
setNamedItemNS(attr) {
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
return attributes.setAttribute(this._element, attr);
|
||||
}
|
||||
removeNamedItem(qualifiedName) {
|
||||
const attr = attributes.removeAttributeByName(this._element, qualifiedName);
|
||||
if (attr === null) {
|
||||
throw DOMException.create(this._globalObject, [
|
||||
"Tried to remove an attribute that was not present",
|
||||
"NotFoundError"
|
||||
]);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
removeNamedItemNS(namespace, localName) {
|
||||
const attr = attributes.removeAttributeByNameNS(this._element, namespace, localName);
|
||||
if (attr === null) {
|
||||
throw DOMException.create(this._globalObject, [
|
||||
"Tried to remove an attribute that was not present",
|
||||
"NotFoundError"
|
||||
]);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
};
|
75
node_modules/jsdom/lib/jsdom/living/constraint-validation/DefaultConstraintValidation-impl.js
generated
vendored
Normal file
75
node_modules/jsdom/lib/jsdom/living/constraint-validation/DefaultConstraintValidation-impl.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
|
||||
const ValidityState = require("../generated/ValidityState");
|
||||
const { isDisabled } = require("../helpers/form-controls");
|
||||
const { closest } = require("../helpers/traversal");
|
||||
const { fireAnEvent } = require("../helpers/events");
|
||||
|
||||
exports.implementation = class DefaultConstraintValidationImpl {
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-willvalidate
|
||||
get willValidate() {
|
||||
return this._isCandidateForConstraintValidation();
|
||||
}
|
||||
|
||||
get validity() {
|
||||
if (!this._validity) {
|
||||
this._validity = ValidityState.createImpl(this._globalObject, [], {
|
||||
element: this
|
||||
});
|
||||
}
|
||||
return this._validity;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-checkvalidity
|
||||
checkValidity() {
|
||||
if (!this._isCandidateForConstraintValidation()) {
|
||||
return true;
|
||||
}
|
||||
if (this._satisfiesConstraints()) {
|
||||
return true;
|
||||
}
|
||||
fireAnEvent("invalid", this, undefined, { cancelable: true });
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-setcustomvalidity
|
||||
setCustomValidity(message) {
|
||||
this._customValidityErrorMessage = message;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
|
||||
// Since jsdom has no user interaction, it's the same as #checkValidity
|
||||
reportValidity() {
|
||||
return this.checkValidity();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-validationmessage
|
||||
get validationMessage() {
|
||||
const { validity } = this;
|
||||
if (!this._isCandidateForConstraintValidation() || this._satisfiesConstraints()) {
|
||||
return "";
|
||||
}
|
||||
const isSufferingFromCustomError = validity.customError;
|
||||
if (isSufferingFromCustomError) {
|
||||
return this._customValidityErrorMessage;
|
||||
}
|
||||
return "Constraints not satisfied";
|
||||
}
|
||||
|
||||
_isCandidateForConstraintValidation() {
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
|
||||
return !isDisabled(this) &&
|
||||
// If an element has a datalist element ancestor,
|
||||
// it is barred from constraint validation.
|
||||
closest(this, "datalist") === null &&
|
||||
!this._barredFromConstraintValidationSpecialization();
|
||||
}
|
||||
|
||||
_isBarredFromConstraintValidation() {
|
||||
return !this._isCandidateForConstraintValidation();
|
||||
}
|
||||
|
||||
_satisfiesConstraints() {
|
||||
return this.validity.valid;
|
||||
}
|
||||
};
|
66
node_modules/jsdom/lib/jsdom/living/constraint-validation/ValidityState-impl.js
generated
vendored
Normal file
66
node_modules/jsdom/lib/jsdom/living/constraint-validation/ValidityState-impl.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
|
||||
exports.implementation = class ValidityStateImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
const { element, state = {} } = privateData;
|
||||
|
||||
this._element = element;
|
||||
this._state = state;
|
||||
}
|
||||
|
||||
get badInput() {
|
||||
return this._failsConstraint("badInput");
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-custom-error
|
||||
get customError() {
|
||||
return this._element._customValidityErrorMessage !== "";
|
||||
}
|
||||
|
||||
get patternMismatch() {
|
||||
return this._failsConstraint("patternMismatch");
|
||||
}
|
||||
|
||||
get rangeOverflow() {
|
||||
return this._failsConstraint("rangeOverflow");
|
||||
}
|
||||
|
||||
get rangeUnderflow() {
|
||||
return this._failsConstraint("rangeUnderflow");
|
||||
}
|
||||
|
||||
get stepMismatch() {
|
||||
return this._failsConstraint("stepMismatch");
|
||||
}
|
||||
|
||||
get tooLong() {
|
||||
return this._failsConstraint("tooLong");
|
||||
}
|
||||
|
||||
get tooShort() {
|
||||
return this._failsConstraint("tooShort");
|
||||
}
|
||||
|
||||
get typeMismatch() {
|
||||
return this._failsConstraint("typeMismatch");
|
||||
}
|
||||
|
||||
get valueMissing() {
|
||||
return this._failsConstraint("valueMissing");
|
||||
}
|
||||
|
||||
_failsConstraint(method) {
|
||||
const validationMethod = this._state[method];
|
||||
if (validationMethod) {
|
||||
return validationMethod();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
get valid() {
|
||||
return !(this.badInput || this.valueMissing || this.customError ||
|
||||
this.patternMismatch || this.rangeOverflow || this.rangeUnderflow ||
|
||||
this.stepMismatch || this.tooLong || this.tooShort || this.typeMismatch);
|
||||
}
|
||||
};
|
47
node_modules/jsdom/lib/jsdom/living/crypto/Crypto-impl.js
generated
vendored
Normal file
47
node_modules/jsdom/lib/jsdom/living/crypto/Crypto-impl.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
|
||||
const nodeCrypto = require("crypto");
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
// https://w3c.github.io/webcrypto/#crypto-interface
|
||||
class CryptoImpl {
|
||||
constructor(globalObject) {
|
||||
this._globalObject = globalObject;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues
|
||||
getRandomValues(array) {
|
||||
// Note: this rejects Float32Array, Float64Array and DataView.
|
||||
//
|
||||
// We perform "instance tests" by comparing `array.constructor.name` so
|
||||
// that the tests will be successful across realms.
|
||||
const typeName = array.constructor.name;
|
||||
if (!(typeName === "Int8Array" ||
|
||||
typeName === "Uint8Array" ||
|
||||
typeName === "Uint8ClampedArray" ||
|
||||
typeName === "Int16Array" ||
|
||||
typeName === "Uint16Array" ||
|
||||
typeName === "Int32Array" ||
|
||||
typeName === "Uint32Array" ||
|
||||
typeName === "BigInt64Array" ||
|
||||
typeName === "BigUint64Array")) {
|
||||
throw DOMException.create(this._globalObject, [
|
||||
`getRandomValues() only accepts integer typed arrays`,
|
||||
"TypeMismatchError"
|
||||
]);
|
||||
}
|
||||
|
||||
if (array.byteLength > 65536) {
|
||||
throw DOMException.create(this._globalObject, [
|
||||
`getRandomValues() cannot generate more than 65536 bytes of random values; ` +
|
||||
`${array.byteLength} bytes were requested`,
|
||||
"QuotaExceededError"
|
||||
]);
|
||||
}
|
||||
|
||||
nodeCrypto.randomFillSync(array);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
exports.implementation = CryptoImpl;
|
38
node_modules/jsdom/lib/jsdom/living/cssom/StyleSheetList-impl.js
generated
vendored
Normal file
38
node_modules/jsdom/lib/jsdom/living/cssom/StyleSheetList-impl.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
|
||||
const idlUtils = require("../generated/utils.js");
|
||||
|
||||
exports.implementation = class StyleSheetList {
|
||||
constructor() {
|
||||
this._list = [];
|
||||
}
|
||||
|
||||
get length() {
|
||||
return this._list.length;
|
||||
}
|
||||
|
||||
item(index) {
|
||||
const result = this._list[index];
|
||||
return result !== undefined ? result : null;
|
||||
}
|
||||
|
||||
get [idlUtils.supportedPropertyIndices]() {
|
||||
return this._list.keys();
|
||||
}
|
||||
|
||||
_add(sheet) {
|
||||
const { _list } = this;
|
||||
if (!_list.includes(sheet)) {
|
||||
_list.push(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
_remove(sheet) {
|
||||
const { _list } = this;
|
||||
|
||||
const index = _list.indexOf(sheet);
|
||||
if (index >= 0) {
|
||||
_list.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
265
node_modules/jsdom/lib/jsdom/living/custom-elements/CustomElementRegistry-impl.js
generated
vendored
Normal file
265
node_modules/jsdom/lib/jsdom/living/custom-elements/CustomElementRegistry-impl.js
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
"use strict";
|
||||
|
||||
const webIDLConversions = require("webidl-conversions");
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
const NODE_TYPE = require("../node-type");
|
||||
|
||||
const { HTML_NS } = require("../helpers/namespaces");
|
||||
const { getHTMLElementInterface } = require("../helpers/create-element");
|
||||
const { shadowIncludingInclusiveDescendantsIterator } = require("../helpers/shadow-dom");
|
||||
const { isValidCustomElementName, tryUpgradeElement, enqueueCEUpgradeReaction } = require("../helpers/custom-elements");
|
||||
|
||||
const idlUtils = require("../generated/utils");
|
||||
const IDLFunction = require("../generated/Function.js");
|
||||
const HTMLUnknownElement = require("../generated/HTMLUnknownElement");
|
||||
|
||||
const LIFECYCLE_CALLBACKS = [
|
||||
"connectedCallback",
|
||||
"disconnectedCallback",
|
||||
"adoptedCallback",
|
||||
"attributeChangedCallback"
|
||||
];
|
||||
|
||||
function convertToSequenceDOMString(obj) {
|
||||
if (!obj || !obj[Symbol.iterator]) {
|
||||
throw new TypeError("Invalid Sequence");
|
||||
}
|
||||
|
||||
return Array.from(obj).map(webIDLConversions.DOMString);
|
||||
}
|
||||
|
||||
// Returns true is the passed value is a valid constructor.
|
||||
// Borrowed from: https://stackoverflow.com/a/39336206/3832710
|
||||
function isConstructor(value) {
|
||||
if (typeof value !== "function") {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const P = new Proxy(value, {
|
||||
construct() {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new P();
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#customelementregistry
|
||||
class CustomElementRegistryImpl {
|
||||
constructor(globalObject) {
|
||||
this._customElementDefinitions = [];
|
||||
this._elementDefinitionIsRunning = false;
|
||||
this._whenDefinedPromiseMap = Object.create(null);
|
||||
|
||||
this._globalObject = globalObject;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#dom-customelementregistry-define
|
||||
define(name, constructor, options) {
|
||||
const { _globalObject } = this;
|
||||
const ctor = constructor.objectReference;
|
||||
|
||||
if (!isConstructor(ctor)) {
|
||||
throw new TypeError("Constructor argument is not a constructor.");
|
||||
}
|
||||
|
||||
if (!isValidCustomElementName(name)) {
|
||||
throw DOMException.create(_globalObject, ["Name argument is not a valid custom element name.", "SyntaxError"]);
|
||||
}
|
||||
|
||||
const nameAlreadyRegistered = this._customElementDefinitions.some(entry => entry.name === name);
|
||||
if (nameAlreadyRegistered) {
|
||||
throw DOMException.create(_globalObject, [
|
||||
"This name has already been registered in the registry.",
|
||||
"NotSupportedError"
|
||||
]);
|
||||
}
|
||||
|
||||
const ctorAlreadyRegistered = this._customElementDefinitions.some(entry => entry.objectReference === ctor);
|
||||
if (ctorAlreadyRegistered) {
|
||||
throw DOMException.create(_globalObject, [
|
||||
"This constructor has already been registered in the registry.",
|
||||
"NotSupportedError"
|
||||
]);
|
||||
}
|
||||
|
||||
let localName = name;
|
||||
|
||||
let extendsOption = null;
|
||||
if (options !== undefined && options.extends) {
|
||||
extendsOption = options.extends;
|
||||
}
|
||||
|
||||
if (extendsOption !== null) {
|
||||
if (isValidCustomElementName(extendsOption)) {
|
||||
throw DOMException.create(_globalObject, [
|
||||
"Option extends value can't be a valid custom element name.",
|
||||
"NotSupportedError"
|
||||
]);
|
||||
}
|
||||
|
||||
const extendsInterface = getHTMLElementInterface(extendsOption);
|
||||
if (extendsInterface === HTMLUnknownElement) {
|
||||
throw DOMException.create(_globalObject, [
|
||||
`${extendsOption} is an HTMLUnknownElement.`,
|
||||
"NotSupportedError"
|
||||
]);
|
||||
}
|
||||
|
||||
localName = extendsOption;
|
||||
}
|
||||
|
||||
if (this._elementDefinitionIsRunning) {
|
||||
throw DOMException.create(_globalObject, [
|
||||
"Invalid nested custom element definition.",
|
||||
"NotSupportedError"
|
||||
]);
|
||||
}
|
||||
|
||||
this._elementDefinitionIsRunning = true;
|
||||
|
||||
let disableShadow = false;
|
||||
let observedAttributes = [];
|
||||
const lifecycleCallbacks = {
|
||||
connectedCallback: null,
|
||||
disconnectedCallback: null,
|
||||
adoptedCallback: null,
|
||||
attributeChangedCallback: null
|
||||
};
|
||||
|
||||
let caughtError;
|
||||
try {
|
||||
const { prototype } = ctor;
|
||||
|
||||
if (typeof prototype !== "object") {
|
||||
throw new TypeError("Invalid constructor prototype.");
|
||||
}
|
||||
|
||||
for (const callbackName of LIFECYCLE_CALLBACKS) {
|
||||
const callbackValue = prototype[callbackName];
|
||||
|
||||
if (callbackValue !== undefined) {
|
||||
lifecycleCallbacks[callbackName] = IDLFunction.convert(_globalObject, callbackValue, {
|
||||
context: `The lifecycle callback "${callbackName}"`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (lifecycleCallbacks.attributeChangedCallback !== null) {
|
||||
const observedAttributesIterable = ctor.observedAttributes;
|
||||
|
||||
if (observedAttributesIterable !== undefined) {
|
||||
observedAttributes = convertToSequenceDOMString(observedAttributesIterable);
|
||||
}
|
||||
}
|
||||
|
||||
let disabledFeatures = [];
|
||||
const disabledFeaturesIterable = ctor.disabledFeatures;
|
||||
if (disabledFeaturesIterable) {
|
||||
disabledFeatures = convertToSequenceDOMString(disabledFeaturesIterable);
|
||||
}
|
||||
|
||||
disableShadow = disabledFeatures.includes("shadow");
|
||||
} catch (err) {
|
||||
caughtError = err;
|
||||
} finally {
|
||||
this._elementDefinitionIsRunning = false;
|
||||
}
|
||||
|
||||
if (caughtError !== undefined) {
|
||||
throw caughtError;
|
||||
}
|
||||
|
||||
const definition = {
|
||||
name,
|
||||
localName,
|
||||
constructor,
|
||||
objectReference: ctor,
|
||||
observedAttributes,
|
||||
lifecycleCallbacks,
|
||||
disableShadow,
|
||||
constructionStack: []
|
||||
};
|
||||
|
||||
this._customElementDefinitions.push(definition);
|
||||
|
||||
const document = idlUtils.implForWrapper(this._globalObject._document);
|
||||
|
||||
const upgradeCandidates = [];
|
||||
for (const candidate of shadowIncludingInclusiveDescendantsIterator(document)) {
|
||||
if (
|
||||
(candidate._namespaceURI === HTML_NS && candidate._localName === localName) &&
|
||||
(extendsOption === null || candidate._isValue === name)
|
||||
) {
|
||||
upgradeCandidates.push(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
for (const upgradeCandidate of upgradeCandidates) {
|
||||
enqueueCEUpgradeReaction(upgradeCandidate, definition);
|
||||
}
|
||||
|
||||
if (this._whenDefinedPromiseMap[name] !== undefined) {
|
||||
this._whenDefinedPromiseMap[name].resolve(ctor);
|
||||
delete this._whenDefinedPromiseMap[name];
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#dom-customelementregistry-get
|
||||
get(name) {
|
||||
const definition = this._customElementDefinitions.find(entry => entry.name === name);
|
||||
return definition && definition.objectReference;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#dom-customelementregistry-whendefined
|
||||
whenDefined(name) {
|
||||
if (!isValidCustomElementName(name)) {
|
||||
return Promise.reject(DOMException.create(
|
||||
this._globalObject,
|
||||
["Name argument is not a valid custom element name.", "SyntaxError"]
|
||||
));
|
||||
}
|
||||
|
||||
const alreadyRegistered = this._customElementDefinitions.find(entry => entry.name === name);
|
||||
if (alreadyRegistered) {
|
||||
return Promise.resolve(alreadyRegistered.objectReference);
|
||||
}
|
||||
|
||||
if (this._whenDefinedPromiseMap[name] === undefined) {
|
||||
let resolve;
|
||||
const promise = new Promise(r => {
|
||||
resolve = r;
|
||||
});
|
||||
|
||||
// Store the pending Promise along with the extracted resolve callback to actually resolve the returned Promise,
|
||||
// once the custom element is registered.
|
||||
this._whenDefinedPromiseMap[name] = {
|
||||
promise,
|
||||
resolve
|
||||
};
|
||||
}
|
||||
|
||||
return this._whenDefinedPromiseMap[name].promise;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#dom-customelementregistry-upgrade
|
||||
upgrade(root) {
|
||||
for (const candidate of shadowIncludingInclusiveDescendantsIterator(root)) {
|
||||
if (candidate.nodeType === NODE_TYPE.ELEMENT_NODE) {
|
||||
tryUpgradeElement(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
implementation: CustomElementRegistryImpl
|
||||
};
|
15
node_modules/jsdom/lib/jsdom/living/documents.js
generated
vendored
Normal file
15
node_modules/jsdom/lib/jsdom/living/documents.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
const XMLDocument = require("../living/generated/XMLDocument.js");
|
||||
const Document = require("../living/generated/Document.js");
|
||||
const { wrapperForImpl } = require("./generated/utils.js");
|
||||
|
||||
exports.createImpl = (globalObject, options, { alwaysUseDocumentClass = false } = {}) => {
|
||||
if (options.parsingMode === "xml" && !alwaysUseDocumentClass) {
|
||||
return XMLDocument.createImpl(globalObject, [], { options });
|
||||
}
|
||||
return Document.createImpl(globalObject, [], { options });
|
||||
};
|
||||
|
||||
exports.createWrapper = (...args) => {
|
||||
return wrapperForImpl(exports.createImpl(...args));
|
||||
};
|
58
node_modules/jsdom/lib/jsdom/living/domparsing/DOMParser-impl.js
generated
vendored
Normal file
58
node_modules/jsdom/lib/jsdom/living/domparsing/DOMParser-impl.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
|
||||
const { parseIntoDocument } = require("../../browser/parser");
|
||||
|
||||
const Document = require("../generated/Document");
|
||||
|
||||
exports.implementation = class DOMParserImpl {
|
||||
constructor(globalObject) {
|
||||
this._globalObject = globalObject;
|
||||
}
|
||||
|
||||
parseFromString(string, contentType) {
|
||||
switch (String(contentType)) {
|
||||
case "text/html": {
|
||||
return this.createScriptingDisabledDocument("html", contentType, string);
|
||||
}
|
||||
|
||||
case "text/xml":
|
||||
case "application/xml":
|
||||
case "application/xhtml+xml":
|
||||
case "image/svg+xml": {
|
||||
try {
|
||||
return this.createScriptingDisabledDocument("xml", contentType, string);
|
||||
} catch (error) {
|
||||
const document = this.createScriptingDisabledDocument("xml", contentType);
|
||||
const element = document.createElementNS("http://www.mozilla.org/newlayout/xml/parsererror.xml", "parsererror");
|
||||
|
||||
element.textContent = error.message;
|
||||
|
||||
document.appendChild(element);
|
||||
return document;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
throw new TypeError("Invalid contentType");
|
||||
}
|
||||
}
|
||||
|
||||
createScriptingDisabledDocument(parsingMode, contentType, string) {
|
||||
const document = Document.createImpl(this._globalObject, [], {
|
||||
options: {
|
||||
parsingMode,
|
||||
encoding: "UTF-8",
|
||||
contentType,
|
||||
readyState: "complete",
|
||||
scriptingDisabled: true
|
||||
// TODO: somehow set URL to active document's URL
|
||||
}
|
||||
});
|
||||
|
||||
if (string !== undefined) {
|
||||
parseIntoDocument(string, document);
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
};
|
30
node_modules/jsdom/lib/jsdom/living/domparsing/InnerHTML-impl.js
generated
vendored
Normal file
30
node_modules/jsdom/lib/jsdom/living/domparsing/InnerHTML-impl.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
|
||||
const { parseFragment } = require("../../browser/parser");
|
||||
const { HTML_NS } = require("../helpers/namespaces.js");
|
||||
const { isShadowRoot } = require("../helpers/shadow-dom.js");
|
||||
const NODE_TYPE = require("../node-type.js");
|
||||
const { fragmentSerialization } = require("./serialization.js");
|
||||
|
||||
// https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin
|
||||
exports.implementation = class InnerHTMLImpl {
|
||||
// https://w3c.github.io/DOM-Parsing/#dom-innerhtml-innerhtml
|
||||
get innerHTML() {
|
||||
return fragmentSerialization(this, {
|
||||
outer: false,
|
||||
requireWellFormed: true,
|
||||
globalObject: this._globalObject
|
||||
});
|
||||
}
|
||||
set innerHTML(markup) {
|
||||
const contextElement = isShadowRoot(this) ? this.host : this;
|
||||
const fragment = parseFragment(markup, contextElement);
|
||||
|
||||
let contextObject = this;
|
||||
if (this.nodeType === NODE_TYPE.ELEMENT_NODE && this.localName === "template" && this.namespaceURI === HTML_NS) {
|
||||
contextObject = this._templateContents;
|
||||
}
|
||||
|
||||
contextObject._replaceAll(fragment);
|
||||
}
|
||||
};
|
18
node_modules/jsdom/lib/jsdom/living/domparsing/XMLSerializer-impl.js
generated
vendored
Normal file
18
node_modules/jsdom/lib/jsdom/living/domparsing/XMLSerializer-impl.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
const serialize = require("w3c-xmlserializer");
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
const utils = require("../generated/utils");
|
||||
|
||||
exports.implementation = class XMLSerializerImpl {
|
||||
constructor(globalObject) {
|
||||
this._globalObject = globalObject;
|
||||
}
|
||||
|
||||
serializeToString(root) {
|
||||
try {
|
||||
return serialize(utils.wrapperForImpl(root), { requireWellFormed: false });
|
||||
} catch (e) {
|
||||
throw DOMException.create(this._globalObject, [e.message, "InvalidStateError"]);
|
||||
}
|
||||
}
|
||||
};
|
63
node_modules/jsdom/lib/jsdom/living/domparsing/parse5-adapter-serialization.js
generated
vendored
Normal file
63
node_modules/jsdom/lib/jsdom/living/domparsing/parse5-adapter-serialization.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
"use strict";
|
||||
const nodeTypes = require("../node-type");
|
||||
const { domSymbolTree } = require("../helpers/internal-constants");
|
||||
// Serialization only requires a subset of the tree adapter interface.
|
||||
|
||||
// Tree traversing
|
||||
exports.getFirstChild = node => node.firstChild;
|
||||
|
||||
exports.getChildNodes = node => domSymbolTree.childrenToArray(node);
|
||||
|
||||
exports.getParentNode = node => node.parentNode;
|
||||
|
||||
exports.getAttrList = element => {
|
||||
const attributeList = [...element._attributeList];
|
||||
|
||||
if (element._isValue && attributeList.every(attr => attr.name !== "is")) {
|
||||
attributeList.unshift({
|
||||
name: "is",
|
||||
namespace: null,
|
||||
prefix: null,
|
||||
value: element._isValue
|
||||
});
|
||||
}
|
||||
|
||||
return attributeList;
|
||||
};
|
||||
|
||||
// Node data
|
||||
exports.getTagName = element => element._qualifiedName; // https://github.com/inikulin/parse5/issues/231
|
||||
|
||||
exports.getNamespaceURI = element => element.namespaceURI;
|
||||
|
||||
exports.getTextNodeContent = exports.getCommentNodeContent = node => node.data;
|
||||
|
||||
exports.getDocumentTypeNodeName = node => node.name;
|
||||
|
||||
exports.getDocumentTypeNodePublicId = node => node.publicId;
|
||||
|
||||
exports.getDocumentTypeNodeSystemId = node => node.systemId;
|
||||
|
||||
exports.getTemplateContent = templateElement => templateElement._templateContents;
|
||||
|
||||
exports.getDocumentMode = document => document._mode;
|
||||
|
||||
// Node types
|
||||
exports.isTextNode = node => node.nodeType === nodeTypes.TEXT_NODE;
|
||||
|
||||
exports.isCommentNode = node => node.nodeType === nodeTypes.COMMENT_NODE;
|
||||
|
||||
exports.isDocumentTypeNode = node => node.nodeType === nodeTypes.DOCUMENT_TYPE_NODE;
|
||||
|
||||
exports.isElementNode = node => node.nodeType === nodeTypes.ELEMENT_NODE;
|
||||
|
||||
// Source code location
|
||||
exports.setNodeSourceCodeLocation = (node, location) => {
|
||||
node.sourceCodeLocation = location;
|
||||
};
|
||||
|
||||
exports.getNodeSourceCodeLocation = node => node.sourceCodeLocation;
|
||||
|
||||
exports.updateNodeSourceCodeLocation = (node, endLocation) => {
|
||||
Object.assign(node.sourceCodeLocation, endLocation);
|
||||
};
|
36
node_modules/jsdom/lib/jsdom/living/domparsing/serialization.js
generated
vendored
Normal file
36
node_modules/jsdom/lib/jsdom/living/domparsing/serialization.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
|
||||
const produceXMLSerialization = require("w3c-xmlserializer");
|
||||
const parse5 = require("parse5");
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
const utils = require("../generated/utils");
|
||||
const treeAdapter = require("./parse5-adapter-serialization");
|
||||
const NODE_TYPE = require("../node-type");
|
||||
|
||||
module.exports.fragmentSerialization = (node, { outer, requireWellFormed, globalObject }) => {
|
||||
const contextDocument =
|
||||
node.nodeType === NODE_TYPE.DOCUMENT_NODE ? node : node._ownerDocument;
|
||||
if (contextDocument._parsingMode === "html") {
|
||||
const config = {
|
||||
...contextDocument._parseOptions,
|
||||
treeAdapter
|
||||
};
|
||||
return outer ? parse5.serializeOuter(node, config) : parse5.serialize(node, config);
|
||||
}
|
||||
|
||||
const childNodes = outer ? [node] : node.childNodes;
|
||||
|
||||
try {
|
||||
let serialized = "";
|
||||
for (let i = 0; i < childNodes.length; ++i) {
|
||||
serialized += produceXMLSerialization(
|
||||
utils.wrapperForImpl(childNodes[i] || childNodes.item(i)),
|
||||
{ requireWellFormed }
|
||||
);
|
||||
}
|
||||
return serialized;
|
||||
} catch (e) {
|
||||
throw DOMException.create(globalObject, [e.message, "InvalidStateError"]);
|
||||
}
|
||||
};
|
10
node_modules/jsdom/lib/jsdom/living/events/CloseEvent-impl.js
generated
vendored
Normal file
10
node_modules/jsdom/lib/jsdom/living/events/CloseEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const CloseEventInit = require("../generated/CloseEventInit");
|
||||
|
||||
class CloseEventImpl extends EventImpl {}
|
||||
CloseEventImpl.defaultInit = CloseEventInit.convert(undefined, undefined);
|
||||
|
||||
exports.implementation = CloseEventImpl;
|
20
node_modules/jsdom/lib/jsdom/living/events/CompositionEvent-impl.js
generated
vendored
Normal file
20
node_modules/jsdom/lib/jsdom/living/events/CompositionEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
const UIEventImpl = require("./UIEvent-impl").implementation;
|
||||
const CompositionEventInit = require("../generated/CompositionEventInit");
|
||||
|
||||
class CompositionEventImpl extends UIEventImpl {
|
||||
initCompositionEvent(type, bubbles, cancelable, view, data) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initUIEvent(type, bubbles, cancelable, view, 0);
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
CompositionEventImpl.defaultInit = CompositionEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: CompositionEventImpl
|
||||
};
|
21
node_modules/jsdom/lib/jsdom/living/events/CustomEvent-impl.js
generated
vendored
Normal file
21
node_modules/jsdom/lib/jsdom/living/events/CustomEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const CustomEventInit = require("../generated/CustomEventInit");
|
||||
|
||||
class CustomEventImpl extends EventImpl {
|
||||
initCustomEvent(type, bubbles, cancelable, detail) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initEvent(type, bubbles, cancelable);
|
||||
this.detail = detail;
|
||||
}
|
||||
}
|
||||
CustomEventImpl.defaultInit = CustomEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: CustomEventImpl
|
||||
};
|
14
node_modules/jsdom/lib/jsdom/living/events/ErrorEvent-impl.js
generated
vendored
Normal file
14
node_modules/jsdom/lib/jsdom/living/events/ErrorEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const ErrorEventInit = require("../generated/ErrorEventInit");
|
||||
|
||||
class ErrorEventImpl extends EventImpl {
|
||||
|
||||
}
|
||||
ErrorEventImpl.defaultInit = ErrorEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: ErrorEventImpl
|
||||
};
|
197
node_modules/jsdom/lib/jsdom/living/events/Event-impl.js
generated
vendored
Normal file
197
node_modules/jsdom/lib/jsdom/living/events/Event-impl.js
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
"use strict";
|
||||
|
||||
const idlUtils = require("../generated/utils");
|
||||
const EventInit = require("../generated/EventInit");
|
||||
|
||||
class EventImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
const [type, eventInitDict = this.constructor.defaultInit] = args;
|
||||
|
||||
this.type = type;
|
||||
|
||||
this.bubbles = false;
|
||||
this.cancelable = false;
|
||||
for (const key in eventInitDict) {
|
||||
if (key in this.constructor.defaultInit) {
|
||||
this[key] = eventInitDict[key];
|
||||
}
|
||||
}
|
||||
for (const key in this.constructor.defaultInit) {
|
||||
if (!(key in this)) {
|
||||
this[key] = this.constructor.defaultInit[key];
|
||||
}
|
||||
}
|
||||
|
||||
this.target = null;
|
||||
this.currentTarget = null;
|
||||
this.eventPhase = 0;
|
||||
|
||||
this._globalObject = globalObject;
|
||||
this._initializedFlag = true;
|
||||
this._stopPropagationFlag = false;
|
||||
this._stopImmediatePropagationFlag = false;
|
||||
this._canceledFlag = false;
|
||||
this._inPassiveListenerFlag = false;
|
||||
this._dispatchFlag = false;
|
||||
this._path = [];
|
||||
|
||||
this.isTrusted = privateData.isTrusted || false;
|
||||
this.timeStamp = Date.now();
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#set-the-canceled-flag
|
||||
_setTheCanceledFlag() {
|
||||
if (this.cancelable && !this._inPassiveListenerFlag) {
|
||||
this._canceledFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
get srcElement() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
get returnValue() {
|
||||
return !this._canceledFlag;
|
||||
}
|
||||
|
||||
set returnValue(v) {
|
||||
if (v === false) {
|
||||
this._setTheCanceledFlag();
|
||||
}
|
||||
}
|
||||
|
||||
get defaultPrevented() {
|
||||
return this._canceledFlag;
|
||||
}
|
||||
|
||||
stopPropagation() {
|
||||
this._stopPropagationFlag = true;
|
||||
}
|
||||
|
||||
get cancelBubble() {
|
||||
return this._stopPropagationFlag;
|
||||
}
|
||||
|
||||
set cancelBubble(v) {
|
||||
if (v) {
|
||||
this._stopPropagationFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
stopImmediatePropagation() {
|
||||
this._stopPropagationFlag = true;
|
||||
this._stopImmediatePropagationFlag = true;
|
||||
}
|
||||
|
||||
preventDefault() {
|
||||
this._setTheCanceledFlag();
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-event-composedpath
|
||||
// Current implementation is based of https://whatpr.org/dom/699.html#dom-event-composedpath
|
||||
// due to a bug in composed path implementation https://github.com/whatwg/dom/issues/684
|
||||
composedPath() {
|
||||
const composedPath = [];
|
||||
|
||||
const { currentTarget, _path: path } = this;
|
||||
|
||||
if (path.length === 0) {
|
||||
return composedPath;
|
||||
}
|
||||
|
||||
composedPath.push(currentTarget);
|
||||
|
||||
let currentTargetIndex = 0;
|
||||
let currentTargetHiddenSubtreeLevel = 0;
|
||||
|
||||
for (let index = path.length - 1; index >= 0; index--) {
|
||||
const { item, rootOfClosedTree, slotInClosedTree } = path[index];
|
||||
|
||||
if (rootOfClosedTree) {
|
||||
currentTargetHiddenSubtreeLevel++;
|
||||
}
|
||||
|
||||
if (item === idlUtils.implForWrapper(currentTarget)) {
|
||||
currentTargetIndex = index;
|
||||
break;
|
||||
}
|
||||
|
||||
if (slotInClosedTree) {
|
||||
currentTargetHiddenSubtreeLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
let currentHiddenLevel = currentTargetHiddenSubtreeLevel;
|
||||
let maxHiddenLevel = currentTargetHiddenSubtreeLevel;
|
||||
|
||||
for (let i = currentTargetIndex - 1; i >= 0; i--) {
|
||||
const { item, rootOfClosedTree, slotInClosedTree } = path[i];
|
||||
|
||||
if (rootOfClosedTree) {
|
||||
currentHiddenLevel++;
|
||||
}
|
||||
|
||||
if (currentHiddenLevel <= maxHiddenLevel) {
|
||||
composedPath.unshift(idlUtils.wrapperForImpl(item));
|
||||
}
|
||||
|
||||
if (slotInClosedTree) {
|
||||
currentHiddenLevel--;
|
||||
if (currentHiddenLevel < maxHiddenLevel) {
|
||||
maxHiddenLevel = currentHiddenLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentHiddenLevel = currentTargetHiddenSubtreeLevel;
|
||||
maxHiddenLevel = currentTargetHiddenSubtreeLevel;
|
||||
|
||||
for (let index = currentTargetIndex + 1; index < path.length; index++) {
|
||||
const { item, rootOfClosedTree, slotInClosedTree } = path[index];
|
||||
|
||||
if (slotInClosedTree) {
|
||||
currentHiddenLevel++;
|
||||
}
|
||||
|
||||
if (currentHiddenLevel <= maxHiddenLevel) {
|
||||
composedPath.push(idlUtils.wrapperForImpl(item));
|
||||
}
|
||||
|
||||
if (rootOfClosedTree) {
|
||||
currentHiddenLevel--;
|
||||
if (currentHiddenLevel < maxHiddenLevel) {
|
||||
maxHiddenLevel = currentHiddenLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return composedPath;
|
||||
}
|
||||
|
||||
_initialize(type, bubbles, cancelable) {
|
||||
this.type = type;
|
||||
this._initializedFlag = true;
|
||||
|
||||
this._stopPropagationFlag = false;
|
||||
this._stopImmediatePropagationFlag = false;
|
||||
this._canceledFlag = false;
|
||||
|
||||
this.isTrusted = false;
|
||||
this.target = null;
|
||||
this.bubbles = bubbles;
|
||||
this.cancelable = cancelable;
|
||||
}
|
||||
|
||||
initEvent(type, bubbles, cancelable) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._initialize(type, bubbles, cancelable);
|
||||
}
|
||||
}
|
||||
EventImpl.defaultInit = EventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: EventImpl
|
||||
};
|
18
node_modules/jsdom/lib/jsdom/living/events/EventModifierMixin-impl.js
generated
vendored
Normal file
18
node_modules/jsdom/lib/jsdom/living/events/EventModifierMixin-impl.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
// This mixin doesn't have an IDL equivalent, but since MouseEvent and KeyboardEvent implement getModifierState() the
|
||||
// same way, its implementation is shared here.
|
||||
|
||||
class EventModifierMixinImpl {
|
||||
// Event's constructor assumes all options correspond to IDL attributes with the same names, and sets them on `this`.
|
||||
// That is not the case for these modifier boolean options, but since the options are set on `this` anyway we'll
|
||||
// access them that way. The spec doesn't say much about the case where keyArg is not one of the valid ones
|
||||
// (https://w3c.github.io/uievents-key/#keys-modifier), but at least Chrome returns false for invalid modifiers. Since
|
||||
// these invalid modifiers will be undefined on `this` (thus `false` after casting it to boolean), we don't need to do
|
||||
// extra checking for validity.
|
||||
getModifierState(keyArg) {
|
||||
return Boolean(this[`modifier${keyArg}`]);
|
||||
}
|
||||
}
|
||||
|
||||
exports.implementation = EventModifierMixinImpl;
|
419
node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js
generated
vendored
Normal file
419
node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js
generated
vendored
Normal file
@@ -0,0 +1,419 @@
|
||||
"use strict";
|
||||
const DOMException = require("domexception/webidl2js-wrapper");
|
||||
|
||||
const reportException = require("../helpers/runtime-script-errors");
|
||||
const idlUtils = require("../generated/utils");
|
||||
const { nodeRoot } = require("../helpers/node");
|
||||
const {
|
||||
isNode, isShadowRoot, isSlotable, getEventTargetParent,
|
||||
isShadowInclusiveAncestor, retarget
|
||||
} = require("../helpers/shadow-dom");
|
||||
|
||||
const MouseEvent = require("../generated/MouseEvent");
|
||||
|
||||
const EVENT_PHASE = {
|
||||
NONE: 0,
|
||||
CAPTURING_PHASE: 1,
|
||||
AT_TARGET: 2,
|
||||
BUBBLING_PHASE: 3
|
||||
};
|
||||
|
||||
class EventTargetImpl {
|
||||
constructor(globalObject) {
|
||||
this._globalObject = globalObject;
|
||||
this._eventListeners = Object.create(null);
|
||||
}
|
||||
|
||||
addEventListener(type, callback, options) {
|
||||
options = normalizeEventHandlerOptions(options, ["capture", "once", "passive"]);
|
||||
|
||||
if (options.signal !== null && options.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._eventListeners[type]) {
|
||||
this._eventListeners[type] = [];
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._eventListeners[type].length; ++i) {
|
||||
const listener = this._eventListeners[type][i];
|
||||
if (
|
||||
listener.callback.objectReference === callback.objectReference &&
|
||||
listener.options.capture === options.capture
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this._eventListeners[type].push({
|
||||
callback,
|
||||
options
|
||||
});
|
||||
|
||||
if (options.signal !== null) {
|
||||
options.signal._addAlgorithm(() => {
|
||||
this.removeEventListener(type, callback, options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
removeEventListener(type, callback, options) {
|
||||
options = normalizeEventHandlerOptions(options, ["capture"]);
|
||||
|
||||
if (callback === null) {
|
||||
// Optimization, not in the spec.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._eventListeners[type]) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._eventListeners[type].length; ++i) {
|
||||
const listener = this._eventListeners[type][i];
|
||||
if (
|
||||
listener.callback.objectReference === callback.objectReference &&
|
||||
listener.options.capture === options.capture
|
||||
) {
|
||||
this._eventListeners[type].splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatchEvent(eventImpl) {
|
||||
if (eventImpl._dispatchFlag || !eventImpl._initializedFlag) {
|
||||
throw DOMException.create(this._globalObject, [
|
||||
"Tried to dispatch an uninitialized event",
|
||||
"InvalidStateError"
|
||||
]);
|
||||
}
|
||||
if (eventImpl.eventPhase !== EVENT_PHASE.NONE) {
|
||||
throw DOMException.create(this._globalObject, [
|
||||
"Tried to dispatch a dispatching event",
|
||||
"InvalidStateError"
|
||||
]);
|
||||
}
|
||||
|
||||
eventImpl.isTrusted = false;
|
||||
|
||||
return this._dispatch(eventImpl);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#get-the-parent
|
||||
_getTheParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-event-dispatch
|
||||
// legacyOutputDidListenersThrowFlag optional parameter is not necessary here since it is only used by indexDB.
|
||||
_dispatch(eventImpl, legacyTargetOverrideFlag /* , legacyOutputDidListenersThrowFlag */) {
|
||||
let targetImpl = this;
|
||||
let clearTargets = false;
|
||||
let activationTarget = null;
|
||||
|
||||
eventImpl._dispatchFlag = true;
|
||||
|
||||
const targetOverride = legacyTargetOverrideFlag ?
|
||||
idlUtils.implForWrapper(targetImpl._globalObject._document) :
|
||||
targetImpl;
|
||||
let relatedTarget = retarget(eventImpl.relatedTarget, targetImpl);
|
||||
|
||||
if (targetImpl !== relatedTarget || targetImpl === eventImpl.relatedTarget) {
|
||||
const touchTargets = [];
|
||||
|
||||
appendToEventPath(eventImpl, targetImpl, targetOverride, relatedTarget, touchTargets, false);
|
||||
|
||||
const isActivationEvent = MouseEvent.isImpl(eventImpl) && eventImpl.type === "click";
|
||||
|
||||
if (isActivationEvent && targetImpl._hasActivationBehavior) {
|
||||
activationTarget = targetImpl;
|
||||
}
|
||||
|
||||
let slotInClosedTree = false;
|
||||
let slotable = isSlotable(targetImpl) && targetImpl._assignedSlot ? targetImpl : null;
|
||||
let parent = getEventTargetParent(targetImpl, eventImpl);
|
||||
|
||||
// Populate event path
|
||||
// https://dom.spec.whatwg.org/#event-path
|
||||
while (parent !== null) {
|
||||
if (slotable !== null) {
|
||||
if (parent.localName !== "slot") {
|
||||
throw new Error(`JSDOM Internal Error: Expected parent to be a Slot`);
|
||||
}
|
||||
|
||||
slotable = null;
|
||||
|
||||
const parentRoot = nodeRoot(parent);
|
||||
if (isShadowRoot(parentRoot) && parentRoot.mode === "closed") {
|
||||
slotInClosedTree = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSlotable(parent) && parent._assignedSlot) {
|
||||
slotable = parent;
|
||||
}
|
||||
|
||||
relatedTarget = retarget(eventImpl.relatedTarget, parent);
|
||||
|
||||
if (
|
||||
(isNode(parent) && isShadowInclusiveAncestor(nodeRoot(targetImpl), parent)) ||
|
||||
idlUtils.wrapperForImpl(parent).constructor.name === "Window"
|
||||
) {
|
||||
if (isActivationEvent && eventImpl.bubbles && activationTarget === null &&
|
||||
parent._hasActivationBehavior) {
|
||||
activationTarget = parent;
|
||||
}
|
||||
|
||||
appendToEventPath(eventImpl, parent, null, relatedTarget, touchTargets, slotInClosedTree);
|
||||
} else if (parent === relatedTarget) {
|
||||
parent = null;
|
||||
} else {
|
||||
targetImpl = parent;
|
||||
|
||||
if (isActivationEvent && activationTarget === null && targetImpl._hasActivationBehavior) {
|
||||
activationTarget = targetImpl;
|
||||
}
|
||||
|
||||
appendToEventPath(eventImpl, parent, targetImpl, relatedTarget, touchTargets, slotInClosedTree);
|
||||
}
|
||||
|
||||
if (parent !== null) {
|
||||
parent = getEventTargetParent(parent, eventImpl);
|
||||
}
|
||||
|
||||
slotInClosedTree = false;
|
||||
}
|
||||
|
||||
let clearTargetsStructIndex = -1;
|
||||
for (let i = eventImpl._path.length - 1; i >= 0 && clearTargetsStructIndex === -1; i--) {
|
||||
if (eventImpl._path[i].target !== null) {
|
||||
clearTargetsStructIndex = i;
|
||||
}
|
||||
}
|
||||
const clearTargetsStruct = eventImpl._path[clearTargetsStructIndex];
|
||||
|
||||
clearTargets =
|
||||
(isNode(clearTargetsStruct.target) && isShadowRoot(nodeRoot(clearTargetsStruct.target))) ||
|
||||
(isNode(clearTargetsStruct.relatedTarget) && isShadowRoot(nodeRoot(clearTargetsStruct.relatedTarget)));
|
||||
|
||||
if (activationTarget !== null && activationTarget._legacyPreActivationBehavior) {
|
||||
activationTarget._legacyPreActivationBehavior();
|
||||
}
|
||||
|
||||
for (let i = eventImpl._path.length - 1; i >= 0; --i) {
|
||||
const struct = eventImpl._path[i];
|
||||
|
||||
if (struct.target !== null) {
|
||||
eventImpl.eventPhase = EVENT_PHASE.AT_TARGET;
|
||||
} else {
|
||||
eventImpl.eventPhase = EVENT_PHASE.CAPTURING_PHASE;
|
||||
}
|
||||
|
||||
invokeEventListeners(struct, eventImpl, "capturing");
|
||||
}
|
||||
|
||||
for (let i = 0; i < eventImpl._path.length; i++) {
|
||||
const struct = eventImpl._path[i];
|
||||
|
||||
if (struct.target !== null) {
|
||||
eventImpl.eventPhase = EVENT_PHASE.AT_TARGET;
|
||||
} else {
|
||||
if (!eventImpl.bubbles) {
|
||||
continue;
|
||||
}
|
||||
|
||||
eventImpl.eventPhase = EVENT_PHASE.BUBBLING_PHASE;
|
||||
}
|
||||
|
||||
invokeEventListeners(struct, eventImpl, "bubbling");
|
||||
}
|
||||
}
|
||||
|
||||
eventImpl.eventPhase = EVENT_PHASE.NONE;
|
||||
|
||||
eventImpl.currentTarget = null;
|
||||
eventImpl._path = [];
|
||||
eventImpl._dispatchFlag = false;
|
||||
eventImpl._stopPropagationFlag = false;
|
||||
eventImpl._stopImmediatePropagationFlag = false;
|
||||
|
||||
if (clearTargets) {
|
||||
eventImpl.target = null;
|
||||
eventImpl.relatedTarget = null;
|
||||
}
|
||||
|
||||
if (activationTarget !== null) {
|
||||
if (!eventImpl._canceledFlag) {
|
||||
activationTarget._activationBehavior(eventImpl);
|
||||
} else if (activationTarget._legacyCanceledActivationBehavior) {
|
||||
activationTarget._legacyCanceledActivationBehavior();
|
||||
}
|
||||
}
|
||||
|
||||
return !eventImpl._canceledFlag;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
implementation: EventTargetImpl
|
||||
};
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-event-listener-invoke
|
||||
function invokeEventListeners(struct, eventImpl, phase) {
|
||||
const structIndex = eventImpl._path.indexOf(struct);
|
||||
for (let i = structIndex; i >= 0; i--) {
|
||||
const t = eventImpl._path[i];
|
||||
if (t.target) {
|
||||
eventImpl.target = t.target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eventImpl.relatedTarget = idlUtils.wrapperForImpl(struct.relatedTarget);
|
||||
|
||||
if (eventImpl._stopPropagationFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
eventImpl.currentTarget = idlUtils.wrapperForImpl(struct.item);
|
||||
|
||||
const listeners = struct.item._eventListeners;
|
||||
innerInvokeEventListeners(eventImpl, listeners, phase, struct.itemInShadowTree);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
|
||||
function innerInvokeEventListeners(eventImpl, listeners, phase, itemInShadowTree) {
|
||||
let found = false;
|
||||
|
||||
const { type, target } = eventImpl;
|
||||
const wrapper = idlUtils.wrapperForImpl(target);
|
||||
|
||||
if (!listeners || !listeners[type]) {
|
||||
return found;
|
||||
}
|
||||
|
||||
// Copy event listeners before iterating since the list can be modified during the iteration.
|
||||
const handlers = listeners[type].slice();
|
||||
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
const listener = handlers[i];
|
||||
const { capture, once, passive } = listener.options;
|
||||
|
||||
// Check if the event listener has been removed since the listeners has been cloned.
|
||||
if (!listeners[type].includes(listener)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
|
||||
if (
|
||||
(phase === "capturing" && !capture) ||
|
||||
(phase === "bubbling" && capture)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (once) {
|
||||
listeners[type].splice(listeners[type].indexOf(listener), 1);
|
||||
}
|
||||
|
||||
let window = null;
|
||||
if (wrapper && wrapper._document) {
|
||||
// Triggered by Window
|
||||
window = wrapper;
|
||||
} else if (target._ownerDocument) {
|
||||
// Triggered by most webidl2js'ed instances
|
||||
window = target._ownerDocument._defaultView;
|
||||
} else if (wrapper._ownerDocument) {
|
||||
// Currently triggered by some non-webidl2js things
|
||||
window = wrapper._ownerDocument._defaultView;
|
||||
}
|
||||
|
||||
let currentEvent;
|
||||
if (window) {
|
||||
currentEvent = window._currentEvent;
|
||||
if (!itemInShadowTree) {
|
||||
window._currentEvent = eventImpl;
|
||||
}
|
||||
}
|
||||
|
||||
if (passive) {
|
||||
eventImpl._inPassiveListenerFlag = true;
|
||||
}
|
||||
|
||||
try {
|
||||
listener.callback.call(eventImpl.currentTarget, eventImpl);
|
||||
} catch (e) {
|
||||
if (window) {
|
||||
reportException(window, e);
|
||||
}
|
||||
// Errors in window-less documents just get swallowed... can you think of anything better?
|
||||
}
|
||||
|
||||
eventImpl._inPassiveListenerFlag = false;
|
||||
|
||||
if (window) {
|
||||
window._currentEvent = currentEvent;
|
||||
}
|
||||
|
||||
if (eventImpl._stopImmediatePropagationFlag) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the event listeners options argument in order to get always a valid options object
|
||||
* @param {Object} options - user defined options
|
||||
* @param {Array} defaultBoolKeys - boolean properties that should belong to the options object
|
||||
* @returns {Object} object containing at least the "defaultBoolKeys"
|
||||
*/
|
||||
function normalizeEventHandlerOptions(options, defaultBoolKeys) {
|
||||
const returnValue = { signal: null };
|
||||
|
||||
// no need to go further here
|
||||
if (typeof options === "boolean" || options === null || typeof options === "undefined") {
|
||||
returnValue.capture = Boolean(options);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// non objects options so we typecast its value as "capture" value
|
||||
if (typeof options !== "object") {
|
||||
returnValue.capture = Boolean(options);
|
||||
// at this point we don't need to loop the "capture" key anymore
|
||||
defaultBoolKeys = defaultBoolKeys.filter(k => k !== "capture");
|
||||
}
|
||||
|
||||
for (const key of defaultBoolKeys) {
|
||||
returnValue[key] = Boolean(options[key]);
|
||||
}
|
||||
|
||||
if (options.signal !== undefined) {
|
||||
returnValue.signal = options.signal;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-event-path-append
|
||||
function appendToEventPath(eventImpl, target, targetOverride, relatedTarget, touchTargets, slotInClosedTree) {
|
||||
const itemInShadowTree = isNode(target) && isShadowRoot(nodeRoot(target));
|
||||
const rootOfClosedTree = isShadowRoot(target) && target.mode === "closed";
|
||||
|
||||
eventImpl._path.push({
|
||||
item: target,
|
||||
itemInShadowTree,
|
||||
target: targetOverride,
|
||||
relatedTarget,
|
||||
touchTargets,
|
||||
rootOfClosedTree,
|
||||
slotInClosedTree
|
||||
});
|
||||
}
|
9
node_modules/jsdom/lib/jsdom/living/events/FocusEvent-impl.js
generated
vendored
Normal file
9
node_modules/jsdom/lib/jsdom/living/events/FocusEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
const UIEventImpl = require("./UIEvent-impl").implementation;
|
||||
|
||||
const FocusEventInit = require("../generated/FocusEventInit");
|
||||
|
||||
class FocusEventImpl extends UIEventImpl {}
|
||||
FocusEventImpl.defaultInit = FocusEventInit.convert(undefined, undefined);
|
||||
|
||||
exports.implementation = FocusEventImpl;
|
14
node_modules/jsdom/lib/jsdom/living/events/HashChangeEvent-impl.js
generated
vendored
Normal file
14
node_modules/jsdom/lib/jsdom/living/events/HashChangeEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const HashChangeEventInit = require("../generated/HashChangeEventInit");
|
||||
|
||||
class HashChangeEventImpl extends EventImpl {
|
||||
|
||||
}
|
||||
HashChangeEventImpl.defaultInit = HashChangeEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: HashChangeEventImpl
|
||||
};
|
11
node_modules/jsdom/lib/jsdom/living/events/InputEvent-impl.js
generated
vendored
Normal file
11
node_modules/jsdom/lib/jsdom/living/events/InputEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
const UIEventImpl = require("./UIEvent-impl").implementation;
|
||||
const InputEventInit = require("../generated/InputEventInit");
|
||||
|
||||
// https://w3c.github.io/uievents/#interface-inputevent
|
||||
class InputEventImpl extends UIEventImpl { }
|
||||
InputEventImpl.defaultInit = InputEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: InputEventImpl
|
||||
};
|
29
node_modules/jsdom/lib/jsdom/living/events/KeyboardEvent-impl.js
generated
vendored
Normal file
29
node_modules/jsdom/lib/jsdom/living/events/KeyboardEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
|
||||
const { mixin } = require("../../utils");
|
||||
const EventModifierMixinImpl = require("./EventModifierMixin-impl").implementation;
|
||||
const UIEventImpl = require("./UIEvent-impl").implementation;
|
||||
|
||||
const KeyboardEventInit = require("../generated/KeyboardEventInit");
|
||||
|
||||
class KeyboardEventImpl extends UIEventImpl {
|
||||
initKeyboardEvent(type, bubbles, cancelable, view, key, location, ctrlKey, altKey, shiftKey, metaKey) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initUIEvent(type, bubbles, cancelable, view, 0);
|
||||
this.key = key;
|
||||
this.location = location;
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.altKey = altKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.metaKey = metaKey;
|
||||
}
|
||||
}
|
||||
mixin(KeyboardEventImpl.prototype, EventModifierMixinImpl.prototype);
|
||||
KeyboardEventImpl.defaultInit = KeyboardEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: KeyboardEventImpl
|
||||
};
|
25
node_modules/jsdom/lib/jsdom/living/events/MessageEvent-impl.js
generated
vendored
Normal file
25
node_modules/jsdom/lib/jsdom/living/events/MessageEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const MessageEventInit = require("../generated/MessageEventInit");
|
||||
|
||||
class MessageEventImpl extends EventImpl {
|
||||
initMessageEvent(type, bubbles, cancelable, data, origin, lastEventId, source, ports) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initEvent(type, bubbles, cancelable);
|
||||
this.data = data;
|
||||
this.origin = origin;
|
||||
this.lastEventId = lastEventId;
|
||||
this.source = source;
|
||||
this.ports = ports;
|
||||
}
|
||||
}
|
||||
MessageEventImpl.defaultInit = MessageEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: MessageEventImpl
|
||||
};
|
49
node_modules/jsdom/lib/jsdom/living/events/MouseEvent-impl.js
generated
vendored
Normal file
49
node_modules/jsdom/lib/jsdom/living/events/MouseEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
|
||||
const { mixin } = require("../../utils");
|
||||
const EventModifierMixinImpl = require("./EventModifierMixin-impl").implementation;
|
||||
const UIEventImpl = require("./UIEvent-impl").implementation;
|
||||
|
||||
const MouseEventInit = require("../generated/MouseEventInit");
|
||||
|
||||
class MouseEventImpl extends UIEventImpl {
|
||||
initMouseEvent(
|
||||
type,
|
||||
bubbles,
|
||||
cancelable,
|
||||
view,
|
||||
detail,
|
||||
screenX,
|
||||
screenY,
|
||||
clientX,
|
||||
clientY,
|
||||
ctrlKey,
|
||||
altKey,
|
||||
shiftKey,
|
||||
metaKey,
|
||||
button,
|
||||
relatedTarget
|
||||
) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initUIEvent(type, bubbles, cancelable, view, detail);
|
||||
this.screenX = screenX;
|
||||
this.screenY = screenY;
|
||||
this.clientX = clientX;
|
||||
this.clientY = clientY;
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.altKey = altKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.metaKey = metaKey;
|
||||
this.button = button;
|
||||
this.relatedTarget = relatedTarget;
|
||||
}
|
||||
}
|
||||
mixin(MouseEventImpl.prototype, EventModifierMixinImpl.prototype);
|
||||
MouseEventImpl.defaultInit = MouseEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: MouseEventImpl
|
||||
};
|
20
node_modules/jsdom/lib/jsdom/living/events/PageTransitionEvent-impl.js
generated
vendored
Normal file
20
node_modules/jsdom/lib/jsdom/living/events/PageTransitionEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const PageTransitionEventInit = require("../generated/PageTransitionEventInit");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#pagetransitionevent
|
||||
class PageTransitionEventImpl extends EventImpl {
|
||||
initPageTransitionEvent(type, bubbles, cancelable, persisted) {
|
||||
if (this._dispatchFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initEvent(type, bubbles, cancelable);
|
||||
this.persisted = persisted;
|
||||
}
|
||||
}
|
||||
PageTransitionEventImpl.defaultInit = PageTransitionEventInit.convert(undefined, undefined);
|
||||
|
||||
exports.implementation = PageTransitionEventImpl;
|
9
node_modules/jsdom/lib/jsdom/living/events/PopStateEvent-impl.js
generated
vendored
Normal file
9
node_modules/jsdom/lib/jsdom/living/events/PopStateEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
const EventImpl = require("./Event-impl.js").implementation;
|
||||
|
||||
const PopStateEventInit = require("../generated/PopStateEventInit");
|
||||
|
||||
class PopStateEventImpl extends EventImpl {}
|
||||
PopStateEventImpl.defaultInit = PopStateEventInit.convert(undefined, undefined);
|
||||
|
||||
exports.implementation = PopStateEventImpl;
|
14
node_modules/jsdom/lib/jsdom/living/events/ProgressEvent-impl.js
generated
vendored
Normal file
14
node_modules/jsdom/lib/jsdom/living/events/ProgressEvent-impl.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
const EventImpl = require("./Event-impl").implementation;
|
||||
|
||||
const ProgressEventInit = require("../generated/ProgressEventInit");
|
||||
|
||||
class ProgressEventImpl extends EventImpl {
|
||||
|
||||
}
|
||||
ProgressEventImpl.defaultInit = ProgressEventInit.convert(undefined, undefined);
|
||||
|
||||
module.exports = {
|
||||
implementation: ProgressEventImpl
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user