diff options
author | Bartek Iwańczuk <biwanczuk@gmail.com> | 2020-08-07 16:55:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-07 16:55:02 +0200 |
commit | 41215eb29c50cdf7048f7431076ccc986b514f6d (patch) | |
tree | 519d44a39dbd01e6175abf9302f105d67ce2cc52 /cli | |
parent | d7dcbab3efeeac5233c9cedb6edacc7202515449 (diff) |
Op crate for Web APIs (#6906)
Co-authored-by: Ryan Dahl <ry@tinyclouds.org>
Diffstat (limited to 'cli')
-rw-r--r-- | cli/Cargo.toml | 1 | ||||
-rw-r--r-- | cli/build.rs | 75 | ||||
-rw-r--r-- | cli/dts/lib.deno.shared_globals.d.ts | 184 | ||||
-rw-r--r-- | cli/js.rs | 1 | ||||
-rw-r--r-- | cli/main.rs | 3 | ||||
-rw-r--r-- | cli/rt/00_dom_exception.js | 15 | ||||
-rw-r--r-- | cli/rt/01_event.js | 1044 | ||||
-rw-r--r-- | cli/rt/07_base64.js | 157 | ||||
-rw-r--r-- | cli/rt/08_text_encoding.js | 686 | ||||
-rw-r--r-- | cli/tests/performance_stats.out | 2 | ||||
-rw-r--r-- | cli/tsc/99_main_compiler.js | 5 |
11 files changed, 85 insertions, 2088 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 8a8958b63..bedbdb657 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -16,6 +16,7 @@ path = "main.rs" [build-dependencies] deno_core = { path = "../core", version = "0.51.0" } +deno_web = { path = "../op_crates/web", version = "0.1.0" } [target.'cfg(windows)'.build-dependencies] winres = "0.1" diff --git a/cli/build.rs b/cli/build.rs index 777e74558..5a7f173e5 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -38,6 +38,11 @@ fn create_compiler_snapshot( ) { let mut runtime_isolate = CoreIsolate::new(StartupData::None, true); let mut custom_libs: HashMap<String, PathBuf> = HashMap::new(); + let web_scripts = deno_web::get_scripts(); + custom_libs.insert( + "lib.deno.web.d.ts".to_string(), + PathBuf::from(web_scripts.declaration), + ); custom_libs.insert( "lib.deno.window.d.ts".to_string(), cwd.join("dts/lib.deno.window.d.ts"), @@ -80,6 +85,10 @@ fn main() { // op_fetch_asset::trace_serializer(); println!("cargo:rustc-env=TS_VERSION={}", ts_version()); + println!( + "cargo:rustc-env=DENO_WEB_LIB_PATH={}", + deno_web::get_scripts().declaration + ); println!( "cargo:rustc-env=TARGET={}", @@ -93,7 +102,7 @@ fn main() { let runtime_snapshot_path = o.join("CLI_SNAPSHOT.bin"); let compiler_snapshot_path = o.join("COMPILER_SNAPSHOT.bin"); - let js_files = get_js_files("rt"); + let js_files = get_js_files_for_rt(); create_runtime_snapshot(&runtime_snapshot_path, js_files); let js_files = get_js_files("tsc"); @@ -123,3 +132,67 @@ fn get_js_files(d: &str) -> Vec<String> { js_files.sort(); js_files } + +fn get_js_files_for_rt() -> Vec<String> { + let web_scripts = deno_web::get_scripts(); + + let f = vec![ + "rt/00_bootstrap_namespace.js", + &web_scripts.dom_exception, + "rt/01_build.js", + "rt/01_colors.js", + "rt/01_errors.js", + &web_scripts.event, + "rt/01_internals.js", + "rt/01_version.js", + "rt/01_web_util.js", + "rt/02_abort_signal.js", + "rt/02_console.js", + "rt/03_dom_iterable.js", + "rt/06_util.js", + &web_scripts.text_encoding, + "rt/10_dispatch_json.js", + "rt/10_dispatch_minimal.js", + "rt/11_crypto.js", + "rt/11_resources.js", + "rt/11_streams.js", + "rt/11_timers.js", + "rt/11_url.js", + "rt/11_workers.js", + "rt/12_io.js", + "rt/13_buffer.js", + "rt/20_blob.js", + "rt/20_headers.js", + "rt/20_streams_queuing_strategy.js", + "rt/21_dom_file.js", + "rt/22_form_data.js", + "rt/23_multipart.js", + "rt/24_body.js", + "rt/25_request.js", + "rt/26_fetch.js", + "rt/30_files.js", + "rt/30_fs.js", + "rt/30_metrics.js", + "rt/30_net.js", + "rt/30_os.js", + "rt/40_compiler_api.js", + "rt/40_diagnostics.js", + "rt/40_error_stack.js", + "rt/40_fs_events.js", + "rt/40_net_unstable.js", + "rt/40_performance.js", + "rt/40_permissions.js", + "rt/40_plugins.js", + "rt/40_process.js", + "rt/40_read_file.js", + "rt/40_repl.js", + "rt/40_signals.js", + "rt/40_testing.js", + "rt/40_tls.js", + "rt/40_tty.js", + "rt/40_write_file.js", + "rt/90_deno_ns.js", + "rt/99_main.js", + ]; + f.iter().map(|p| p.to_string()).collect() +} diff --git a/cli/dts/lib.deno.shared_globals.d.ts b/cli/dts/lib.deno.shared_globals.d.ts index e331baee1..ec5367962 100644 --- a/cli/dts/lib.deno.shared_globals.d.ts +++ b/cli/dts/lib.deno.shared_globals.d.ts @@ -4,6 +4,7 @@ /// <reference no-default-lib="true" /> /// <reference lib="esnext" /> +/// <reference lib="deno.web" /> // This follows the WebIDL at: https://webassembly.github.io/spec/js-api/ // and: https://webassembly.github.io/spec/web-api/ @@ -529,12 +530,6 @@ interface DOMStringList { [index: number]: string; } -declare class DOMException extends Error { - constructor(message?: string, name?: string); - readonly name: string; - readonly message: string; -} - type BufferSource = ArrayBufferView | ArrayBuffer; type BlobPart = BufferSource | Blob | string; @@ -1030,46 +1025,6 @@ declare function fetch( init?: RequestInit, ): Promise<Response>; -/** Decodes a string of data which has been encoded using base-64 encoding. - * - * console.log(atob("aGVsbG8gd29ybGQ=")); // outputs 'hello world' - */ -declare function atob(s: string): string; - -/** Creates a base-64 ASCII encoded string from the input string. - * - * console.log(btoa("hello world")); // outputs "aGVsbG8gd29ybGQ=" - */ -declare function btoa(s: string): string; - -declare class TextDecoder { - /** Returns encoding's name, lowercased. */ - readonly encoding: string; - /** Returns `true` if error mode is "fatal", and `false` otherwise. */ - readonly fatal: boolean; - /** Returns `true` if ignore BOM flag is set, and `false` otherwise. */ - readonly ignoreBOM = false; - constructor( - label?: string, - options?: { fatal?: boolean; ignoreBOM?: boolean }, - ); - /** Returns the result of running encoding's decoder. */ - decode(input?: BufferSource, options?: { stream?: false }): string; - readonly [Symbol.toStringTag]: string; -} - -declare class TextEncoder { - /** Returns "utf-8". */ - readonly encoding = "utf-8"; - /** Returns the result of running UTF-8's encoder. */ - encode(input?: string): Uint8Array; - encodeInto( - input: string, - dest: Uint8Array, - ): { read: number; written: number }; - readonly [Symbol.toStringTag]: string; -} - interface URLSearchParams { /** Appends a specified key/value pair as a new search parameter. * @@ -1444,143 +1399,6 @@ declare class PerformanceMeasure extends PerformanceEntry { readonly entryType: "measure"; } -interface EventInit { - bubbles?: boolean; - cancelable?: boolean; - composed?: boolean; -} - -/** An event which takes place in the DOM. */ -declare class Event { - constructor(type: string, eventInitDict?: EventInit); - /** Returns true or false depending on how event was initialized. True if - * event goes through its target's ancestors in reverse tree order, and - * false otherwise. */ - readonly bubbles: boolean; - cancelBubble: boolean; - /** Returns true or false depending on how event was initialized. Its return - * value does not always carry meaning, but true can indicate that part of the - * operation during which event was dispatched, can be canceled by invoking - * the preventDefault() method. */ - readonly cancelable: boolean; - /** Returns true or false depending on how event was initialized. True if - * event invokes listeners past a ShadowRoot node that is the root of its - * target, and false otherwise. */ - readonly composed: boolean; - /** Returns the object whose event listener's callback is currently being - * invoked. */ - readonly currentTarget: EventTarget | null; - /** Returns true if preventDefault() was invoked successfully to indicate - * cancellation, and false otherwise. */ - readonly defaultPrevented: boolean; - /** Returns the event's phase, which is one of NONE, CAPTURING_PHASE, - * AT_TARGET, and BUBBLING_PHASE. */ - readonly eventPhase: number; - /** Returns true if event was dispatched by the user agent, and false - * otherwise. */ - readonly isTrusted: boolean; - /** Returns the object to which event is dispatched (its target). */ - readonly target: EventTarget | null; - /** Returns the event's timestamp as the number of milliseconds measured - * relative to the time origin. */ - readonly timeStamp: number; - /** Returns the type of event, e.g. "click", "hashchange", or "submit". */ - readonly type: string; - /** Returns the invocation target objects of event's path (objects on which - * listeners will be invoked), except for any nodes in shadow trees of which - * the shadow root's mode is "closed" that are not reachable from event's - * currentTarget. */ - composedPath(): EventTarget[]; - /** If invoked when the cancelable attribute value is true, and while - * executing a listener for the event with passive set to false, signals to - * the operation that caused event to be dispatched that it needs to be - * canceled. */ - preventDefault(): void; - /** Invoking this method prevents event from reaching any registered event - * listeners after the current one finishes running and, when dispatched in a - * tree, also prevents event from reaching any other objects. */ - stopImmediatePropagation(): void; - /** When dispatched in a tree, invoking this method prevents event from - * reaching any objects other than the current object. */ - stopPropagation(): void; - readonly AT_TARGET: number; - readonly BUBBLING_PHASE: number; - readonly CAPTURING_PHASE: number; - readonly NONE: number; - static readonly AT_TARGET: number; - static readonly BUBBLING_PHASE: number; - static readonly CAPTURING_PHASE: number; - static readonly NONE: number; -} - -/** - * EventTarget is a DOM interface implemented by objects that can receive events - * and may have listeners for them. - */ -declare class EventTarget { - /** Appends an event listener for events whose type attribute value is type. - * The callback argument sets the callback that will be invoked when the event - * is dispatched. - * - * The options argument sets listener-specific options. For compatibility this - * can be a boolean, in which case the method behaves exactly as if the value - * was specified as options's capture. - * - * When set to true, options's capture prevents callback from being invoked - * when the event's eventPhase attribute value is BUBBLING_PHASE. When false - * (or not present), callback will not be invoked when event's eventPhase - * attribute value is CAPTURING_PHASE. Either way, callback will be invoked if - * event's eventPhase attribute value is AT_TARGET. - * - * When set to true, options's passive indicates that the callback will not - * cancel the event by invoking preventDefault(). This is used to enable - * performance optimizations described in § 2.8 Observing event listeners. - * - * When set to true, options's once indicates that the callback will only be - * invoked once after which the event listener will be removed. - * - * The event listener is appended to target's event listener list and is not - * appended if it has the same type, callback, and capture. */ - addEventListener( - type: string, - listener: EventListenerOrEventListenerObject | null, - options?: boolean | AddEventListenerOptions, - ): void; - /** Dispatches a synthetic event event to target and returns true if either - * event's cancelable attribute value is false or its preventDefault() method - * was not invoked, and false otherwise. */ - dispatchEvent(event: Event): boolean; - /** Removes the event listener in target's event listener list with the same - * type, callback, and options. */ - removeEventListener( - type: string, - callback: EventListenerOrEventListenerObject | null, - options?: EventListenerOptions | boolean, - ): void; - [Symbol.toStringTag]: string; -} - -interface EventListener { - (evt: Event): void | Promise<void>; -} - -interface EventListenerObject { - handleEvent(evt: Event): void | Promise<void>; -} - -declare type EventListenerOrEventListenerObject = - | EventListener - | EventListenerObject; - -interface AddEventListenerOptions extends EventListenerOptions { - once?: boolean; - passive?: boolean; -} - -interface EventListenerOptions { - capture?: boolean; -} - /** Events measuring progress of an underlying process, like an HTTP request * (for an XMLHttpRequest, or the loading of the underlying resource of an * <img>, <audio>, <video>, <style> or <link>). */ @@ -5,6 +5,7 @@ pub static CLI_SNAPSHOT: &[u8] = pub static COMPILER_SNAPSHOT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/COMPILER_SNAPSHOT.bin")); pub static DENO_NS_LIB: &str = include_str!("dts/lib.deno.ns.d.ts"); +pub static DENO_WEB_LIB: &str = include_str!(env!("DENO_WEB_LIB_PATH")); pub static SHARED_GLOBALS_LIB: &str = include_str!("dts/lib.deno.shared_globals.d.ts"); pub static WINDOW_LIB: &str = include_str!("dts/lib.deno.window.d.ts"); diff --git a/cli/main.rs b/cli/main.rs index 97f3161df..728a23db0 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -287,8 +287,9 @@ async fn print_file_info( fn get_types(unstable: bool) -> String { let mut types = format!( - "{}\n{}\n{}", + "{}\n{}\n{}\n{}", crate::js::DENO_NS_LIB, + crate::js::DENO_WEB_LIB, crate::js::SHARED_GLOBALS_LIB, crate::js::WINDOW_LIB, ); diff --git a/cli/rt/00_dom_exception.js b/cli/rt/00_dom_exception.js deleted file mode 100644 index 6d72779b0..000000000 --- a/cli/rt/00_dom_exception.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -class DOMException extends Error { - #name = ""; - - constructor(message = "", name = "Error") { - super(message); - this.#name = name; - } - - get name() { - return this.#name; - } -} diff --git a/cli/rt/01_event.js b/cli/rt/01_event.js deleted file mode 100644 index 35967e0a1..000000000 --- a/cli/rt/01_event.js +++ /dev/null @@ -1,1044 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. - -// This module follows most of the WHATWG Living Standard for the DOM logic. -// Many parts of the DOM are not implemented in Deno, but the logic for those -// parts still exists. This means you will observe a lot of strange structures -// and impossible logic branches based on what Deno currently supports. - -((window) => { - const eventData = new WeakMap(); - - function requiredArguments( - name, - length, - required, - ) { - if (length < required) { - const errMsg = `${name} requires at least ${required} argument${ - required === 1 ? "" : "s" - }, but only ${length} present`; - throw new TypeError(errMsg); - } - } - - // accessors for non runtime visible data - - function getDispatched(event) { - return Boolean(eventData.get(event)?.dispatched); - } - - function getPath(event) { - return eventData.get(event)?.path ?? []; - } - - function getStopImmediatePropagation(event) { - return Boolean(eventData.get(event)?.stopImmediatePropagation); - } - - function setCurrentTarget( - event, - value, - ) { - event.currentTarget = value; - } - - function setDispatched(event, value) { - const data = eventData.get(event); - if (data) { - data.dispatched = value; - } - } - - function setEventPhase(event, value) { - event.eventPhase = value; - } - - function setInPassiveListener(event, value) { - const data = eventData.get(event); - if (data) { - data.inPassiveListener = value; - } - } - - function setPath(event, value) { - const data = eventData.get(event); - if (data) { - data.path = value; - } - } - - function setRelatedTarget( - event, - value, - ) { - if ("relatedTarget" in event) { - event.relatedTarget = value; - } - } - - function setTarget(event, value) { - event.target = value; - } - - function setStopImmediatePropagation( - event, - value, - ) { - const data = eventData.get(event); - if (data) { - data.stopImmediatePropagation = value; - } - } - - // Type guards that widen the event type - - function hasRelatedTarget( - event, - ) { - return "relatedTarget" in event; - } - - function isTrusted() { - return eventData.get(this).isTrusted; - } - - class Event { - #canceledFlag = false; - #stopPropagationFlag = false; - #attributes = {}; - - constructor(type, eventInitDict = {}) { - requiredArguments("Event", arguments.length, 1); - type = String(type); - this.#attributes = { - type, - bubbles: eventInitDict.bubbles ?? false, - cancelable: eventInitDict.cancelable ?? false, - composed: eventInitDict.composed ?? false, - currentTarget: null, - eventPhase: Event.NONE, - target: null, - timeStamp: Date.now(), - }; - eventData.set(this, { - dispatched: false, - inPassiveListener: false, - isTrusted: false, - path: [], - stopImmediatePropagation: false, - }); - Reflect.defineProperty(this, "isTrusted", { - enumerable: true, - get: isTrusted, - }); - } - - get bubbles() { - return this.#attributes.bubbles; - } - - get cancelBubble() { - return this.#stopPropagationFlag; - } - - set cancelBubble(value) { - this.#stopPropagationFlag = value; - } - - get cancelable() { - return this.#attributes.cancelable; - } - - get composed() { - return this.#attributes.composed; - } - - get currentTarget() { - return this.#attributes.currentTarget; - } - - set currentTarget(value) { - this.#attributes = { - type: this.type, - bubbles: this.bubbles, - cancelable: this.cancelable, - composed: this.composed, - currentTarget: value, - eventPhase: this.eventPhase, - target: this.target, - timeStamp: this.timeStamp, - }; - } - - get defaultPrevented() { - return this.#canceledFlag; - } - - get eventPhase() { - return this.#attributes.eventPhase; - } - - set eventPhase(value) { - this.#attributes = { - type: this.type, - bubbles: this.bubbles, - cancelable: this.cancelable, - composed: this.composed, - currentTarget: this.currentTarget, - eventPhase: value, - target: this.target, - timeStamp: this.timeStamp, - }; - } - - get initialized() { - return true; - } - - get target() { - return this.#attributes.target; - } - - set target(value) { - this.#attributes = { - type: this.type, - bubbles: this.bubbles, - cancelable: this.cancelable, - composed: this.composed, - currentTarget: this.currentTarget, - eventPhase: this.eventPhase, - target: value, - timeStamp: this.timeStamp, - }; - } - - get timeStamp() { - return this.#attributes.timeStamp; - } - - get type() { - return this.#attributes.type; - } - - composedPath() { - const path = eventData.get(this).path; - if (path.length === 0) { - return []; - } - - if (!this.currentTarget) { - throw new Error("assertion error"); - } - const composedPath = [ - { - item: this.currentTarget, - itemInShadowTree: false, - relatedTarget: null, - rootOfClosedTree: false, - slotInClosedTree: false, - target: null, - touchTargetList: [], - }, - ]; - - let currentTargetIndex = 0; - let currentTargetHiddenSubtreeLevel = 0; - - for (let index = path.length - 1; index >= 0; index--) { - const { item, rootOfClosedTree, slotInClosedTree } = path[index]; - - if (rootOfClosedTree) { - currentTargetHiddenSubtreeLevel++; - } - - if (item === this.currentTarget) { - currentTargetIndex = index; - break; - } - - if (slotInClosedTree) { - currentTargetHiddenSubtreeLevel--; - } - } - - let currentHiddenLevel = currentTargetHiddenSubtreeLevel; - let maxHiddenLevel = currentTargetHiddenSubtreeLevel; - - for (let i = currentTargetIndex - 1; i >= 0; i--) { - const { item, rootOfClosedTree, slotInClosedTree } = path[i]; - - if (rootOfClosedTree) { - currentHiddenLevel++; - } - - if (currentHiddenLevel <= maxHiddenLevel) { - composedPath.unshift({ - item, - itemInShadowTree: false, - relatedTarget: null, - rootOfClosedTree: false, - slotInClosedTree: false, - target: null, - touchTargetList: [], - }); - } - - if (slotInClosedTree) { - currentHiddenLevel--; - - if (currentHiddenLevel < maxHiddenLevel) { - maxHiddenLevel = currentHiddenLevel; - } - } - } - - currentHiddenLevel = currentTargetHiddenSubtreeLevel; - maxHiddenLevel = currentTargetHiddenSubtreeLevel; - - for (let index = currentTargetIndex + 1; index < path.length; index++) { - const { item, rootOfClosedTree, slotInClosedTree } = path[index]; - - if (slotInClosedTree) { - currentHiddenLevel++; - } - - if (currentHiddenLevel <= maxHiddenLevel) { - composedPath.push({ - item, - itemInShadowTree: false, - relatedTarget: null, - rootOfClosedTree: false, - slotInClosedTree: false, - target: null, - touchTargetList: [], - }); - } - - if (rootOfClosedTree) { - currentHiddenLevel--; - - if (currentHiddenLevel < maxHiddenLevel) { - maxHiddenLevel = currentHiddenLevel; - } - } - } - return composedPath.map((p) => p.item); - } - - preventDefault() { - if (this.cancelable && !eventData.get(this).inPassiveListener) { - this.#canceledFlag = true; - } - } - - stopPropagation() { - this.#stopPropagationFlag = true; - } - - stopImmediatePropagation() { - this.#stopPropagationFlag = true; - eventData.get(this).stopImmediatePropagation = true; - } - - get NONE() { - return Event.NONE; - } - - get CAPTURING_PHASE() { - return Event.CAPTURING_PHASE; - } - - get AT_TARGET() { - return Event.AT_TARGET; - } - - get BUBBLING_PHASE() { - return Event.BUBBLING_PHASE; - } - - static get NONE() { - return 0; - } - - static get CAPTURING_PHASE() { - return 1; - } - - static get AT_TARGET() { - return 2; - } - - static get BUBBLING_PHASE() { - return 3; - } - } - - function defineEnumerableProps( - Ctor, - props, - ) { - for (const prop of props) { - Reflect.defineProperty(Ctor.prototype, prop, { enumerable: true }); - } - } - - defineEnumerableProps(Event, [ - "bubbles", - "cancelable", - "composed", - "currentTarget", - "defaultPrevented", - "eventPhase", - "target", - "timeStamp", - "type", - ]); - - // This is currently the only node type we are using, so instead of implementing - // the whole of the Node interface at the moment, this just gives us the one - // value to power the standards based logic - const DOCUMENT_FRAGMENT_NODE = 11; - - // DOM Logic Helper functions and type guards - - /** Get the parent node, for event targets that have a parent. - * - * Ref: https://dom.spec.whatwg.org/#get-the-parent */ - function getParent(eventTarget) { - return isNode(eventTarget) ? eventTarget.parentNode : null; - } - - function getRoot(eventTarget) { - return isNode(eventTarget) - ? eventTarget.getRootNode({ composed: true }) - : null; - } - - function isNode( - eventTarget, - ) { - return Boolean(eventTarget && "nodeType" in eventTarget); - } - - // https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-ancestor - function isShadowInclusiveAncestor( - ancestor, - node, - ) { - while (isNode(node)) { - if (node === ancestor) { - return true; - } - - if (isShadowRoot(node)) { - node = node && getHost(node); - } else { - node = getParent(node); - } - } - - return false; - } - - function isShadowRoot(nodeImpl) { - return Boolean( - nodeImpl && - isNode(nodeImpl) && - nodeImpl.nodeType === DOCUMENT_FRAGMENT_NODE && - getHost(nodeImpl) != null, - ); - } - - function isSlotable( - nodeImpl, - ) { - return Boolean(isNode(nodeImpl) && "assignedSlot" in nodeImpl); - } - - // DOM Logic functions - - /** Append a path item to an event's path. - * - * Ref: https://dom.spec.whatwg.org/#concept-event-path-append - */ - function appendToEventPath( - eventImpl, - target, - targetOverride, - relatedTarget, - touchTargets, - slotInClosedTree, - ) { - const itemInShadowTree = isNode(target) && isShadowRoot(getRoot(target)); - const rootOfClosedTree = isShadowRoot(target) && - getMode(target) === "closed"; - - getPath(eventImpl).push({ - item: target, - itemInShadowTree, - target: targetOverride, - relatedTarget, - touchTargetList: touchTargets, - rootOfClosedTree, - slotInClosedTree, - }); - } - - function dispatch( - targetImpl, - eventImpl, - targetOverride, - ) { - let clearTargets = false; - let activationTarget = null; - - setDispatched(eventImpl, true); - - targetOverride = targetOverride ?? targetImpl; - const eventRelatedTarget = hasRelatedTarget(eventImpl) - ? eventImpl.relatedTarget - : null; - let relatedTarget = retarget(eventRelatedTarget, targetImpl); - - if (targetImpl !== relatedTarget || targetImpl === eventRelatedTarget) { - const touchTargets = []; - - appendToEventPath( - eventImpl, - targetImpl, - targetOverride, - relatedTarget, - touchTargets, - false, - ); - - const isActivationEvent = eventImpl.type === "click"; - - if (isActivationEvent && getHasActivationBehavior(targetImpl)) { - activationTarget = targetImpl; - } - - let slotInClosedTree = false; - let slotable = isSlotable(targetImpl) && getAssignedSlot(targetImpl) - ? targetImpl - : null; - let parent = getParent(targetImpl); - - // Populate event path - // https://dom.spec.whatwg.org/#event-path - while (parent !== null) { - if (slotable !== null) { - slotable = null; - - const parentRoot = getRoot(parent); - if ( - isShadowRoot(parentRoot) && - parentRoot && - getMode(parentRoot) === "closed" - ) { - slotInClosedTree = true; - } - } - - relatedTarget = retarget(eventRelatedTarget, parent); - - if ( - isNode(parent) && - isShadowInclusiveAncestor(getRoot(targetImpl), parent) - ) { - appendToEventPath( - eventImpl, - parent, - null, - relatedTarget, - touchTargets, - slotInClosedTree, - ); - } else if (parent === relatedTarget) { - parent = null; - } else { - targetImpl = parent; - - if ( - isActivationEvent && - activationTarget === null && - getHasActivationBehavior(targetImpl) - ) { - activationTarget = targetImpl; - } - - appendToEventPath( - eventImpl, - parent, - targetImpl, - relatedTarget, - touchTargets, - slotInClosedTree, - ); - } - - if (parent !== null) { - parent = getParent(parent); - } - - slotInClosedTree = false; - } - - let clearTargetsTupleIndex = -1; - const path = getPath(eventImpl); - for ( - let i = path.length - 1; - i >= 0 && clearTargetsTupleIndex === -1; - i-- - ) { - if (path[i].target !== null) { - clearTargetsTupleIndex = i; - } - } - const clearTargetsTuple = path[clearTargetsTupleIndex]; - - clearTargets = (isNode(clearTargetsTuple.target) && - isShadowRoot(getRoot(clearTargetsTuple.target))) || - (isNode(clearTargetsTuple.relatedTarget) && - isShadowRoot(getRoot(clearTargetsTuple.relatedTarget))); - - setEventPhase(eventImpl, Event.CAPTURING_PHASE); - - for (let i = path.length - 1; i >= 0; --i) { - const tuple = path[i]; - - if (tuple.target === null) { - invokeEventListeners(tuple, eventImpl); - } - } - - for (let i = 0; i < path.length; i++) { - const tuple = path[i]; - - if (tuple.target !== null) { - setEventPhase(eventImpl, Event.AT_TARGET); - } else { - setEventPhase(eventImpl, Event.BUBBLING_PHASE); - } - - if ( - (eventImpl.eventPhase === Event.BUBBLING_PHASE && - eventImpl.bubbles) || - eventImpl.eventPhase === Event.AT_TARGET - ) { - invokeEventListeners(tuple, eventImpl); - } - } - } - - setEventPhase(eventImpl, Event.NONE); - setCurrentTarget(eventImpl, null); - setPath(eventImpl, []); - setDispatched(eventImpl, false); - eventImpl.cancelBubble = false; - setStopImmediatePropagation(eventImpl, false); - - if (clearTargets) { - setTarget(eventImpl, null); - setRelatedTarget(eventImpl, null); - } - - // TODO: invoke activation targets if HTML nodes will be implemented - // if (activationTarget !== null) { - // if (!eventImpl.defaultPrevented) { - // activationTarget._activationBehavior(); - // } - // } - - return !eventImpl.defaultPrevented; - } - - /** Inner invoking of the event listeners where the resolved listeners are - * called. - * - * Ref: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke */ - function innerInvokeEventListeners( - eventImpl, - targetListeners, - ) { - let found = false; - - const { type } = eventImpl; - - if (!targetListeners || !targetListeners[type]) { - return found; - } - - // Copy event listeners before iterating since the list can be modified during the iteration. - const handlers = targetListeners[type].slice(); - - for (let i = 0; i < handlers.length; i++) { - const listener = handlers[i]; - - let capture, once, passive; - if (typeof listener.options === "boolean") { - capture = listener.options; - once = false; - passive = false; - } else { - capture = listener.options.capture; - once = listener.options.once; - passive = listener.options.passive; - } - - // Check if the event listener has been removed since the listeners has been cloned. - if (!targetListeners[type].includes(listener)) { - continue; - } - - found = true; - - if ( - (eventImpl.eventPhase === Event.CAPTURING_PHASE && !capture) || - (eventImpl.eventPhase === Event.BUBBLING_PHASE && capture) - ) { - continue; - } - - if (once) { - targetListeners[type].splice( - targetListeners[type].indexOf(listener), - 1, - ); - } - - if (passive) { - setInPassiveListener(eventImpl, true); - } - - if (typeof listener.callback === "object") { - if (typeof listener.callback.handleEvent === "function") { - listener.callback.handleEvent(eventImpl); - } - } else { - listener.callback.call(eventImpl.currentTarget, eventImpl); - } - - setInPassiveListener(eventImpl, false); - - if (getStopImmediatePropagation(eventImpl)) { - return found; - } - } - - return found; - } - - /** Invokes the listeners on a given event path with the supplied event. - * - * Ref: https://dom.spec.whatwg.org/#concept-event-listener-invoke */ - function invokeEventListeners(tuple, eventImpl) { - const path = getPath(eventImpl); - const tupleIndex = path.indexOf(tuple); - for (let i = tupleIndex; i >= 0; i--) { - const t = path[i]; - if (t.target) { - setTarget(eventImpl, t.target); - break; - } - } - - setRelatedTarget(eventImpl, tuple.relatedTarget); - - if (eventImpl.cancelBubble) { - return; - } - - setCurrentTarget(eventImpl, tuple.item); - - innerInvokeEventListeners(eventImpl, getListeners(tuple.item)); - } - - function normalizeAddEventHandlerOptions( - options, - ) { - if (typeof options === "boolean" || typeof options === "undefined") { - return { - capture: Boolean(options), - once: false, - passive: false, - }; - } else { - return options; - } - } - - function normalizeEventHandlerOptions( - options, - ) { - if (typeof options === "boolean" || typeof options === "undefined") { - return { - capture: Boolean(options), - }; - } else { - return options; - } - } - - /** Retarget the target following the spec logic. - * - * Ref: https://dom.spec.whatwg.org/#retarget */ - function retarget(a, b) { - while (true) { - if (!isNode(a)) { - return a; - } - - const aRoot = a.getRootNode(); - - if (aRoot) { - if ( - !isShadowRoot(aRoot) || - (isNode(b) && isShadowInclusiveAncestor(aRoot, b)) - ) { - return a; - } - - a = getHost(aRoot); - } - } - } - - // Accessors for non-public data - - const eventTargetData = new WeakMap(); - - function setEventTargetData(value) { - eventTargetData.set(value, getDefaultTargetData()); - } - - function getAssignedSlot(target) { - return Boolean(eventTargetData.get(target)?.assignedSlot); - } - - function getHasActivationBehavior(target) { - return Boolean( - eventTargetData.get(target)?.hasActivationBehavior, - ); - } - - function getHost(target) { - return eventTargetData.get(target)?.host ?? null; - } - - function getListeners(target) { - return eventTargetData.get(target)?.listeners ?? {}; - } - - function getMode(target) { - return eventTargetData.get(target)?.mode ?? null; - } - - function getDefaultTargetData() { - return { - assignedSlot: false, - hasActivationBehavior: false, - host: null, - listeners: Object.create(null), - mode: "", - }; - } - - class EventTarget { - constructor() { - eventTargetData.set(this, getDefaultTargetData()); - } - - addEventListener( - type, - callback, - options, - ) { - requiredArguments("EventTarget.addEventListener", arguments.length, 2); - if (callback === null) { - return; - } - - options = normalizeAddEventHandlerOptions(options); - const { listeners } = eventTargetData.get(this ?? globalThis); - - if (!(type in listeners)) { - listeners[type] = []; - } - - for (const listener of listeners[type]) { - if ( - ((typeof listener.options === "boolean" && - listener.options === options.capture) || - (typeof listener.options === "object" && - listener.options.capture === options.capture)) && - listener.callback === callback - ) { - return; - } - } - - listeners[type].push({ callback, options }); - } - - removeEventListener( - type, - callback, - options, - ) { - requiredArguments("EventTarget.removeEventListener", arguments.length, 2); - - const listeners = eventTargetData.get(this ?? globalThis).listeners; - if (callback !== null && type in listeners) { - listeners[type] = listeners[type].filter( - (listener) => listener.callback !== callback, - ); - } else if (callback === null || !listeners[type]) { - return; - } - - options = normalizeEventHandlerOptions(options); - - for (let i = 0; i < listeners[type].length; ++i) { - const listener = listeners[type][i]; - if ( - ((typeof listener.options === "boolean" && - listener.options === options.capture) || - (typeof listener.options === "object" && - listener.options.capture === options.capture)) && - listener.callback === callback - ) { - listeners[type].splice(i, 1); - break; - } - } - } - - dispatchEvent(event) { - requiredArguments("EventTarget.dispatchEvent", arguments.length, 1); - const self = this ?? globalThis; - - const listeners = eventTargetData.get(self).listeners; - if (!(event.type in listeners)) { - return true; - } - - if (getDispatched(event)) { - throw new DOMException("Invalid event state.", "InvalidStateError"); - } - - if (event.eventPhase !== Event.NONE) { - throw new DOMException("Invalid event state.", "InvalidStateError"); - } - - return dispatch(self, event); - } - - get [Symbol.toStringTag]() { - return "EventTarget"; - } - - getParent(_event) { - return null; - } - } - - defineEnumerableProps(EventTarget, [ - "addEventListener", - "removeEventListener", - "dispatchEvent", - ]); - - class ErrorEvent extends Event { - #message = ""; - #filename = ""; - #lineno = ""; - #colno = ""; - #error = ""; - - get message() { - return this.#message; - } - get filename() { - return this.#filename; - } - get lineno() { - return this.#lineno; - } - get colno() { - return this.#colno; - } - get error() { - return this.#error; - } - - constructor( - type, - { - bubbles, - cancelable, - composed, - message = "", - filename = "", - lineno = 0, - colno = 0, - error = null, - } = {}, - ) { - super(type, { - bubbles: bubbles, - cancelable: cancelable, - composed: composed, - }); - - this.#message = message; - this.#filename = filename; - this.#lineno = lineno; - this.#colno = colno; - this.#error = error; - } - - get [Symbol.toStringTag]() { - return "ErrorEvent"; - } - } - - defineEnumerableProps(ErrorEvent, [ - "message", - "filename", - "lineno", - "colno", - "error", - ]); - - class CustomEvent extends Event { - #detail = null; - - constructor(type, eventInitDict = {}) { - super(type, eventInitDict); - requiredArguments("CustomEvent", arguments.length, 1); - const { detail } = eventInitDict; - this.#detail = detail; - } - - get detail() { - return this.#detail; - } - - get [Symbol.toStringTag]() { - return "CustomEvent"; - } - } - - Reflect.defineProperty(CustomEvent.prototype, "detail", { - enumerable: true, - }); - - window.Event = Event; - window.EventTarget = EventTarget; - window.ErrorEvent = ErrorEvent; - window.CustomEvent = CustomEvent; - window.__bootstrap.eventTarget = { - setEventTargetData, - }; -})(this); diff --git a/cli/rt/07_base64.js b/cli/rt/07_base64.js deleted file mode 100644 index 86739fd52..000000000 --- a/cli/rt/07_base64.js +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. - -// Forked from https://github.com/beatgammit/base64-js -// Copyright (c) 2014 Jameson Little. MIT License. - -((window) => { - const lookup = []; - const revLookup = []; - - const code = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - for (let i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i]; - revLookup[code.charCodeAt(i)] = i; - } - - // Support decoding URL-safe base64 strings, as Node.js does. - // See: https://en.wikipedia.org/wiki/Base64#URL_applications - revLookup["-".charCodeAt(0)] = 62; - revLookup["_".charCodeAt(0)] = 63; - - function getLens(b64) { - const len = b64.length; - - if (len % 4 > 0) { - throw new Error("Invalid string. Length must be a multiple of 4"); - } - - // Trim off extra bytes after placeholder bytes are found - // See: https://github.com/beatgammit/base64-js/issues/42 - let validLen = b64.indexOf("="); - if (validLen === -1) validLen = len; - - const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4); - - return [validLen, placeHoldersLen]; - } - - // base64 is 4/3 + up to two characters of the original data - function byteLength(b64) { - const lens = getLens(b64); - const validLen = lens[0]; - const placeHoldersLen = lens[1]; - return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen; - } - - function _byteLength( - b64, - validLen, - placeHoldersLen, - ) { - return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen; - } - - function toByteArray(b64) { - let tmp; - const lens = getLens(b64); - const validLen = lens[0]; - const placeHoldersLen = lens[1]; - - const arr = new Uint8Array(_byteLength(b64, validLen, placeHoldersLen)); - - let curByte = 0; - - // if there are placeholders, only get up to the last complete 4 chars - const len = placeHoldersLen > 0 ? validLen - 4 : validLen; - - let i; - for (i = 0; i < len; i += 4) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | - (revLookup[b64.charCodeAt(i + 1)] << 12) | - (revLookup[b64.charCodeAt(i + 2)] << 6) | - revLookup[b64.charCodeAt(i + 3)]; - arr[curByte++] = (tmp >> 16) & 0xff; - arr[curByte++] = (tmp >> 8) & 0xff; - arr[curByte++] = tmp & 0xff; - } - - if (placeHoldersLen === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | - (revLookup[b64.charCodeAt(i + 1)] >> 4); - arr[curByte++] = tmp & 0xff; - } - - if (placeHoldersLen === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | - (revLookup[b64.charCodeAt(i + 1)] << 4) | - (revLookup[b64.charCodeAt(i + 2)] >> 2); - arr[curByte++] = (tmp >> 8) & 0xff; - arr[curByte++] = tmp & 0xff; - } - - return arr; - } - - function tripletToBase64(num) { - return ( - lookup[(num >> 18) & 0x3f] + - lookup[(num >> 12) & 0x3f] + - lookup[(num >> 6) & 0x3f] + - lookup[num & 0x3f] - ); - } - - function encodeChunk(uint8, start, end) { - let tmp; - const output = []; - for (let i = start; i < end; i += 3) { - tmp = ((uint8[i] << 16) & 0xff0000) + - ((uint8[i + 1] << 8) & 0xff00) + - (uint8[i + 2] & 0xff); - output.push(tripletToBase64(tmp)); - } - return output.join(""); - } - - function fromByteArray(uint8) { - let tmp; - const len = uint8.length; - const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes - const parts = []; - const maxChunkLength = 16383; // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push( - encodeChunk( - uint8, - i, - i + maxChunkLength > len2 ? len2 : i + maxChunkLength, - ), - ); - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1]; - parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + "=="); - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + uint8[len - 1]; - parts.push( - lookup[tmp >> 10] + - lookup[(tmp >> 4) & 0x3f] + - lookup[(tmp << 2) & 0x3f] + - "=", - ); - } - - return parts.join(""); - } - - window.__bootstrap.base64 = { - byteLength, - toByteArray, - fromByteArray, - }; -})(this); diff --git a/cli/rt/08_text_encoding.js b/cli/rt/08_text_encoding.js deleted file mode 100644 index a7a9a49e4..000000000 --- a/cli/rt/08_text_encoding.js +++ /dev/null @@ -1,686 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. - -// The following code is based off of text-encoding at: -// https://github.com/inexorabletash/text-encoding -// -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. -// -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -((window) => { - const core = Deno.core; - const base64 = window.__bootstrap.base64; - - const CONTINUE = null; - const END_OF_STREAM = -1; - const FINISHED = -1; - - function decoderError(fatal) { - if (fatal) { - throw new TypeError("Decoder error."); - } - return 0xfffd; // default code point - } - - function inRange(a, min, max) { - return min <= a && a <= max; - } - - function isASCIIByte(a) { - return inRange(a, 0x00, 0x7f); - } - - function stringToCodePoints(input) { - const u = []; - for (const c of input) { - u.push(c.codePointAt(0)); - } - return u; - } - - class UTF8Encoder { - handler(codePoint) { - if (codePoint === END_OF_STREAM) { - return "finished"; - } - - if (inRange(codePoint, 0x00, 0x7f)) { - return [codePoint]; - } - - let count; - let offset; - if (inRange(codePoint, 0x0080, 0x07ff)) { - count = 1; - offset = 0xc0; - } else if (inRange(codePoint, 0x0800, 0xffff)) { - count = 2; - offset = 0xe0; - } else if (inRange(codePoint, 0x10000, 0x10ffff)) { - count = 3; - offset = 0xf0; - } else { - throw TypeError( - `Code point out of range: \\x${codePoint.toString(16)}`, - ); - } - - const bytes = [(codePoint >> (6 * count)) + offset]; - - while (count > 0) { - const temp = codePoint >> (6 * (count - 1)); - bytes.push(0x80 | (temp & 0x3f)); - count--; - } - - return bytes; - } - } - - function atob(s) { - s = String(s); - s = s.replace(/[\t\n\f\r ]/g, ""); - - if (s.length % 4 === 0) { - s = s.replace(/==?$/, ""); - } - - const rem = s.length % 4; - if (rem === 1 || /[^+/0-9A-Za-z]/.test(s)) { - throw new DOMException( - "The string to be decoded is not correctly encoded", - "DataDecodeError", - ); - } - - // base64-js requires length exactly times of 4 - if (rem > 0) { - s = s.padEnd(s.length + (4 - rem), "="); - } - - const byteArray = base64.toByteArray(s); - let result = ""; - for (let i = 0; i < byteArray.length; i++) { - result += String.fromCharCode(byteArray[i]); - } - return result; - } - - function btoa(s) { - const byteArray = []; - for (let i = 0; i < s.length; i++) { - const charCode = s[i].charCodeAt(0); - if (charCode > 0xff) { - throw new TypeError( - "The string to be encoded contains characters " + - "outside of the Latin1 range.", - ); - } - byteArray.push(charCode); - } - const result = base64.fromByteArray(Uint8Array.from(byteArray)); - return result; - } - - class SingleByteDecoder { - #index = []; - #fatal = false; - - constructor( - index, - { ignoreBOM = false, fatal = false } = {}, - ) { - if (ignoreBOM) { - throw new TypeError("Ignoring the BOM is available only with utf-8."); - } - this.#fatal = fatal; - this.#index = index; - } - handler(_stream, byte) { - if (byte === END_OF_STREAM) { - return FINISHED; - } - if (isASCIIByte(byte)) { - return byte; - } - const codePoint = this.#index[byte - 0x80]; - - if (codePoint == null) { - return decoderError(this.#fatal); - } - - return codePoint; - } - } - - // The encodingMap is a hash of labels that are indexed by the conical - // encoding. - const encodingMap = { - "windows-1252": [ - "ansi_x3.4-1968", - "ascii", - "cp1252", - "cp819", - "csisolatin1", - "ibm819", - "iso-8859-1", - "iso-ir-100", - "iso8859-1", - "iso88591", - "iso_8859-1", - "iso_8859-1:1987", - "l1", - "latin1", - "us-ascii", - "windows-1252", - "x-cp1252", - ], - "utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"], - }; - // We convert these into a Map where every label resolves to its canonical - // encoding type. - const encodings = new Map(); - for (const key of Object.keys(encodingMap)) { - const labels = encodingMap[key]; - for (const label of labels) { - encodings.set(label, key); - } - } - - // A map of functions that return new instances of a decoder indexed by the - // encoding type. - const decoders = new Map(); - - // Single byte decoders are an array of code point lookups - const encodingIndexes = new Map(); - // deno-fmt-ignore - encodingIndexes.set("windows-1252", [ - 8364, - 129, - 8218, - 402, - 8222, - 8230, - 8224, - 8225, - 710, - 8240, - 352, - 8249, - 338, - 141, - 381, - 143, - 144, - 8216, - 8217, - 8220, - 8221, - 8226, - 8211, - 8212, - 732, - 8482, - 353, - 8250, - 339, - 157, - 382, - 376, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 213, - 214, - 215, - 216, - 217, - 218, - 219, - 220, - 221, - 222, - 223, - 224, - 225, - 226, - 227, - 228, - 229, - 230, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 249, - 250, - 251, - 252, - 253, - 254, - 255, - ]); - for (const [key, index] of encodingIndexes) { - decoders.set( - key, - (options) => { - return new SingleByteDecoder(index, options); - }, - ); - } - - function codePointsToString(codePoints) { - let s = ""; - for (const cp of codePoints) { - s += String.fromCodePoint(cp); - } - return s; - } - - class Stream { - #tokens = []; - constructor(tokens) { - this.#tokens = [...tokens]; - this.#tokens.reverse(); - } - - endOfStream() { - return !this.#tokens.length; - } - - read() { - return !this.#tokens.length ? END_OF_STREAM : this.#tokens.pop(); - } - - prepend(token) { - if (Array.isArray(token)) { - while (token.length) { - this.#tokens.push(token.pop()); - } - } else { - this.#tokens.push(token); - } - } - - push(token) { - if (Array.isArray(token)) { - while (token.length) { - this.#tokens.unshift(token.shift()); - } - } else { - this.#tokens.unshift(token); - } - } - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - function isEitherArrayBuffer(x) { - return x instanceof SharedArrayBuffer || x instanceof ArrayBuffer; - } - - class TextDecoder { - #encoding = ""; - - get encoding() { - return this.#encoding; - } - fatal = false; - ignoreBOM = false; - - constructor(label = "utf-8", options = { fatal: false }) { - if (options.ignoreBOM) { - this.ignoreBOM = true; - } - if (options.fatal) { - this.fatal = true; - } - label = String(label).trim().toLowerCase(); - const encoding = encodings.get(label); - if (!encoding) { - throw new RangeError( - `The encoding label provided ('${label}') is invalid.`, - ); - } - if (!decoders.has(encoding) && encoding !== "utf-8") { - throw new TypeError(`Internal decoder ('${encoding}') not found.`); - } - this.#encoding = encoding; - } - - decode( - input, - options = { stream: false }, - ) { - if (options.stream) { - throw new TypeError("Stream not supported."); - } - - let bytes; - if (input instanceof Uint8Array) { - bytes = input; - } else if (isEitherArrayBuffer(input)) { - bytes = new Uint8Array(input); - } else if ( - typeof input === "object" && - "buffer" in input && - isEitherArrayBuffer(input.buffer) - ) { - bytes = new Uint8Array( - input.buffer, - input.byteOffset, - input.byteLength, - ); - } else { - bytes = new Uint8Array(0); - } - - // For simple utf-8 decoding "Deno.core.decode" can be used for performance - if ( - this.#encoding === "utf-8" && - this.fatal === false && - this.ignoreBOM === false - ) { - return core.decode(bytes); - } - - // For performance reasons we utilise a highly optimised decoder instead of - // the general decoder. - if (this.#encoding === "utf-8") { - return decodeUtf8(bytes, this.fatal, this.ignoreBOM); - } - - const decoder = decoders.get(this.#encoding)({ - fatal: this.fatal, - ignoreBOM: this.ignoreBOM, - }); - const inputStream = new Stream(bytes); - const output = []; - - while (true) { - const result = decoder.handler(inputStream, inputStream.read()); - if (result === FINISHED) { - break; - } - - if (result !== CONTINUE) { - output.push(result); - } - } - - if (output.length > 0 && output[0] === 0xfeff) { - output.shift(); - } - - return codePointsToString(output); - } - - get [Symbol.toStringTag]() { - return "TextDecoder"; - } - } - - class TextEncoder { - encoding = "utf-8"; - encode(input = "") { - // Deno.core.encode() provides very efficient utf-8 encoding - if (this.encoding === "utf-8") { - return core.encode(input); - } - - const encoder = new UTF8Encoder(); - const inputStream = new Stream(stringToCodePoints(input)); - const output = []; - - while (true) { - const result = encoder.handler(inputStream.read()); - if (result === "finished") { - break; - } - output.push(...result); - } - - return new Uint8Array(output); - } - encodeInto(input, dest) { - const encoder = new UTF8Encoder(); - const inputStream = new Stream(stringToCodePoints(input)); - - let written = 0; - let read = 0; - while (true) { - const result = encoder.handler(inputStream.read()); - if (result === "finished") { - break; - } - if (dest.length - written >= result.length) { - read++; - dest.set(result, written); - written += result.length; - if (result.length > 3) { - // increment read a second time if greater than U+FFFF - read++; - } - } else { - break; - } - } - - return { - read, - written, - }; - } - get [Symbol.toStringTag]() { - return "TextEncoder"; - } - } - - // This function is based on Bjoern Hoehrmann's DFA UTF-8 decoder. - // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. - // - // Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - // SOFTWARE. - function decodeUtf8( - input, - fatal, - ignoreBOM, - ) { - let outString = ""; - - // Prepare a buffer so that we don't have to do a lot of string concats, which - // are very slow. - const outBufferLength = Math.min(1024, input.length); - const outBuffer = new Uint16Array(outBufferLength); - let outIndex = 0; - - let state = 0; - let codepoint = 0; - let type; - - let i = - ignoreBOM && input[0] === 0xef && input[1] === 0xbb && input[2] === 0xbf - ? 3 - : 0; - - for (; i < input.length; ++i) { - // Encoding error handling - if (state === 12 || (state !== 0 && (input[i] & 0xc0) !== 0x80)) { - if (fatal) { - throw new TypeError( - `Decoder error. Invalid byte in sequence at position ${i} in data.`, - ); - } - outBuffer[outIndex++] = 0xfffd; // Replacement character - if (outIndex === outBufferLength) { - outString += String.fromCharCode.apply(null, outBuffer); - outIndex = 0; - } - state = 0; - } - - // deno-fmt-ignore - type = [ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8 - ][input[i]]; - codepoint = state !== 0 - ? (input[i] & 0x3f) | (codepoint << 6) - : (0xff >> type) & input[i]; - // deno-fmt-ignore - state = [ - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12 - ][state + type]; - - if (state !== 0) continue; - - // Add codepoint to buffer (as charcodes for utf-16), and flush buffer to - // string if needed. - if (codepoint > 0xffff) { - outBuffer[outIndex++] = 0xd7c0 + (codepoint >> 10); - if (outIndex === outBufferLength) { - outString += String.fromCharCode.apply(null, outBuffer); - outIndex = 0; - } - outBuffer[outIndex++] = 0xdc00 | (codepoint & 0x3ff); - if (outIndex === outBufferLength) { - outString += String.fromCharCode.apply(null, outBuffer); - outIndex = 0; - } - } else { - outBuffer[outIndex++] = codepoint; - if (outIndex === outBufferLength) { - outString += String.fromCharCode.apply(null, outBuffer); - outIndex = 0; - } - } - } - - // Add a replacement character if we ended in the middle of a sequence or - // encountered an invalid code at the end. - if (state !== 0) { - if (fatal) throw new TypeError(`Decoder error. Unexpected end of data.`); - outBuffer[outIndex++] = 0xfffd; // Replacement character - } - - // Final flush of buffer - outString += String.fromCharCode.apply( - null, - outBuffer.subarray(0, outIndex), - ); - - return outString; - } - - window.TextEncoder = TextEncoder; - window.TextDecoder = TextDecoder; - window.atob = atob; - window.btoa = btoa; -})(this); diff --git a/cli/tests/performance_stats.out b/cli/tests/performance_stats.out index 9fea7715a..c623d81da 100644 --- a/cli/tests/performance_stats.out +++ b/cli/tests/performance_stats.out @@ -1,5 +1,5 @@ [WILDCARD] -Files: 43 +Files: 44 Nodes: [WILDCARD] Identifiers: [WILDCARD] Symbols: [WILDCARD] diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js index b8673b790..41051f2e0 100644 --- a/cli/tsc/99_main_compiler.js +++ b/cli/tsc/99_main_compiler.js @@ -776,6 +776,7 @@ delete Object.prototype.__proto__; // as these are internal APIs of TypeScript which maintain valid libs ts.libs.push("deno.ns", "deno.window", "deno.worker", "deno.shared_globals"); ts.libMap.set("deno.ns", "lib.deno.ns.d.ts"); + ts.libMap.set("deno.web", "lib.deno.web.d.ts"); ts.libMap.set("deno.window", "lib.deno.window.d.ts"); ts.libMap.set("deno.worker", "lib.deno.worker.d.ts"); ts.libMap.set("deno.shared_globals", "lib.deno.shared_globals.d.ts"); @@ -788,6 +789,10 @@ delete Object.prototype.__proto__; ts.ScriptTarget.ESNext, ); SNAPSHOT_HOST.getSourceFile( + `${ASSETS}/lib.deno.web.d.ts`, + ts.ScriptTarget.ESNext, + ); + SNAPSHOT_HOST.getSourceFile( `${ASSETS}/lib.deno.window.d.ts`, ts.ScriptTarget.ESNext, ); |