From d7511accc51e49471b7971faf821d7b93e38d11e Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Wed, 17 Jan 2024 09:36:58 +0100 Subject: [PATCH 1/5] #1216@trivial: Add response clone tests. --- .../happy-dom/test/fetch/Response.test.ts | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/packages/happy-dom/test/fetch/Response.test.ts b/packages/happy-dom/test/fetch/Response.test.ts index 6f1d35eab..cc85dca30 100644 --- a/packages/happy-dom/test/fetch/Response.test.ts +++ b/packages/happy-dom/test/fetch/Response.test.ts @@ -1,19 +1,19 @@ -import IWindow from '../../src/window/IWindow.js'; -import Window from '../../src/window/Window.js'; -import IDocument from '../../src/nodes/document/IDocument.js'; -import Headers from '../../src/fetch/Headers.js'; -import Blob from '../../src/file/Blob.js'; -import FormData from '../../src/form-data/FormData.js'; -import FetchBodyUtility from '../../src/fetch/utilities/FetchBodyUtility.js'; -import MultipartFormDataParser from '../../src/fetch/multipart/MultipartFormDataParser.js'; import FS from 'fs'; import Path from 'path'; -import File from '../../src/file/File.js'; +import Stream from 'stream'; +import { URLSearchParams } from 'url'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import DOMException from '../../src/exception/DOMException.js'; import DOMExceptionNameEnum from '../../src/exception/DOMExceptionNameEnum.js'; -import { URLSearchParams } from 'url'; -import Stream from 'stream'; -import { beforeEach, afterEach, describe, it, expect, vi } from 'vitest'; +import Headers from '../../src/fetch/Headers.js'; +import MultipartFormDataParser from '../../src/fetch/multipart/MultipartFormDataParser.js'; +import FetchBodyUtility from '../../src/fetch/utilities/FetchBodyUtility.js'; +import Blob from '../../src/file/Blob.js'; +import File from '../../src/file/File.js'; +import FormData from '../../src/form-data/FormData.js'; +import IDocument from '../../src/nodes/document/IDocument.js'; +import IWindow from '../../src/window/IWindow.js'; +import Window from '../../src/window/Window.js'; describe('Response', () => { let window: IWindow; @@ -465,6 +465,48 @@ describe('Response', () => { expect(bodyText).toBe('Hello World'); }); + + it('Can use the body of the cloned Response independently (cached).', async () => { + const originalResponse = new window.Response('Hello World', { + status: 200, + statusText: 'OK', + headers: { 'Content-Type': 'text/plain' } + }); + const clonedResponse = originalResponse.clone(); + + const originalResponseText = await originalResponse.text(); + const clonedResponseText = await clonedResponse.text(); + expect(originalResponseText).toBe('Hello World'); + expect(clonedResponseText).toBe('Hello World'); + }); + + it('Can use the body of the cloned Response independently (stream).', async () => { + const originalResponse = new window.Response(Stream.Readable.from(['Hello World']), { + status: 200, + statusText: 'OK', + headers: { 'Content-Type': 'text/plain' } + }); + const clonedResponse = originalResponse.clone(); + + const originalResponseText = await originalResponse.text(); + const clonedResponseText = await clonedResponse.text(); + expect(originalResponseText).toBe('Hello World'); + expect(clonedResponseText).toBe('Hello World'); + }); + + it('Fails if the body of the original Response is already used.', async () => { + const originalResponse = new window.Response(Stream.Readable.from(['Hello World']), { + status: 200, + statusText: 'OK', + headers: { 'Content-Type': 'text/plain' } + }); + await expect(originalResponse.text()).resolves.toBe('Hello World'); + + expect(() => originalResponse.clone()).toThrowError(DOMException); + expect(() => originalResponse.clone()).toThrowError( + 'Failed to clone body stream of request: Request body is already used.' + ); + }); }); describe('static redirect()', () => { From ac1315a180c1e17582a3da337feb588dda8797fd Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Wed, 17 Jan 2024 10:21:10 +0100 Subject: [PATCH 2/5] #1216@patch: Clone response body when cloning a response. --- packages/happy-dom/src/fetch/Response.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/happy-dom/src/fetch/Response.ts b/packages/happy-dom/src/fetch/Response.ts index 078b53386..ee0aa2f6a 100644 --- a/packages/happy-dom/src/fetch/Response.ts +++ b/packages/happy-dom/src/fetch/Response.ts @@ -267,7 +267,9 @@ export default class Response implements IResponse { * @returns Clone. */ public clone(): Response { - const response = new this.#window.Response(this.body, { + const body = FetchBodyUtility.cloneBodyStream(this); + + const response = new this.#window.Response(body, { status: this.status, statusText: this.statusText, headers: this.headers From 032bdc4b304853bd69d8a20dc9675d4ff031d5b5 Mon Sep 17 00:00:00 2001 From: David Ortner Date: Sat, 9 Mar 2024 13:11:24 +0100 Subject: [PATCH 3/5] chore: [#1216] Adds support for piping underlying Node stream when cloning a Response body --- packages/happy-dom/src/PropertySymbol.ts | 1 + packages/happy-dom/src/fetch/Fetch.ts | 65 +++++++------- packages/happy-dom/src/fetch/Response.ts | 5 -- .../src/fetch/utilities/FetchBodyUtility.ts | 87 ++++++++++++++----- 4 files changed, 98 insertions(+), 60 deletions(-) diff --git a/packages/happy-dom/src/PropertySymbol.ts b/packages/happy-dom/src/PropertySymbol.ts index 74f9963c5..bc9fcf70e 100644 --- a/packages/happy-dom/src/PropertySymbol.ts +++ b/packages/happy-dom/src/PropertySymbol.ts @@ -151,3 +151,4 @@ export const host = Symbol('host'); export const setURL = Symbol('setURL'); export const localName = Symbol('localName'); export const registedClass = Symbol('registedClass'); +export const nodeStream = Symbol('nodeStream'); diff --git a/packages/happy-dom/src/fetch/Fetch.ts b/packages/happy-dom/src/fetch/Fetch.ts index a82d54998..a925db861 100644 --- a/packages/happy-dom/src/fetch/Fetch.ts +++ b/packages/happy-dom/src/fetch/Fetch.ts @@ -14,7 +14,6 @@ import { Socket } from 'net'; import Stream from 'stream'; import DataURIParser from './data-uri/DataURIParser.js'; import FetchCORSUtility from './utilities/FetchCORSUtility.js'; -import { ReadableStream } from 'stream/web'; import Request from './Request.js'; import Response from './Response.js'; import Event from '../event/Event.js'; @@ -28,6 +27,7 @@ import FetchResponseRedirectUtility from './utilities/FetchResponseRedirectUtili import FetchResponseHeaderUtility from './utilities/FetchResponseHeaderUtility.js'; import FetchHTTPSCertificate from './certificate/FetchHTTPSCertificate.js'; import { Buffer } from 'buffer'; +import FetchBodyUtility from './utilities/FetchBodyUtility.js'; const LAST_CHUNK = Buffer.from('0\r\n\r\n'); @@ -123,7 +123,11 @@ export default class Fetch { this.#window.location.protocol === 'https:' ) { throw new DOMException( - `Mixed Content: The page at '${this.#window.location.href}' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${this.request.url}'. This request has been blocked; the content must be served over HTTPS.`, + `Mixed Content: The page at '${ + this.#window.location.href + }' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${ + this.request.url + }'. This request has been blocked; the content must be served over HTTPS.`, DOMExceptionNameEnum.securityError ); } @@ -545,7 +549,10 @@ export default class Fetch { nodeResponse.statusCode === 204 || nodeResponse.statusCode === 304 ) { - this.response = new this.#window.Response(this.nodeToWebStream(body), responseOptions); + this.response = new this.#window.Response( + FetchBodyUtility.nodeToWebStream(body), + responseOptions + ); (this.response.redirected) = this.redirectCount > 0; (this.response.url) = this.request.url; this.resolve(this.response); @@ -567,7 +574,10 @@ export default class Fetch { // Ignore error as it is forwarded to the response body. } }); - this.response = new this.#window.Response(this.nodeToWebStream(body), responseOptions); + this.response = new this.#window.Response( + FetchBodyUtility.nodeToWebStream(body), + responseOptions + ); (this.response.redirected) = this.redirectCount > 0; (this.response.url) = this.request.url; this.resolve(this.response); @@ -599,7 +609,10 @@ export default class Fetch { }); } - this.response = new this.#window.Response(this.nodeToWebStream(body), responseOptions); + this.response = new this.#window.Response( + FetchBodyUtility.nodeToWebStream(body), + responseOptions + ); (this.response.redirected) = this.redirectCount > 0; (this.response.url) = this.request.url; this.resolve(this.response); @@ -607,7 +620,10 @@ export default class Fetch { raw.on('end', () => { // Some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. if (!this.response) { - this.response = new this.#window.Response(this.nodeToWebStream(body), responseOptions); + this.response = new this.#window.Response( + FetchBodyUtility.nodeToWebStream(body), + responseOptions + ); (this.response.redirected) = this.redirectCount > 0; (this.response.url) = this.request.url; this.resolve(this.response); @@ -623,7 +639,10 @@ export default class Fetch { // Ignore error as it is forwarded to the response body. } }); - this.response = new this.#window.Response(this.nodeToWebStream(body), responseOptions); + this.response = new this.#window.Response( + FetchBodyUtility.nodeToWebStream(body), + responseOptions + ); (this.response.redirected) = this.redirectCount > 0; (this.response.url) = this.request.url; this.resolve(this.response); @@ -631,7 +650,10 @@ export default class Fetch { } // Otherwise, use response as is - this.response = new this.#window.Response(this.nodeToWebStream(body), responseOptions); + this.response = new this.#window.Response( + FetchBodyUtility.nodeToWebStream(body), + responseOptions + ); (this.response.redirected) = this.redirectCount > 0; (this.response.url) = this.request.url; this.resolve(this.response); @@ -806,31 +828,4 @@ export default class Fetch { this.reject(error); } } - - /** - * Wraps a Node.js stream into a browser-compatible ReadableStream. - * - * Enables the use of Node.js streams where browser ReadableStreams are required. - * Handles 'data', 'end', and 'error' events from the Node.js stream. - * - * @param nodeStream The Node.js stream to be converted. - * @returns ReadableStream - */ - private nodeToWebStream(nodeStream: Stream): ReadableStream { - return new ReadableStream({ - start(controller) { - nodeStream.on('data', (chunk) => { - controller.enqueue(chunk); - }); - - nodeStream.on('end', () => { - controller.close(); - }); - - nodeStream.on('error', (err) => { - controller.error(err); - }); - } - }); - } } diff --git a/packages/happy-dom/src/fetch/Response.ts b/packages/happy-dom/src/fetch/Response.ts index bf0184ce1..098387825 100644 --- a/packages/happy-dom/src/fetch/Response.ts +++ b/packages/happy-dom/src/fetch/Response.ts @@ -275,12 +275,7 @@ export default class Response implements IResponse { headers: this.headers }); - (response.status) = this.status; - (response.statusText) = this.statusText; (response.ok) = this.ok; - (response.headers) = new Headers(this.headers); - (response.body) = this.body; - (response.bodyUsed) = this.bodyUsed; (response.redirected) = this.redirected; (response.type) = this.type; (response.url) = this.url; diff --git a/packages/happy-dom/src/fetch/utilities/FetchBodyUtility.ts b/packages/happy-dom/src/fetch/utilities/FetchBodyUtility.ts index d203fc3c5..555be0137 100644 --- a/packages/happy-dom/src/fetch/utilities/FetchBodyUtility.ts +++ b/packages/happy-dom/src/fetch/utilities/FetchBodyUtility.ts @@ -9,29 +9,12 @@ import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum.js'; import IRequestBody from '../types/IRequestBody.js'; import IResponseBody from '../types/IResponseBody.js'; import { Buffer } from 'buffer'; +import Stream from 'stream'; /** * Fetch body utility. */ export default class FetchBodyUtility { - /** - * Wraps a given value in a browser ReadableStream. - * - * This method creates a ReadableStream and immediately enqueues and closes it - * with the provided value, useful for stream API compatibility. - * - * @param value The value to be wrapped in a ReadableStream. - * @returns ReadableStream - */ - public static toReadableStream(value): ReadableStream { - return new ReadableStream({ - start(controller) { - controller.enqueue(value); - controller.close(); - } - }); - } - /** * Parses body and returns stream and type. * @@ -115,8 +98,8 @@ export default class FetchBodyUtility { * It creates a pass through stream and pipes the original stream to it. * * @param requestOrResponse Request or Response. - * @param requestOrResponse.body - * @param requestOrResponse.bodyUsed + * @param requestOrResponse.body Body. + * @param requestOrResponse.bodyUsed Body used. * @returns New stream. */ public static cloneBodyStream(requestOrResponse: { @@ -130,7 +113,25 @@ export default class FetchBodyUtility { ); } + // If a buffer is set, use it to create a new stream. + if (requestOrResponse[PropertySymbol.buffer]) { + return this.toReadableStream(requestOrResponse[PropertySymbol.buffer]); + } + + // Pipe underlying node stream if it exists. + if (requestOrResponse.body[PropertySymbol.nodeStream]) { + const stream1 = new Stream.PassThrough(); + const stream2 = new Stream.PassThrough(); + requestOrResponse.body[PropertySymbol.nodeStream].pipe(stream1); + requestOrResponse.body[PropertySymbol.nodeStream].pipe(stream2); + // Sets the body of the cloned request/response to the first pass through stream. + requestOrResponse.body = this.nodeToWebStream(stream1); + // Returns the clone. + return this.nodeToWebStream(stream2); + } + // Uses the tee() method to clone the ReadableStream + // This requires the stream to be consumed in parallel which is not the case for the fetch API const [stream1, stream2] = requestOrResponse.body.tee(); // Sets the body of the cloned request to the first pass through stream. @@ -198,4 +199,50 @@ export default class FetchBodyUtility { ); } } + /** + * Wraps a given value in a browser ReadableStream. + * + * This method creates a ReadableStream and immediately enqueues and closes it + * with the provided value, useful for stream API compatibility. + * + * @param value The value to be wrapped in a ReadableStream. + * @returns ReadableStream + */ + public static toReadableStream(value): ReadableStream { + return new ReadableStream({ + start(controller) { + controller.enqueue(value); + controller.close(); + } + }); + } + + /** + * Wraps a Node.js stream into a browser-compatible ReadableStream. + * + * Enables the use of Node.js streams where browser ReadableStreams are required. + * Handles 'data', 'end', and 'error' events from the Node.js stream. + * + * @param nodeStream The Node.js stream to be converted. + * @returns ReadableStream + */ + public static nodeToWebStream(nodeStream: Stream): ReadableStream { + const readableStream = new ReadableStream({ + start(controller) { + nodeStream.on('data', (chunk) => { + controller.enqueue(chunk); + }); + + nodeStream.on('end', () => { + controller.close(); + }); + + nodeStream.on('error', (err) => { + controller.error(err); + }); + } + }); + readableStream[PropertySymbol.nodeStream] = nodeStream; + return readableStream; + } } From 5d892709ff8f7356f4e73746769b62e769f5e789 Mon Sep 17 00:00:00 2001 From: David Ortner Date: Sat, 9 Mar 2024 13:13:52 +0100 Subject: [PATCH 4/5] chore: [#1216] Fixes linting problems --- .../happy-dom/src/config/IHTMLElementTagNameMap.ts | 5 ++++- .../CSSStyleDeclarationPropertySetParser.ts | 12 ++++++------ packages/happy-dom/src/fetch/SyncFetch.ts | 6 +++++- packages/happy-dom/src/file/FileReader.ts | 5 +++-- packages/happy-dom/src/location/Location.ts | 2 +- .../happy-dom/src/match-media/MediaQueryParser.ts | 4 ++-- packages/happy-dom/src/nodes/node/NodeUtility.ts | 4 ++-- packages/happy-dom/src/range/Range.ts | 4 ++-- .../happy-dom/test/AdoptedStyleSheetCustomElement.ts | 4 ++-- packages/happy-dom/test/CustomElement.ts | 4 ++-- 10 files changed, 29 insertions(+), 21 deletions(-) diff --git a/packages/happy-dom/src/config/IHTMLElementTagNameMap.ts b/packages/happy-dom/src/config/IHTMLElementTagNameMap.ts index 05a48856a..66cadb725 100644 --- a/packages/happy-dom/src/config/IHTMLElementTagNameMap.ts +++ b/packages/happy-dom/src/config/IHTMLElementTagNameMap.ts @@ -23,8 +23,11 @@ import IHTMLVideoElement from '../nodes/html-video-element/IHTMLVideoElement.js' // Makes it work with custom elements when they declare their own interface. declare global { - /* eslint-disable-next-line @typescript-eslint/naming-convention */ + /* eslint-disable @typescript-eslint/naming-convention */ + /* eslint-disable @typescript-eslint/no-empty-interface */ interface HTMLElementTagNameMap {} + /* eslint-enable @typescript-eslint/naming-convention */ + /* eslint-enable @typescript-eslint/no-empty-interface */ } export default interface IHTMLElementTagNameMap extends HTMLElementTagNameMap { diff --git a/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts b/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts index 536bee2f8..146d11da2 100644 --- a/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts +++ b/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts @@ -533,7 +533,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'outline-color': { value: color, important } - } + } : null; } @@ -1417,7 +1417,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-top-color': { value: color, important } - } + } : null; } @@ -1445,7 +1445,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-right-color': { value: color, important } - } + } : null; } @@ -1473,7 +1473,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-bottom-color': { value: color, important } - } + } : null; } @@ -1501,7 +1501,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-left-color': { value: color, important } - } + } : null; } @@ -2769,7 +2769,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { ['background-color']: { important, value: color } - } + } : null; } diff --git a/packages/happy-dom/src/fetch/SyncFetch.ts b/packages/happy-dom/src/fetch/SyncFetch.ts index b29fb3c8f..91c3cd794 100644 --- a/packages/happy-dom/src/fetch/SyncFetch.ts +++ b/packages/happy-dom/src/fetch/SyncFetch.ts @@ -112,7 +112,11 @@ export default class SyncFetch { this.#window.location.protocol === 'https:' ) { throw new DOMException( - `Mixed Content: The page at '${this.#window.location.href}' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${this.request.url}'. This request has been blocked; the content must be served over HTTPS.`, + `Mixed Content: The page at '${ + this.#window.location.href + }' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${ + this.request.url + }'. This request has been blocked; the content must be served over HTTPS.`, DOMExceptionNameEnum.securityError ); } diff --git a/packages/happy-dom/src/file/FileReader.ts b/packages/happy-dom/src/file/FileReader.ts index b49637958..0b7e2346d 100644 --- a/packages/happy-dom/src/file/FileReader.ts +++ b/packages/happy-dom/src/file/FileReader.ts @@ -162,8 +162,9 @@ export default class FileReader extends EventTarget { case FileReaderFormatEnum.dataURL: { // Spec seems very unclear here; see https://github.com/w3c/FileAPI/issues/104. const contentType = WhatwgMIMEType.parse(blob.type) || 'application/octet-stream'; - (this.result) = - `data:${contentType};base64,${data.toString('base64')}`; + (( + this.result + )) = `data:${contentType};base64,${data.toString('base64')}`; break; } case FileReaderFormatEnum.text: { diff --git a/packages/happy-dom/src/location/Location.ts b/packages/happy-dom/src/location/Location.ts index 76f3eafe2..9bd0fdce5 100644 --- a/packages/happy-dom/src/location/Location.ts +++ b/packages/happy-dom/src/location/Location.ts @@ -8,7 +8,7 @@ import { URL } from 'url'; */ export default class Location { // Public properties - public [Symbol.toStringTag]: string = 'Location'; + public [Symbol.toStringTag] = 'Location'; // Private properties #browserFrame: IBrowserFrame; diff --git a/packages/happy-dom/src/match-media/MediaQueryParser.ts b/packages/happy-dom/src/match-media/MediaQueryParser.ts index b6fac0319..3b9913070 100644 --- a/packages/happy-dom/src/match-media/MediaQueryParser.ts +++ b/packages/happy-dom/src/match-media/MediaQueryParser.ts @@ -77,14 +77,14 @@ export default class MediaQueryParser { ? { value: resolutionMatch[1], operator: resolutionMatch[2] - } + } : null, type: resolutionMatch[3], after: resolutionMatch[5] ? { value: resolutionMatch[5], operator: resolutionMatch[4] - } + } : null }); } else { diff --git a/packages/happy-dom/src/nodes/node/NodeUtility.ts b/packages/happy-dom/src/nodes/node/NodeUtility.ts index 3ec32cef6..4f19aca0d 100644 --- a/packages/happy-dom/src/nodes/node/NodeUtility.ts +++ b/packages/happy-dom/src/nodes/node/NodeUtility.ts @@ -290,8 +290,8 @@ export default class NodeUtility { parent = parent[PropertySymbol.parentNode] ? parent[PropertySymbol.parentNode] : includeShadowRoots && (parent).host - ? (parent).host - : null; + ? (parent).host + : null; } return false; diff --git a/packages/happy-dom/src/range/Range.ts b/packages/happy-dom/src/range/Range.ts index 1ad63bea8..3d984de6f 100644 --- a/packages/happy-dom/src/range/Range.ts +++ b/packages/happy-dom/src/range/Range.ts @@ -811,7 +811,7 @@ export default class Range { this[PropertySymbol.start].node[PropertySymbol.nodeType] === NodeTypeEnum.textNode ? this[PropertySymbol.start].node : (this[PropertySymbol.start].node)[PropertySymbol.childNodes][this.startOffset] || - null; + null; const parent = !referenceNode ? this[PropertySymbol.start].node : referenceNode[PropertySymbol.parentNode]; @@ -833,7 +833,7 @@ export default class Range { ? NodeUtility.getNodeLength(parent) : (referenceNode[PropertySymbol.parentNode])[PropertySymbol.childNodes].indexOf( referenceNode - ); + ); newOffset += newNode[PropertySymbol.nodeType] === NodeTypeEnum.documentFragmentNode ? NodeUtility.getNodeLength(newNode) diff --git a/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts b/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts index 6a42c9cd0..11ba5c3bd 100644 --- a/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts +++ b/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts @@ -67,8 +67,8 @@ export default class AdoptedStyleSheetCustomElement extends HTMLElement {
key1 is "${this.getAttribute('key1')}" and key2 is "${this.getAttribute( - 'key2' - )}". + 'key2' + )}". ${this.childNodes .map( diff --git a/packages/happy-dom/test/CustomElement.ts b/packages/happy-dom/test/CustomElement.ts index 399bd1990..a337a1e9d 100644 --- a/packages/happy-dom/test/CustomElement.ts +++ b/packages/happy-dom/test/CustomElement.ts @@ -62,8 +62,8 @@ export default class CustomElement extends HTMLElement {
key1 is "${this.getAttribute('key1')}" and key2 is "${this.getAttribute( - 'key2' - )}". + 'key2' + )}". ${this.childNodes .map( From 1559f62b85da693246f5c3750594faa0d3edf2c9 Mon Sep 17 00:00:00 2001 From: David Ortner Date: Sat, 9 Mar 2024 13:20:42 +0100 Subject: [PATCH 5/5] chore: [#1216] Fixes linting problems --- .../CSSStyleDeclarationPropertySetParser.ts | 12 ++++++------ packages/happy-dom/src/fetch/Fetch.ts | 6 +----- packages/happy-dom/src/fetch/SyncFetch.ts | 6 +----- packages/happy-dom/src/file/FileReader.ts | 5 ++--- .../happy-dom/src/match-media/MediaQueryParser.ts | 4 ++-- packages/happy-dom/src/nodes/node/NodeUtility.ts | 4 ++-- packages/happy-dom/src/range/Range.ts | 4 ++-- .../happy-dom/test/AdoptedStyleSheetCustomElement.ts | 4 ++-- packages/happy-dom/test/CustomElement.ts | 4 ++-- 9 files changed, 20 insertions(+), 29 deletions(-) diff --git a/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts b/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts index 146d11da2..536bee2f8 100644 --- a/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts +++ b/packages/happy-dom/src/css/declaration/property-manager/CSSStyleDeclarationPropertySetParser.ts @@ -533,7 +533,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'outline-color': { value: color, important } - } + } : null; } @@ -1417,7 +1417,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-top-color': { value: color, important } - } + } : null; } @@ -1445,7 +1445,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-right-color': { value: color, important } - } + } : null; } @@ -1473,7 +1473,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-bottom-color': { value: color, important } - } + } : null; } @@ -1501,7 +1501,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { 'border-left-color': { value: color, important } - } + } : null; } @@ -2769,7 +2769,7 @@ export default class CSSStyleDeclarationPropertySetParser { return color ? { ['background-color']: { important, value: color } - } + } : null; } diff --git a/packages/happy-dom/src/fetch/Fetch.ts b/packages/happy-dom/src/fetch/Fetch.ts index a925db861..e59eab331 100644 --- a/packages/happy-dom/src/fetch/Fetch.ts +++ b/packages/happy-dom/src/fetch/Fetch.ts @@ -123,11 +123,7 @@ export default class Fetch { this.#window.location.protocol === 'https:' ) { throw new DOMException( - `Mixed Content: The page at '${ - this.#window.location.href - }' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${ - this.request.url - }'. This request has been blocked; the content must be served over HTTPS.`, + `Mixed Content: The page at '${this.#window.location.href}' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${this.request.url}'. This request has been blocked; the content must be served over HTTPS.`, DOMExceptionNameEnum.securityError ); } diff --git a/packages/happy-dom/src/fetch/SyncFetch.ts b/packages/happy-dom/src/fetch/SyncFetch.ts index 91c3cd794..b29fb3c8f 100644 --- a/packages/happy-dom/src/fetch/SyncFetch.ts +++ b/packages/happy-dom/src/fetch/SyncFetch.ts @@ -112,11 +112,7 @@ export default class SyncFetch { this.#window.location.protocol === 'https:' ) { throw new DOMException( - `Mixed Content: The page at '${ - this.#window.location.href - }' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${ - this.request.url - }'. This request has been blocked; the content must be served over HTTPS.`, + `Mixed Content: The page at '${this.#window.location.href}' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '${this.request.url}'. This request has been blocked; the content must be served over HTTPS.`, DOMExceptionNameEnum.securityError ); } diff --git a/packages/happy-dom/src/file/FileReader.ts b/packages/happy-dom/src/file/FileReader.ts index 0b7e2346d..b49637958 100644 --- a/packages/happy-dom/src/file/FileReader.ts +++ b/packages/happy-dom/src/file/FileReader.ts @@ -162,9 +162,8 @@ export default class FileReader extends EventTarget { case FileReaderFormatEnum.dataURL: { // Spec seems very unclear here; see https://github.com/w3c/FileAPI/issues/104. const contentType = WhatwgMIMEType.parse(blob.type) || 'application/octet-stream'; - (( - this.result - )) = `data:${contentType};base64,${data.toString('base64')}`; + (this.result) = + `data:${contentType};base64,${data.toString('base64')}`; break; } case FileReaderFormatEnum.text: { diff --git a/packages/happy-dom/src/match-media/MediaQueryParser.ts b/packages/happy-dom/src/match-media/MediaQueryParser.ts index 3b9913070..b6fac0319 100644 --- a/packages/happy-dom/src/match-media/MediaQueryParser.ts +++ b/packages/happy-dom/src/match-media/MediaQueryParser.ts @@ -77,14 +77,14 @@ export default class MediaQueryParser { ? { value: resolutionMatch[1], operator: resolutionMatch[2] - } + } : null, type: resolutionMatch[3], after: resolutionMatch[5] ? { value: resolutionMatch[5], operator: resolutionMatch[4] - } + } : null }); } else { diff --git a/packages/happy-dom/src/nodes/node/NodeUtility.ts b/packages/happy-dom/src/nodes/node/NodeUtility.ts index 4f19aca0d..3ec32cef6 100644 --- a/packages/happy-dom/src/nodes/node/NodeUtility.ts +++ b/packages/happy-dom/src/nodes/node/NodeUtility.ts @@ -290,8 +290,8 @@ export default class NodeUtility { parent = parent[PropertySymbol.parentNode] ? parent[PropertySymbol.parentNode] : includeShadowRoots && (parent).host - ? (parent).host - : null; + ? (parent).host + : null; } return false; diff --git a/packages/happy-dom/src/range/Range.ts b/packages/happy-dom/src/range/Range.ts index 3d984de6f..1ad63bea8 100644 --- a/packages/happy-dom/src/range/Range.ts +++ b/packages/happy-dom/src/range/Range.ts @@ -811,7 +811,7 @@ export default class Range { this[PropertySymbol.start].node[PropertySymbol.nodeType] === NodeTypeEnum.textNode ? this[PropertySymbol.start].node : (this[PropertySymbol.start].node)[PropertySymbol.childNodes][this.startOffset] || - null; + null; const parent = !referenceNode ? this[PropertySymbol.start].node : referenceNode[PropertySymbol.parentNode]; @@ -833,7 +833,7 @@ export default class Range { ? NodeUtility.getNodeLength(parent) : (referenceNode[PropertySymbol.parentNode])[PropertySymbol.childNodes].indexOf( referenceNode - ); + ); newOffset += newNode[PropertySymbol.nodeType] === NodeTypeEnum.documentFragmentNode ? NodeUtility.getNodeLength(newNode) diff --git a/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts b/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts index 11ba5c3bd..6a42c9cd0 100644 --- a/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts +++ b/packages/happy-dom/test/AdoptedStyleSheetCustomElement.ts @@ -67,8 +67,8 @@ export default class AdoptedStyleSheetCustomElement extends HTMLElement {
key1 is "${this.getAttribute('key1')}" and key2 is "${this.getAttribute( - 'key2' - )}". + 'key2' + )}". ${this.childNodes .map( diff --git a/packages/happy-dom/test/CustomElement.ts b/packages/happy-dom/test/CustomElement.ts index a337a1e9d..399bd1990 100644 --- a/packages/happy-dom/test/CustomElement.ts +++ b/packages/happy-dom/test/CustomElement.ts @@ -62,8 +62,8 @@ export default class CustomElement extends HTMLElement {
key1 is "${this.getAttribute('key1')}" and key2 is "${this.getAttribute( - 'key2' - )}". + 'key2' + )}". ${this.childNodes .map(