[ci] yarn format

This commit is contained in:
natemoo-re 2022-03-07 21:37:50 +00:00 committed by GitHub Actions
parent f18ee36dc0
commit 63adaeec34
45 changed files with 10089 additions and 7013 deletions

View file

@ -1,12 +1,87 @@
export { AbortController, AbortSignal, Blob, ByteLengthQueuingStrategy, CanvasRenderingContext2D, CharacterData, Comment, CountQueuingStrategy, CSSStyleSheet, CustomElementRegistry, CustomEvent, DOMException, Document, DocumentFragment, Element, Event, EventTarget, File, FormData, HTMLDocument, HTMLElement, HTMLBodyElement, HTMLCanvasElement, HTMLDivElement, HTMLHeadElement, HTMLHtmlElement, HTMLImageElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement, Headers, IntersectionObserver, Image, ImageData, MediaQueryList, MutationObserver, Node, NodeFilter, NodeIterator, OffscreenCanvas, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, Request, ResizeObserver, Response, ShadowRoot, StyleSheet, Text, TransformStream, TreeWalker, URLPattern, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter, Window, alert, atob, btoa, cancelAnimationFrame, cancelIdleCallback, clearTimeout, fetch, requestAnimationFrame, requestIdleCallback, setTimeout, structuredClone, } from './mod.js'; export {
export { pathToPosix } from './lib/utils'; AbortController,
AbortSignal,
Blob,
ByteLengthQueuingStrategy,
CanvasRenderingContext2D,
CharacterData,
Comment,
CountQueuingStrategy,
CSSStyleSheet,
CustomElementRegistry,
CustomEvent,
DOMException,
Document,
DocumentFragment,
Element,
Event,
EventTarget,
File,
FormData,
HTMLDocument,
HTMLElement,
HTMLBodyElement,
HTMLCanvasElement,
HTMLDivElement,
HTMLHeadElement,
HTMLHtmlElement,
HTMLImageElement,
HTMLSpanElement,
HTMLStyleElement,
HTMLTemplateElement,
HTMLUnknownElement,
Headers,
IntersectionObserver,
Image,
ImageData,
MediaQueryList,
MutationObserver,
Node,
NodeFilter,
NodeIterator,
OffscreenCanvas,
ReadableByteStreamController,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamBYOBRequest,
ReadableStreamDefaultController,
ReadableStreamDefaultReader,
Request,
ResizeObserver,
Response,
ShadowRoot,
StyleSheet,
Text,
TransformStream,
TreeWalker,
URLPattern,
WritableStream,
WritableStreamDefaultController,
WritableStreamDefaultWriter,
Window,
alert,
atob,
btoa,
cancelAnimationFrame,
cancelIdleCallback,
clearTimeout,
fetch,
requestAnimationFrame,
requestIdleCallback,
setTimeout,
structuredClone,
} from './mod.js'
export { pathToPosix } from './lib/utils'
export declare const polyfill: { export declare const polyfill: {
(target: any, options?: PolyfillOptions | undefined): any; (target: any, options?: PolyfillOptions | undefined): any
internals(target: any, name: string): any; internals(target: any, name: string): any
}; }
interface PolyfillOptions { interface PolyfillOptions {
exclude?: string | string[]; exclude?: string | string[]
override?: Record<string, { override?: Record<
(...args: any[]): any; string,
}>; {
} (...args: any[]): any
}
>
}

File diff suppressed because one or more lines are too long

View file

@ -2,7 +2,12 @@ import { rollup } from 'rollup'
import { nodeResolve } from '@rollup/plugin-node-resolve' import { nodeResolve } from '@rollup/plugin-node-resolve'
import { posix as path } from 'node:path' import { posix as path } from 'node:path'
import { createRequire } from 'node:module' import { createRequire } from 'node:module'
import { readFile as nodeReadFile, rename, rm, writeFile } from 'node:fs/promises' import {
readFile as nodeReadFile,
rename,
rm,
writeFile,
} from 'node:fs/promises'
import { default as MagicString } from 'magic-string' import { default as MagicString } from 'magic-string'
import { default as alias } from '@rollup/plugin-alias' import { default as alias } from '@rollup/plugin-alias'
import { default as inject } from '@rollup/plugin-inject' import { default as inject } from '@rollup/plugin-inject'
@ -11,11 +16,26 @@ import { default as typescript } from '@rollup/plugin-typescript'
const readFileCache = Object.create(null) const readFileCache = Object.create(null)
const require = createRequire(import.meta.url) const require = createRequire(import.meta.url)
const readFile = (/** @type {string} */ id) => readFileCache[id] || (readFileCache[id] = nodeReadFile(id, 'utf8')) const readFile = (/** @type {string} */ id) =>
readFileCache[id] || (readFileCache[id] = nodeReadFile(id, 'utf8'))
const pathToDOMException = path.resolve('src', 'lib', 'DOMException.js') const pathToDOMException = path.resolve('src', 'lib', 'DOMException.js')
const pathToEventTargetShim = path.join('..', '..', 'node_modules', 'event-target-shim', 'index.mjs') const pathToEventTargetShim = path.join(
const pathToStructuredClone = path.join('..', '..', 'node_modules', '@ungap', 'structured-clone', 'esm', 'index.js') '..',
'..',
'node_modules',
'event-target-shim',
'index.mjs'
)
const pathToStructuredClone = path.join(
'..',
'..',
'node_modules',
'@ungap',
'structured-clone',
'esm',
'index.js'
)
const plugins = [ const plugins = [
typescript({ typescript({
@ -25,38 +45,50 @@ const plugins = [
entries: [ entries: [
{ find: '@ungap/structured-clone', replacement: pathToStructuredClone }, { find: '@ungap/structured-clone', replacement: pathToStructuredClone },
{ find: 'event-target-shim', replacement: pathToEventTargetShim }, { find: 'event-target-shim', replacement: pathToEventTargetShim },
{ find: 'event-target-shim/dist/event-target-shim.js', replacement: pathToEventTargetShim }, {
{ find: 'event-target-shim/dist/event-target-shim.umd.js', replacement: pathToEventTargetShim }, find: 'event-target-shim/dist/event-target-shim.js',
replacement: pathToEventTargetShim,
},
{
find: 'event-target-shim/dist/event-target-shim.umd.js',
replacement: pathToEventTargetShim,
},
{ find: 'node-domexception', replacement: pathToDOMException }, { find: 'node-domexception', replacement: pathToDOMException },
], ],
}), }),
nodeResolve({ nodeResolve({
dedupe: [ dedupe: ['net', 'node:net'],
'net',
'node:net'
]
}), }),
inject({ inject({
// import { Promise as P } from 'es6-promise' // import { Promise as P } from 'es6-promise'
// P: [ 'es6-promise', 'Promise' ], // P: [ 'es6-promise', 'Promise' ],
'AbortController': [ 'abort-controller/dist/abort-controller.mjs', 'AbortController' ], AbortController: [
'Blob': [ 'fetch-blob/from.js', 'Blob' ], 'abort-controller/dist/abort-controller.mjs',
'DOMException': [pathToDOMException, 'DOMException'], 'AbortController',
'Document': [ './Document', 'Document' ], ],
'Element': [ './Element', 'Element' ], Blob: ['fetch-blob/from.js', 'Blob'],
'Event': [ 'event-target-shim', 'Event' ], DOMException: [pathToDOMException, 'DOMException'],
'EventTarget': [ 'event-target-shim', 'EventTarget' ], Document: ['./Document', 'Document'],
'defineEventAttribute': [ 'event-target-shim', 'defineEventAttribute' ], Element: ['./Element', 'Element'],
'HTMLElement': ['./Element', 'HTMLElement'], Event: ['event-target-shim', 'Event'],
'HTMLImageElement': ['./Element', 'HTMLImageElement'], EventTarget: ['event-target-shim', 'EventTarget'],
'HTMLUnknownElement': ['./Element', 'HTMLUnknownElement'], defineEventAttribute: ['event-target-shim', 'defineEventAttribute'],
'MediaQueryList': [ './MediaQueryList', 'MediaQueryList' ], HTMLElement: ['./Element', 'HTMLElement'],
'Node': [ './Node', 'Node' ], HTMLImageElement: ['./Element', 'HTMLImageElement'],
'ReadableStream': [ 'web-streams-polyfill/dist/ponyfill.es6.mjs', 'ReadableStream' ], HTMLUnknownElement: ['./Element', 'HTMLUnknownElement'],
'ShadowRoot': [ './Node', 'ShadowRoot' ], MediaQueryList: ['./MediaQueryList', 'MediaQueryList'],
'Window': [ './Window', 'Window' ], Node: ['./Node', 'Node'],
'globalThis.ReadableStream': [ 'web-streams-polyfill/dist/ponyfill.es6.mjs', 'ReadableStream' ], ReadableStream: [
'web-streams-polyfill/dist/ponyfill.es6.mjs',
'ReadableStream',
],
ShadowRoot: ['./Node', 'ShadowRoot'],
Window: ['./Window', 'Window'],
'globalThis.ReadableStream': [
'web-streams-polyfill/dist/ponyfill.es6.mjs',
'ReadableStream',
],
}), }),
{ {
async load(id) { async load(id) {
@ -69,36 +101,42 @@ const plugins = [
const replacements = [ const replacements = [
// remove unused imports // remove unused imports
[ /(^|\n)import\s+[^']+'node:(buffer|fs|path|worker_threads)'/g, `` ], [/(^|\n)import\s+[^']+'node:(buffer|fs|path|worker_threads)'/g, ``],
[ /const \{ stat \} = fs/g, `` ], [/const \{ stat \} = fs/g, ``],
// remove unused polyfill utils // remove unused polyfill utils
[ /\nif \(\s*typeof Global[\W\w]+?\n\}/g, `` ], [/\nif \(\s*typeof Global[\W\w]+?\n\}/g, ``],
[ /\nif \(\s*typeof window[\W\w]+?\n\}/g, `` ], [/\nif \(\s*typeof window[\W\w]+?\n\}/g, ``],
[ /\nif \(!globalThis\.ReadableStream\) \{[\W\w]+?\n\}/g, `` ], [/\nif \(!globalThis\.ReadableStream\) \{[\W\w]+?\n\}/g, ``],
[ /\nif \(typeof SymbolPolyfill[\W\w]+?\n\}/g, `` ], [/\nif \(typeof SymbolPolyfill[\W\w]+?\n\}/g, ``],
// remove unused polyfills // remove unused polyfills
[ /\nconst globals = getGlobals\(\);/g, `` ], [/\nconst globals = getGlobals\(\);/g, ``],
[ /\nconst queueMicrotask = [\W\w]+?\n\}\)\(\);/g, ``], [/\nconst queueMicrotask = [\W\w]+?\n\}\)\(\);/g, ``],
[ /\nconst NativeDOMException =[^;]+;/g, `` ], [/\nconst NativeDOMException =[^;]+;/g, ``],
[ /\nconst SymbolPolyfill\s*=[^;]+;/g, '\nconst SymbolPolyfill = Symbol;'], [
[ /\n(const|let) DOMException[^;]*;/g, `let DOMException$1=DOMException` ], /\nconst SymbolPolyfill\s*=[^;]+;/g,
[ /\nconst DOMException = globalThis.DOMException[\W\w]+?\}\)\(\)/g, `` ], '\nconst SymbolPolyfill = Symbol;',
[ /\nimport DOMException from 'node-domexception'/g, `` ], ],
[
/\n(const|let) DOMException[^;]*;/g,
`let DOMException$1=DOMException`,
],
[/\nconst DOMException = globalThis.DOMException[\W\w]+?\}\)\(\)/g, ``],
[/\nimport DOMException from 'node-domexception'/g, ``],
// use shared AbortController methods // use shared AbortController methods
[ / new DOMException\$1/g, `new DOMException` ], [/ new DOMException\$1/g, `new DOMException`],
[ / from 'net'/g, `from 'node:net'` ], [/ from 'net'/g, `from 'node:net'`],
[ / throw createInvalidStateError/g, `throw new DOMException` ], [/ throw createInvalidStateError/g, `throw new DOMException`],
[ /= createAbortController/g, `= new AbortController` ], [/= createAbortController/g, `= new AbortController`],
[ /\nconst queueMicrotask = [\W\w]+?\n\}\)\(\)\;/g, `` ], [/\nconst queueMicrotask = [\W\w]+?\n\}\)\(\)\;/g, ``],
// remove Body.prototype.buffer deprecation notice // remove Body.prototype.buffer deprecation notice
[ /\nBody\.prototype\.buffer[^\n]+/g, `` ], [/\nBody\.prototype\.buffer[^\n]+/g, ``],
// remove Body.prototype.data deprecation notice // remove Body.prototype.data deprecation notice
[ /\n data: \{get: deprecate[\W\w]+?\)\}/g, `` ], [/\n data: \{get: deprecate[\W\w]+?\)\}/g, ``],
] ]
for (const [replacee, replacer] of replacements) { for (const [replacee, replacer] of replacements) {
@ -110,22 +148,24 @@ const plugins = [
const leadIndex = replaced.index const leadIndex = replaced.index
const tailIndex = replaced.index + replaced[0].length const tailIndex = replaced.index + replaced[0].length
indexes.unshift([ leadIndex, tailIndex, replacer ]) indexes.unshift([leadIndex, tailIndex, replacer])
} }
} }
if (indexes.length) { if (indexes.length) {
const magicString = new MagicString(code) const magicString = new MagicString(code)
indexes.sort( indexes.sort(([leadOfA], [leadOfB]) => leadOfA - leadOfB)
([leadOfA], [leadOfB]) => leadOfA - leadOfB
)
for (const [leadIndex, tailindex, replacer] of indexes) { for (const [leadIndex, tailindex, replacer] of indexes) {
magicString.overwrite(leadIndex, tailindex, replacer) magicString.overwrite(leadIndex, tailindex, replacer)
} }
const magicMap = magicString.generateMap({ source: pathToEsm, file: pathToMap, includeContent: true }) const magicMap = magicString.generateMap({
source: pathToEsm,
file: pathToMap,
includeContent: true,
})
const modifiedEsm = magicString.toString() const modifiedEsm = magicString.toString()
const modifiedMap = magicMap.toString() const modifiedMap = magicMap.toString()
@ -182,8 +222,16 @@ async function build() {
const modDTS = await readFile('./mod.d.ts') const modDTS = await readFile('./mod.d.ts')
writeFile('mod.d.ts', modDTS.replace('\n//# sourceMappingURL=polyfill.d.ts.map', '').replace('ponyfill.js', 'mod.js')) writeFile(
writeFile('apply.js', `import { polyfill } from './mod.js'\n\nexport * from './mod.js'\n\npolyfill(globalThis)\n`) 'mod.d.ts',
modDTS
.replace('\n//# sourceMappingURL=polyfill.d.ts.map', '')
.replace('ponyfill.js', 'mod.js')
)
writeFile(
'apply.js',
`import { polyfill } from './mod.js'\n\nexport * from './mod.js'\n\npolyfill(globalThis)\n`
)
} }
} }

