[ci] yarn format
This commit is contained in:
parent
f18ee36dc0
commit
63adaeec34
45 changed files with 10089 additions and 7013 deletions
95
packages/webapi/mod.d.ts
vendored
95
packages/webapi/mod.d.ts
vendored
|
@ -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 { pathToPosix } from './lib/utils';
|
||||
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 { pathToPosix } from './lib/utils'
|
||||
export declare const polyfill: {
|
||||
(target: any, options?: PolyfillOptions | undefined): any;
|
||||
internals(target: any, name: string): any;
|
||||
};
|
||||
(target: any, options?: PolyfillOptions | undefined): any
|
||||
internals(target: any, name: string): any
|
||||
}
|
||||
interface PolyfillOptions {
|
||||
exclude?: string | string[];
|
||||
override?: Record<string, {
|
||||
(...args: any[]): any;
|
||||
}>;
|
||||
}
|
||||
exclude?: string | string[]
|
||||
override?: Record<
|
||||
string,
|
||||
{
|
||||
(...args: any[]): any
|
||||
}
|
||||
>
|
||||
}
|
||||
|
|
15565
packages/webapi/mod.js
15565
packages/webapi/mod.js
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,12 @@ import { rollup } from 'rollup'
|
|||
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||
import { posix as path } from 'node:path'
|
||||
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 alias } from '@rollup/plugin-alias'
|
||||
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 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 pathToEventTargetShim = path.join('..', '..', 'node_modules', 'event-target-shim', 'index.mjs')
|
||||
const pathToStructuredClone = path.join('..', '..', 'node_modules', '@ungap', 'structured-clone', 'esm', 'index.js')
|
||||
const pathToEventTargetShim = path.join(
|
||||
'..',
|
||||
'..',
|
||||
'node_modules',
|
||||
'event-target-shim',
|
||||
'index.mjs'
|
||||
)
|
||||
const pathToStructuredClone = path.join(
|
||||
'..',
|
||||
'..',
|
||||
'node_modules',
|
||||
'@ungap',
|
||||
'structured-clone',
|
||||
'esm',
|
||||
'index.js'
|
||||
)
|
||||
|
||||
const plugins = [
|
||||
typescript({
|
||||
|
@ -25,38 +45,50 @@ const plugins = [
|
|||
entries: [
|
||||
{ find: '@ungap/structured-clone', replacement: pathToStructuredClone },
|
||||
{ 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 },
|
||||
],
|
||||
}),
|
||||
nodeResolve({
|
||||
dedupe: [
|
||||
'net',
|
||||
'node:net'
|
||||
]
|
||||
dedupe: ['net', 'node:net'],
|
||||
}),
|
||||
inject({
|
||||
// import { Promise as P } from 'es6-promise'
|
||||
// P: [ 'es6-promise', 'Promise' ],
|
||||
|
||||
'AbortController': [ 'abort-controller/dist/abort-controller.mjs', 'AbortController' ],
|
||||
'Blob': [ 'fetch-blob/from.js', 'Blob' ],
|
||||
'DOMException': [pathToDOMException, 'DOMException'],
|
||||
'Document': [ './Document', 'Document' ],
|
||||
'Element': [ './Element', 'Element' ],
|
||||
'Event': [ 'event-target-shim', 'Event' ],
|
||||
'EventTarget': [ 'event-target-shim', 'EventTarget' ],
|
||||
'defineEventAttribute': [ 'event-target-shim', 'defineEventAttribute' ],
|
||||
'HTMLElement': ['./Element', 'HTMLElement'],
|
||||
'HTMLImageElement': ['./Element', 'HTMLImageElement'],
|
||||
'HTMLUnknownElement': ['./Element', 'HTMLUnknownElement'],
|
||||
'MediaQueryList': [ './MediaQueryList', 'MediaQueryList' ],
|
||||
'Node': [ './Node', 'Node' ],
|
||||
'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' ],
|
||||
AbortController: [
|
||||
'abort-controller/dist/abort-controller.mjs',
|
||||
'AbortController',
|
||||
],
|
||||
Blob: ['fetch-blob/from.js', 'Blob'],
|
||||
DOMException: [pathToDOMException, 'DOMException'],
|
||||
Document: ['./Document', 'Document'],
|
||||
Element: ['./Element', 'Element'],
|
||||
Event: ['event-target-shim', 'Event'],
|
||||
EventTarget: ['event-target-shim', 'EventTarget'],
|
||||
defineEventAttribute: ['event-target-shim', 'defineEventAttribute'],
|
||||
HTMLElement: ['./Element', 'HTMLElement'],
|
||||
HTMLImageElement: ['./Element', 'HTMLImageElement'],
|
||||
HTMLUnknownElement: ['./Element', 'HTMLUnknownElement'],
|
||||
MediaQueryList: ['./MediaQueryList', 'MediaQueryList'],
|
||||
Node: ['./Node', 'Node'],
|
||||
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) {
|
||||
|
@ -69,36 +101,42 @@ const plugins = [
|
|||
|
||||
const replacements = [
|
||||
// remove unused imports
|
||||
[ /(^|\n)import\s+[^']+'node:(buffer|fs|path|worker_threads)'/g, `` ],
|
||||
[ /const \{ stat \} = fs/g, `` ],
|
||||
[/(^|\n)import\s+[^']+'node:(buffer|fs|path|worker_threads)'/g, ``],
|
||||
[/const \{ stat \} = fs/g, ``],
|
||||
|
||||
// remove unused polyfill utils
|
||||
[ /\nif \(\s*typeof Global[\W\w]+?\n\}/g, `` ],
|
||||
[ /\nif \(\s*typeof window[\W\w]+?\n\}/g, `` ],
|
||||
[ /\nif \(!globalThis\.ReadableStream\) \{[\W\w]+?\n\}/g, `` ],
|
||||
[ /\nif \(typeof SymbolPolyfill[\W\w]+?\n\}/g, `` ],
|
||||
[/\nif \(\s*typeof Global[\W\w]+?\n\}/g, ``],
|
||||
[/\nif \(\s*typeof window[\W\w]+?\n\}/g, ``],
|
||||
[/\nif \(!globalThis\.ReadableStream\) \{[\W\w]+?\n\}/g, ``],
|
||||
[/\nif \(typeof SymbolPolyfill[\W\w]+?\n\}/g, ``],
|
||||
|
||||
// remove unused polyfills
|
||||
[ /\nconst globals = getGlobals\(\);/g, `` ],
|
||||
[ /\nconst queueMicrotask = [\W\w]+?\n\}\)\(\);/g, ``],
|
||||
[ /\nconst NativeDOMException =[^;]+;/g, `` ],
|
||||
[ /\nconst SymbolPolyfill\s*=[^;]+;/g, '\nconst SymbolPolyfill = Symbol;'],
|
||||
[ /\n(const|let) DOMException[^;]*;/g, `let DOMException$1=DOMException` ],
|
||||
[ /\nconst DOMException = globalThis.DOMException[\W\w]+?\}\)\(\)/g, `` ],
|
||||
[ /\nimport DOMException from 'node-domexception'/g, `` ],
|
||||
[/\nconst globals = getGlobals\(\);/g, ``],
|
||||
[/\nconst queueMicrotask = [\W\w]+?\n\}\)\(\);/g, ``],
|
||||
[/\nconst NativeDOMException =[^;]+;/g, ``],
|
||||
[
|
||||
/\nconst SymbolPolyfill\s*=[^;]+;/g,
|
||||
'\nconst SymbolPolyfill = Symbol;',
|
||||
],
|
||||
[
|
||||
/\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
|
||||
[ / new DOMException\$1/g, `new DOMException` ],
|
||||
[ / from 'net'/g, `from 'node:net'` ],
|
||||
[ / throw createInvalidStateError/g, `throw new DOMException` ],
|
||||
[ /= createAbortController/g, `= new AbortController` ],
|
||||
[ /\nconst queueMicrotask = [\W\w]+?\n\}\)\(\)\;/g, `` ],
|
||||
[/ new DOMException\$1/g, `new DOMException`],
|
||||
[/ from 'net'/g, `from 'node:net'`],
|
||||
[/ throw createInvalidStateError/g, `throw new DOMException`],
|
||||
[/= createAbortController/g, `= new AbortController`],
|
||||
[/\nconst queueMicrotask = [\W\w]+?\n\}\)\(\)\;/g, ``],
|
||||
|
||||
// remove Body.prototype.buffer deprecation notice
|
||||
[ /\nBody\.prototype\.buffer[^\n]+/g, `` ],
|
||||
[/\nBody\.prototype\.buffer[^\n]+/g, ``],
|
||||
|
||||
// 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) {
|
||||
|
@ -110,22 +148,24 @@ const plugins = [
|
|||
const leadIndex = replaced.index
|
||||
const tailIndex = replaced.index + replaced[0].length
|
||||
|
||||
indexes.unshift([ leadIndex, tailIndex, replacer ])
|
||||
indexes.unshift([leadIndex, tailIndex, replacer])
|
||||
}
|
||||
}
|
||||
|
||||
if (indexes.length) {
|
||||
const magicString = new MagicString(code)
|
||||
|
||||
indexes.sort(
|
||||
([leadOfA], [leadOfB]) => leadOfA - leadOfB
|
||||
)
|
||||
indexes.sort(([leadOfA], [leadOfB]) => leadOfA - leadOfB)
|
||||
|
||||
for (const [leadIndex, tailindex, replacer] of indexes) {
|
||||
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 modifiedMap = magicMap.toString()
|
||||
|
@ -182,8 +222,16 @@ async function build() {
|
|||
|
||||
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('apply.js', `import { polyfill } from './mod.js'\n\nexport * from './mod.js'\n\npolyfill(globalThis)\n`)
|
||||
writeFile(
|
||||
'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`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ import { fileURLToPath } from 'url'
|
|||
|
||||
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) => {
|
||||
console.log(`Testing Node ${process.version}:`)
|
||||
|
|
|
@ -1,17 +1,60 @@
|
|||
const exclusionsForHTMLElement = [ 'CustomElementsRegistry', 'HTMLElement', 'HTMLBodyElement', 'HTMLCanvasElement', '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
|
||||
const exclusionsForHTMLElement = [
|
||||
'CustomElementsRegistry',
|
||||
'HTMLElement',
|
||||
'HTMLBodyElement',
|
||||
'HTMLCanvasElement',
|
||||
'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 = {
|
||||
'Blob+': [ 'Blob', 'File' ],
|
||||
'Blob+': ['Blob', 'File'],
|
||||
'Document+': exclusionsForDocument,
|
||||
'Element+': exclusionsForElement,
|
||||
'Event+': exclusionsForEvent,
|
||||
'EventTarget+': exclusionsForEventTarget,
|
||||
'HTMLElement+': exclusionsForHTMLElement,
|
||||
'Node+': exclusionsForNode,
|
||||
'StyleSheet+': [ 'StyleSheet', 'CSSStyleSheet' ],
|
||||
'StyleSheet+': ['StyleSheet', 'CSSStyleSheet'],
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
||||
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) {
|
||||
nodeSetTimeout(() => {
|
||||
const next = _.__performance_now()
|
||||
|
|
|
@ -10,11 +10,13 @@ export class CanvasRenderingContext2D {
|
|||
}
|
||||
|
||||
get direction(): 'ltr' | 'rtl' | 'inherit' {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'direction').direction
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'direction')
|
||||
.direction
|
||||
}
|
||||
|
||||
get fillStyle(): string {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'fillStyle').fillStyle
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'fillStyle')
|
||||
.fillStyle
|
||||
}
|
||||
|
||||
get filter(): string {
|
||||
|
@ -22,11 +24,16 @@ export class CanvasRenderingContext2D {
|
|||
}
|
||||
|
||||
get globalAlpha(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'globalAlpha').globalAlpha
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'globalAlpha')
|
||||
.globalAlpha
|
||||
}
|
||||
|
||||
get globalCompositeOperation(): string {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'globalCompositeOperation').globalCompositeOperation
|
||||
return _.internalsOf(
|
||||
this,
|
||||
'CanvasRenderingContext2D',
|
||||
'globalCompositeOperation'
|
||||
).globalCompositeOperation
|
||||
}
|
||||
|
||||
get font(): string {
|
||||
|
@ -34,11 +41,19 @@ export class CanvasRenderingContext2D {
|
|||
}
|
||||
|
||||
get imageSmoothingEnabled(): boolean {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'imageSmoothingEnabled').imageSmoothingEnabled
|
||||
return _.internalsOf(
|
||||
this,
|
||||
'CanvasRenderingContext2D',
|
||||
'imageSmoothingEnabled'
|
||||
).imageSmoothingEnabled
|
||||
}
|
||||
|
||||
get imageSmoothingQuality(): 'low' | 'medium' | 'high' {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'imageSmoothingQuality').imageSmoothingQuality
|
||||
return _.internalsOf(
|
||||
this,
|
||||
'CanvasRenderingContext2D',
|
||||
'imageSmoothingQuality'
|
||||
).imageSmoothingQuality
|
||||
}
|
||||
|
||||
get lineCap(): 'butt' | 'round' | 'square' {
|
||||
|
@ -46,7 +61,8 @@ export class CanvasRenderingContext2D {
|
|||
}
|
||||
|
||||
get lineDashOffset(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineDashOffset').lineDashOffset
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineDashOffset')
|
||||
.lineDashOffset
|
||||
}
|
||||
|
||||
get lineJoin(): 'bevel' | 'round' | 'miter' {
|
||||
|
@ -54,39 +70,54 @@ export class CanvasRenderingContext2D {
|
|||
}
|
||||
|
||||
get lineWidth(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineWidth').lineWidth
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'lineWidth')
|
||||
.lineWidth
|
||||
}
|
||||
|
||||
get miterLimit(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'miterLimit').miterLimit
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'miterLimit')
|
||||
.miterLimit
|
||||
}
|
||||
|
||||
get strokeStyle(): string {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'strokeStyle').strokeStyle
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'strokeStyle')
|
||||
.strokeStyle
|
||||
}
|
||||
|
||||
get shadowOffsetX(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetX').shadowOffsetX
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetX')
|
||||
.shadowOffsetX
|
||||
}
|
||||
|
||||
get shadowOffsetY(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetY').shadowOffsetY
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowOffsetY')
|
||||
.shadowOffsetY
|
||||
}
|
||||
|
||||
get shadowBlur(): number {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowBlur').shadowBlur
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowBlur')
|
||||
.shadowBlur
|
||||
}
|
||||
|
||||
get shadowColor(): string {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowColor').shadowColor
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'shadowColor')
|
||||
.shadowColor
|
||||
}
|
||||
|
||||
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' {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'textBaseline').textBaseline
|
||||
get textBaseline():
|
||||
| 'top'
|
||||
| 'hanging'
|
||||
| 'middle'
|
||||
| 'alphabetic'
|
||||
| 'ideographic'
|
||||
| 'bottom' {
|
||||
return _.internalsOf(this, 'CanvasRenderingContext2D', 'textBaseline')
|
||||
.textBaseline
|
||||
}
|
||||
|
||||
arc() {}
|
||||
|
@ -104,9 +135,11 @@ export class CanvasRenderingContext2D {
|
|||
/** Whether ImageData is provided. */
|
||||
const hasData = _.__object_isPrototypeOf(ImageData.prototype, arg0)
|
||||
|
||||
const w = hasData ? (arg0 as ImageData).width : arg0 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 w = hasData ? (arg0 as ImageData).width : (arg0 as number)
|
||||
const h = hasData ? (arg0 as ImageData).height : (arg1 as number)
|
||||
const d = hasData
|
||||
? (arg0 as ImageData).data
|
||||
: new Uint8ClampedArray(w * h * 4)
|
||||
|
||||
return new ImageData(d, w, h)
|
||||
}
|
||||
|
@ -148,8 +181,12 @@ export class CanvasRenderingContext2D {
|
|||
|
||||
_.allowStringTag(CanvasRenderingContext2D)
|
||||
|
||||
export const __createCanvasRenderingContext2D = (canvas: EventTarget): CanvasRenderingContext2D => {
|
||||
const renderingContext2D = Object.create(CanvasRenderingContext2D.prototype) as CanvasRenderingContext2D
|
||||
export const __createCanvasRenderingContext2D = (
|
||||
canvas: EventTarget
|
||||
): CanvasRenderingContext2D => {
|
||||
const renderingContext2D = Object.create(
|
||||
CanvasRenderingContext2D.prototype
|
||||
) as CanvasRenderingContext2D
|
||||
|
||||
_.INTERNALS.set(renderingContext2D, {
|
||||
canvas,
|
||||
|
@ -179,4 +216,7 @@ export const __createCanvasRenderingContext2D = (canvas: EventTarget): CanvasRen
|
|||
}
|
||||
|
||||
/** 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
|
||||
|
|
|
@ -7,11 +7,16 @@ export class CharacterData extends Node {
|
|||
} as CharacterDataInternals)
|
||||
}
|
||||
get data(): string {
|
||||
return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'data').data
|
||||
return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'data')
|
||||
.data
|
||||
}
|
||||
|
||||
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 {
|
||||
return _.internalsOf<CharacterDataInternals>(this, 'CharacterData', 'textContent').data
|
||||
return _.internalsOf<CharacterDataInternals>(
|
||||
this,
|
||||
'CharacterData',
|
||||
'textContent'
|
||||
).data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,15 @@ export type Context<T = unknown> = {
|
|||
}
|
||||
|
||||
/** 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 */
|
||||
export function createContext<T>(name: string, initialValue?: T): Readonly<Context<T>> {
|
||||
export function createContext<T>(
|
||||
name: string,
|
||||
initialValue?: T
|
||||
): Readonly<Context<T>> {
|
||||
return {
|
||||
name,
|
||||
initialValue,
|
||||
|
|
|
@ -2,14 +2,29 @@ import * as _ from './utils'
|
|||
|
||||
export class CustomElementRegistry {
|
||||
/** Defines a new custom element using the given tag name and HTMLElement constructor. */
|
||||
define(name: string, constructor: Function, options?: ElementDefinitionOptions) {
|
||||
const internals = _.internalsOf<CustomElementRegistryInternals>(this, 'CustomElementRegistry', 'define')
|
||||
define(
|
||||
name: string,
|
||||
constructor: Function,
|
||||
options?: ElementDefinitionOptions
|
||||
) {
|
||||
const internals = _.internalsOf<CustomElementRegistryInternals>(
|
||||
this,
|
||||
'CustomElementRegistry',
|
||||
'define'
|
||||
)
|
||||
|
||||
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)) 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')
|
||||
if (/[A-Z]/.test(name))
|
||||
throw new SyntaxError(
|
||||
'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.nameByConstructor.set(constructor, name)
|
||||
|
@ -19,7 +34,11 @@ export class CustomElementRegistry {
|
|||
|
||||
/** Returns the constructor associated with the given tag name. */
|
||||
get(name: string) {
|
||||
const internals = _.internalsOf<CustomElementRegistryInternals>(this, 'CustomElementRegistry', 'get')
|
||||
const internals = _.internalsOf<CustomElementRegistryInternals>(
|
||||
this,
|
||||
'CustomElementRegistry',
|
||||
'get'
|
||||
)
|
||||
|
||||
name = String(name).toLowerCase()
|
||||
|
||||
|
@ -27,7 +46,11 @@ export class CustomElementRegistry {
|
|||
}
|
||||
|
||||
getName(constructor: Function) {
|
||||
const internals = _.internalsOf<CustomElementRegistryInternals>(this, 'CustomElementRegistry', 'getName')
|
||||
const internals = _.internalsOf<CustomElementRegistryInternals>(
|
||||
this,
|
||||
'CustomElementRegistry',
|
||||
'getName'
|
||||
)
|
||||
|
||||
return internals.nameByConstructor.get(constructor)
|
||||
}
|
||||
|
@ -36,23 +59,28 @@ export class CustomElementRegistry {
|
|||
_.allowStringTag(CustomElementRegistry)
|
||||
|
||||
interface CustomElementRegistryInternals {
|
||||
constructorByName: Map<string, Function>;
|
||||
nameByConstructor: Map<Function, string>;
|
||||
constructorByName: Map<string, Function>
|
||||
nameByConstructor: Map<Function, string>
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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, {
|
||||
constructorByName: new Map,
|
||||
nameByConstructor: new Map,
|
||||
constructorByName: new Map(),
|
||||
nameByConstructor: new Map(),
|
||||
} as CustomElementRegistryInternals)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import * as _ from './utils'
|
||||
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) {
|
||||
params = Object(params) as Required<CustomEventInit>
|
||||
|
||||
|
|
|
@ -4,15 +4,27 @@ import { TreeWalker } from './TreeWalker'
|
|||
|
||||
export class Document extends Node {
|
||||
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()
|
||||
|
||||
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, {
|
||||
attributes: {},
|
||||
|
@ -25,10 +37,20 @@ export class Document extends Node {
|
|||
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)
|
||||
|
||||
_.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
|
||||
}
|
||||
|
@ -37,10 +59,20 @@ export class Document extends Node {
|
|||
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)
|
||||
|
||||
_.INTERNALS.set(target, { filter, currentNode: root, root, whatToShow } as TreeWalkerInternals)
|
||||
_.INTERNALS.set(target, {
|
||||
filter,
|
||||
currentNode: root,
|
||||
root,
|
||||
whatToShow,
|
||||
} as TreeWalkerInternals)
|
||||
|
||||
return target
|
||||
}
|
||||
|
@ -69,7 +101,10 @@ export const initDocument = (target: Target, exclude: Set<string>) => {
|
|||
const EventTarget = target.EventTarget || globalThis.EventTarget
|
||||
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, {
|
||||
target,
|
||||
|
@ -83,7 +118,7 @@ export const initDocument = (target: Target, exclude: Set<string>) => {
|
|||
['span', target.HTMLSpanElement],
|
||||
['style', target.HTMLStyleElement],
|
||||
]),
|
||||
nameByConstructor: new Map,
|
||||
nameByConstructor: new Map(),
|
||||
} as DocumentInternals)
|
||||
|
||||
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.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 {
|
||||
|
@ -120,7 +158,7 @@ interface CustomElementRegistryInternals {
|
|||
}
|
||||
|
||||
interface ElementInternals {
|
||||
attributes: { [name: string]: string },
|
||||
attributes: { [name: string]: string }
|
||||
localName: string
|
||||
ownerDocument: Document
|
||||
shadowRoot: ShadowRoot
|
||||
|
|
|
@ -21,13 +21,26 @@ export class Element extends Node {
|
|||
}
|
||||
|
||||
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.')
|
||||
|
||||
|
@ -36,7 +49,14 @@ export class Element extends Node {
|
|||
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
|
||||
}
|
||||
|
@ -58,21 +78,34 @@ export class Element extends Node {
|
|||
}
|
||||
|
||||
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 {
|
||||
return _.internalsOf<ElementInternals>(this, 'Element', 'localName').localName as string
|
||||
return _.internalsOf<ElementInternals>(this, 'Element', 'localName')
|
||||
.localName as 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 {
|
||||
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)
|
||||
|
||||
export interface ElementInternals {
|
||||
attributes: { [name: string]: string },
|
||||
attributes: { [name: string]: string }
|
||||
localName?: string
|
||||
shadowRoot: ShadowRoot | null
|
||||
shadowInit: ShadowRootInit | void
|
||||
|
@ -115,4 +148,4 @@ export interface ElementInternals {
|
|||
export interface ShadowRootInit {
|
||||
mode: 'open' | 'closed'
|
||||
delegatesFocus: boolean
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ export class HTMLCanvasElement extends HTMLElement {
|
|||
}
|
||||
|
||||
set height(value) {
|
||||
_.internalsOf(this, 'HTMLCanvasElement', 'height').height = Number(value) || 0
|
||||
_.internalsOf(this, 'HTMLCanvasElement', 'height').height =
|
||||
Number(value) || 0
|
||||
}
|
||||
|
||||
get width(): number {
|
||||
|
@ -24,8 +25,14 @@ export class HTMLCanvasElement extends HTMLElement {
|
|||
return null
|
||||
}
|
||||
|
||||
getContext(contextType: PredefinedContextId): CanvasRenderingContext2D | null {
|
||||
const internals = _.internalsOf<HTMLCanvasElementInternals>(this, 'HTMLCanvasElement', 'getContext')
|
||||
getContext(
|
||||
contextType: PredefinedContextId
|
||||
): CanvasRenderingContext2D | null {
|
||||
const internals = _.internalsOf<HTMLCanvasElementInternals>(
|
||||
this,
|
||||
'HTMLCanvasElement',
|
||||
'getContext'
|
||||
)
|
||||
|
||||
switch (contextType) {
|
||||
case '2d':
|
||||
|
@ -54,4 +61,9 @@ interface HTMLCanvasElementInternals {
|
|||
renderingContext2D: CanvasRenderingContext2D
|
||||
}
|
||||
|
||||
type PredefinedContextId = '2d' | 'bitmaprenderer' | 'webgl' | 'webgl2' | 'webgpu'
|
||||
type PredefinedContextId =
|
||||
| '2d'
|
||||
| 'bitmaprenderer'
|
||||
| 'webgl'
|
||||
| 'webgl2'
|
||||
| 'webgpu'
|
||||
|
|
|
@ -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'
|
||||
|
||||
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) {
|
||||
nodeSetTimeout(() => {
|
||||
const next = _.__performance_now()
|
||||
|
|
|
@ -1,20 +1,36 @@
|
|||
import * as _ from './utils'
|
||||
|
||||
export class ImageData {
|
||||
constructor(width: number, height: number);
|
||||
constructor(width: number, height: number, settings: ImageDataSettings);
|
||||
constructor(data: Uint8ClampedArray, width: number);
|
||||
constructor(data: Uint8ClampedArray, width: number, height: number);
|
||||
constructor(data: Uint8ClampedArray, width: number, height: number, settings: ImageDataSettings);
|
||||
constructor(width: number, height: number)
|
||||
constructor(width: number, height: number, settings: ImageDataSettings)
|
||||
constructor(data: Uint8ClampedArray, width: number)
|
||||
constructor(data: Uint8ClampedArray, width: number, height: number)
|
||||
constructor(
|
||||
data: Uint8ClampedArray,
|
||||
width: number,
|
||||
height: number,
|
||||
settings: ImageDataSettings
|
||||
)
|
||||
|
||||
constructor(arg0: number | Uint8ClampedArray, arg1: number, ...args: [] | [number] | [ImageDataSettings] | [number, ImageDataSettings]) {
|
||||
if (arguments.length < 2) throw new TypeError(`Failed to construct 'ImageData': 2 arguments required.`)
|
||||
constructor(
|
||||
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. */
|
||||
const hasData = _.__object_isPrototypeOf(Uint8ClampedArray.prototype, arg0)
|
||||
|
||||
/** 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. */
|
||||
const w = asNumber(hasData ? arg1 : arg0, 'width')
|
||||
|
@ -23,23 +39,42 @@ export class ImageData {
|
|||
const h = d.length / w / 4
|
||||
|
||||
/** 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
|
||||
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
|
||||
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 {
|
||||
_.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'] {
|
||||
|
@ -57,7 +92,8 @@ _.allowStringTag(ImageData)
|
|||
const asNumber = (value: any, axis: string): number => {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -19,7 +19,10 @@ export const initMediaQueryList = (target: Target, exclude: Set<string>) => {
|
|||
const MediaQueryList = target.MediaQueryList || globalThis.MediaQueryList
|
||||
|
||||
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, {
|
||||
matches: false,
|
||||
|
|
|
@ -71,8 +71,11 @@ export class Node extends EventTarget {
|
|||
return null
|
||||
}
|
||||
|
||||
[Symbol.for('nodejs.util.inspect.custom')](depth: number, options: Record<string, any>) {
|
||||
return `${this.constructor.name}`;
|
||||
[Symbol.for('nodejs.util.inspect.custom')](
|
||||
depth: number,
|
||||
options: Record<string, any>
|
||||
) {
|
||||
return `${this.constructor.name}`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,28 +91,31 @@ export class ShadowRoot extends DocumentFragment {
|
|||
}
|
||||
}
|
||||
|
||||
export const NodeFilter = Object.assign({
|
||||
NodeFilter() {
|
||||
throw new TypeError('Illegal constructor')
|
||||
export const NodeFilter = Object.assign(
|
||||
{
|
||||
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 {
|
||||
nextNode(): Node | null {
|
||||
|
@ -121,27 +127,47 @@ export class NodeIterator {
|
|||
}
|
||||
|
||||
get filter(): NodeFilter {
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'filter')
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(
|
||||
this,
|
||||
'NodeIterator',
|
||||
'filter'
|
||||
)
|
||||
return internals.filter
|
||||
}
|
||||
|
||||
get pointerBeforeReferenceNode(): boolean {
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'pointerBeforeReferenceNode')
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(
|
||||
this,
|
||||
'NodeIterator',
|
||||
'pointerBeforeReferenceNode'
|
||||
)
|
||||
return internals.pointerBeforeReferenceNode
|
||||
}
|
||||
|
||||
get referenceNode(): Node {
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'referenceNode')
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(
|
||||
this,
|
||||
'NodeIterator',
|
||||
'referenceNode'
|
||||
)
|
||||
return internals.referenceNode
|
||||
}
|
||||
|
||||
get root(): Node {
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'root')
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(
|
||||
this,
|
||||
'NodeIterator',
|
||||
'root'
|
||||
)
|
||||
return internals.root
|
||||
}
|
||||
|
||||
get whatToShow(): number {
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(this, 'NodeIterator', 'whatToShow')
|
||||
const internals = _.internalsOf<NodeIteratorInternals>(
|
||||
this,
|
||||
'NodeIterator',
|
||||
'whatToShow'
|
||||
)
|
||||
return internals.whatToShow
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@ import * as _ from './utils'
|
|||
export const hasOwn = {
|
||||
hasOwn(instance: object, property: any) {
|
||||
return _.__object_hasOwnProperty(instance, property)
|
||||
}
|
||||
},
|
||||
}.hasOwn
|
||||
|
||||
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
|
||||
|
||||
|
@ -15,6 +16,6 @@ export const initObject = (target: any, exclude: Set<string>) => {
|
|||
value: hasOwn,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
configurable: true,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@ export class OffscreenCanvas extends EventTarget {
|
|||
constructor(width: number, height: number) {
|
||||
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
|
||||
height = Number(height) || 0
|
||||
|
@ -31,8 +34,14 @@ export class OffscreenCanvas extends EventTarget {
|
|||
_.internalsOf(this, 'OffscreenCanvas', 'width').width = Number(value) || 0
|
||||
}
|
||||
|
||||
getContext(contextType: PredefinedContextId): CanvasRenderingContext2D | null {
|
||||
const internals = _.internalsOf<OffscreenCanvasInternals>(this, 'HTMLCanvasElement', 'getContext')
|
||||
getContext(
|
||||
contextType: PredefinedContextId
|
||||
): CanvasRenderingContext2D | null {
|
||||
const internals = _.internalsOf<OffscreenCanvasInternals>(
|
||||
this,
|
||||
'HTMLCanvasElement',
|
||||
'getContext'
|
||||
)
|
||||
|
||||
switch (contextType) {
|
||||
case '2d':
|
||||
|
@ -54,15 +63,19 @@ export class OffscreenCanvas extends EventTarget {
|
|||
|
||||
void quality
|
||||
|
||||
return Promise.resolve(
|
||||
new Blob([], { type })
|
||||
)
|
||||
return Promise.resolve(new Blob([], { type }))
|
||||
}
|
||||
}
|
||||
|
||||
_.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 {
|
||||
height: number
|
||||
|
@ -75,6 +88,15 @@ interface ConvertToBlobOptions {
|
|||
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'
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
export const any = {
|
||||
async any <T>(
|
||||
iterable: Iterable<T | PromiseLike<T>>
|
||||
): Promise<T> {
|
||||
async any<T>(iterable: Iterable<T | PromiseLike<T>>): Promise<T> {
|
||||
return Promise.all(
|
||||
[...iterable].map(promise => {
|
||||
[...iterable].map((promise) => {
|
||||
return new Promise((resolve, reject) =>
|
||||
Promise.resolve(promise).then(reject, resolve)
|
||||
)
|
||||
})
|
||||
).then(
|
||||
errors => Promise.reject(errors),
|
||||
value => Promise.resolve<T>(value)
|
||||
(errors) => Promise.reject(errors),
|
||||
(value) => Promise.resolve<T>(value)
|
||||
)
|
||||
}
|
||||
},
|
||||
}.any
|
||||
|
||||
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
|
||||
|
||||
if (!Class.any) Object.defineProperty(Class, 'any', {
|
||||
value: any,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
})
|
||||
if (!Class.any)
|
||||
Object.defineProperty(Class, 'any', {
|
||||
value: any,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
at<T extends Array<any> | string | TypedArray>(this: T, index: number) {
|
||||
index = Math.trunc(index) || 0
|
||||
|
||||
if (index < 0) index += this.length;
|
||||
|
||||
if (index < 0 || index >= this.length) return undefined;
|
||||
|
||||
return this[index];
|
||||
}
|
||||
|
||||
if (index < 0) index += this.length
|
||||
|
||||
if (index < 0 || index >= this.length) return undefined
|
||||
|
||||
return this[index]
|
||||
},
|
||||
}.at
|
||||
|
||||
export const initRelativeIndexingMethod = (target: any, exclude: Set<string>) => {
|
||||
export const initRelativeIndexingMethod = (
|
||||
target: any,
|
||||
exclude: Set<string>
|
||||
) => {
|
||||
if (exclude.has('at')) return
|
||||
|
||||
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('String')) Classes.push(target.String || globalThis.String)
|
||||
|
||||
for (const Class of Classes) {
|
||||
if (!Class.prototype.at) Object.defineProperty(Class.prototype, 'at', {
|
||||
value: at,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
})
|
||||
if (!Class.prototype.at)
|
||||
Object.defineProperty(Class.prototype, 'at', {
|
||||
value: at,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,20 +7,35 @@ export class Storage {
|
|||
|
||||
getItem(key: string): string | null {
|
||||
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 {
|
||||
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 {
|
||||
_.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.delete(String(key))
|
||||
_.internalsOf<StorageInternals>(this, 'Storage', 'getItem').storage.delete(
|
||||
String(key)
|
||||
)
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -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>) => {
|
||||
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>()
|
||||
|
||||
_.INTERNALS.set(target.localStorage, {
|
||||
storage: storageInternals
|
||||
storage: storageInternals,
|
||||
} as StorageInternals)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
import * as _ from './utils'
|
||||
|
||||
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)
|
||||
? 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
|
||||
|
||||
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
|
||||
|
||||
if (!Class.prototype.replaceAll) Object.defineProperty(Class.prototype, 'replaceAll', {
|
||||
value: replaceAll,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
})
|
||||
if (!Class.prototype.replaceAll)
|
||||
Object.defineProperty(Class.prototype, 'replaceAll', {
|
||||
value: replaceAll,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
||||
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 tick = ++INTERNAL.tick
|
||||
const timeout = nodeSetTimeout(func, delay, ...args)
|
||||
|
|
|
@ -30,17 +30,29 @@ export class TreeWalker {
|
|||
}
|
||||
|
||||
get currentNode(): Node {
|
||||
const internals = _.internalsOf<TreeWalkerInternals>(this, 'TreeWalker', 'currentNode')
|
||||
const internals = _.internalsOf<TreeWalkerInternals>(
|
||||
this,
|
||||
'TreeWalker',
|
||||
'currentNode'
|
||||
)
|
||||
return internals.currentNode
|
||||
}
|
||||
|
||||
get root(): Node {
|
||||
const internals = _.internalsOf<TreeWalkerInternals>(this, 'TreeWalker', 'root')
|
||||
const internals = _.internalsOf<TreeWalkerInternals>(
|
||||
this,
|
||||
'TreeWalker',
|
||||
'root'
|
||||
)
|
||||
return internals.root
|
||||
}
|
||||
|
||||
get whatToShow(): number {
|
||||
const internals = _.internalsOf<TreeWalkerInternals>(this, 'TreeWalker', 'whatToShow')
|
||||
const internals = _.internalsOf<TreeWalkerInternals>(
|
||||
this,
|
||||
'TreeWalker',
|
||||
'whatToShow'
|
||||
)
|
||||
return internals.whatToShow
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 * as _ from './utils'
|
||||
|
||||
export { Headers, Request, Response }
|
||||
|
||||
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(
|
||||
_.__object_isPrototypeOf(Request.prototype, resource)
|
||||
? (resource as Request).url
|
||||
: _.pathToPosix(resource),
|
||||
typeof Object(globalThis.process).cwd === 'function' ? 'file:' + _.pathToPosix(process.cwd()) + '/' : 'file:'
|
||||
: _.pathToPosix(resource),
|
||||
typeof Object(globalThis.process).cwd === 'function'
|
||||
? 'file:' + _.pathToPosix(process.cwd()) + '/'
|
||||
: 'file:'
|
||||
)
|
||||
|
||||
if (resourceURL.protocol.toLowerCase() === 'file:') {
|
||||
return import('node:fs').then(
|
||||
fs => {
|
||||
try {
|
||||
const stats = fs.statSync(resourceURL)
|
||||
const body = fs.createReadStream(resourceURL)
|
||||
return import('node:fs').then((fs) => {
|
||||
try {
|
||||
const stats = fs.statSync(resourceURL)
|
||||
const body = fs.createReadStream(resourceURL)
|
||||
|
||||
return new Response(
|
||||
body,
|
||||
{
|
||||
status: 200,
|
||||
statusText: '',
|
||||
headers: {
|
||||
'content-length': String(stats.size),
|
||||
'date': new Date().toUTCString(),
|
||||
'last-modified': new Date(stats.mtimeMs).toUTCString(),
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
const body = new Stream.Readable()
|
||||
return new Response(body, {
|
||||
status: 200,
|
||||
statusText: '',
|
||||
headers: {
|
||||
'content-length': String(stats.size),
|
||||
date: new Date().toUTCString(),
|
||||
'last-modified': new Date(stats.mtimeMs).toUTCString(),
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
const body = new Stream.Readable()
|
||||
|
||||
body._read = () => {}
|
||||
body.push(null)
|
||||
body._read = () => {}
|
||||
body.push(null)
|
||||
|
||||
return new Response(
|
||||
body,
|
||||
{
|
||||
status: 404,
|
||||
statusText: '',
|
||||
headers: {
|
||||
'date': new Date().toUTCString(),
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
return new Response(body, {
|
||||
status: 404,
|
||||
statusText: '',
|
||||
headers: {
|
||||
date: new Date().toUTCString(),
|
||||
},
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
} else {
|
||||
return nodeFetch(resource, init)
|
||||
}
|
||||
}
|
||||
},
|
||||
}.fetch
|
||||
|
||||
type USVString = ({} & string)
|
||||
type USVString = {} & string
|
||||
|
||||
interface FetchInit {
|
||||
body: Blob | BufferSource | FormData | URLSearchParams | ReadableStream | USVString
|
||||
cache: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached'
|
||||
body:
|
||||
| Blob
|
||||
| BufferSource
|
||||
| FormData
|
||||
| URLSearchParams
|
||||
| ReadableStream
|
||||
| USVString
|
||||
cache:
|
||||
| 'default'
|
||||
| 'no-store'
|
||||
| 'reload'
|
||||
| 'no-cache'
|
||||
| 'force-cache'
|
||||
| 'only-if-cached'
|
||||
credentials: 'omit' | 'same-origin' | 'include'
|
||||
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
|
||||
redirect: 'follow' | 'manual' | 'error'
|
||||
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
|
||||
keepalive: boolean
|
||||
signal: AbortSignal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { deserialize } from '@ungap/structured-clone/esm/deserialize.js';
|
||||
import { serialize } from '@ungap/structured-clone/esm/serialize.js';
|
||||
import { deserialize } from '@ungap/structured-clone/esm/deserialize.js'
|
||||
import { serialize } from '@ungap/structured-clone/esm/serialize.js'
|
||||
|
||||
export default (any: any, options: any) => deserialize(serialize(any, options))
|
||||
|
|
|
@ -4,58 +4,93 @@ import { performance } from 'node:perf_hooks'
|
|||
export const __date_now = Date.now
|
||||
|
||||
/** 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. */
|
||||
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. */
|
||||
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. */
|
||||
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. */
|
||||
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. */
|
||||
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. */
|
||||
export const __performance_now = performance.now as () => number
|
||||
|
||||
/** 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
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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. */
|
||||
export const pathToPosix = (pathname: any) => String(
|
||||
pathname == null ? '' : pathname
|
||||
).replace(
|
||||
// convert slashes
|
||||
/\\+/g, '/'
|
||||
).replace(
|
||||
// prefix a slash to drive letters
|
||||
/^(?=[A-Za-z]:\/)/, '/'
|
||||
).replace(
|
||||
// encode path characters
|
||||
/%/g, '%25'
|
||||
).replace(
|
||||
/\n/g, '%0A'
|
||||
).replace(
|
||||
/\r/g, '%0D'
|
||||
).replace(
|
||||
/\t/g, '%09'
|
||||
)
|
||||
export const pathToPosix = (pathname: any) =>
|
||||
String(pathname == null ? '' : pathname)
|
||||
.replace(
|
||||
// convert slashes
|
||||
/\\+/g,
|
||||
'/'
|
||||
)
|
||||
.replace(
|
||||
// prefix a slash to drive letters
|
||||
/^(?=[A-Za-z]:\/)/,
|
||||
'/'
|
||||
)
|
||||
.replace(
|
||||
// encode path characters
|
||||
/%/g,
|
||||
'%25'
|
||||
)
|
||||
.replace(/\n/g, '%0A')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\t/g, '%09')
|
||||
|
|
|
@ -60,7 +60,6 @@ import {
|
|||
WritableStreamDefaultController,
|
||||
WritableStreamDefaultWriter,
|
||||
Window,
|
||||
|
||||
alert,
|
||||
atob,
|
||||
btoa,
|
||||
|
@ -72,7 +71,6 @@ import {
|
|||
requestIdleCallback,
|
||||
setTimeout,
|
||||
structuredClone,
|
||||
|
||||
initCustomElementRegistry,
|
||||
initDocument,
|
||||
initMediaQueryList,
|
||||
|
@ -148,7 +146,6 @@ export {
|
|||
WritableStreamDefaultController,
|
||||
WritableStreamDefaultWriter,
|
||||
Window,
|
||||
|
||||
alert,
|
||||
atob,
|
||||
btoa,
|
||||
|
@ -245,18 +242,25 @@ export const polyfill = (target: any, options?: PolyfillOptions) => {
|
|||
const excludeOptions = new Set(
|
||||
typeof Object(options).exclude === 'string'
|
||||
? String(Object(options).exclude).trim().split(/\s+/)
|
||||
: Array.isArray(Object(options).exclude)
|
||||
: Array.isArray(Object(options).exclude)
|
||||
? 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>
|
||||
|
||||
// expand exclude options using exclusion shorthands
|
||||
for (const excludeOption of excludeOptions) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -267,11 +271,16 @@ export const polyfill = (target: any, options?: PolyfillOptions) => {
|
|||
// skip WebAPIs that are excluded
|
||||
if (excludeOptions.has(name)) continue
|
||||
|
||||
// skip WebAPIs that are built-in
|
||||
// skip WebAPIs that are built-in
|
||||
if (Object.hasOwnProperty.call(target, name)) continue
|
||||
|
||||
// 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
|
||||
|
@ -288,14 +297,17 @@ export const polyfill = (target: any, options?: PolyfillOptions) => {
|
|||
// skip WebAPIs that are not available
|
||||
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
|
||||
|
||||
// define WebAPIs inheritence
|
||||
Object.setPrototypeOf(Class.prototype, Super.prototype)
|
||||
}
|
||||
|
||||
if (!excludeOptions.has('HTMLDocument') && !excludeOptions.has('HTMLElement')) {
|
||||
if (
|
||||
!excludeOptions.has('HTMLDocument') &&
|
||||
!excludeOptions.has('HTMLElement')
|
||||
) {
|
||||
initDocument(target, excludeOptions)
|
||||
|
||||
if (!excludeOptions.has('CustomElementRegistry')) {
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
// @ts-check
|
||||
|
||||
import { AbortController, AbortSignal } from 'abort-controller/dist/abort-controller.mjs'
|
||||
import { requestAnimationFrame, cancelAnimationFrame } from './lib/AnimationFrame'
|
||||
import {
|
||||
AbortController,
|
||||
AbortSignal,
|
||||
} from 'abort-controller/dist/abort-controller.mjs'
|
||||
import {
|
||||
requestAnimationFrame,
|
||||
cancelAnimationFrame,
|
||||
} from './lib/AnimationFrame'
|
||||
import { atob, btoa } from './lib/Base64'
|
||||
import { CharacterData, Comment, Text } from './lib/CharacterData'
|
||||
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 { fetch, Headers, Request, Response } from './lib/fetch'
|
||||
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 { setTimeout, clearTimeout } from './lib/Timeout'
|
||||
import structuredClone from './lib/structuredClone'
|
||||
|
||||
import { CanvasRenderingContext2D } from './lib/CanvasRenderingContext2D'
|
||||
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 { DocumentFragment, Node, NodeFilter, NodeIterator, ShadowRoot } from './lib/Node'
|
||||
import { Element, HTMLElement, HTMLBodyElement, HTMLDivElement, HTMLHeadElement, HTMLHtmlElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement } from './lib/Element'
|
||||
import {
|
||||
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 { HTMLImageElement } from './lib/HTMLImageElement'
|
||||
import { Image } from './lib/Image'
|
||||
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 { OffscreenCanvas } from './lib/OffscreenCanvas'
|
||||
import { Storage, initStorage } from './lib/Storage'
|
||||
|
@ -102,7 +145,6 @@ export {
|
|||
WritableStreamDefaultController,
|
||||
WritableStreamDefaultWriter,
|
||||
Window,
|
||||
|
||||
alert,
|
||||
atob,
|
||||
btoa,
|
||||
|
@ -114,7 +156,6 @@ export {
|
|||
requestIdleCallback,
|
||||
setTimeout,
|
||||
structuredClone,
|
||||
|
||||
initCustomElementRegistry,
|
||||
initDocument,
|
||||
initMediaQueryList,
|
||||
|
|
|
@ -7,9 +7,9 @@ test(() => {
|
|||
name: 'Supports Base64 Methods',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal('atob' in target, true)
|
||||
assert.equal('btoa' in target, true)
|
||||
assert.equal(typeof target['atob'], 'function')
|
||||
|
@ -20,7 +20,7 @@ test(() => {
|
|||
name: 'Supports atob(data)',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const a = 'SGVsbG8sIHdvcmxk'
|
||||
|
@ -34,7 +34,7 @@ test(() => {
|
|||
name: 'Supports btoa(data)',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const b = 'Hello, world'
|
||||
|
|
|
@ -8,8 +8,62 @@ test(() => {
|
|||
{
|
||||
name: 'Globals exist',
|
||||
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) {
|
||||
assert.equal(typeof globalThis[name], 'function')
|
||||
}
|
||||
|
@ -19,7 +73,7 @@ test(() => {
|
|||
name: 'Constructs an Event',
|
||||
test() {
|
||||
const e = new Event('test')
|
||||
|
||||
|
||||
assert.equal(e.type, 'test')
|
||||
},
|
||||
},
|
||||
|
@ -33,17 +87,17 @@ test(() => {
|
|||
name: 'Dispatches an Event on an EventTarget',
|
||||
test() {
|
||||
const t = new EventTarget()
|
||||
|
||||
|
||||
let pass = false
|
||||
|
||||
|
||||
t.addEventListener('test', (event) => {
|
||||
pass = true
|
||||
})
|
||||
|
||||
|
||||
const e = new Event('test')
|
||||
|
||||
|
||||
t.dispatchEvent(e)
|
||||
|
||||
|
||||
assert.equal(pass, true)
|
||||
},
|
||||
},
|
||||
|
@ -80,7 +134,7 @@ test(() => {
|
|||
test() {
|
||||
assert.equal(typeof String.prototype.at, 'function')
|
||||
assert.equal(String.prototype.at.length, 1)
|
||||
|
||||
|
||||
const example = 'The quick brown fox jumps over the lazy dog.'
|
||||
|
||||
assert.equal(example.at(2), 'e')
|
||||
|
@ -92,7 +146,7 @@ test(() => {
|
|||
test() {
|
||||
assert.equal(typeof Array.prototype.at, 'function')
|
||||
assert.equal(Array.prototype.at.length, 1)
|
||||
|
||||
|
||||
const example = [1, 3, 5, 7, 9]
|
||||
|
||||
assert.equal(example.at(1), 3)
|
||||
|
@ -104,7 +158,7 @@ test(() => {
|
|||
test() {
|
||||
assert.equal(typeof Int8Array.prototype.at, 'function')
|
||||
assert.equal(Int8Array.prototype.at.length, 1)
|
||||
|
||||
|
||||
const example = new Int8Array([1, 3, 5, 7, 9])
|
||||
|
||||
assert.equal(example.at(1), 3)
|
||||
|
@ -120,7 +174,7 @@ test(() => {
|
|||
const example = {}
|
||||
|
||||
assert.equal(Object.hasOwn(example, 'prop'), false)
|
||||
|
||||
|
||||
example.prop = 'exists'
|
||||
|
||||
assert.equal(Object.hasOwn(example, 'prop'), true)
|
||||
|
@ -132,11 +186,13 @@ test(() => {
|
|||
assert.equal(typeof Promise.any, 'function')
|
||||
assert.equal(Promise.any.length, 1)
|
||||
|
||||
Promise.any([Promise.resolve(42), Promise.reject(-1), Promise.reject(Infinity)]).then(
|
||||
result => {
|
||||
assert.equal(result, 42)
|
||||
}
|
||||
)
|
||||
Promise.any([
|
||||
Promise.resolve(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(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 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)
|
||||
},
|
||||
|
|
|
@ -33,7 +33,10 @@ test(() => {
|
|||
})
|
||||
|
||||
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').textContent, 'hello')
|
||||
|
@ -49,7 +52,10 @@ test(() => {
|
|||
})
|
||||
|
||||
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').textContent, 'hello')
|
||||
|
|
|
@ -27,7 +27,10 @@ test(() => {
|
|||
target.customElements.define('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.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 {}
|
||||
|
||||
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'
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -7,9 +7,9 @@ test(() => {
|
|||
name: 'Fetch functionality',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'fetch'), true)
|
||||
assert.equal(typeof target.fetch, 'function')
|
||||
},
|
||||
|
@ -18,7 +18,7 @@ test(() => {
|
|||
name: 'Fetch with https',
|
||||
async test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const { fetch } = target
|
||||
|
@ -36,7 +36,7 @@ test(() => {
|
|||
name: 'Fetch with file',
|
||||
async test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const { fetch } = target
|
||||
|
@ -62,7 +62,7 @@ test(() => {
|
|||
name: 'Fetch with missing file',
|
||||
async test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const { fetch } = target
|
||||
|
@ -84,7 +84,7 @@ test(() => {
|
|||
name: 'Fetch with (file) Request',
|
||||
async test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const { Request, fetch } = target
|
||||
|
@ -104,7 +104,7 @@ test(() => {
|
|||
name: 'Fetch with relative file',
|
||||
async test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const { fetch } = target
|
||||
|
@ -120,14 +120,16 @@ test(() => {
|
|||
name: 'Fetch with data',
|
||||
async test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const { fetch } = target
|
||||
|
||||
const jsonURI = `data:application/json,${encodeURIComponent(JSON.stringify({
|
||||
name: '@astrojs/webapi'
|
||||
}))}`
|
||||
const jsonURI = `data:application/json,${encodeURIComponent(
|
||||
JSON.stringify({
|
||||
name: '@astrojs/webapi',
|
||||
})
|
||||
)}`
|
||||
|
||||
const response = await fetch(jsonURI)
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ test(() => {
|
|||
name: 'Supports ImageData',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal('ImageData' in target, true)
|
||||
assert.equal(typeof target['ImageData'], 'function')
|
||||
},
|
||||
|
@ -18,7 +18,7 @@ test(() => {
|
|||
name: 'Supports new (data: Uint8ClampedArray, width: number, height: number): ImageData',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const w = 640
|
||||
|
@ -36,7 +36,7 @@ test(() => {
|
|||
name: 'Supports new (data: Uint8ClampedArray, width: number): ImageData',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const w = 640
|
||||
|
@ -54,7 +54,7 @@ test(() => {
|
|||
name: 'Supports new (width: number, height: number): ImageData',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const w = 640
|
||||
|
@ -71,7 +71,7 @@ test(() => {
|
|||
name: 'Supports Object.keys(new ImageData(640, 480))',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const keys = Object.keys(new target.ImageData(640, 480))
|
||||
|
|
|
@ -7,7 +7,7 @@ test(() => {
|
|||
name: 'Includes polyfill.internals functionality',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target, { exclude: 'window document' })
|
||||
|
||||
const pseudo = { ...target }
|
||||
|
@ -22,8 +22,13 @@ test(() => {
|
|||
|
||||
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
|
||||
)
|
||||
},
|
||||
}
|
||||
},
|
||||
]
|
||||
})
|
||||
|
|
|
@ -7,9 +7,9 @@ test(() => {
|
|||
name: 'Includes MediaQueryList functionality',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'MediaQueryList'), true)
|
||||
assert.equal(Reflect.has(target, 'matchMedia'), true)
|
||||
},
|
||||
|
@ -18,7 +18,7 @@ test(() => {
|
|||
name: 'Supports matchMedia creation',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const mql = target.matchMedia('(min-width: 640px)')
|
||||
|
|
|
@ -7,9 +7,9 @@ test(() => {
|
|||
name: 'Supports OffscreenCanvas',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal('OffscreenCanvas' in target, true)
|
||||
assert.equal(typeof target['OffscreenCanvas'], 'function')
|
||||
},
|
||||
|
@ -18,7 +18,7 @@ test(() => {
|
|||
name: 'Supports new (width: number, height: number): OffscreenCanvas',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const w = 640
|
||||
|
@ -34,7 +34,7 @@ test(() => {
|
|||
name: 'Supports OffscreenCanvas#getContext',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target)
|
||||
|
||||
const w = 640
|
||||
|
|
|
@ -7,11 +7,11 @@ test(() => {
|
|||
name: 'Can exclude HTMLElement+',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target, {
|
||||
exclude: 'HTMLElement+'
|
||||
exclude: 'HTMLElement+',
|
||||
})
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'Event'), true)
|
||||
assert.equal(Reflect.has(target, 'EventTarget'), true)
|
||||
assert.equal(Reflect.has(target, 'Element'), true)
|
||||
|
@ -23,11 +23,11 @@ test(() => {
|
|||
name: 'Can exclude Event+',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target, {
|
||||
exclude: 'Event+'
|
||||
exclude: 'Event+',
|
||||
})
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'Event'), false)
|
||||
assert.equal(Reflect.has(target, 'EventTarget'), false)
|
||||
assert.equal(Reflect.has(target, 'Element'), false)
|
||||
|
@ -39,11 +39,11 @@ test(() => {
|
|||
name: 'Can exclude document',
|
||||
test() {
|
||||
const target = {}
|
||||
|
||||
|
||||
polyfill(target, {
|
||||
exclude: 'document'
|
||||
exclude: 'document',
|
||||
})
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'Document'), true)
|
||||
assert.equal(Reflect.has(target, 'HTMLDocument'), true)
|
||||
assert.equal(Reflect.has(target, 'document'), false)
|
||||
|
|
|
@ -9,7 +9,7 @@ test(() => {
|
|||
const target = {}
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'Storage'), true)
|
||||
assert.equal(Reflect.has(target, 'localStorage'), true)
|
||||
assert.equal(typeof target.Storage, 'function')
|
||||
|
|
|
@ -9,7 +9,7 @@ test(() => {
|
|||
const target = {}
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'structuredClone'), true)
|
||||
assert.equal(typeof target.structuredClone, 'function')
|
||||
},
|
||||
|
@ -22,9 +22,9 @@ test(() => {
|
|||
polyfill(target)
|
||||
|
||||
const obj = {
|
||||
foo: "bar",
|
||||
foo: 'bar',
|
||||
baz: {
|
||||
qux: "quux",
|
||||
qux: 'quux',
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ test(() => {
|
|||
const target = {}
|
||||
|
||||
polyfill(target)
|
||||
|
||||
|
||||
assert.equal(Reflect.has(target, 'URLPattern'), true)
|
||||
assert.equal(typeof target.URLPattern, 'function')
|
||||
},
|
||||
|
|
|
@ -12,4 +12,4 @@
|
|||
"sourceMap": true,
|
||||
"declarationMap": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue