diff options
Diffstat (limited to 'op_crates/web')
-rw-r--r-- | op_crates/web/00_infra.js | 68 | ||||
-rw-r--r-- | op_crates/web/01_mimesniff.js | 88 | ||||
-rw-r--r-- | op_crates/web/03_abort_signal.js | 7 | ||||
-rw-r--r-- | op_crates/web/internal.d.ts | 12 |
4 files changed, 117 insertions, 58 deletions
diff --git a/op_crates/web/00_infra.js b/op_crates/web/00_infra.js index ff9cb7cd4..bc87c8217 100644 --- a/op_crates/web/00_infra.js +++ b/op_crates/web/00_infra.js @@ -46,6 +46,15 @@ const HTTP_QUOTED_STRING_TOKEN_POINT_RE = new RegExp( `^[${regexMatcher(HTTP_QUOTED_STRING_TOKEN_POINT)}]+$`, ); + const HTTP_TAB_OR_SPACE_MATCHER = regexMatcher(HTTP_TAB_OR_SPACE); + const HTTP_TAB_OR_SPACE_PREFIX_RE = new RegExp( + `^[${HTTP_TAB_OR_SPACE_MATCHER}]+`, + "g", + ); + const HTTP_TAB_OR_SPACE_SUFFIX_RE = new RegExp( + `[${HTTP_TAB_OR_SPACE_MATCHER}]+$`, + "g", + ); const HTTP_WHITESPACE_MATCHER = regexMatcher(HTTP_WHITESPACE); const HTTP_WHITESPACE_PREFIX_RE = new RegExp( `^[${HTTP_WHITESPACE_MATCHER}]+`, @@ -113,6 +122,62 @@ }); } + /** + * https://fetch.spec.whatwg.org/#collect-an-http-quoted-string + * @param {string} input + * @param {number} position + * @param {boolean} extractValue + * @returns {{result: string, position: number}} + */ + function collectHttpQuotedString(input, position, extractValue) { + // 1. + const positionStart = position; + // 2. + let value = ""; + // 3. + if (input[position] !== "\u0022") throw new Error('must be "'); + // 4. + position++; + // 5. + while (true) { + // 5.1. + const res = collectSequenceOfCodepoints( + input, + position, + (c) => c !== "\u0022" && c !== "\u005C", + ); + value += res.result; + position = res.position; + // 5.2. + if (position >= input.length) break; + // 5.3. + const quoteOrBackslash = input[position]; + // 5.4. + position++; + // 5.5. + if (quoteOrBackslash === "\u005C") { + // 5.5.1. + if (position >= input.length) { + value += "\u005C"; + break; + } + // 5.5.2. + value += input[position]; + // 5.5.3. + position++; + } else { // 5.6. + // 5.6.1 + if (quoteOrBackslash !== "\u0022") throw new Error('must be "'); + // 5.6.2 + break; + } + } + // 6. + if (extractValue) return { result: value, position }; + // 7. + return { result: input.substring(positionStart, position + 1), position }; + } + window.__bootstrap.infra = { collectSequenceOfCodepoints, ASCII_DIGIT, @@ -126,10 +191,13 @@ HTTP_TOKEN_CODE_POINT_RE, HTTP_QUOTED_STRING_TOKEN_POINT, HTTP_QUOTED_STRING_TOKEN_POINT_RE, + HTTP_TAB_OR_SPACE_PREFIX_RE, + HTTP_TAB_OR_SPACE_SUFFIX_RE, HTTP_WHITESPACE_PREFIX_RE, HTTP_WHITESPACE_SUFFIX_RE, regexMatcher, byteUpperCase, byteLowerCase, + collectHttpQuotedString, }; })(globalThis); diff --git a/op_crates/web/01_mimesniff.js b/op_crates/web/01_mimesniff.js index 534e39c31..077a40df1 100644 --- a/op_crates/web/01_mimesniff.js +++ b/op_crates/web/01_mimesniff.js @@ -15,65 +15,10 @@ HTTP_WHITESPACE_SUFFIX_RE, HTTP_QUOTED_STRING_TOKEN_POINT_RE, HTTP_TOKEN_CODE_POINT_RE, + collectHttpQuotedString, } = window.__bootstrap.infra; /** - * https://fetch.spec.whatwg.org/#collect-an-http-quoted-string - * @param {string} input - * @param {number} position - * @param {boolean} extractValue - * @returns {{result: string, position: number}} - */ - function collectHttpQuotedString(input, position, extractValue) { - // 1. - const positionStart = position; - // 2. - let value = ""; - // 3. - if (input[position] !== "\u0022") throw new Error('must be "'); - // 4. - position++; - // 5. - while (true) { - // 5.1. - const res = collectSequenceOfCodepoints( - input, - position, - (c) => c !== "\u0022" && c !== "\u005C", - ); - value += res.result; - position = res.position; - // 5.2. - if (position >= input.length) break; - // 5.3. - const quoteOrBackslash = input[position]; - // 5.4. - position++; - // 5.5. - if (quoteOrBackslash === "\u005C") { - // 5.5.1. - if (position >= input.length) { - value += "\u005C"; - break; - } - // 5.5.2. - value += input[position]; - // 5.5.3. - position++; - } else { // 5.6. - // 5.6.1 - if (input[position] !== "\u0022") throw new Error('must be "'); - // 5.6.2 - break; - } - } - // 6. - if (extractValue) return { result: value, position }; - // 7. - return { result: input.substring(positionStart, position + 1), position }; - } - - /** * @typedef MimeType * @property {string} type * @property {string} subtype @@ -172,7 +117,7 @@ let parameterValue = null; // 11.8. - if (input[position] == "\u0022") { + if (input[position] === "\u0022") { // 11.8.1. const res = collectHttpQuotedString(input, position, true); parameterValue = res.result; @@ -214,5 +159,32 @@ return mimeType; } - window.__bootstrap.mimesniff = { parseMimeType }; + /** + * @param {MimeType} mimeType + * @returns {string} + */ + function essence(mimeType) { + return `${mimeType.type}/${mimeType.subtype}`; + } + + /** + * @param {MimeType} mimeType + * @returns {string} + */ + function serializeMimeType(mimeType) { + let serialization = essence(mimeType); + for (const param of mimeType.parameters) { + serialization += `;${param[0]}=`; + let value = param[1]; + if (!HTTP_TOKEN_CODE_POINT_RE.test(value)) { + value = value.replaceAll("\\", "\\\\"); + value = value.replaceAll('"', '\\"'); + value = `"${value}"`; + } + serialization += value; + } + return serialization; + } + + window.__bootstrap.mimesniff = { parseMimeType, essence, serializeMimeType }; })(this); diff --git a/op_crates/web/03_abort_signal.js b/op_crates/web/03_abort_signal.js index 693b5342a..b87a56ce3 100644 --- a/op_crates/web/03_abort_signal.js +++ b/op_crates/web/03_abort_signal.js @@ -2,6 +2,7 @@ "use strict"; ((window) => { + const webidl = window.__bootstrap.webidl; const { setIsTrusted } = window.__bootstrap.event; const add = Symbol("add"); @@ -47,6 +48,7 @@ throw new TypeError("Illegal constructor."); } super(); + this[webidl.brand] = webidl.brand; } get aborted() { @@ -111,6 +113,11 @@ }); } + webidl.converters["AbortSignal"] = webidl.createInterfaceConverter( + "AbortSignal", + AbortSignal, + ); + window.AbortSignal = AbortSignal; window.AbortController = AbortController; window.__bootstrap = window.__bootstrap || {}; diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index a5b653218..bfce3e1e1 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -28,11 +28,21 @@ declare namespace globalThis { HTTP_TOKEN_CODE_POINT_RE: RegExp; HTTP_QUOTED_STRING_TOKEN_POINT: string[]; HTTP_QUOTED_STRING_TOKEN_POINT_RE: RegExp; + HTTP_TAB_OR_SPACE_PREFIX_RE: RegExp; + HTTP_TAB_OR_SPACE_SUFFIX_RE: RegExp; HTTP_WHITESPACE_PREFIX_RE: RegExp; HTTP_WHITESPACE_SUFFIX_RE: RegExp; regexMatcher(chars: string[]): string; byteUpperCase(s: string): string; byteLowerCase(s: string): string; + collectHttpQuotedString( + input: string, + position: number, + extractValue: boolean, + ): { + result: string; + position: number; + }; }; declare namespace mimesniff { @@ -42,6 +52,8 @@ declare namespace globalThis { parameters: Map<string, string>; } declare function parseMimeType(input: string): MimeType | null; + declare function essence(mimeType: MimeType): string; + declare function serializeMimeType(mimeType: MimeType): string; } declare var eventTarget: { |