View file

@ -2,7 +2,8 @@ import { fileURLToPath } from 'url'
export { strict as assert } from 'assert' export { strict as assert } from 'assert'
export const pathFrom = (...args) => fileURLToPath(args.reduce((url, bit) => new URL(bit, url), new URL('file:'))) export const pathFrom = (...args) =>
fileURLToPath(args.reduce((url, bit) => new URL(bit, url), new URL('file:')))
export const test = async (setup) => { export const test = async (setup) => {
console.log(`Testing Node ${process.version}:`) console.log(`Testing Node ${process.version}:`)

View file

@ -1,17 +1,60 @@
const exclusionsForHTMLElement = [ 'CustomElementsRegistry', 'HTMLElement', 'HTMLBodyElement', 'HTMLCanvasElement', 'HTMLDivElement', 'HTMLHeadElement', 'HTMLHtmlElement', 'HTMLImageElement', 'HTMLStyleElement', 'HTMLTemplateElement', 'HTMLUnknownElement', 'Image' ] const exclusionsForHTMLElement = [
const exclusionsForElement = [ 'Element', ...exclusionsForHTMLElement ] as const 'CustomElementsRegistry',
const exclusionsForDocument = [ 'CustomElementsRegistry', 'Document', 'HTMLDocument', 'document', 'customElements' ] as const 'HTMLElement',
const exclusionsForNode = [ 'Node', 'DocumentFragment', 'ShadowRoot', ...exclusionsForDocument, ...exclusionsForElement ] as const 'HTMLBodyElement',
const exclusionsForEventTarget = [ 'AbortSignal', 'Event', 'CustomEvent', 'EventTarget', 'OffscreenCanvas', 'MediaQueryList', 'Window', ...exclusionsForNode ] as const 'HTMLCanvasElement',
const exclusionsForEvent = [ 'AbortSignal', 'Event', 'CustomEvent', 'EventTarget', 'MediaQueryList', 'OffscreenCanvas', 'Window', ...exclusionsForNode ] as const 'HTMLDivElement',
'HTMLHeadElement',
'HTMLHtmlElement',
'HTMLImageElement',
'HTMLStyleElement',
'HTMLTemplateElement',
'HTMLUnknownElement',
'Image',
]
const exclusionsForElement = ['Element', ...exclusionsForHTMLElement] as const
const exclusionsForDocument = [
'CustomElementsRegistry',
'Document',
'HTMLDocument',
'document',
'customElements',
] as const
const exclusionsForNode = [
'Node',
'DocumentFragment',
'ShadowRoot',
...exclusionsForDocument,
...exclusionsForElement,
] as const
const exclusionsForEventTarget = [
'AbortSignal',
'Event',
'CustomEvent',
'EventTarget',
'OffscreenCanvas',
'MediaQueryList',
'Window',
...exclusionsForNode,
] as const
const exclusionsForEvent = [
'AbortSignal',
'Event',
'CustomEvent',
'EventTarget',
'MediaQueryList',
'OffscreenCanvas',
'Window',
...exclusionsForNode,
] as const
export const exclusions = { export const exclusions = {
'Blob+': [ 'Blob', 'File' ], 'Blob+': ['Blob', 'File'],
'Document+': exclusionsForDocument, 'Document+': exclusionsForDocument,
'Element+': exclusionsForElement, 'Element+': exclusionsForElement,
'Event+': exclusionsForEvent, 'Event+': exclusionsForEvent,
'EventTarget+': exclusionsForEventTarget, 'EventTarget+': exclusionsForEventTarget,
'HTMLElement+': exclusionsForHTMLElement, 'HTMLElement+': exclusionsForHTMLElement,
'Node+': exclusionsForNode, 'Node+': exclusionsForNode,
'StyleSheet+': [ 'StyleSheet', 'CSSStyleSheet' ], 'StyleSheet+': ['StyleSheet', 'CSSStyleSheet'],
} }

View file

@ -1,9 +1,15 @@
import { setTimeout as nodeSetTimeout, clearTimeout as nodeClearTimeout } from 'node:timers' import {
setTimeout as nodeSetTimeout,
clearTimeout as nodeClearTimeout,
} from 'node:timers'
import * as _ from './utils.js' import * as _ from './utils.js'
const INTERNAL = { tick: 0, pool: new Map } const INTERNAL = { tick: 0, pool: new Map() }
export function requestAnimationFrame<TArgs extends any[], TFunc extends (...args: TArgs) => any>(callback: TFunc): number { export function requestAnimationFrame<
TArgs extends any[],
TFunc extends (...args: TArgs) => any
>(callback: TFunc): number {
if (!INTERNAL.pool.size) { if (!INTERNAL.pool.size) {
nodeSetTimeout(() => { nodeSetTimeout(() => {
const next = _.__performance_now() const next = _.__performance_now()

View file

@ -10,11 +10,13 @@ export class CanvasRenderingContext2D {
} }
get direction(): 'ltr' | 'rtl' | 'inherit' { get direction(): 'ltr' | 'rtl' | 'inherit' {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'direction').direction return _.internalsOf(this, 'CanvasRenderingContext2D', 'direction')
.direction
} }
get fillStyle(): string { get fillStyle(): string {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'fillStyle').fillStyle return _.internalsOf(this, 'CanvasRenderingContext2D', 'fillStyle')
.fillStyle
} }
get filter(): string { get filter(): string {
@ -22,11 +24,16 @@ export class CanvasRenderingContext2D {
} }
get globalAlpha(): number { get globalAlpha(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'globalAlpha').globalAlpha return _.internalsOf(this, 'CanvasRenderingContext2D', 'globalAlpha')
.globalAlpha
} }
get globalCompositeOperation(): string { get globalCompositeOperation(): string {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'globalCompositeOperation').globalCompositeOperation return _.internalsOf(
this,
'CanvasRenderingContext2D',
'globalCompositeOperation'
).globalCompositeOperation
} }
get font(): string { get font(): string {
@ -34,11 +41,19 @@ export class CanvasRenderingContext2D {
} }
get imageSmoothingEnabled(): boolean { get imageSmoothingEnabled(): boolean {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'imageSmoothingEnabled').imageSmoothingEnabled return _.internalsOf(
this,
'CanvasRenderingContext2D',
'imageSmoothingEnabled'
).imageSmoothingEnabled
} }
get imageSmoothingQuality(): 'low' | 'medium' | 'high' { get imageSmoothingQuality(): 'low' | 'medium' | 'high' {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'imageSmoothingQuality').imageSmoothingQuality return _.internalsOf(
this,
'CanvasRenderingContext2D',
'imageSmoothingQuality'
).imageSmoothingQuality
} }
get lineCap(): 'butt' | 'round' | 'square' { get lineCap(): 'butt' | 'round' | 'square' {
@ -46,7 +61,8 @@ export class CanvasRenderingContext2D {
} }
get lineDashOffset(): number { get lineDashOffset(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineDashOffset').lineDashOffset return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineDashOffset')
.lineDashOffset
} }
get lineJoin(): 'bevel' | 'round' | 'miter' { get lineJoin(): 'bevel' | 'round' | 'miter' {
@ -54,39 +70,54 @@ export class CanvasRenderingContext2D {
} }
get lineWidth(): number { get lineWidth(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineWidth').lineWidth return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineWidth')
.lineWidth
} }
get miterLimit(): number { get miterLimit(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'miterLimit').miterLimit return _.internalsOf(this, 'CanvasRenderingContext2D', 'miterLimit')
.miterLimit
} }
get strokeStyle(): string { get strokeStyle(): string {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'strokeStyle').strokeStyle return _.internalsOf(this, 'CanvasRenderingContext2D', 'strokeStyle')
.strokeStyle
} }
get shadowOffsetX(): number { get shadowOffsetX(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetX').shadowOffsetX return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetX')
.shadowOffsetX
} }
get shadowOffsetY(): number { get shadowOffsetY(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetY').shadowOffsetY return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetY')
.shadowOffsetY
} }
get shadowBlur(): number { get shadowBlur(): number {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowBlur').shadowBlur return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowBlur')
.shadowBlur
} }
get shadowColor(): string { get shadowColor(): string {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowColor').shadowColor return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowColor')
.shadowColor
} }
get textAlign(): 'left' | 'right' | 'center' | 'start' | 'end' { get textAlign(): 'left' | 'right' | 'center' | 'start' | 'end' {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'textAlign').textAlign return _.internalsOf(this, 'CanvasRenderingContext2D', 'textAlign')
.textAlign
} }
get textBaseline(): 'top' | 'hanging' | 'middle' | 'alphabetic' | 'ideographic' | 'bottom' { get textBaseline():
return _.internalsOf(this, 'CanvasRenderingContext2D', 'textBaseline').textBaseline | 'top'
| 'hanging'
| 'middle'
| 'alphabetic'
| 'ideographic'
| 'bottom' {
return _.internalsOf(this, 'CanvasRenderingContext2D', 'textBaseline')
.textBaseline
} }
arc() {} arc() {}
@ -104,9 +135,11 @@ export class CanvasRenderingContext2D {
/** Whether ImageData is provided. */ /** Whether ImageData is provided. */
const hasData = _.__object_isPrototypeOf(ImageData.prototype, arg0) const hasData = _.__object_isPrototypeOf(ImageData.prototype, arg0)
const w = hasData ? (arg0 as ImageData).width : arg0 as number const w = hasData ? (arg0 as ImageData).width : (arg0 as number)
const h = hasData ? (arg0 as ImageData).height : arg1 as number const h = hasData ? (arg0 as ImageData).height : (arg1 as number)
const d = hasData ? (arg0 as ImageData).data : new Uint8ClampedArray(w * h * 4) const d = hasData
? (arg0 as ImageData).data
: new Uint8ClampedArray(w * h * 4)
return new ImageData(d, w, h) return new ImageData(d, w, h)
} }
@ -148,8 +181,12 @@ export class CanvasRenderingContext2D {
_.allowStringTag(CanvasRenderingContext2D) _.allowStringTag(CanvasRenderingContext2D)
export const __createCanvasRenderingContext2D = (canvas: EventTarget): CanvasRenderingContext2D => { export const __createCanvasRenderingContext2D = (
const renderingContext2D = Object.create(CanvasRenderingContext2D.prototype) as CanvasRenderingContext2D canvas: EventTarget
): CanvasRenderingContext2D => {
const renderingContext2D = Object.create(
CanvasRenderingContext2D.prototype
) as CanvasRenderingContext2D
_.INTERNALS.set(renderingContext2D, { _.INTERNALS.set(renderingContext2D, {
canvas, canvas,
@ -179,4 +216,7 @@ export const __createCanvasRenderingContext2D = (canvas: EventTarget): CanvasRen
} }
/** Returns whether the value is an instance of ImageData. */ /** Returns whether the value is an instance of ImageData. */
const isImageData = <T>(value: T) => (Object(value).data instanceof Uint8ClampedArray) as T extends ImageData ? true : false const isImageData = <T>(value: T) =>
(Object(value).data instanceof Uint8ClampedArray) as T extends ImageData
? true
: false

View file

@ -7,11 +7,16 @@ export class CharacterData extends Node {
} as CharacterDataInternals) } as CharacterDataInternals)
} }
get data(): string { get data(): string {
return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'data').data return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'data')
.data
} }
get textContent(): string { get textContent(): string {
return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'textContent').data return _.internalsOf<CharacterDataInternals>(
this,
'CharacterData',
'textContent'
).data
} }
} }
@ -23,7 +28,11 @@ export class Text extends CharacterData {
} }
get wholeText(): string { get wholeText(): string {
return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'textContent').data return _.internalsOf<CharacterDataInternals>(
this,
'CharacterData',
'textContent'
).data
} }
} }

