diff options
Diffstat (limited to 'cli/rt')
-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 |
4 files changed, 0 insertions, 1902 deletions
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); |