| "use strict"; | ||
| const { TextDecoder } = require("@exodus/bytes/encoding.js"); | ||
| // A thin wrapper is needed since there are constructor arguments, which mismatches webidl2js's assumed pattern. | ||
| exports.implementation = class TextDecoderImpl { | ||
| constructor(globalObject, [label, options]) { | ||
| this._innerImpl = new TextDecoder(label, options); | ||
| } | ||
| decode(input, options) { | ||
| return this._innerImpl.decode(input, options); | ||
| } | ||
| get encoding() { | ||
| return this._innerImpl.encoding; | ||
| } | ||
| get fatal() { | ||
| return this._innerImpl.fatal; | ||
| } | ||
| get ignoreBOM() { | ||
| return this._innerImpl.ignoreBOM; | ||
| } | ||
| }; |
| "use strict"; | ||
| const { TextEncoder } = require("@exodus/bytes/encoding.js"); | ||
| // No wrapper needed since there are no constructor arguments. | ||
| exports.implementation = TextEncoder; |
| "use strict"; | ||
| const conversions = require("webidl-conversions"); | ||
| const utils = require("./utils.js"); | ||
| exports._convertInherit = (globalObject, obj, ret, { context = "The provided value" } = {}) => { | ||
| { | ||
| const key = "stream"; | ||
| let value = obj === undefined || obj === null ? undefined : obj[key]; | ||
| if (value !== undefined) { | ||
| value = conversions["boolean"](value, { context: context + " has member 'stream' that", globals: globalObject }); | ||
| ret[key] = value; | ||
| } else { | ||
| ret[key] = false; | ||
| } | ||
| } | ||
| }; | ||
| exports.convert = (globalObject, obj, { context = "The provided value" } = {}) => { | ||
| if (obj !== undefined && typeof obj !== "object" && typeof obj !== "function") { | ||
| throw new globalObject.TypeError(`${context} is not an object.`); | ||
| } | ||
| const ret = Object.create(null); | ||
| exports._convertInherit(globalObject, obj, ret, { context }); | ||
| return ret; | ||
| }; |
| "use strict"; | ||
| const conversions = require("webidl-conversions"); | ||
| const utils = require("./utils.js"); | ||
| const TextDecoderOptions = require("./TextDecoderOptions.js"); | ||
| const TextDecodeOptions = require("./TextDecodeOptions.js"); | ||
| const implSymbol = utils.implSymbol; | ||
| const ctorRegistrySymbol = utils.ctorRegistrySymbol; | ||
| const interfaceName = "TextDecoder"; | ||
| exports.is = value => { | ||
| return utils.isObject(value) && Object.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation; | ||
| }; | ||
| exports.isImpl = value => { | ||
| return utils.isObject(value) && value instanceof Impl.implementation; | ||
| }; | ||
| exports.convert = (globalObject, value, { context = "The provided value" } = {}) => { | ||
| if (exports.is(value)) { | ||
| return utils.implForWrapper(value); | ||
| } | ||
| throw new globalObject.TypeError(`${context} is not of type 'TextDecoder'.`); | ||
| }; | ||
| function makeWrapper(globalObject, newTarget) { | ||
| let proto; | ||
| if (newTarget !== undefined) { | ||
| proto = newTarget.prototype; | ||
| } | ||
| if (!utils.isObject(proto)) { | ||
| proto = globalObject[ctorRegistrySymbol]["TextDecoder"].prototype; | ||
| } | ||
| return Object.create(proto); | ||
| } | ||
| exports.create = (globalObject, constructorArgs, privateData) => { | ||
| const wrapper = makeWrapper(globalObject); | ||
| return exports.setup(wrapper, globalObject, constructorArgs, privateData); | ||
| }; | ||
| exports.createImpl = (globalObject, constructorArgs, privateData) => { | ||
| const wrapper = exports.create(globalObject, constructorArgs, privateData); | ||
| return utils.implForWrapper(wrapper); | ||
| }; | ||
| exports._internalSetup = (wrapper, globalObject) => {}; | ||
| exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => { | ||
| privateData.wrapper = wrapper; | ||
| exports._internalSetup(wrapper, globalObject); | ||
| Object.defineProperty(wrapper, implSymbol, { | ||
| value: new Impl.implementation(globalObject, constructorArgs, privateData), | ||
| configurable: true | ||
| }); | ||
| wrapper[implSymbol][utils.wrapperSymbol] = wrapper; | ||
| if (Impl.init) { | ||
| Impl.init(wrapper[implSymbol]); | ||
| } | ||
| return wrapper; | ||
| }; | ||
| exports.new = (globalObject, newTarget) => { | ||
| const wrapper = makeWrapper(globalObject, newTarget); | ||
| exports._internalSetup(wrapper, globalObject); | ||
| Object.defineProperty(wrapper, implSymbol, { | ||
| value: Object.create(Impl.implementation.prototype), | ||
| configurable: true | ||
| }); | ||
| wrapper[implSymbol][utils.wrapperSymbol] = wrapper; | ||
| if (Impl.init) { | ||
| Impl.init(wrapper[implSymbol]); | ||
| } | ||
| return wrapper[implSymbol]; | ||
| }; | ||
| const exposed = new Set(["Window"]); | ||
| exports.install = (globalObject, globalNames) => { | ||
| if (!globalNames.some(globalName => exposed.has(globalName))) { | ||
| return; | ||
| } | ||
| const ctorRegistry = utils.initCtorRegistry(globalObject); | ||
| class TextDecoder { | ||
| constructor() { | ||
| const args = []; | ||
| { | ||
| let curArg = arguments[0]; | ||
| if (curArg !== undefined) { | ||
| curArg = conversions["DOMString"](curArg, { | ||
| context: "Failed to construct 'TextDecoder': parameter 1", | ||
| globals: globalObject | ||
| }); | ||
| } else { | ||
| curArg = "utf-8"; | ||
| } | ||
| args.push(curArg); | ||
| } | ||
| { | ||
| let curArg = arguments[1]; | ||
| curArg = TextDecoderOptions.convert(globalObject, curArg, { | ||
| context: "Failed to construct 'TextDecoder': parameter 2" | ||
| }); | ||
| args.push(curArg); | ||
| } | ||
| return exports.setup(Object.create(new.target.prototype), globalObject, args); | ||
| } | ||
| decode() { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError("'decode' called on an object that is not a valid instance of TextDecoder."); | ||
| } | ||
| const args = []; | ||
| { | ||
| let curArg = arguments[0]; | ||
| if (curArg !== undefined) { | ||
| if (utils.isArrayBuffer(curArg)) { | ||
| curArg = conversions["ArrayBuffer"](curArg, { | ||
| context: "Failed to execute 'decode' on 'TextDecoder': parameter 1", | ||
| globals: globalObject | ||
| }); | ||
| } else if (utils.isSharedArrayBuffer(curArg)) { | ||
| curArg = conversions["SharedArrayBuffer"](curArg, { | ||
| context: "Failed to execute 'decode' on 'TextDecoder': parameter 1", | ||
| globals: globalObject | ||
| }); | ||
| } else if (ArrayBuffer.isView(curArg)) { | ||
| curArg = conversions["ArrayBufferView"](curArg, { | ||
| context: "Failed to execute 'decode' on 'TextDecoder': parameter 1", | ||
| globals: globalObject, | ||
| allowShared: true | ||
| }); | ||
| } else { | ||
| throw new globalObject.TypeError( | ||
| "Failed to execute 'decode' on 'TextDecoder': parameter 1" + " is not of any supported type." | ||
| ); | ||
| } | ||
| } | ||
| args.push(curArg); | ||
| } | ||
| { | ||
| let curArg = arguments[1]; | ||
| curArg = TextDecodeOptions.convert(globalObject, curArg, { | ||
| context: "Failed to execute 'decode' on 'TextDecoder': parameter 2" | ||
| }); | ||
| args.push(curArg); | ||
| } | ||
| return esValue[implSymbol].decode(...args); | ||
| } | ||
| get encoding() { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError( | ||
| "'get encoding' called on an object that is not a valid instance of TextDecoder." | ||
| ); | ||
| } | ||
| return esValue[implSymbol]["encoding"]; | ||
| } | ||
| get fatal() { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError( | ||
| "'get fatal' called on an object that is not a valid instance of TextDecoder." | ||
| ); | ||
| } | ||
| return esValue[implSymbol]["fatal"]; | ||
| } | ||
| get ignoreBOM() { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError( | ||
| "'get ignoreBOM' called on an object that is not a valid instance of TextDecoder." | ||
| ); | ||
| } | ||
| return esValue[implSymbol]["ignoreBOM"]; | ||
| } | ||
| } | ||
| Object.defineProperties(TextDecoder.prototype, { | ||
| decode: { enumerable: true }, | ||
| encoding: { enumerable: true }, | ||
| fatal: { enumerable: true }, | ||
| ignoreBOM: { enumerable: true }, | ||
| [Symbol.toStringTag]: { value: "TextDecoder", configurable: true } | ||
| }); | ||
| ctorRegistry[interfaceName] = TextDecoder; | ||
| Object.defineProperty(globalObject, interfaceName, { | ||
| configurable: true, | ||
| writable: true, | ||
| value: TextDecoder | ||
| }); | ||
| }; | ||
| const Impl = require("../encoding/TextDecoder-impl.js"); |
| "use strict"; | ||
| const conversions = require("webidl-conversions"); | ||
| const utils = require("./utils.js"); | ||
| exports._convertInherit = (globalObject, obj, ret, { context = "The provided value" } = {}) => { | ||
| { | ||
| const key = "fatal"; | ||
| let value = obj === undefined || obj === null ? undefined : obj[key]; | ||
| if (value !== undefined) { | ||
| value = conversions["boolean"](value, { context: context + " has member 'fatal' that", globals: globalObject }); | ||
| ret[key] = value; | ||
| } else { | ||
| ret[key] = false; | ||
| } | ||
| } | ||
| { | ||
| const key = "ignoreBOM"; | ||
| let value = obj === undefined || obj === null ? undefined : obj[key]; | ||
| if (value !== undefined) { | ||
| value = conversions["boolean"](value, { | ||
| context: context + " has member 'ignoreBOM' that", | ||
| globals: globalObject | ||
| }); | ||
| ret[key] = value; | ||
| } else { | ||
| ret[key] = false; | ||
| } | ||
| } | ||
| }; | ||
| exports.convert = (globalObject, obj, { context = "The provided value" } = {}) => { | ||
| if (obj !== undefined && typeof obj !== "object" && typeof obj !== "function") { | ||
| throw new globalObject.TypeError(`${context} is not an object.`); | ||
| } | ||
| const ret = Object.create(null); | ||
| exports._convertInherit(globalObject, obj, ret, { context }); | ||
| return ret; | ||
| }; |
| "use strict"; | ||
| const conversions = require("webidl-conversions"); | ||
| const utils = require("./utils.js"); | ||
| const implSymbol = utils.implSymbol; | ||
| const ctorRegistrySymbol = utils.ctorRegistrySymbol; | ||
| const interfaceName = "TextEncoder"; | ||
| exports.is = value => { | ||
| return utils.isObject(value) && Object.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation; | ||
| }; | ||
| exports.isImpl = value => { | ||
| return utils.isObject(value) && value instanceof Impl.implementation; | ||
| }; | ||
| exports.convert = (globalObject, value, { context = "The provided value" } = {}) => { | ||
| if (exports.is(value)) { | ||
| return utils.implForWrapper(value); | ||
| } | ||
| throw new globalObject.TypeError(`${context} is not of type 'TextEncoder'.`); | ||
| }; | ||
| function makeWrapper(globalObject, newTarget) { | ||
| let proto; | ||
| if (newTarget !== undefined) { | ||
| proto = newTarget.prototype; | ||
| } | ||
| if (!utils.isObject(proto)) { | ||
| proto = globalObject[ctorRegistrySymbol]["TextEncoder"].prototype; | ||
| } | ||
| return Object.create(proto); | ||
| } | ||
| exports.create = (globalObject, constructorArgs, privateData) => { | ||
| const wrapper = makeWrapper(globalObject); | ||
| return exports.setup(wrapper, globalObject, constructorArgs, privateData); | ||
| }; | ||
| exports.createImpl = (globalObject, constructorArgs, privateData) => { | ||
| const wrapper = exports.create(globalObject, constructorArgs, privateData); | ||
| return utils.implForWrapper(wrapper); | ||
| }; | ||
| exports._internalSetup = (wrapper, globalObject) => {}; | ||
| exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => { | ||
| privateData.wrapper = wrapper; | ||
| exports._internalSetup(wrapper, globalObject); | ||
| Object.defineProperty(wrapper, implSymbol, { | ||
| value: new Impl.implementation(globalObject, constructorArgs, privateData), | ||
| configurable: true | ||
| }); | ||
| wrapper[implSymbol][utils.wrapperSymbol] = wrapper; | ||
| if (Impl.init) { | ||
| Impl.init(wrapper[implSymbol]); | ||
| } | ||
| return wrapper; | ||
| }; | ||
| exports.new = (globalObject, newTarget) => { | ||
| const wrapper = makeWrapper(globalObject, newTarget); | ||
| exports._internalSetup(wrapper, globalObject); | ||
| Object.defineProperty(wrapper, implSymbol, { | ||
| value: Object.create(Impl.implementation.prototype), | ||
| configurable: true | ||
| }); | ||
| wrapper[implSymbol][utils.wrapperSymbol] = wrapper; | ||
| if (Impl.init) { | ||
| Impl.init(wrapper[implSymbol]); | ||
| } | ||
| return wrapper[implSymbol]; | ||
| }; | ||
| const exposed = new Set(["Window"]); | ||
| exports.install = (globalObject, globalNames) => { | ||
| if (!globalNames.some(globalName => exposed.has(globalName))) { | ||
| return; | ||
| } | ||
| const ctorRegistry = utils.initCtorRegistry(globalObject); | ||
| class TextEncoder { | ||
| constructor() { | ||
| return exports.setup(Object.create(new.target.prototype), globalObject, undefined); | ||
| } | ||
| encode() { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError("'encode' called on an object that is not a valid instance of TextEncoder."); | ||
| } | ||
| const args = []; | ||
| { | ||
| let curArg = arguments[0]; | ||
| if (curArg !== undefined) { | ||
| curArg = conversions["USVString"](curArg, { | ||
| context: "Failed to execute 'encode' on 'TextEncoder': parameter 1", | ||
| globals: globalObject | ||
| }); | ||
| } else { | ||
| curArg = ""; | ||
| } | ||
| args.push(curArg); | ||
| } | ||
| return esValue[implSymbol].encode(...args); | ||
| } | ||
| encodeInto(source, destination) { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError( | ||
| "'encodeInto' called on an object that is not a valid instance of TextEncoder." | ||
| ); | ||
| } | ||
| if (arguments.length < 2) { | ||
| throw new globalObject.TypeError( | ||
| `Failed to execute 'encodeInto' on 'TextEncoder': 2 arguments required, but only ${arguments.length} present.` | ||
| ); | ||
| } | ||
| const args = []; | ||
| { | ||
| let curArg = arguments[0]; | ||
| curArg = conversions["USVString"](curArg, { | ||
| context: "Failed to execute 'encodeInto' on 'TextEncoder': parameter 1", | ||
| globals: globalObject | ||
| }); | ||
| args.push(curArg); | ||
| } | ||
| { | ||
| let curArg = arguments[1]; | ||
| curArg = conversions["Uint8Array"](curArg, { | ||
| context: "Failed to execute 'encodeInto' on 'TextEncoder': parameter 2", | ||
| globals: globalObject, | ||
| allowShared: true | ||
| }); | ||
| args.push(curArg); | ||
| } | ||
| return utils.tryWrapperForImpl(esValue[implSymbol].encodeInto(...args)); | ||
| } | ||
| get encoding() { | ||
| const esValue = this !== null && this !== undefined ? this : globalObject; | ||
| if (!exports.is(esValue)) { | ||
| throw new globalObject.TypeError( | ||
| "'get encoding' called on an object that is not a valid instance of TextEncoder." | ||
| ); | ||
| } | ||
| return esValue[implSymbol]["encoding"]; | ||
| } | ||
| } | ||
| Object.defineProperties(TextEncoder.prototype, { | ||
| encode: { enumerable: true }, | ||
| encodeInto: { enumerable: true }, | ||
| encoding: { enumerable: true }, | ||
| [Symbol.toStringTag]: { value: "TextEncoder", configurable: true } | ||
| }); | ||
| ctorRegistry[interfaceName] = TextEncoder; | ||
| Object.defineProperty(globalObject, interfaceName, { | ||
| configurable: true, | ||
| writable: true, | ||
| value: TextEncoder | ||
| }); | ||
| }; | ||
| const Impl = require("../encoding/TextEncoder-impl.js"); |
| "use strict"; | ||
| const conversions = require("webidl-conversions"); | ||
| const utils = require("./utils.js"); | ||
| exports._convertInherit = (globalObject, obj, ret, { context = "The provided value" } = {}) => { | ||
| { | ||
| const key = "read"; | ||
| let value = obj === undefined || obj === null ? undefined : obj[key]; | ||
| if (value !== undefined) { | ||
| value = conversions["unsigned long long"](value, { | ||
| context: context + " has member 'read' that", | ||
| globals: globalObject | ||
| }); | ||
| ret[key] = value; | ||
| } | ||
| } | ||
| { | ||
| const key = "written"; | ||
| let value = obj === undefined || obj === null ? undefined : obj[key]; | ||
| if (value !== undefined) { | ||
| value = conversions["unsigned long long"](value, { | ||
| context: context + " has member 'written' that", | ||
| globals: globalObject | ||
| }); | ||
| ret[key] = value; | ||
| } | ||
| } | ||
| }; | ||
| exports.convert = (globalObject, obj, { context = "The provided value" } = {}) => { | ||
| if (obj !== undefined && typeof obj !== "object" && typeof obj !== "function") { | ||
| throw new globalObject.TypeError(`${context} is not an object.`); | ||
| } | ||
| const ret = Object.create(null); | ||
| exports._convertInherit(globalObject, obj, ret, { context }); | ||
| return ret; | ||
| }; |
+3
-3
@@ -8,3 +8,3 @@ "use strict"; | ||
| const whatwgURL = require("whatwg-url"); | ||
| const whatwgEncoding = require("whatwg-encoding"); | ||
| const { legacyHookDecode } = require("@exodus/bytes/encoding.js"); | ||
| const { URL } = require("whatwg-url"); | ||
@@ -302,6 +302,6 @@ const MIMEType = require("whatwg-mimetype"); | ||
| encoding = sniffHTMLEncoding(html, { | ||
| defaultEncoding: mimeType.isXML() ? "UTF-8" : "windows-1252", | ||
| xml: mimeType.isXML(), | ||
| transportLayerEncodingLabel: mimeType.parameters.get("charset") | ||
| }); | ||
| html = whatwgEncoding.decode(html, encoding); | ||
| html = legacyHookDecode(html, encoding); | ||
| } else { | ||
@@ -308,0 +308,0 @@ html = String(html); |
| "use strict"; | ||
| const whatwgEncoding = require("whatwg-encoding"); | ||
| const { labelToName, legacyHookDecode } = require("@exodus/bytes/encoding.js"); | ||
| const MIMEType = require("whatwg-mimetype"); | ||
@@ -42,4 +42,4 @@ const DOMException = require("../generated/DOMException"); | ||
| } | ||
| readAsText(file, encoding) { | ||
| this._readFile(file, "text", whatwgEncoding.labelToName(encoding) || "UTF-8"); | ||
| readAsText(file, encodingLabel) { | ||
| this._readFile(file, "text", labelToName(encodingLabel) || "UTF-8"); | ||
| } | ||
@@ -67,3 +67,3 @@ | ||
| _readFile(file, format, encoding) { | ||
| _readFile(file, format, encodingLabel) { | ||
| if (this.readyState === READY_STATES.LOADING) { | ||
@@ -114,3 +114,3 @@ throw DOMException.create(this._globalObject, [ | ||
| case "text": { | ||
| this.result = whatwgEncoding.decode(data, encoding); | ||
| this.result = legacyHookDecode(data, encodingLabel); | ||
| break; | ||
@@ -117,0 +117,0 @@ } |
@@ -9,2 +9,5 @@ "use strict"; | ||
| exports.asciiLowercase = s => { | ||
| if (!/[^\x00-\x7f]/.test(s)) { | ||
| return s.toLowerCase(); | ||
| } | ||
| const len = s.length; | ||
@@ -22,2 +25,5 @@ const out = new Array(len); | ||
| exports.asciiUppercase = s => { | ||
| if (!/[^\x00-\x7f]/.test(s)) { | ||
| return s.toUpperCase(); | ||
| } | ||
| const len = s.length; | ||
@@ -24,0 +30,0 @@ const out = new Array(len); |
| "use strict"; | ||
| const cssom = require("@acemir/cssom"); | ||
| const whatwgEncoding = require("whatwg-encoding"); | ||
| const { legacyHookDecode } = require("@exodus/bytes/encoding.js"); | ||
| const whatwgURL = require("whatwg-url"); | ||
@@ -11,7 +11,7 @@ const { invalidateStyleCache } = require("./style-rules"); | ||
| const document = elementImpl._ownerDocument; | ||
| let defaultEncoding = document._encoding; | ||
| let defaultEncodingLabel = document._encoding; | ||
| const resourceLoader = document._resourceLoader; | ||
| if (elementImpl.localName === "link" && elementImpl.hasAttributeNS(null, "charset")) { | ||
| defaultEncoding = whatwgEncoding.labelToName(elementImpl.getAttributeNS(null, "charset")); | ||
| defaultEncodingLabel = elementImpl.getAttributeNS(null, "charset"); | ||
| } | ||
@@ -25,3 +25,3 @@ | ||
| const css = whatwgEncoding.decode(data, defaultEncoding); | ||
| const css = legacyHookDecode(data, defaultEncodingLabel); | ||
@@ -28,0 +28,0 @@ // TODO: MIME type checking? |
@@ -217,3 +217,6 @@ "use strict"; | ||
| DOMRectReadOnly: require("./generated/DOMRectReadOnly"), | ||
| DOMRect: require("./generated/DOMRect") | ||
| DOMRect: require("./generated/DOMRect"), | ||
| TextDecoder: require("./generated/TextDecoder"), | ||
| TextEncoder: require("./generated/TextEncoder") | ||
| }; | ||
@@ -220,0 +223,0 @@ |
@@ -87,3 +87,3 @@ "use strict"; | ||
| for (const range of this._referencedRanges) { | ||
| for (const range of this._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -90,0 +90,0 @@ |
| "use strict"; | ||
| const MIMEType = require("whatwg-mimetype"); | ||
| const whatwgEncoding = require("whatwg-encoding"); | ||
| const { legacyHookDecode } = require("@exodus/bytes/encoding.js"); | ||
| const { parseURL, serializeURL } = require("whatwg-url"); | ||
@@ -38,22 +38,25 @@ const sniffHTMLEncoding = require("html-encoding-sniffer"); | ||
| function onFrameLoaded(data) { | ||
| const sniffOptions = { | ||
| defaultEncoding: document._encoding | ||
| }; | ||
| let xml = false; | ||
| let transportLayerEncodingLabel; | ||
| if (request.response) { | ||
| const contentType = MIMEType.parse(request.response.headers["content-type"]) || new MIMEType("text/plain"); | ||
| sniffOptions.transportLayerEncodingLabel = contentType.parameters.get("charset"); | ||
| xml = contentType.isXML(); | ||
| transportLayerEncodingLabel = contentType.parameters.get("charset"); | ||
| if (contentType) { | ||
| if (contentType.isXML()) { | ||
| contentDoc._parsingMode = "xml"; | ||
| } | ||
| contentDoc.contentType = contentType.essence; | ||
| if (xml) { | ||
| contentDoc._parsingMode = "xml"; | ||
| } | ||
| contentDoc.contentType = contentType.essence; | ||
| } | ||
| const encoding = sniffHTMLEncoding(data, sniffOptions); | ||
| contentDoc._encoding = encoding; | ||
| contentDoc._encoding = sniffHTMLEncoding(data, { | ||
| xml, | ||
| transportLayerEncodingLabel, | ||
| // half-assed implementation of | ||
| // https://html.spec.whatwg.org/multipage/parsing.html#determining-the-character-encoding step 6 | ||
| defaultEncoding: xml ? "UTF-8" : document._encoding | ||
| }); | ||
| const html = whatwgEncoding.decode(data, contentDoc._encoding); | ||
| const html = legacyHookDecode(data, contentDoc._encoding); | ||
@@ -60,0 +63,0 @@ try { |
| "use strict"; | ||
| const vm = require("vm"); | ||
| const whatwgEncoding = require("whatwg-encoding"); | ||
| const { getBOMEncoding, labelToName, legacyHookDecode } = require("@exodus/bytes/encoding.js"); | ||
| const MIMEType = require("whatwg-mimetype"); | ||
@@ -65,3 +65,3 @@ const { serializeURL } = require("whatwg-url"); | ||
| const resourceLoader = document._resourceLoader; | ||
| const defaultEncoding = whatwgEncoding.labelToName(this.getAttributeNS(null, "charset")) || document._encoding; | ||
| const defaultEncoding = labelToName(this.getAttributeNS(null, "charset")) || document._encoding; | ||
| let request; | ||
@@ -92,6 +92,6 @@ | ||
| const encoding = whatwgEncoding.getBOMEncoding(data) || | ||
| (contentType && whatwgEncoding.labelToName(contentType.parameters.get("charset"))) || | ||
| const encoding = labelToName(getBOMEncoding(data)) || | ||
| (contentType && labelToName(contentType.parameters.get("charset"))) || | ||
| defaultEncoding; | ||
| const script = whatwgEncoding.decode(data, encoding); | ||
| const script = legacyHookDecode(data, encoding); | ||
@@ -98,0 +98,0 @@ this._innerEval(script, urlString); |
@@ -130,5 +130,19 @@ "use strict"; | ||
| this._registeredObserverList = []; | ||
| this._referencedRanges = new Set(); | ||
| this._referencedRanges = new Set(); // Set of WeakRef<Range> | ||
| } | ||
| // Generator that yields live Range objects from _referencedRanges, | ||
| // cleaning up any dead WeakRefs encountered during iteration. | ||
| * _liveRanges() { | ||
| for (const weakRef of this._referencedRanges) { | ||
| const range = weakRef.deref(); | ||
| if (range) { | ||
| yield range; | ||
| } else { | ||
| // Range was garbage collected - remove the dead WeakRef | ||
| this._referencedRanges.delete(weakRef); | ||
| } | ||
| } | ||
| } | ||
| _getTheParent() { | ||
@@ -327,3 +341,3 @@ if (this._assignedSlot) { | ||
| for (const range of node._referencedRanges) { | ||
| for (const range of node._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -339,3 +353,3 @@ | ||
| for (const range of parentNode._referencedRanges) { | ||
| for (const range of parentNode._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -774,3 +788,3 @@ | ||
| for (const range of this._referencedRanges) { | ||
| for (const range of this._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -1079,3 +1093,3 @@ | ||
| for (const descendant of domSymbolTree.treeIterator(nodeImpl)) { | ||
| for (const range of descendant._referencedRanges) { | ||
| for (const range of descendant._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -1093,3 +1107,3 @@ | ||
| for (const range of this._referencedRanges) { | ||
| for (const range of this._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -1096,0 +1110,0 @@ |
@@ -43,3 +43,3 @@ "use strict"; | ||
| for (const range of this._referencedRanges) { | ||
| for (const range of this._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -57,3 +57,3 @@ | ||
| const nodeIndex = domSymbolTree.index(this); | ||
| for (const range of parent._referencedRanges) { | ||
| for (const range of parent._liveRanges()) { | ||
| const { _start, _end } = range; | ||
@@ -60,0 +60,0 @@ |
@@ -32,2 +32,7 @@ "use strict"; | ||
| // Store a WeakRef to this Range for use in _referencedRanges. | ||
| // This allows Ranges to be garbage collected when no longer referenced by user code, | ||
| // preventing accumulation in long-lived nodes like document.body. | ||
| this._weakRef = new WeakRef(this); | ||
| const defaultBoundaryPoint = { | ||
@@ -459,7 +464,7 @@ node: implForWrapper(globalObject._document), | ||
| ) { | ||
| this._start.node._referencedRanges.delete(this); | ||
| this._start.node._referencedRanges.delete(this._weakRef); | ||
| } | ||
| if (!node._referencedRanges.has(this)) { | ||
| node._referencedRanges.add(this); | ||
| if (!node._referencedRanges.has(this._weakRef)) { | ||
| node._referencedRanges.add(this._weakRef); | ||
| } | ||
@@ -479,7 +484,7 @@ | ||
| ) { | ||
| this._end.node._referencedRanges.delete(this); | ||
| this._end.node._referencedRanges.delete(this._weakRef); | ||
| } | ||
| if (!node._referencedRanges.has(this)) { | ||
| node._referencedRanges.add(this); | ||
| if (!node._referencedRanges.has(this._weakRef)) { | ||
| node._referencedRanges.add(this._weakRef); | ||
| } | ||
@@ -486,0 +491,0 @@ |
@@ -6,3 +6,3 @@ "use strict"; | ||
| const { URL } = require("whatwg-url"); | ||
| const whatwgEncoding = require("whatwg-encoding"); | ||
| const { getBOMEncoding, labelToName, legacyHookDecode } = require("@exodus/bytes/encoding.js"); | ||
| const tough = require("tough-cookie"); | ||
@@ -252,4 +252,4 @@ const MIMEType = require("whatwg-mimetype"); | ||
| const fallbackEncoding = finalCharset(this) || whatwgEncoding.getBOMEncoding(responseBuffer) || "UTF-8"; | ||
| const res = whatwgEncoding.decode(responseBuffer, fallbackEncoding); | ||
| const fallbackEncodingLabel = finalCharset(this) || getBOMEncoding(responseBuffer) || "UTF-8"; | ||
| const res = legacyHookDecode(responseBuffer, fallbackEncodingLabel); | ||
@@ -294,4 +294,4 @@ properties.responseTextCache = res; | ||
| const encoding = finalCharset(this) || whatwgEncoding.getBOMEncoding(responseBuffer) || "UTF-8"; | ||
| const resText = whatwgEncoding.decode(responseBuffer, encoding); | ||
| const encoding = finalCharset(this) || labelToName(getBOMEncoding(responseBuffer)) || "UTF-8"; | ||
| const resText = legacyHookDecode(responseBuffer, encoding); | ||
@@ -506,3 +506,3 @@ if (!resText) { | ||
| if (charset) { | ||
| this.flag.overrideCharset = whatwgEncoding.labelToName(charset); | ||
| this.flag.overrideCharset = labelToName(charset); | ||
| } | ||
@@ -952,3 +952,3 @@ } | ||
| if (parsedContentType) { | ||
| return whatwgEncoding.labelToName(parsedContentType.parameters.get("charset")); | ||
| return labelToName(parsedContentType.parameters.get("charset")); | ||
| } | ||
@@ -955,0 +955,0 @@ return null; |
+3
-3
| { | ||
| "name": "jsdom", | ||
| "version": "27.3.0", | ||
| "version": "27.4.0", | ||
| "description": "A JavaScript implementation of many web standards", | ||
@@ -28,6 +28,7 @@ "keywords": [ | ||
| "@asamuzakjp/dom-selector": "^6.7.6", | ||
| "@exodus/bytes": "^1.6.0", | ||
| "cssstyle": "^5.3.4", | ||
| "data-urls": "^6.0.0", | ||
| "decimal.js": "^10.6.0", | ||
| "html-encoding-sniffer": "^4.0.0", | ||
| "html-encoding-sniffer": "^6.0.0", | ||
| "http-proxy-agent": "^7.0.2", | ||
@@ -42,3 +43,2 @@ "https-proxy-agent": "^7.0.6", | ||
| "webidl-conversions": "^8.0.0", | ||
| "whatwg-encoding": "^3.1.1", | ||
| "whatwg-mimetype": "^4.0.0", | ||
@@ -45,0 +45,0 @@ "whatwg-url": "^15.1.0", |
Network access
Supply chain riskThis module accesses the network.
Found 5 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 5 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
3305759
0.53%533
1.33%87965
0.54%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated