diff options
Diffstat (limited to 'op_crates/web')
-rw-r--r-- | op_crates/web/00_infra.js | 104 | ||||
-rw-r--r-- | op_crates/web/01_mimesniff.js | 82 | ||||
-rw-r--r-- | op_crates/web/internal.d.ts | 25 |
3 files changed, 141 insertions, 70 deletions
diff --git a/op_crates/web/00_infra.js b/op_crates/web/00_infra.js index 0590ffd03..ff9cb7cd4 100644 --- a/op_crates/web/00_infra.js +++ b/op_crates/web/00_infra.js @@ -8,6 +8,74 @@ "use strict"; ((window) => { + const ASCII_DIGIT = ["\u0030-\u0039"]; + const ASCII_UPPER_ALPHA = ["\u0041-\u005A"]; + const ASCII_LOWER_ALPHA = ["\u0061-\u007A"]; + const ASCII_ALPHA = [...ASCII_UPPER_ALPHA, ...ASCII_LOWER_ALPHA]; + const ASCII_ALPHANUMERIC = [...ASCII_DIGIT, ...ASCII_ALPHA]; + + const HTTP_TAB_OR_SPACE = ["\u0009", "\u0020"]; + const HTTP_WHITESPACE = ["\u000A", "\u000D", ...HTTP_TAB_OR_SPACE]; + + const HTTP_TOKEN_CODE_POINT = [ + "\u0021", + "\u0023", + "\u0024", + "\u0025", + "\u0026", + "\u0027", + "\u002A", + "\u002B", + "\u002D", + "\u002E", + "\u005E", + "\u005F", + "\u0060", + "\u007C", + "\u007E", + ...ASCII_ALPHANUMERIC, + ]; + const HTTP_TOKEN_CODE_POINT_RE = new RegExp( + `^[${regexMatcher(HTTP_TOKEN_CODE_POINT)}]+$`, + ); + const HTTP_QUOTED_STRING_TOKEN_POINT = [ + "\u0009", + "\u0020-\u007E", + "\u0080-\u00FF", + ]; + const HTTP_QUOTED_STRING_TOKEN_POINT_RE = new RegExp( + `^[${regexMatcher(HTTP_QUOTED_STRING_TOKEN_POINT)}]+$`, + ); + const HTTP_WHITESPACE_MATCHER = regexMatcher(HTTP_WHITESPACE); + const HTTP_WHITESPACE_PREFIX_RE = new RegExp( + `^[${HTTP_WHITESPACE_MATCHER}]+`, + "g", + ); + const HTTP_WHITESPACE_SUFFIX_RE = new RegExp( + `[${HTTP_WHITESPACE_MATCHER}]+$`, + "g", + ); + + /** + * Turn a string of chars into a regex safe matcher. + * @param {string[]} chars + * @returns {string} + */ + function regexMatcher(chars) { + const matchers = chars.map((char) => { + if (char.length === 1) { + return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`; + } else if (char.length === 3 && char[1] === "-") { + return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}-\\u${ + char.charCodeAt(2).toString(16).padStart(4, "0") + }`; + } else { + throw TypeError("unreachable"); + } + }); + return matchers.join(""); + } + /** * https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points * @param {string} input @@ -25,7 +93,43 @@ return { result: input.slice(start, position), position }; } + /** + * @param {string} s + * @returns {string} + */ + function byteUpperCase(s) { + return String(s).replace(/[a-z]/g, function byteUpperCaseReplace(c) { + return c.toUpperCase(); + }); + } + + /** + * @param {string} s + * @returns {string} + */ + function byteLowerCase(s) { + return String(s).replace(/[A-Z]/g, function byteUpperCaseReplace(c) { + return c.toLowerCase(); + }); + } + window.__bootstrap.infra = { collectSequenceOfCodepoints, + ASCII_DIGIT, + ASCII_UPPER_ALPHA, + ASCII_LOWER_ALPHA, + ASCII_ALPHA, + ASCII_ALPHANUMERIC, + HTTP_TAB_OR_SPACE, + HTTP_WHITESPACE, + HTTP_TOKEN_CODE_POINT, + HTTP_TOKEN_CODE_POINT_RE, + HTTP_QUOTED_STRING_TOKEN_POINT, + HTTP_QUOTED_STRING_TOKEN_POINT_RE, + HTTP_WHITESPACE_PREFIX_RE, + HTTP_WHITESPACE_SUFFIX_RE, + regexMatcher, + byteUpperCase, + byteLowerCase, }; })(globalThis); diff --git a/op_crates/web/01_mimesniff.js b/op_crates/web/01_mimesniff.js index f58130132..534e39c31 100644 --- a/op_crates/web/01_mimesniff.js +++ b/op_crates/web/01_mimesniff.js @@ -8,72 +8,14 @@ "use strict"; ((window) => { - const { collectSequenceOfCodepoints } = window.__bootstrap.infra; - - /** - * @param {string[]} chars - * @returns {string} - */ - function regexMatcher(chars) { - const matchers = chars.map((char) => { - if (char.length === 1) { - return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`; - } else if (char.length === 3 && char[1] === "-") { - return `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}-\\u${ - char.charCodeAt(2).toString(16).padStart(4, "0") - }`; - } else { - throw TypeError("unreachable"); - } - }); - return matchers.join(""); - } - - const HTTP_TAB_OR_SPACE = ["\u0009", "\u0020"]; - const HTTP_WHITESPACE = ["\u000A", "\u000D", ...HTTP_TAB_OR_SPACE]; - - const ASCII_DIGIT = ["\u0030-\u0039"]; - const ASCII_UPPER_ALPHA = ["\u0041-\u005A"]; - const ASCII_LOWER_ALPHA = ["\u0061-\u007A"]; - const ASCII_ALPHA = [...ASCII_UPPER_ALPHA, ...ASCII_LOWER_ALPHA]; - const ASCII_ALPHANUMERIC = [...ASCII_DIGIT, ...ASCII_ALPHA]; - const HTTP_TOKEN_CODE_POINT = [ - "\u0021", - "\u0023", - "\u0025", - "\u0026", - "\u0027", - "\u002A", - "\u002B", - "\u002D", - "\u002E", - "\u005E", - "\u005F", - "\u0060", - "\u007C", - "\u007E", - ...ASCII_ALPHANUMERIC, - ]; - const HTTP_TOKEN_CODE_POINT_RE = new RegExp( - `^[${regexMatcher(HTTP_TOKEN_CODE_POINT)}]+$`, - ); - const HTTP_QUOTED_STRING_TOKEN_POINT = [ - "\u0009", - "\u0020-\u007E", - "\u0080-\u00FF", - ]; - const HTTP_QUOTED_STRING_TOKEN_POINT_RE = new RegExp( - `^[${regexMatcher(HTTP_QUOTED_STRING_TOKEN_POINT)}]+$`, - ); - const HTTP_WHITESPACE_MATCHER = regexMatcher(HTTP_WHITESPACE); - const HTTP_WHITESPACE_PREFIX_RE = new RegExp( - `^[${HTTP_WHITESPACE_MATCHER}]+`, - "g", - ); - const HTTP_WHITESPACE_SUFFIX_RE = new RegExp( - `[${HTTP_WHITESPACE_MATCHER}]+$`, - "g", - ); + const { + collectSequenceOfCodepoints, + HTTP_WHITESPACE, + HTTP_WHITESPACE_PREFIX_RE, + HTTP_WHITESPACE_SUFFIX_RE, + HTTP_QUOTED_STRING_TOKEN_POINT_RE, + HTTP_TOKEN_CODE_POINT_RE, + } = window.__bootstrap.infra; /** * https://fetch.spec.whatwg.org/#collect-an-http-quoted-string @@ -132,7 +74,15 @@ } /** + * @typedef MimeType + * @property {string} type + * @property {string} subtype + * @property {Map<string,string>} parameters + */ + + /** * @param {string} input + * @returns {MimeType | null} */ function parseMimeType(input) { // 1. diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 5681edc7b..a5b653218 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -17,15 +17,32 @@ declare namespace globalThis { result: string; position: number; }; + ASCII_DIGIT: string[]; + ASCII_UPPER_ALPHA: string[]; + ASCII_LOWER_ALPHA: string[]; + ASCII_ALPHA: string[]; + ASCII_ALPHANUMERIC: string[]; + HTTP_TAB_OR_SPACE: string[]; + HTTP_WHITESPACE: string[]; + HTTP_TOKEN_CODE_POINT: string[]; + HTTP_TOKEN_CODE_POINT_RE: RegExp; + HTTP_QUOTED_STRING_TOKEN_POINT: string[]; + HTTP_QUOTED_STRING_TOKEN_POINT_RE: RegExp; + HTTP_WHITESPACE_PREFIX_RE: RegExp; + HTTP_WHITESPACE_SUFFIX_RE: RegExp; + regexMatcher(chars: string[]): string; + byteUpperCase(s: string): string; + byteLowerCase(s: string): string; }; - declare var mimesniff: { - parseMimeType(input: string): { + declare namespace mimesniff { + declare interface MimeType { type: string; subtype: string; parameters: Map<string, string>; - } | null; - }; + } + declare function parseMimeType(input: string): MimeType | null; + } declare var eventTarget: { EventTarget: typeof EventTarget; |