View file

@ -28,10 +28,15 @@ export type Context<T = unknown> = {
} }
/** A helper type which can extract a Context value type from a Context type. */ /** A helper type which can extract a Context value type from a Context type. */
export type ContextType<T extends Context> = T extends Context<infer Y> ? Y : never export type ContextType<T extends Context> = T extends Context<infer Y>
? Y
: never
/** A function which creates a Context value object */ /** A function which creates a Context value object */
export function createContext<T>(name: string, initialValue?: T): Readonly<Context<T>> { export function createContext<T>(
name: string,
initialValue?: T
): Readonly<Context<T>> {
return { return {
name, name,
initialValue, initialValue,

View file

@ -2,14 +2,29 @@ import * as _ from './utils'
export class CustomElementRegistry { export class CustomElementRegistry {
/** Defines a new custom element using the given tag name and HTMLElement constructor. */ /** Defines a new custom element using the given tag name and HTMLElement constructor. */
define(name: string, constructor: Function, options?: ElementDefinitionOptions) { define(
const internals = _.internalsOf<CustomElementRegistryInternals>(this, 'CustomElementRegistry', 'define') name: string,
constructor: Function,
options?: ElementDefinitionOptions
) {
const internals = _.internalsOf<CustomElementRegistryInternals>(
this,
'CustomElementRegistry',
'define'
)
name = String(name) name = String(name)
if (/[A-Z]/.test(name)) throw new SyntaxError('Custom element name cannot contain an uppercase ASCII letter') if (/[A-Z]/.test(name))
if (!/^[a-z]/.test(name)) throw new SyntaxError('Custom element name must have a lowercase ASCII letter as its first character') throw new SyntaxError(
if (!/-/.test(name)) throw new SyntaxError('Custom element name must contain a hyphen') 'Custom element name cannot contain an uppercase ASCII letter'
)
if (!/^[a-z]/.test(name))
throw new SyntaxError(
'Custom element name must have a lowercase ASCII letter as its first character'
)
if (!/-/.test(name))
throw new SyntaxError('Custom element name must contain a hyphen')
internals.constructorByName.set(name, constructor) internals.constructorByName.set(name, constructor)
internals.nameByConstructor.set(constructor, name) internals.nameByConstructor.set(constructor, name)
@ -19,7 +34,11 @@ export class CustomElementRegistry {
/** Returns the constructor associated with the given tag name. */ /** Returns the constructor associated with the given tag name. */
get(name: string) { get(name: string) {
const internals = _.internalsOf<CustomElementRegistryInternals>(this, 'CustomElementRegistry', 'get') const internals = _.internalsOf<CustomElementRegistryInternals>(
this,
'CustomElementRegistry',
'get'
)
name = String(name).toLowerCase() name = String(name).toLowerCase()
@ -27,7 +46,11 @@ export class CustomElementRegistry {
} }
getName(constructor: Function) { getName(constructor: Function) {
const internals = _.internalsOf<CustomElementRegistryInternals>(this, 'CustomElementRegistry', 'getName') const internals = _.internalsOf<CustomElementRegistryInternals>(
this,
'CustomElementRegistry',
'getName'
)
return internals.nameByConstructor.get(constructor) return internals.nameByConstructor.get(constructor)
} }
@ -36,23 +59,28 @@ export class CustomElementRegistry {
_.allowStringTag(CustomElementRegistry) _.allowStringTag(CustomElementRegistry)
interface CustomElementRegistryInternals { interface CustomElementRegistryInternals {
constructorByName: Map<string, Function>; constructorByName: Map<string, Function>
nameByConstructor: Map<Function, string>; nameByConstructor: Map<Function, string>
} }
interface ElementDefinitionOptions { interface ElementDefinitionOptions {
extends?: string | undefined; extends?: string | undefined
} }
export const initCustomElementRegistry = (target: Record<any, any>, exclude: Set<string>) => { export const initCustomElementRegistry = (
target: Record<any, any>,
exclude: Set<string>
) => {
if (exclude.has('customElements')) return if (exclude.has('customElements')) return
const CustomElementRegistry = target.CustomElementRegistry || globalThis.CustomElementRegistry const CustomElementRegistry =
target.CustomElementRegistry || globalThis.CustomElementRegistry
const customElements: CustomElementRegistry = target.customElements = Object.create(CustomElementRegistry.prototype) const customElements: CustomElementRegistry = (target.customElements =
Object.create(CustomElementRegistry.prototype))
_.INTERNALS.set(customElements, { _.INTERNALS.set(customElements, {
constructorByName: new Map, constructorByName: new Map(),
nameByConstructor: new Map, nameByConstructor: new Map(),
} as CustomElementRegistryInternals) } as CustomElementRegistryInternals)
} }

View file

@ -1,7 +1,9 @@
import * as _ from './utils' import * as _ from './utils'
import { Event } from 'event-target-shim' import { Event } from 'event-target-shim'
class CustomEvent<TEventType extends string = string> extends Event<TEventType> { class CustomEvent<
TEventType extends string = string
> extends Event<TEventType> {
constructor(type: TEventType, params?: CustomEventInit) { constructor(type: TEventType, params?: CustomEventInit) {
params = Object(params) as Required<CustomEventInit> params = Object(params) as Required<CustomEventInit>

View file

@ -4,15 +4,27 @@ import { TreeWalker } from './TreeWalker'
export class Document extends Node { export class Document extends Node {
createElement(name: string) { createElement(name: string) {
const internals = _.internalsOf<DocumentInternals>(this, 'Document', 'createElement') const internals = _.internalsOf<DocumentInternals>(
this,
'Document',
'createElement'
)
const customElementInternals: CustomElementRegistryInternals = _.INTERNALS.get(internals.target.customElements) const customElementInternals: CustomElementRegistryInternals =
_.INTERNALS.get(internals.target.customElements)
name = String(name).toLowerCase() name = String(name).toLowerCase()
const TypeOfHTMLElement = internals.constructorByName.get(name) || (customElementInternals && customElementInternals.constructorByName.get(name)) || HTMLUnknownElement const TypeOfHTMLElement =
internals.constructorByName.get(name) ||
(customElementInternals &&
customElementInternals.constructorByName.get(name)) ||
HTMLUnknownElement
const element = Object.setPrototypeOf(new EventTarget(), TypeOfHTMLElement.prototype) as HTMLElement const element = Object.setPrototypeOf(
new EventTarget(),
TypeOfHTMLElement.prototype
) as HTMLElement
_.INTERNALS.set(element, { _.INTERNALS.set(element, {
attributes: {}, attributes: {},
@ -25,10 +37,20 @@ export class Document extends Node {
return element return element
} }
createNodeIterator(root: Node, whatToShow: number = NodeFilter.SHOW_ALL, filter?: NodeIteratorInternals['filter']) { createNodeIterator(
root: Node,
whatToShow: number = NodeFilter.SHOW_ALL,
filter?: NodeIteratorInternals['filter']
) {
const target = Object.create(NodeIterator.prototype) const target = Object.create(NodeIterator.prototype)
_.INTERNALS.set(target, { filter, pointerBeforeReferenceNode: false, referenceNode: root, root, whatToShow } as NodeIteratorInternals) _.INTERNALS.set(target, {
filter,
pointerBeforeReferenceNode: false,
referenceNode: root,
root,
whatToShow,
} as NodeIteratorInternals)
return target return target
} }
@ -37,10 +59,20 @@ export class Document extends Node {
return new Text(data) return new Text(data)
} }
createTreeWalker(root: Node, whatToShow: number = NodeFilter.SHOW_ALL, filter?: NodeFilter, expandEntityReferences?: boolean) { createTreeWalker(
root: Node,
whatToShow: number = NodeFilter.SHOW_ALL,
filter?: NodeFilter,
expandEntityReferences?: boolean
) {
const target = Object.create(TreeWalker.prototype) const target = Object.create(TreeWalker.prototype)
_.INTERNALS.set(target, { filter, currentNode: root, root, whatToShow } as TreeWalkerInternals) _.INTERNALS.set(target, {
filter,
currentNode: root,
root,
whatToShow,
} as TreeWalkerInternals)
return target return target
} }
@ -69,7 +101,10 @@ export const initDocument = (target: Target, exclude: Set<string>) => {
const EventTarget = target.EventTarget || globalThis.EventTarget const EventTarget = target.EventTarget || globalThis.EventTarget
const HTMLDocument = target.HTMLDocument || globalThis.HTMLDocument const HTMLDocument = target.HTMLDocument || globalThis.HTMLDocument
const document: HTMLDocument = target.document = Object.setPrototypeOf(new EventTarget(), HTMLDocument.prototype) const document: HTMLDocument = (target.document = Object.setPrototypeOf(
new EventTarget(),
HTMLDocument.prototype
))
_.INTERNALS.set(document, { _.INTERNALS.set(document, {
target, target,
@ -83,7 +118,7 @@ export const initDocument = (target: Target, exclude: Set<string>) => {
['span', target.HTMLSpanElement], ['span', target.HTMLSpanElement],
['style', target.HTMLStyleElement], ['style', target.HTMLStyleElement],
]), ]),
nameByConstructor: new Map, nameByConstructor: new Map(),
} as DocumentInternals) } as DocumentInternals)
const initElement = (name: string, Class: Function) => { const initElement = (name: string, Class: Function) => {
@ -102,7 +137,10 @@ export const initDocument = (target: Target, exclude: Set<string>) => {
document.body = initElement('body', target.HTMLBodyElement) as HTMLBodyElement document.body = initElement('body', target.HTMLBodyElement) as HTMLBodyElement
document.head = initElement('head', target.HTMLHeadElement) as HTMLHeadElement document.head = initElement('head', target.HTMLHeadElement) as HTMLHeadElement
document.documentElement = initElement('html', target.HTMLHtmlElement) as HTMLHtmlElement document.documentElement = initElement(
'html',
target.HTMLHtmlElement
) as HTMLHtmlElement
} }
interface DocumentInternals { interface DocumentInternals {
@ -120,7 +158,7 @@ interface CustomElementRegistryInternals {
} }
interface ElementInternals { interface ElementInternals {
attributes: { [name: string]: string }, attributes: { [name: string]: string }
localName: string localName: string
ownerDocument: Document ownerDocument: Document
shadowRoot: ShadowRoot shadowRoot: ShadowRoot

View file

@ -21,13 +21,26 @@ export class Element extends Node {
} }
attachShadow(init: Partial<ShadowRootInit>) { attachShadow(init: Partial<ShadowRootInit>) {
if (arguments.length < 1) throw new TypeError(`Failed to execute 'attachShadow' on 'Element': 1 argument required, but only 0 present.`) if (arguments.length < 1)
throw new TypeError(
`Failed to execute 'attachShadow' on 'Element': 1 argument required, but only 0 present.`
)
if (init !== Object(init)) throw new TypeError(`Failed to execute 'attachShadow' on 'Element': The provided value is not of type 'ShadowRootInit'.`) if (init !== Object(init))
throw new TypeError(
`Failed to execute 'attachShadow' on 'Element': The provided value is not of type 'ShadowRootInit'.`
)
if (init.mode !== 'open' && init.mode !== 'closed') throw new TypeError(`Failed to execute 'attachShadow' on 'Element': Failed to read the 'mode' property from 'ShadowRootInit': The provided value '${init.mode}' is not a valid enum value of type ShadowRootMode.`) if (init.mode !== 'open' && init.mode !== 'closed')
throw new TypeError(
`Failed to execute 'attachShadow' on 'Element': Failed to read the 'mode' property from 'ShadowRootInit': The provided value '${init.mode}' is not a valid enum value of type ShadowRootMode.`
)
const internals = _.internalsOf<ElementInternals>(this, 'Element', 'attachShadow') const internals = _.internalsOf<ElementInternals>(
this,
'Element',
'attachShadow'
)
if (internals.shadowRoot) throw new Error('The operation is not supported.') if (internals.shadowRoot) throw new Error('The operation is not supported.')
@ -36,7 +49,14 @@ export class Element extends Node {
delegatesFocus: Boolean(init.delegatesFocus), delegatesFocus: Boolean(init.delegatesFocus),
} }
internals.shadowRoot = internals.shadowRoot || (/^open$/.test(internals.shadowInit.mode as string) ? Object.setPrototypeOf(new EventTarget(), ShadowRoot.prototype) as ShadowRoot : null) internals.shadowRoot =
internals.shadowRoot ||
(/^open$/.test(internals.shadowInit.mode as string)
? (Object.setPrototypeOf(
new EventTarget(),
ShadowRoot.prototype
) as ShadowRoot)
: null)
return internals.shadowRoot return internals.shadowRoot
} }
@ -58,21 +78,34 @@ export class Element extends Node {
} }
get shadowRoot(): ShadowRoot | null { get shadowRoot(): ShadowRoot | null {
const internals = _.internalsOf<ElementInternals>(this, 'Element', 'shadowRoot') const internals = _.internalsOf<ElementInternals>(
this,
'Element',
'shadowRoot'
)
return Object(internals.shadowInit).mode === 'open' ? internals.shadowRoot : null return Object(internals.shadowInit).mode === 'open'
? internals.shadowRoot
: null
} }
get localName(): string { get localName(): string {
return _.internalsOf<ElementInternals>(this, 'Element', 'localName').localName as string return _.internalsOf<ElementInternals>(this, 'Element', 'localName')
.localName as string
} }
get nodeName(): string { get nodeName(): string {
return (_.internalsOf<ElementInternals>(this, 'Element', 'nodeName').localName as string).toUpperCase() return (
_.internalsOf<ElementInternals>(this, 'Element', 'nodeName')
.localName as string
).toUpperCase()
} }
get tagName(): string { get tagName(): string {
return (_.internalsOf<ElementInternals>(this, 'Element', 'tagName').localName as string).toUpperCase() return (
_.internalsOf<ElementInternals>(this, 'Element', 'tagName')
.localName as string
).toUpperCase()
} }
} }
@ -106,7 +139,7 @@ _.allowStringTag(HTMLTemplateElement)
_.allowStringTag(HTMLUnknownElement) _.allowStringTag(HTMLUnknownElement)
export interface ElementInternals { export interface ElementInternals {
attributes: { [name: string]: string }, attributes: { [name: string]: string }
localName?: string localName?: string
shadowRoot: ShadowRoot | null shadowRoot: ShadowRoot | null
shadowInit: ShadowRootInit | void shadowInit: ShadowRootInit | void
@ -115,4 +148,4 @@ export interface ElementInternals {
export interface ShadowRootInit { export interface ShadowRootInit {
mode: 'open' | 'closed' mode: 'open' | 'closed'
delegatesFocus: boolean delegatesFocus: boolean
} }

View file

@ -9,7 +9,8 @@ export class HTMLCanvasElement extends HTMLElement {
} }
set height(value) { set height(value) {
_.internalsOf(this, 'HTMLCanvasElement', 'height').height = Number(value) || 0 _.internalsOf(this, 'HTMLCanvasElement', 'height').height =
Number(value) || 0
} }
get width(): number { get width(): number {
@ -24,8 +25,14 @@ export class HTMLCanvasElement extends HTMLElement {
return null return null
} }
getContext(contextType: PredefinedContextId): CanvasRenderingContext2D | null { getContext(
const internals = _.internalsOf<HTMLCanvasElementInternals>(this, 'HTMLCanvasElement', 'getContext') contextType: PredefinedContextId
): CanvasRenderingContext2D | null {
const internals = _.internalsOf<HTMLCanvasElementInternals>(
this,
'HTMLCanvasElement',
'getContext'
)
switch (contextType) { switch (contextType) {
case '2d': case '2d':
@ -54,4 +61,9 @@ interface HTMLCanvasElementInternals {
renderingContext2D: CanvasRenderingContext2D renderingContext2D: CanvasRenderingContext2D
} }
type PredefinedContextId = '2d' | 'bitmaprenderer' | 'webgl' | 'webgl2' | 'webgpu' type PredefinedContextId =
| '2d'
| 'bitmaprenderer'
| 'webgl'
| 'webgl2'
| 'webgpu'

View file

@ -1,9 +1,15 @@
import { setTimeout as nodeSetTimeout, clearTimeout as nodeClearTimeout } from 'node:timers' import {
setTimeout as nodeSetTimeout,
clearTimeout as nodeClearTimeout,
} from 'node:timers'
import * as _ from './utils.js' import * as _ from './utils.js'
const INTERNAL = { tick: 0, pool: new Map } const INTERNAL = { tick: 0, pool: new Map() }
export function requestIdleCallback<TArgs extends any[], TFunc extends (...args: TArgs) => any>(callback: TFunc): number { export function requestIdleCallback<
TArgs extends any[],
TFunc extends (...args: TArgs) => any
>(callback: TFunc): number {
if (!INTERNAL.pool.size) { if (!INTERNAL.pool.size) {
nodeSetTimeout(() => { nodeSetTimeout(() => {
const next = _.__performance_now() const next = _.__performance_now()

View file

@ -1,20 +1,36 @@
import * as _ from './utils' import * as _ from './utils'
export class ImageData { export class ImageData {
constructor(width: number, height: number); constructor(width: number, height: number)
constructor(width: number, height: number, settings: ImageDataSettings); constructor(width: number, height: number, settings: ImageDataSettings)
constructor(data: Uint8ClampedArray, width: number); constructor(data: Uint8ClampedArray, width: number)
constructor(data: Uint8ClampedArray, width: number, height: number); constructor(data: Uint8ClampedArray, width: number, height: number)
constructor(data: Uint8ClampedArray, width: number, height: number, settings: ImageDataSettings); constructor(
data: Uint8ClampedArray,
width: number,
height: number,
settings: ImageDataSettings
)
constructor(arg0: number | Uint8ClampedArray, arg1: number, ...args: [] | [number] | [ImageDataSettings] | [number, ImageDataSettings]) { constructor(
if (arguments.length < 2) throw new TypeError(`Failed to construct 'ImageData': 2 arguments required.`) arg0: number | Uint8ClampedArray,
arg1: number,
...args: [] | [number] | [ImageDataSettings] | [number, ImageDataSettings]
) {
if (arguments.length < 2)
throw new TypeError(
`Failed to construct 'ImageData': 2 arguments required.`
)
/** Whether Uint8ClampedArray data is provided. */ /** Whether Uint8ClampedArray data is provided. */
const hasData = _.__object_isPrototypeOf(Uint8ClampedArray.prototype, arg0) const hasData = _.__object_isPrototypeOf(Uint8ClampedArray.prototype, arg0)
/** Image data, either provided or calculated. */ /** Image data, either provided or calculated. */
const d = hasData ? arg0 as Uint8ClampedArray : new Uint8ClampedArray(asNumber(arg0, 'width') * asNumber(arg1, 'height') * 4) const d = hasData
? (arg0 as Uint8ClampedArray)
: new Uint8ClampedArray(
asNumber(arg0, 'width') * asNumber(arg1, 'height') * 4
)
/** Image width. */ /** Image width. */
const w = asNumber(hasData ? arg1 : arg0, 'width') const w = asNumber(hasData ? arg1 : arg0, 'width')
@ -23,23 +39,42 @@ export class ImageData {
const h = d.length / w / 4 const h = d.length / w / 4
/** Image color space. */ /** Image color space. */
const c = String(Object(hasData ? args[1] : args[0]).colorSpace || 'srgb') as PredefinedColorSpace const c = String(
Object(hasData ? args[1] : args[0]).colorSpace || 'srgb'
) as PredefinedColorSpace
// throw if a provided height does not match the calculated height // throw if a provided height does not match the calculated height
if (args.length && asNumber(args[0], 'height') !== h) throw new DOMException('height is not equal to (4 * width * height)', 'IndexSizeError') if (args.length && asNumber(args[0], 'height') !== h)
throw new DOMException(
'height is not equal to (4 * width * height)',
'IndexSizeError'
)
// throw if a provided colorspace does not match a known colorspace // throw if a provided colorspace does not match a known colorspace
if (c !== 'srgb' && c !== 'rec2020' && c !== 'display-p3') throw new TypeError('colorSpace is not known value') if (c !== 'srgb' && c !== 'rec2020' && c !== 'display-p3')
throw new TypeError('colorSpace is not known value')
Object.defineProperty(this, 'data', { configurable: true, enumerable: true, value: d }) Object.defineProperty(this, 'data', {
configurable: true,
enumerable: true,
value: d,
})
_.INTERNALS.set(this, { width: w, height: h, colorSpace: c } as ImageDataInternals) _.INTERNALS.set(this, {
width: w,
height: h,
colorSpace: c,
} as ImageDataInternals)
} }
get data(): Uint8ClampedArray { get data(): Uint8ClampedArray {
_.internalsOf<ImageDataInternals>(this, 'ImageData', 'data') _.internalsOf<ImageDataInternals>(this, 'ImageData', 'data')
return (Object.getOwnPropertyDescriptor(this, 'data') as { value: Uint8ClampedArray }).value return (
Object.getOwnPropertyDescriptor(this, 'data') as {
value: Uint8ClampedArray
}
).value
} }
get width(): ImageDataInternals['width'] { get width(): ImageDataInternals['width'] {
@ -57,7 +92,8 @@ _.allowStringTag(ImageData)
const asNumber = (value: any, axis: string): number => { const asNumber = (value: any, axis: string): number => {
value = Number(value) || 0 value = Number(value) || 0
if (value === 0) throw new TypeError(`The source ${axis} is zero or not a number.`) if (value === 0)
throw new TypeError(`The source ${axis} is zero or not a number.`)
return value return value
} }

View file

@ -19,7 +19,10 @@ export const initMediaQueryList = (target: Target, exclude: Set<string>) => {
const MediaQueryList = target.MediaQueryList || globalThis.MediaQueryList const MediaQueryList = target.MediaQueryList || globalThis.MediaQueryList
target.matchMedia = function matchMedia(media: string) { target.matchMedia = function matchMedia(media: string) {
const mql = Object.setPrototypeOf(new EventTarget(), MediaQueryList.prototype) as MediaQueryList const mql = Object.setPrototypeOf(
new EventTarget(),
MediaQueryList.prototype
) as MediaQueryList
_.INTERNALS.set(mql, { _.INTERNALS.set(mql, {
matches: false, matches: false,

View file

@ -71,8 +71,11 @@ export class Node extends EventTarget {
return null return null
} }
[Symbol.for('nodejs.util.inspect.custom')](depth: number, options: Record<string, any>) { [Symbol.for('nodejs.util.inspect.custom')](
return `${this.constructor.name}`; depth: number,
options: Record<string, any>
) {
return `${this.constructor.name}`
} }
} }
@ -88,28 +91,31 @@ export class ShadowRoot extends DocumentFragment {
} }
} }
export const NodeFilter = Object.assign({ export const NodeFilter = Object.assign(
NodeFilter() { {
throw new TypeError('Illegal constructor') NodeFilter() {
throw new TypeError('Illegal constructor')
},
}.NodeFilter,
{
FILTER_ACCEPT: 1,
FILTER_REJECT: 2,
FILTER_SKIP: 3,
SHOW_ALL: 4294967295,
SHOW_ELEMENT: 1,
SHOW_ATTRIBUTE: 2,
SHOW_TEXT: 4,
SHOW_CDATA_SECTION: 8,
SHOW_ENTITY_REFERENCE: 16,
SHOW_ENTITY: 32,
SHOW_PROCESSING_INSTRUCTION: 64,
SHOW_COMMENT: 128,
SHOW_DOCUMENT: 256,
SHOW_DOCUMENT_TYPE: 512,
SHOW_DOCUMENT_FRAGMENT: 1024,
SHOW_NOTATION: 2048,
} }
}.NodeFilter, { )
FILTER_ACCEPT: 1,
FILTER_REJECT: 2,
FILTER_SKIP: 3,
SHOW_ALL: 4294967295,
SHOW_ELEMENT: 1,
SHOW_ATTRIBUTE: 2,
SHOW_TEXT: 4,
SHOW_CDATA_SECTION: 8,
SHOW_ENTITY_REFERENCE: 16,
SHOW_ENTITY: 32,
SHOW_PROCESSING_INSTRUCTION: 64,
SHOW_COMMENT: 128,
SHOW_DOCUMENT: 256,
SHOW_DOCUMENT_TYPE: 512,
SHOW_DOCUMENT_FRAGMENT: 1024,
SHOW_NOTATION: 2048,
})
export class NodeIterator { export class NodeIterator {
nextNode(): Node | null { nextNode(): Node | null {
@ -121,27 +127,47 @@ export class NodeIterator {
} }
get filter(): NodeFilter { get filter(): NodeFilter {
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'filter') const internals = _.internalsOf<NodeIteratorInternals>(
this,
'NodeIterator',
'filter'
)
return internals.filter return internals.filter
} }
get pointerBeforeReferenceNode(): boolean { get pointerBeforeReferenceNode(): boolean {
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'pointerBeforeReferenceNode') const internals = _.internalsOf<NodeIteratorInternals>(
this,
'NodeIterator',
'pointerBeforeReferenceNode'
)
return internals.pointerBeforeReferenceNode return internals.pointerBeforeReferenceNode
} }
get referenceNode(): Node { get referenceNode(): Node {
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'referenceNode') const internals = _.internalsOf<NodeIteratorInternals>(
this,
'NodeIterator',
'referenceNode'
)
return internals.referenceNode return internals.referenceNode
} }
get root(): Node { get root(): Node {
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'root') const internals = _.internalsOf<NodeIteratorInternals>(
this,
'NodeIterator',
'root'
)
return internals.root return internals.root
} }
get whatToShow(): number { get whatToShow(): number {
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'whatToShow') const internals = _.internalsOf<NodeIteratorInternals>(
this,
'NodeIterator',
'whatToShow'
)
return internals.whatToShow return internals.whatToShow
} }
} }

View file

@ -3,11 +3,12 @@ import * as _ from './utils'
export const hasOwn = { export const hasOwn = {
hasOwn(instance: object, property: any) { hasOwn(instance: object, property: any) {
return _.__object_hasOwnProperty(instance, property) return _.__object_hasOwnProperty(instance, property)
} },
}.hasOwn }.hasOwn
export const initObject = (target: any, exclude: Set<string>) => { export const initObject = (target: any, exclude: Set<string>) => {
if (exclude.has('Object') || exclude.has('object') || exclude.has('hasOwn')) return if (exclude.has('Object') || exclude.has('object') || exclude.has('hasOwn'))
return
const Class = target.Object || globalThis.Object const Class = target.Object || globalThis.Object
@ -15,6 +16,6 @@ export const initObject = (target: any, exclude: Set<string>) => {
value: hasOwn, value: hasOwn,
writable: true, writable: true,
enumerable: false, enumerable: false,
configurable: true configurable: true,
}) })
} }

View file

@ -7,7 +7,10 @@ export class OffscreenCanvas extends EventTarget {
constructor(width: number, height: number) { constructor(width: number, height: number) {
super() super()
if (arguments.length < 2) throw new TypeError(`Failed to construct 'OffscreenCanvas': 2 arguments required.`) if (arguments.length < 2)
throw new TypeError(
`Failed to construct 'OffscreenCanvas': 2 arguments required.`
)
width = Number(width) || 0 width = Number(width) || 0
height = Number(height) || 0 height = Number(height) || 0
@ -31,8 +34,14 @@ export class OffscreenCanvas extends EventTarget {
_.internalsOf(this, 'OffscreenCanvas', 'width').width = Number(value) || 0 _.internalsOf(this, 'OffscreenCanvas', 'width').width = Number(value) || 0
} }
getContext(contextType: PredefinedContextId): CanvasRenderingContext2D | null { getContext(
const internals = _.internalsOf<OffscreenCanvasInternals>(this, 'HTMLCanvasElement', 'getContext') contextType: PredefinedContextId
): CanvasRenderingContext2D | null {
const internals = _.internalsOf<OffscreenCanvasInternals>(
this,
'HTMLCanvasElement',
'getContext'
)
switch (contextType) { switch (contextType) {
case '2d': case '2d':
@ -54,15 +63,19 @@ export class OffscreenCanvas extends EventTarget {
void quality void quality
return Promise.resolve( return Promise.resolve(new Blob([], { type }))
new Blob([], { type })
)
} }
} }
_.allowStringTag(OffscreenCanvas) _.allowStringTag(OffscreenCanvas)
const getImageType = (type: string): PredefinedImageType => type === 'image/avif' || type === 'image/jpeg' || type === 'image/png' || type === 'image/webp' ? type : 'image/png' const getImageType = (type: string): PredefinedImageType =>
type === 'image/avif' ||
type === 'image/jpeg' ||
type === 'image/png' ||
type === 'image/webp'
? type
: 'image/png'
interface OffscreenCanvasInternals { interface OffscreenCanvasInternals {
height: number height: number
@ -75,6 +88,15 @@ interface ConvertToBlobOptions {
type: PredefinedImageType type: PredefinedImageType
} }
type PredefinedContextId = '2d' | 'bitmaprenderer' | 'webgl' | 'webgl2' | 'webgpu' type PredefinedContextId =
| '2d'
| 'bitmaprenderer'
| 'webgl'
| 'webgl2'
| 'webgpu'
type PredefinedImageType = 'image/avif' | 'image/jpeg' | 'image/png' | 'image/webp' type PredefinedImageType =
| 'image/avif'
| 'image/jpeg'
| 'image/png'
| 'image/webp'

View file

@ -1,18 +1,16 @@
export const any = { export const any = {
async any <T>( async any<T>(iterable: Iterable<T | PromiseLike<T>>): Promise<T> {
iterable: Iterable<T | PromiseLike<T>>
): Promise<T> {
return Promise.all( return Promise.all(
[...iterable].map(promise => { [...iterable].map((promise) => {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
Promise.resolve(promise).then(reject, resolve) Promise.resolve(promise).then(reject, resolve)
) )
}) })
).then( ).then(
errors => Promise.reject(errors), (errors) => Promise.reject(errors),
value => Promise.resolve<T>(value) (value) => Promise.resolve<T>(value)
) )
} },
}.any }.any
export const initPromise = (target: any, exclude: Set<string>) => { export const initPromise = (target: any, exclude: Set<string>) => {
@ -20,10 +18,11 @@ export const initPromise = (target: any, exclude: Set<string>) => {
const Class = target.Promise || globalThis.Promise const Class = target.Promise || globalThis.Promise
if (!Class.any) Object.defineProperty(Class, 'any', { if (!Class.any)
value: any, Object.defineProperty(Class, 'any', {
writable: true, value: any,
enumerable: false, writable: true,
configurable: true enumerable: false,
}) configurable: true,
})
} }

View file

@ -1,32 +1,50 @@
type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array type TypedArray =
| Int8Array
| Uint8Array
| Uint8ClampedArray
| Int16Array
| Uint16Array
| Int32Array
| Uint32Array
| Float32Array
| Float64Array
| BigInt64Array
| BigUint64Array
export const at = { export const at = {
at<T extends Array<any> | string | TypedArray>(this: T, index: number) { at<T extends Array<any> | string | TypedArray>(this: T, index: number) {
index = Math.trunc(index) || 0 index = Math.trunc(index) || 0
if (index < 0) index += this.length; if (index < 0) index += this.length
if (index < 0 || index >= this.length) return undefined; if (index < 0 || index >= this.length) return undefined
return this[index]; return this[index]
} },
}.at }.at
export const initRelativeIndexingMethod = (target: any, exclude: Set<string>) => { export const initRelativeIndexingMethod = (
target: any,
exclude: Set<string>
) => {
if (exclude.has('at')) return if (exclude.has('at')) return
const Classes = [] const Classes = []
if (!exclude.has('TypedArray')) Classes.push(Object.getPrototypeOf(target.Int8Array || globalThis.Int8Array)) if (!exclude.has('TypedArray'))
Classes.push(
Object.getPrototypeOf(target.Int8Array || globalThis.Int8Array)
)
if (!exclude.has('Array')) Classes.push(target.Array || globalThis.Array) if (!exclude.has('Array')) Classes.push(target.Array || globalThis.Array)
if (!exclude.has('String')) Classes.push(target.String || globalThis.String) if (!exclude.has('String')) Classes.push(target.String || globalThis.String)
for (const Class of Classes) { for (const Class of Classes) {
if (!Class.prototype.at) Object.defineProperty(Class.prototype, 'at', { if (!Class.prototype.at)
value: at, Object.defineProperty(Class.prototype, 'at', {
writable: true, value: at,
enumerable: false, writable: true,
configurable: true enumerable: false,
}) configurable: true,
})
} }
} }

View file

@ -7,20 +7,35 @@ export class Storage {
getItem(key: string): string | null { getItem(key: string): string | null {
return getStringOrNull( return getStringOrNull(
_.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.get(String(key)) _.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.get(
String(key)
)
) )
} }
key(index: number): string | null { key(index: number): string | null {
return getStringOrNull([ ..._.internalsOf<StorageInternals>(this, 'Storage', 'key').storage.keys() ][Number(index) || 0]) return getStringOrNull(
[
..._.internalsOf<StorageInternals>(
this,
'Storage',
'key'
).storage.keys(),
][Number(index) || 0]
)
} }
removeItem(key: string): void { removeItem(key: string): void {
_.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.delete(String(key)) _.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.delete(
String(key)
)
} }
setItem(key: string, value: any): void { setItem(key: string, value: any): void {
_.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.set(String(key), String(value)) _.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.set(
String(key),
String(value)
)
} }
get length() { get length() {
@ -28,7 +43,8 @@ export class Storage {
} }
} }
const getStringOrNull = (value: string | void) => typeof value === 'string' ? value : null const getStringOrNull = (value: string | void) =>
typeof value === 'string' ? value : null
export const initStorage = (target: Target, exclude: Set<string>) => { export const initStorage = (target: Target, exclude: Set<string>) => {
if (exclude.has('Storage') || exclude.has('localStorage')) return if (exclude.has('Storage') || exclude.has('localStorage')) return
@ -38,7 +54,7 @@ export const initStorage = (target: Target, exclude: Set<string>) => {
const storageInternals = new Map<string, string>() const storageInternals = new Map<string, string>()
_.INTERNALS.set(target.localStorage, { _.INTERNALS.set(target.localStorage, {
storage: storageInternals storage: storageInternals,
} as StorageInternals) } as StorageInternals)
} }

View file

@ -1,11 +1,18 @@
import * as _ from './utils' import * as _ from './utils'
export const replaceAll = { export const replaceAll = {
replaceAll(this: string, searchValue: RegExp | string, replaceValue: string | ((substring: string, ...args: any[]) => string)) { replaceAll(
this: string,
searchValue: RegExp | string,
replaceValue: string | ((substring: string, ...args: any[]) => string)
) {
return _.__object_isPrototypeOf(RegExp.prototype, searchValue) return _.__object_isPrototypeOf(RegExp.prototype, searchValue)
? this.replace(searchValue as RegExp, replaceValue as string) ? this.replace(searchValue as RegExp, replaceValue as string)
: this.replace(new RegExp(_.__string_escapeRegExp(searchValue as string), 'g'), replaceValue as string) : this.replace(
} new RegExp(_.__string_escapeRegExp(searchValue as string), 'g'),
replaceValue as string
)
},
}.replaceAll }.replaceAll
export const initString = (target: any, exclude: Set<string>) => { export const initString = (target: any, exclude: Set<string>) => {
@ -13,10 +20,11 @@ export const initString = (target: any, exclude: Set<string>) => {
const Class = target.String || globalThis.String const Class = target.String || globalThis.String
if (!Class.prototype.replaceAll) Object.defineProperty(Class.prototype, 'replaceAll', { if (!Class.prototype.replaceAll)
value: replaceAll, Object.defineProperty(Class.prototype, 'replaceAll', {
writable: true, value: replaceAll,
enumerable: false, writable: true,
configurable: true enumerable: false,
}) configurable: true,
})
} }

View file

@ -1,9 +1,15 @@
import { setTimeout as nodeSetTimeout, clearTimeout as nodeClearTimeout } from 'node:timers' import {
setTimeout as nodeSetTimeout,
clearTimeout as nodeClearTimeout,
} from 'node:timers'
import * as _ from './utils.js' import * as _ from './utils.js'
const INTERNAL = { tick: 0, pool: new Map } const INTERNAL = { tick: 0, pool: new Map() }
export function setTimeout<TArgs extends any[], TFunc extends (...args: TArgs) => any>(callback: TFunc, delay = 0, ...args: TArgs): number { export function setTimeout<
TArgs extends any[],
TFunc extends (...args: TArgs) => any
>(callback: TFunc, delay = 0, ...args: TArgs): number {
const func = _.__function_bind(callback, globalThis) const func = _.__function_bind(callback, globalThis)
const tick = ++INTERNAL.tick const tick = ++INTERNAL.tick
const timeout = nodeSetTimeout(func, delay, ...args) const timeout = nodeSetTimeout(func, delay, ...args)

View file

@ -30,17 +30,29 @@ export class TreeWalker {
} }
get currentNode(): Node { get currentNode(): Node {
const internals = _.internalsOf<TreeWalkerInternals>(this, 'TreeWalker', 'currentNode') const internals = _.internalsOf<TreeWalkerInternals>(
this,
'TreeWalker',
'currentNode'
)
return internals.currentNode return internals.currentNode
} }
get root(): Node { get root(): Node {
const internals = _.internalsOf<TreeWalkerInternals>(this, 'TreeWalker', 'root') const internals = _.internalsOf<TreeWalkerInternals>(
this,
'TreeWalker',
'root'
)
return internals.root return internals.root
} }
get whatToShow(): number { get whatToShow(): number {
const internals = _.internalsOf<TreeWalkerInternals>(this, 'TreeWalker', 'whatToShow') const internals = _.internalsOf<TreeWalkerInternals>(
this,
'TreeWalker',
'whatToShow'
)
return internals.whatToShow return internals.whatToShow
} }
} }

View file

@ -1,74 +1,106 @@
import { default as nodeFetch, Headers, Request, Response } from 'node-fetch/src/index.js' import {
default as nodeFetch,
Headers,
Request,
Response,
} from 'node-fetch/src/index.js'
import Stream from 'node:stream' import Stream from 'node:stream'
import * as _ from './utils' import * as _ from './utils'
export { Headers, Request, Response } export { Headers, Request, Response }
export const fetch = { export const fetch = {
fetch(resource: string | URL | Request, init?: Partial<FetchInit>): Promise<Response> { fetch(
resource: string | URL | Request,
init?: Partial<FetchInit>
): Promise<Response> {
const resourceURL = new URL( const resourceURL = new URL(
_.__object_isPrototypeOf(Request.prototype, resource) _.__object_isPrototypeOf(Request.prototype, resource)
? (resource as Request).url ? (resource as Request).url
: _.pathToPosix(resource), : _.pathToPosix(resource),
typeof Object(globalThis.process).cwd === 'function' ? 'file:' + _.pathToPosix(process.cwd()) + '/' : 'file:' typeof Object(globalThis.process).cwd === 'function'
? 'file:' + _.pathToPosix(process.cwd()) + '/'
: 'file:'
) )
if (resourceURL.protocol.toLowerCase() === 'file:') { if (resourceURL.protocol.toLowerCase() === 'file:') {
return import('node:fs').then( return import('node:fs').then((fs) => {
fs => { try {
try { const stats = fs.statSync(resourceURL)
const stats = fs.statSync(resourceURL) const body = fs.createReadStream(resourceURL)
const body = fs.createReadStream(resourceURL)
return new Response( return new Response(body, {
body, status: 200,
{ statusText: '',
status: 200, headers: {
statusText: '', 'content-length': String(stats.size),
headers: { date: new Date().toUTCString(),
'content-length': String(stats.size), 'last-modified': new Date(stats.mtimeMs).toUTCString(),
'date': new Date().toUTCString(), },
'last-modified': new Date(stats.mtimeMs).toUTCString(), })
} } catch (error) {
} const body = new Stream.Readable()
)
} catch (error) {
const body = new Stream.Readable()
body._read = () => {} body._read = () => {}
body.push(null) body.push(null)
return new Response( return new Response(body, {
body, status: 404,
{ statusText: '',
status: 404, headers: {
statusText: '', date: new Date().toUTCString(),
headers: { },
'date': new Date().toUTCString(), })
}
}
)
}
} }
) })
} else { } else {
return nodeFetch(resource, init) return nodeFetch(resource, init)
} }
} },
}.fetch }.fetch
type USVString = ({} & string) type USVString = {} & string
interface FetchInit { interface FetchInit {
body: Blob | BufferSource | FormData | URLSearchParams | ReadableStream | USVString body:
cache: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached' | Blob
| BufferSource
| FormData
| URLSearchParams
| ReadableStream
| USVString
cache:
| 'default'
| 'no-store'
| 'reload'
| 'no-cache'
| 'force-cache'
| 'only-if-cached'
credentials: 'omit' | 'same-origin' | 'include' credentials: 'omit' | 'same-origin' | 'include'
headers: Headers | Record<string, string> headers: Headers | Record<string, string>
method: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH' | USVString method:
| 'GET'
| 'HEAD'
| 'POST'
| 'PUT'
| 'DELETE'
| 'CONNECT'
| 'OPTIONS'
| 'TRACE'
| 'PATCH'
| USVString
mode: 'cors' | 'no-cors' | 'same-origin' | USVString mode: 'cors' | 'no-cors' | 'same-origin' | USVString
redirect: 'follow' | 'manual' | 'error' redirect: 'follow' | 'manual' | 'error'
referrer: USVString referrer: USVString
referrerPolicy: 'no-referrer' | 'no-referrer-when-downgrade' | 'same-origin' | 'origin' | 'strict-origin' | 'origin-when-cross-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url' referrerPolicy:
| 'no-referrer'
| 'no-referrer-when-downgrade'
| 'same-origin'
| 'origin'
| 'strict-origin'
| 'origin-when-cross-origin'
| 'strict-origin-when-cross-origin'
| 'unsafe-url'
integrity: USVString integrity: USVString
keepalive: boolean keepalive: boolean
signal: AbortSignal signal: AbortSignal

View file

@ -1,4 +1,4 @@
import { deserialize } from '@ungap/structured-clone/esm/deserialize.js'; import { deserialize } from '@ungap/structured-clone/esm/deserialize.js'
import { serialize } from '@ungap/structured-clone/esm/serialize.js'; import { serialize } from '@ungap/structured-clone/esm/serialize.js'
export default (any: any, options: any) => deserialize(serialize(any, options)) export default (any: any, options: any) => deserialize(serialize(any, options))

View file

@ -4,58 +4,93 @@ import { performance } from 'node:perf_hooks'
export const __date_now = Date.now export const __date_now = Date.now
/** Returns the function bound to the given object. */ /** Returns the function bound to the given object. */
export const __function_bind = Function.bind.bind(Function.call as unknown as any) as <TArgs extends any[], TFunc extends (...args: TArgs) => any>(callback: TFunc, thisArg: unknown, ...args: TArgs) => TFunc export const __function_bind = Function.bind.bind(
Function.call as unknown as any
) as <TArgs extends any[], TFunc extends (...args: TArgs) => any>(
callback: TFunc,
thisArg: unknown,
...args: TArgs
) => TFunc
/** Returns the function called with the specified values. */ /** Returns the function called with the specified values. */
export const __function_call = Function.call.bind(Function.call as unknown as any) as <TArgs extends any, TFunc extends (...args: TArgs[]) => any>(callback: TFunc, thisArg: unknown, ...args: TArgs[]) => ReturnType<TFunc> export const __function_call = Function.call.bind(
Function.call as unknown as any
) as <TArgs extends any, TFunc extends (...args: TArgs[]) => any>(
callback: TFunc,
thisArg: unknown,
...args: TArgs[]
) => ReturnType<TFunc>
/** Returns an object with the specified prototype. */ /** Returns an object with the specified prototype. */
export const __object_create = Object.create as { <T extends any = any>(value: T): any extends T ? Record<any, any> : T } export const __object_create = Object.create as {
<T extends any = any>(value: T): any extends T ? Record<any, any> : T
}
/** Returns whether an object has a property with the specified name. */ /** Returns whether an object has a property with the specified name. */
export const __object_hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty) as { <T1 extends object, T2>(object: T1, key: T2): T2 extends keyof T1 ? true : false } export const __object_hasOwnProperty = Function.call.bind(
Object.prototype.hasOwnProperty
) as {
<T1 extends object, T2>(object: T1, key: T2): T2 extends keyof T1
? true
: false
}
/** Returns a string representation of an object. */ /** Returns a string representation of an object. */
export const __object_toString = Function.call.bind(Object.prototype.toString) as { (value: any): string } export const __object_toString = Function.call.bind(
Object.prototype.toString
) as { (value: any): string }
/** Returns whether the object prototype exists in another object. */ /** Returns whether the object prototype exists in another object. */
export const __object_isPrototypeOf = Function.call.bind(Object.prototype.isPrototypeOf) as { <T1 extends object, T2>(p: T1, v: T2): T2 extends T1 ? true : false } export const __object_isPrototypeOf = Function.call.bind(
Object.prototype.isPrototypeOf
) as { <T1 extends object, T2>(p: T1, v: T2): T2 extends T1 ? true : false }
/** Current high resolution millisecond timestamp. */ /** Current high resolution millisecond timestamp. */
export const __performance_now = performance.now as () => number export const __performance_now = performance.now as () => number
/** Returns the string escaped for use inside regular expressions. */ /** Returns the string escaped for use inside regular expressions. */
export const __string_escapeRegExp = (value: string) => value.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&') export const __string_escapeRegExp = (value: string) =>
value.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&')
// @ts-ignore // @ts-ignore
export const INTERNALS = new WeakMap<unknown, any>() export const INTERNALS = new WeakMap<unknown, any>()
export const internalsOf = <T extends object>(target: T | object, className: string, propName: string): T => { export const internalsOf = <T extends object>(
target: T | object,
className: string,
propName: string
): T => {
const internals: T = INTERNALS.get(target) const internals: T = INTERNALS.get(target)
if (!internals) throw new TypeError(`${className}.${propName} can only be used on instances of ${className}`) if (!internals)
throw new TypeError(
`${className}.${propName} can only be used on instances of ${className}`
)
return internals return internals
} }
export const allowStringTag = (value: any) => value.prototype[Symbol.toStringTag] = value.name export const allowStringTag = (value: any) =>
(value.prototype[Symbol.toStringTag] = value.name)
/** Returns any kind of path as a posix path. */ /** Returns any kind of path as a posix path. */
export const pathToPosix = (pathname: any) => String( export const pathToPosix = (pathname: any) =>
pathname == null ? '' : pathname String(pathname == null ? '' : pathname)
).replace( .replace(
// convert slashes // convert slashes
/\\+/g, '/' /\\+/g,
).replace( '/'
// prefix a slash to drive letters )
/^(?=[A-Za-z]:\/)/, '/' .replace(
).replace( // prefix a slash to drive letters
// encode path characters /^(?=[A-Za-z]:\/)/,
/%/g, '%25' '/'
).replace( )
/\n/g, '%0A' .replace(
).replace( // encode path characters
/\r/g, '%0D' /%/g,
).replace( '%25'
/\t/g, '%09' )
) .replace(/\n/g, '%0A')
.replace(/\r/g, '%0D')
.replace(/\t/g, '%09')

View file

@ -60,7 +60,6 @@ import {
WritableStreamDefaultController, WritableStreamDefaultController,
WritableStreamDefaultWriter, WritableStreamDefaultWriter,
Window, Window,
alert, alert,
atob, atob,
btoa, btoa,
@ -72,7 +71,6 @@ import {
requestIdleCallback, requestIdleCallback,
setTimeout, setTimeout,
structuredClone, structuredClone,
initCustomElementRegistry, initCustomElementRegistry,
initDocument, initDocument,
initMediaQueryList, initMediaQueryList,
@ -148,7 +146,6 @@ export {
WritableStreamDefaultController, WritableStreamDefaultController,
WritableStreamDefaultWriter, WritableStreamDefaultWriter,
Window, Window,
alert, alert,
atob, atob,
btoa, btoa,
@ -245,18 +242,25 @@ export const polyfill = (target: any, options?: PolyfillOptions) => {
const excludeOptions = new Set( const excludeOptions = new Set(
typeof Object(options).exclude === 'string' typeof Object(options).exclude === 'string'
? String(Object(options).exclude).trim().split(/\s+/) ? String(Object(options).exclude).trim().split(/\s+/)
: Array.isArray(Object(options).exclude) : Array.isArray(Object(options).exclude)
? Object(options).exclude.reduce( ? Object(options).exclude.reduce(
(array: string[], entry: unknown) => array.splice(array.length, 0, ...(typeof entry === 'string' ? entry.trim().split(/\s+/) : [])) && array, (array: string[], entry: unknown) =>
[] array.splice(
) array.length,
: [] 0,
...(typeof entry === 'string' ? entry.trim().split(/\s+/) : [])
) && array,
[]
)
: []
) as Set<string> ) as Set<string>
// expand exclude options using exclusion shorthands // expand exclude options using exclusion shorthands
for (const excludeOption of excludeOptions) { for (const excludeOption of excludeOptions) {
if (excludeOption in exclusions) { if (excludeOption in exclusions) {
for (const exclusion of exclusions[excludeOption as keyof typeof exclusions]) { for (const exclusion of exclusions[
excludeOption as keyof typeof exclusions
]) {
excludeOptions.add(exclusion) excludeOptions.add(exclusion)
} }
} }
@ -267,11 +271,16 @@ export const polyfill = (target: any, options?: PolyfillOptions) => {
// skip WebAPIs that are excluded // skip WebAPIs that are excluded
if (excludeOptions.has(name)) continue if (excludeOptions.has(name)) continue
// skip WebAPIs that are built-in // skip WebAPIs that are built-in
if (Object.hasOwnProperty.call(target, name)) continue if (Object.hasOwnProperty.call(target, name)) continue
// define WebAPIs on the target // define WebAPIs on the target
Object.defineProperty(target, name, { configurable: true, enumerable: true, writable: true, value: webAPIs[name as keyof typeof webAPIs] }) Object.defineProperty(target, name, {
configurable: true,
enumerable: true,
writable: true,
value: webAPIs[name as keyof typeof webAPIs],
})
} }
// ensure WebAPIs correctly inherit other WebAPIs // ensure WebAPIs correctly inherit other WebAPIs
@ -288,14 +297,17 @@ export const polyfill = (target: any, options?: PolyfillOptions) => {
// skip WebAPIs that are not available // skip WebAPIs that are not available
if (!Class || !Super) continue if (!Class || !Super) continue
// skip WebAPIs that are already inherited correctly // skip WebAPIs that are already inherited correctly
if (Object.getPrototypeOf(Class.prototype) === Super.prototype) continue if (Object.getPrototypeOf(Class.prototype) === Super.prototype) continue
// define WebAPIs inheritence // define WebAPIs inheritence
Object.setPrototypeOf(Class.prototype, Super.prototype) Object.setPrototypeOf(Class.prototype, Super.prototype)
} }
if (!excludeOptions.has('HTMLDocument') && !excludeOptions.has('HTMLElement')) { if (
!excludeOptions.has('HTMLDocument') &&
!excludeOptions.has('HTMLElement')
) {
initDocument(target, excludeOptions) initDocument(target, excludeOptions)
if (!excludeOptions.has('CustomElementRegistry')) { if (!excludeOptions.has('CustomElementRegistry')) {

View file

@ -1,7 +1,13 @@
// @ts-check // @ts-check
import { AbortController, AbortSignal } from 'abort-controller/dist/abort-controller.mjs' import {
import { requestAnimationFrame, cancelAnimationFrame } from './lib/AnimationFrame' AbortController,
AbortSignal,
} from 'abort-controller/dist/abort-controller.mjs'
import {
requestAnimationFrame,
cancelAnimationFrame,
} from './lib/AnimationFrame'
import { atob, btoa } from './lib/Base64' import { atob, btoa } from './lib/Base64'
import { CharacterData, Comment, Text } from './lib/CharacterData' import { CharacterData, Comment, Text } from './lib/CharacterData'
import { File, Blob } from 'fetch-blob/from.js' import { File, Blob } from 'fetch-blob/from.js'
@ -12,22 +18,59 @@ import { cancelIdleCallback, requestIdleCallback } from './lib/IdleCallback'
import { Event, EventTarget } from 'event-target-shim' import { Event, EventTarget } from 'event-target-shim'
import { fetch, Headers, Request, Response } from './lib/fetch' import { fetch, Headers, Request, Response } from './lib/fetch'
import { FormData } from 'formdata-polyfill/esm.min.js' import { FormData } from 'formdata-polyfill/esm.min.js'
import { ByteLengthQueuingStrategy, CountQueuingStrategy, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, TransformStream, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter } from 'web-streams-polyfill/dist/ponyfill.es6.mjs' import {
ByteLengthQueuingStrategy,
CountQueuingStrategy,
ReadableByteStreamController,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamBYOBRequest,
ReadableStreamDefaultController,
ReadableStreamDefaultReader,
TransformStream,
WritableStream,
WritableStreamDefaultController,
WritableStreamDefaultWriter,
} from 'web-streams-polyfill/dist/ponyfill.es6.mjs'
import { URLPattern } from 'urlpattern-polyfill' import { URLPattern } from 'urlpattern-polyfill'
import { setTimeout, clearTimeout } from './lib/Timeout' import { setTimeout, clearTimeout } from './lib/Timeout'
import structuredClone from './lib/structuredClone' import structuredClone from './lib/structuredClone'
import { CanvasRenderingContext2D } from './lib/CanvasRenderingContext2D' import { CanvasRenderingContext2D } from './lib/CanvasRenderingContext2D'
import { CSSStyleSheet, StyleSheet } from './lib/StyleSheet' import { CSSStyleSheet, StyleSheet } from './lib/StyleSheet'
import { CustomElementRegistry, initCustomElementRegistry } from './lib/CustomElementRegistry' import {
CustomElementRegistry,
initCustomElementRegistry,
} from './lib/CustomElementRegistry'
import { Document, HTMLDocument, initDocument } from './lib/Document' import { Document, HTMLDocument, initDocument } from './lib/Document'
import { DocumentFragment, Node, NodeFilter, NodeIterator, ShadowRoot } from './lib/Node' import {
import { Element, HTMLElement, HTMLBodyElement, HTMLDivElement, HTMLHeadElement, HTMLHtmlElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement } from './lib/Element' DocumentFragment,
Node,
NodeFilter,
NodeIterator,
ShadowRoot,
} from './lib/Node'
import {
Element,
HTMLElement,
HTMLBodyElement,
HTMLDivElement,
HTMLHeadElement,
HTMLHtmlElement,
HTMLSpanElement,
HTMLStyleElement,
HTMLTemplateElement,
HTMLUnknownElement,
} from './lib/Element'
import { HTMLCanvasElement } from './lib/HTMLCanvasElement' import { HTMLCanvasElement } from './lib/HTMLCanvasElement'
import { HTMLImageElement } from './lib/HTMLImageElement' import { HTMLImageElement } from './lib/HTMLImageElement'
import { Image } from './lib/Image' import { Image } from './lib/Image'
import { ImageData } from './lib/ImageData' import { ImageData } from './lib/ImageData'
import { IntersectionObserver, MutationObserver, ResizeObserver } from './lib/Observer' import {
IntersectionObserver,
MutationObserver,
ResizeObserver,
} from './lib/Observer'
import { MediaQueryList, initMediaQueryList } from './lib/MediaQueryList' import { MediaQueryList, initMediaQueryList } from './lib/MediaQueryList'
import { OffscreenCanvas } from './lib/OffscreenCanvas' import { OffscreenCanvas } from './lib/OffscreenCanvas'
import { Storage, initStorage } from './lib/Storage' import { Storage, initStorage } from './lib/Storage'
@ -102,7 +145,6 @@ export {
WritableStreamDefaultController, WritableStreamDefaultController,
WritableStreamDefaultWriter, WritableStreamDefaultWriter,
Window, Window,
alert, alert,
atob, atob,
btoa, btoa,
@ -114,7 +156,6 @@ export {
requestIdleCallback, requestIdleCallback,
setTimeout, setTimeout,
structuredClone, structuredClone,
initCustomElementRegistry, initCustomElementRegistry,
initDocument, initDocument,
initMediaQueryList, initMediaQueryList,

View file

@ -7,9 +7,9 @@ test(() => {
name: 'Supports Base64 Methods', name: 'Supports Base64 Methods',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal('atob' in target, true) assert.equal('atob' in target, true)
assert.equal('btoa' in target, true) assert.equal('btoa' in target, true)
assert.equal(typeof target['atob'], 'function') assert.equal(typeof target['atob'], 'function')
@ -20,7 +20,7 @@ test(() => {
name: 'Supports atob(data)', name: 'Supports atob(data)',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const a = 'SGVsbG8sIHdvcmxk' const a = 'SGVsbG8sIHdvcmxk'
@ -34,7 +34,7 @@ test(() => {
name: 'Supports btoa(data)', name: 'Supports btoa(data)',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const b = 'Hello, world' const b = 'Hello, world'

View file

@ -8,8 +8,62 @@ test(() => {
{ {
name: 'Globals exist', name: 'Globals exist',
test() { test() {
const webAPIs = [ 'AbortController', 'AbortSignal', 'Blob', 'ByteLengthQueuingStrategy', 'CSSStyleSheet', 'CountQueuingStrategy', 'CustomElementRegistry', 'CustomEvent', 'DOMException', 'Document', 'DocumentFragment', 'Element', 'Event', 'EventTarget', 'File', 'FormData', 'HTMLDocument', 'HTMLElement', 'HTMLDivElement', 'HTMLHeadElement', 'HTMLHtmlElement', 'HTMLImageElement', 'HTMLStyleElement', 'HTMLTemplateElement', 'HTMLUnknownElement', 'Headers', 'IntersectionObserver', 'Image', 'MediaQueryList', 'MutationObserver', 'Node', 'ReadableByteStreamController', 'ReadableStream', 'ReadableStreamBYOBReader', 'ReadableStreamBYOBRequest', 'ReadableStreamDefaultController', 'ReadableStreamDefaultReader', 'Request', 'Response', 'ShadowRoot', 'StyleSheet', 'TransformStream', 'WritableStream', 'WritableStreamDefaultController', 'WritableStreamDefaultWriter', 'Window', 'cancelAnimationFrame', 'cancelIdleCallback', 'clearTimeout', 'fetch', 'requestAnimationFrame', 'requestIdleCallback', 'setTimeout' ] const webAPIs = [
'AbortController',
'AbortSignal',
'Blob',
'ByteLengthQueuingStrategy',
'CSSStyleSheet',
'CountQueuingStrategy',
'CustomElementRegistry',
'CustomEvent',
'DOMException',
'Document',
'DocumentFragment',
'Element',
'Event',
'EventTarget',
'File',
'FormData',
'HTMLDocument',
'HTMLElement',
'HTMLDivElement',
'HTMLHeadElement',
'HTMLHtmlElement',
'HTMLImageElement',
'HTMLStyleElement',
'HTMLTemplateElement',
'HTMLUnknownElement',
'Headers',
'IntersectionObserver',
'Image',
'MediaQueryList',
'MutationObserver',
'Node',
'ReadableByteStreamController',
'ReadableStream',
'ReadableStreamBYOBReader',
'ReadableStreamBYOBRequest',
'ReadableStreamDefaultController',
'ReadableStreamDefaultReader',
'Request',
'Response',
'ShadowRoot',
'StyleSheet',
'TransformStream',
'WritableStream',
'WritableStreamDefaultController',
'WritableStreamDefaultWriter',
'Window',
'cancelAnimationFrame',
'cancelIdleCallback',
'clearTimeout',
'fetch',
'requestAnimationFrame',
'requestIdleCallback',
'setTimeout',
]
for (const name of webAPIs) { for (const name of webAPIs) {
assert.equal(typeof globalThis[name], 'function') assert.equal(typeof globalThis[name], 'function')
} }
@ -19,7 +73,7 @@ test(() => {
name: 'Constructs an Event', name: 'Constructs an Event',
test() { test() {
const e = new Event('test') const e = new Event('test')
assert.equal(e.type, 'test') assert.equal(e.type, 'test')
}, },
}, },
@ -33,17 +87,17 @@ test(() => {
name: 'Dispatches an Event on an EventTarget', name: 'Dispatches an Event on an EventTarget',
test() { test() {
const t = new EventTarget() const t = new EventTarget()
let pass = false let pass = false
t.addEventListener('test', (event) => { t.addEventListener('test', (event) => {
pass = true pass = true
}) })
const e = new Event('test') const e = new Event('test')
t.dispatchEvent(e) t.dispatchEvent(e)
assert.equal(pass, true) assert.equal(pass, true)
}, },
}, },
@ -80,7 +134,7 @@ test(() => {
test() { test() {
assert.equal(typeof String.prototype.at, 'function') assert.equal(typeof String.prototype.at, 'function')
assert.equal(String.prototype.at.length, 1) assert.equal(String.prototype.at.length, 1)
const example = 'The quick brown fox jumps over the lazy dog.' const example = 'The quick brown fox jumps over the lazy dog.'
assert.equal(example.at(2), 'e') assert.equal(example.at(2), 'e')
@ -92,7 +146,7 @@ test(() => {
test() { test() {
assert.equal(typeof Array.prototype.at, 'function') assert.equal(typeof Array.prototype.at, 'function')
assert.equal(Array.prototype.at.length, 1) assert.equal(Array.prototype.at.length, 1)
const example = [1, 3, 5, 7, 9] const example = [1, 3, 5, 7, 9]
assert.equal(example.at(1), 3) assert.equal(example.at(1), 3)
@ -104,7 +158,7 @@ test(() => {
test() { test() {
assert.equal(typeof Int8Array.prototype.at, 'function') assert.equal(typeof Int8Array.prototype.at, 'function')
assert.equal(Int8Array.prototype.at.length, 1) assert.equal(Int8Array.prototype.at.length, 1)
const example = new Int8Array([1, 3, 5, 7, 9]) const example = new Int8Array([1, 3, 5, 7, 9])
assert.equal(example.at(1), 3) assert.equal(example.at(1), 3)
@ -120,7 +174,7 @@ test(() => {
const example = {} const example = {}
assert.equal(Object.hasOwn(example, 'prop'), false) assert.equal(Object.hasOwn(example, 'prop'), false)
example.prop = 'exists' example.prop = 'exists'
assert.equal(Object.hasOwn(example, 'prop'), true) assert.equal(Object.hasOwn(example, 'prop'), true)
@ -132,11 +186,13 @@ test(() => {
assert.equal(typeof Promise.any, 'function') assert.equal(typeof Promise.any, 'function')
assert.equal(Promise.any.length, 1) assert.equal(Promise.any.length, 1)
Promise.any([Promise.resolve(42), Promise.reject(-1), Promise.reject(Infinity)]).then( Promise.any([
result => { Promise.resolve(42),
assert.equal(result, 42) Promise.reject(-1),
} Promise.reject(Infinity),
) ]).then((result) => {
assert.equal(result, 42)
})
}, },
}, },
{ {
@ -145,9 +201,11 @@ test(() => {
assert.equal(typeof String.prototype.replaceAll, 'function') assert.equal(typeof String.prototype.replaceAll, 'function')
assert.equal(String.prototype.replaceAll.length, 2) assert.equal(String.prototype.replaceAll.length, 2)
const t1 = 'Of all the sorcerers in Harry Potter, Halo is my favorite sorcerer.' const t1 =
'Of all the sorcerers in Harry Potter, Halo is my favorite sorcerer.'
const t2 = t1.replaceAll('sorcerer', 'philosopher') const t2 = t1.replaceAll('sorcerer', 'philosopher')
const t3 = 'Of all the philosophers in Harry Potter, Halo is my favorite philosopher.' const t3 =
'Of all the philosophers in Harry Potter, Halo is my favorite philosopher.'
assert.equal(t2, t3) assert.equal(t2, t3)
}, },

View file

@ -33,7 +33,10 @@ test(() => {
}) })
assert.equal(new target.Comment().constructor.name, 'Comment') assert.equal(new target.Comment().constructor.name, 'Comment')
assert.equal(Object.prototype.toString.call(new target.Comment()), '[object Comment]') assert.equal(
Object.prototype.toString.call(new target.Comment()),
'[object Comment]'
)
assert.equal(new target.Comment('hello').data, 'hello') assert.equal(new target.Comment('hello').data, 'hello')
assert.equal(new target.Comment('hello').textContent, 'hello') assert.equal(new target.Comment('hello').textContent, 'hello')
@ -49,7 +52,10 @@ test(() => {
}) })
assert.equal(new target.Text().constructor.name, 'Text') assert.equal(new target.Text().constructor.name, 'Text')
assert.equal(Object.prototype.toString.call(new target.Text()), '[object Text]') assert.equal(
Object.prototype.toString.call(new target.Text()),
'[object Text]'
)
assert.equal(new target.Text('hello').data, 'hello') assert.equal(new target.Text('hello').data, 'hello')
assert.equal(new target.Text('hello').textContent, 'hello') assert.equal(new target.Text('hello').textContent, 'hello')

View file

@ -27,7 +27,10 @@ test(() => {
target.customElements.define('custom-element', CustomElement) target.customElements.define('custom-element', CustomElement)
assert.equal(target.customElements.get('custom-element'), CustomElement) assert.equal(target.customElements.get('custom-element'), CustomElement)
assert.equal(target.customElements.getName(CustomElement), 'custom-element') assert.equal(
target.customElements.getName(CustomElement),
'custom-element'
)
}, },
}, },
{ {
@ -40,13 +43,19 @@ test(() => {
assert.equal(target.document.body.localName, 'body') assert.equal(target.document.body.localName, 'body')
assert.equal(target.document.body.tagName, 'BODY') assert.equal(target.document.body.tagName, 'BODY')
assert.equal(target.document.createElement('custom-element').constructor.name, 'HTMLUnknownElement') assert.equal(
target.document.createElement('custom-element').constructor.name,
'HTMLUnknownElement'
)
const CustomElement = class HTMLCustomElement extends target.HTMLElement {} const CustomElement = class HTMLCustomElement extends target.HTMLElement {}
target.customElements.define('custom-element', CustomElement) target.customElements.define('custom-element', CustomElement)
assert.equal(target.document.createElement('custom-element').constructor.name, 'HTMLCustomElement') assert.equal(
target.document.createElement('custom-element').constructor.name,
'HTMLCustomElement'
)
}, },
}, },
{ {

View file

@ -7,9 +7,9 @@ test(() => {
name: 'Fetch functionality', name: 'Fetch functionality',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal(Reflect.has(target, 'fetch'), true) assert.equal(Reflect.has(target, 'fetch'), true)
assert.equal(typeof target.fetch, 'function') assert.equal(typeof target.fetch, 'function')
}, },
@ -18,7 +18,7 @@ test(() => {
name: 'Fetch with https', name: 'Fetch with https',
async test() { async test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const { fetch } = target const { fetch } = target
@ -36,7 +36,7 @@ test(() => {
name: 'Fetch with file', name: 'Fetch with file',
async test() { async test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const { fetch } = target const { fetch } = target
@ -62,7 +62,7 @@ test(() => {
name: 'Fetch with missing file', name: 'Fetch with missing file',
async test() { async test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const { fetch } = target const { fetch } = target
@ -84,7 +84,7 @@ test(() => {
name: 'Fetch with (file) Request', name: 'Fetch with (file) Request',
async test() { async test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const { Request, fetch } = target const { Request, fetch } = target
@ -104,7 +104,7 @@ test(() => {
name: 'Fetch with relative file', name: 'Fetch with relative file',
async test() { async test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const { fetch } = target const { fetch } = target
@ -120,14 +120,16 @@ test(() => {
name: 'Fetch with data', name: 'Fetch with data',
async test() { async test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const { fetch } = target const { fetch } = target
const jsonURI = `data:application/json,${encodeURIComponent(JSON.stringify({ const jsonURI = `data:application/json,${encodeURIComponent(
name: '@astrojs/webapi' JSON.stringify({
}))}` name: '@astrojs/webapi',
})
)}`
const response = await fetch(jsonURI) const response = await fetch(jsonURI)

View file

@ -7,9 +7,9 @@ test(() => {
name: 'Supports ImageData', name: 'Supports ImageData',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal('ImageData' in target, true) assert.equal('ImageData' in target, true)
assert.equal(typeof target['ImageData'], 'function') assert.equal(typeof target['ImageData'], 'function')
}, },
@ -18,7 +18,7 @@ test(() => {
name: 'Supports new (data: Uint8ClampedArray, width: number, height: number): ImageData', name: 'Supports new (data: Uint8ClampedArray, width: number, height: number): ImageData',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const w = 640 const w = 640
@ -36,7 +36,7 @@ test(() => {
name: 'Supports new (data: Uint8ClampedArray, width: number): ImageData', name: 'Supports new (data: Uint8ClampedArray, width: number): ImageData',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const w = 640 const w = 640
@ -54,7 +54,7 @@ test(() => {
name: 'Supports new (width: number, height: number): ImageData', name: 'Supports new (width: number, height: number): ImageData',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const w = 640 const w = 640
@ -71,7 +71,7 @@ test(() => {
name: 'Supports Object.keys(new ImageData(640, 480))', name: 'Supports Object.keys(new ImageData(640, 480))',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const keys = Object.keys(new target.ImageData(640, 480)) const keys = Object.keys(new target.ImageData(640, 480))

View file

@ -7,7 +7,7 @@ test(() => {
name: 'Includes polyfill.internals functionality', name: 'Includes polyfill.internals functionality',
test() { test() {
const target = {} const target = {}
polyfill(target, { exclude: 'window document' }) polyfill(target, { exclude: 'window document' })
const pseudo = { ...target } const pseudo = { ...target }
@ -22,8 +22,13 @@ test(() => {
assert.equal(Reflect.has(pseudo, 'document'), true) assert.equal(Reflect.has(pseudo, 'document'), true)
assert.equal(CustomElement.prototype.isPrototypeOf(pseudo.document.createElement('custom-element')), true) assert.equal(
CustomElement.prototype.isPrototypeOf(
pseudo.document.createElement('custom-element')
),
true
)
}, },
} },
] ]
}) })

View file

@ -7,9 +7,9 @@ test(() => {
name: 'Includes MediaQueryList functionality', name: 'Includes MediaQueryList functionality',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal(Reflect.has(target, 'MediaQueryList'), true) assert.equal(Reflect.has(target, 'MediaQueryList'), true)
assert.equal(Reflect.has(target, 'matchMedia'), true) assert.equal(Reflect.has(target, 'matchMedia'), true)
}, },
@ -18,7 +18,7 @@ test(() => {
name: 'Supports matchMedia creation', name: 'Supports matchMedia creation',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const mql = target.matchMedia('(min-width: 640px)') const mql = target.matchMedia('(min-width: 640px)')

View file

@ -7,9 +7,9 @@ test(() => {
name: 'Supports OffscreenCanvas', name: 'Supports OffscreenCanvas',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal('OffscreenCanvas' in target, true) assert.equal('OffscreenCanvas' in target, true)
assert.equal(typeof target['OffscreenCanvas'], 'function') assert.equal(typeof target['OffscreenCanvas'], 'function')
}, },
@ -18,7 +18,7 @@ test(() => {
name: 'Supports new (width: number, height: number): OffscreenCanvas', name: 'Supports new (width: number, height: number): OffscreenCanvas',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const w = 640 const w = 640
@ -34,7 +34,7 @@ test(() => {
name: 'Supports OffscreenCanvas#getContext', name: 'Supports OffscreenCanvas#getContext',
test() { test() {
const target = {} const target = {}
polyfill(target) polyfill(target)
const w = 640 const w = 640

View file

@ -7,11 +7,11 @@ test(() => {
name: 'Can exclude HTMLElement+', name: 'Can exclude HTMLElement+',
test() { test() {
const target = {} const target = {}
polyfill(target, { polyfill(target, {
exclude: 'HTMLElement+' exclude: 'HTMLElement+',
}) })
assert.equal(Reflect.has(target, 'Event'), true) assert.equal(Reflect.has(target, 'Event'), true)
assert.equal(Reflect.has(target, 'EventTarget'), true) assert.equal(Reflect.has(target, 'EventTarget'), true)
assert.equal(Reflect.has(target, 'Element'), true) assert.equal(Reflect.has(target, 'Element'), true)
@ -23,11 +23,11 @@ test(() => {
name: 'Can exclude Event+', name: 'Can exclude Event+',
test() { test() {
const target = {} const target = {}
polyfill(target, { polyfill(target, {
exclude: 'Event+' exclude: 'Event+',
}) })
assert.equal(Reflect.has(target, 'Event'), false) assert.equal(Reflect.has(target, 'Event'), false)
assert.equal(Reflect.has(target, 'EventTarget'), false) assert.equal(Reflect.has(target, 'EventTarget'), false)
assert.equal(Reflect.has(target, 'Element'), false) assert.equal(Reflect.has(target, 'Element'), false)
@ -39,11 +39,11 @@ test(() => {
name: 'Can exclude document', name: 'Can exclude document',
test() { test() {
const target = {} const target = {}
polyfill(target, { polyfill(target, {
exclude: 'document' exclude: 'document',
}) })
assert.equal(Reflect.has(target, 'Document'), true) assert.equal(Reflect.has(target, 'Document'), true)
assert.equal(Reflect.has(target, 'HTMLDocument'), true) assert.equal(Reflect.has(target, 'HTMLDocument'), true)
assert.equal(Reflect.has(target, 'document'), false) assert.equal(Reflect.has(target, 'document'), false)

View file

@ -9,7 +9,7 @@ test(() => {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal(Reflect.has(target, 'Storage'), true) assert.equal(Reflect.has(target, 'Storage'), true)
assert.equal(Reflect.has(target, 'localStorage'), true) assert.equal(Reflect.has(target, 'localStorage'), true)
assert.equal(typeof target.Storage, 'function') assert.equal(typeof target.Storage, 'function')

View file

@ -9,7 +9,7 @@ test(() => {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal(Reflect.has(target, 'structuredClone'), true) assert.equal(Reflect.has(target, 'structuredClone'), true)
assert.equal(typeof target.structuredClone, 'function') assert.equal(typeof target.structuredClone, 'function')
}, },
@ -22,9 +22,9 @@ test(() => {
polyfill(target) polyfill(target)
const obj = { const obj = {
foo: "bar", foo: 'bar',
baz: { baz: {
qux: "quux", qux: 'quux',
}, },
} }

View file

@ -9,7 +9,7 @@ test(() => {
const target = {} const target = {}
polyfill(target) polyfill(target)
assert.equal(Reflect.has(target, 'URLPattern'), true) assert.equal(Reflect.has(target, 'URLPattern'), true)
assert.equal(typeof target.URLPattern, 'function') assert.equal(typeof target.URLPattern, 'function')
}, },

View file

@ -12,4 +12,4 @@
"sourceMap": true, "sourceMap": true,
"declarationMap": true "declarationMap": true
} }
} }