mirror of
https://github.com/denoland/deno.git
synced 2025-03-04 01:44:26 -05:00
Support window.onload (#2643)
This commit is contained in:
parent
bd6ebb32df
commit
9c45499864
14 changed files with 162 additions and 88 deletions
|
@ -14,6 +14,7 @@
|
||||||
"@typescript-eslint/array-type": ["error", "array-simple"],
|
"@typescript-eslint/array-type": ["error", "array-simple"],
|
||||||
"@typescript-eslint/explicit-member-accessibility": ["off"],
|
"@typescript-eslint/explicit-member-accessibility": ["off"],
|
||||||
"@typescript-eslint/no-non-null-assertion": ["off"],
|
"@typescript-eslint/no-non-null-assertion": ["off"],
|
||||||
|
"@typescript-eslint/no-use-before-define": ["off"],
|
||||||
"@typescript-eslint/no-parameter-properties": ["off"],
|
"@typescript-eslint/no-parameter-properties": ["off"],
|
||||||
"@typescript-eslint/no-unused-vars": [
|
"@typescript-eslint/no-unused-vars": [
|
||||||
"error",
|
"error",
|
||||||
|
|
|
@ -314,6 +314,7 @@ fn run_script(flags: DenoFlags, argv: Vec<String>) {
|
||||||
worker
|
worker
|
||||||
.execute_mod_async(&main_module, false)
|
.execute_mod_async(&main_module, false)
|
||||||
.and_then(move |()| {
|
.and_then(move |()| {
|
||||||
|
js_check(worker.execute("window.dispatchEvent(new Event('load'))"));
|
||||||
worker.then(|result| {
|
worker.then(|result| {
|
||||||
js_check(result);
|
js_check(result);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -71,11 +71,16 @@ export enum NodeType {
|
||||||
DOCUMENT_FRAGMENT_NODE = 11
|
DOCUMENT_FRAGMENT_NODE = 11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const eventTargetHost: unique symbol = Symbol();
|
||||||
|
export const eventTargetListeners: unique symbol = Symbol();
|
||||||
|
export const eventTargetMode: unique symbol = Symbol();
|
||||||
|
export const eventTargetNodeType: unique symbol = Symbol();
|
||||||
|
|
||||||
export interface EventTarget {
|
export interface EventTarget {
|
||||||
host: EventTarget | null;
|
[eventTargetHost]: EventTarget | null;
|
||||||
listeners: { [type in string]: EventListener[] };
|
[eventTargetListeners]: { [type in string]: EventListener[] };
|
||||||
mode: string;
|
[eventTargetMode]: string;
|
||||||
nodeType: NodeType;
|
[eventTargetNodeType]: NodeType;
|
||||||
addEventListener(
|
addEventListener(
|
||||||
type: string,
|
type: string,
|
||||||
callback: (event: Event) => void | null,
|
callback: (event: Event) => void | null,
|
||||||
|
|
|
@ -9,16 +9,18 @@ export function isNode(nodeImpl: domTypes.EventTarget | null): boolean {
|
||||||
export function isShadowRoot(nodeImpl: domTypes.EventTarget | null): boolean {
|
export function isShadowRoot(nodeImpl: domTypes.EventTarget | null): boolean {
|
||||||
return Boolean(
|
return Boolean(
|
||||||
nodeImpl &&
|
nodeImpl &&
|
||||||
nodeImpl.nodeType === domTypes.NodeType.DOCUMENT_FRAGMENT_NODE &&
|
nodeImpl[domTypes.eventTargetNodeType] ===
|
||||||
"host" in nodeImpl
|
domTypes.NodeType.DOCUMENT_FRAGMENT_NODE &&
|
||||||
|
nodeImpl[domTypes.eventTargetHost] != null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isSlotable(nodeImpl: domTypes.EventTarget | null): boolean {
|
export function isSlotable(nodeImpl: domTypes.EventTarget | null): boolean {
|
||||||
return Boolean(
|
return Boolean(
|
||||||
nodeImpl &&
|
nodeImpl &&
|
||||||
(nodeImpl.nodeType === domTypes.NodeType.ELEMENT_NODE ||
|
(nodeImpl[domTypes.eventTargetNodeType] ===
|
||||||
nodeImpl.nodeType === domTypes.NodeType.TEXT_NODE)
|
domTypes.NodeType.ELEMENT_NODE ||
|
||||||
|
nodeImpl[domTypes.eventTargetNodeType] === domTypes.NodeType.TEXT_NODE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ export function isShadowInclusiveAncestor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isShadowRoot(node)) {
|
if (isShadowRoot(node)) {
|
||||||
node = node && node.host;
|
node = node && node[domTypes.eventTargetHost];
|
||||||
} else {
|
} else {
|
||||||
node = null; // domSymbolTree.parent(node);
|
node = null; // domSymbolTree.parent(node);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +79,7 @@ export function retarget(
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = aRoot.host;
|
a = aRoot[domTypes.eventTargetHost];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,13 +98,19 @@ export class EventListener implements domTypes.EventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const eventTargetAssignedSlot: unique symbol = Symbol();
|
||||||
|
export const eventTargetHasActivationBehavior: unique symbol = Symbol();
|
||||||
|
|
||||||
export class EventTarget implements domTypes.EventTarget {
|
export class EventTarget implements domTypes.EventTarget {
|
||||||
public host: domTypes.EventTarget | null = null;
|
public [domTypes.eventTargetHost]: domTypes.EventTarget | null = null;
|
||||||
public listeners: { [type in string]: domTypes.EventListener[] } = {};
|
public [domTypes.eventTargetListeners]: {
|
||||||
public mode = "";
|
[type in string]: domTypes.EventListener[]
|
||||||
public nodeType: domTypes.NodeType = domTypes.NodeType.DOCUMENT_FRAGMENT_NODE;
|
} = {};
|
||||||
private _assignedSlot = false;
|
public [domTypes.eventTargetMode] = "";
|
||||||
private _hasActivationBehavior = false;
|
public [domTypes.eventTargetNodeType]: domTypes.NodeType =
|
||||||
|
domTypes.NodeType.DOCUMENT_FRAGMENT_NODE;
|
||||||
|
private [eventTargetAssignedSlot] = false;
|
||||||
|
private [eventTargetHasActivationBehavior] = false;
|
||||||
|
|
||||||
public addEventListener(
|
public addEventListener(
|
||||||
type: string,
|
type: string,
|
||||||
|
@ -112,7 +118,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
options?: domTypes.AddEventListenerOptions | boolean
|
options?: domTypes.AddEventListenerOptions | boolean
|
||||||
): void {
|
): void {
|
||||||
requiredArguments("EventTarget.addEventListener", arguments.length, 2);
|
requiredArguments("EventTarget.addEventListener", arguments.length, 2);
|
||||||
const normalizedOptions: domTypes.AddEventListenerOptions = this._normalizeAddEventHandlerOptions(
|
const normalizedOptions: domTypes.AddEventListenerOptions = eventTargetHelpers.normalizeAddEventHandlerOptions(
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -120,12 +126,14 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasOwnProperty(this.listeners, type)) {
|
const listeners = this[domTypes.eventTargetListeners];
|
||||||
this.listeners[type] = [];
|
|
||||||
|
if (!hasOwnProperty(listeners, type)) {
|
||||||
|
listeners[type] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.listeners[type].length; ++i) {
|
for (let i = 0; i < listeners[type].length; ++i) {
|
||||||
const listener = this.listeners[type][i];
|
const listener = listeners[type][i];
|
||||||
if (
|
if (
|
||||||
((typeof listener.options === "boolean" &&
|
((typeof listener.options === "boolean" &&
|
||||||
listener.options === normalizedOptions.capture) ||
|
listener.options === normalizedOptions.capture) ||
|
||||||
|
@ -137,7 +145,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listeners[type].push(new EventListener(callback, normalizedOptions));
|
listeners[type].push(new EventListener(callback, normalizedOptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeEventListener(
|
public removeEventListener(
|
||||||
|
@ -146,13 +154,14 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
options?: domTypes.EventListenerOptions | boolean
|
options?: domTypes.EventListenerOptions | boolean
|
||||||
): void {
|
): void {
|
||||||
requiredArguments("EventTarget.removeEventListener", arguments.length, 2);
|
requiredArguments("EventTarget.removeEventListener", arguments.length, 2);
|
||||||
if (hasOwnProperty(this.listeners, type) && callback !== null) {
|
const listeners = this[domTypes.eventTargetListeners];
|
||||||
this.listeners[type] = this.listeners[type].filter(
|
if (hasOwnProperty(listeners, type) && callback !== null) {
|
||||||
|
listeners[type] = listeners[type].filter(
|
||||||
(listener): boolean => listener.callback !== callback
|
(listener): boolean => listener.callback !== callback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizedOptions: domTypes.EventListenerOptions = this._normalizeEventHandlerOptions(
|
const normalizedOptions: domTypes.EventListenerOptions = eventTargetHelpers.normalizeEventHandlerOptions(
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -161,12 +170,12 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.listeners[type]) {
|
if (!listeners[type]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.listeners[type].length; ++i) {
|
for (let i = 0; i < listeners[type].length; ++i) {
|
||||||
const listener = this.listeners[type][i];
|
const listener = listeners[type][i];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
((typeof listener.options === "boolean" &&
|
((typeof listener.options === "boolean" &&
|
||||||
|
@ -175,7 +184,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
listener.options.capture === normalizedOptions.capture)) &&
|
listener.options.capture === normalizedOptions.capture)) &&
|
||||||
listener.callback === callback
|
listener.callback === callback
|
||||||
) {
|
) {
|
||||||
this.listeners[type].splice(i, 1);
|
listeners[type].splice(i, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +192,8 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
|
|
||||||
public dispatchEvent(event: domTypes.Event): boolean {
|
public dispatchEvent(event: domTypes.Event): boolean {
|
||||||
requiredArguments("EventTarget.dispatchEvent", arguments.length, 1);
|
requiredArguments("EventTarget.dispatchEvent", arguments.length, 1);
|
||||||
if (!hasOwnProperty(this.listeners, event.type)) {
|
const listeners = this[domTypes.eventTargetListeners];
|
||||||
|
if (!hasOwnProperty(listeners, event.type)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,15 +211,21 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._dispatch(event);
|
return eventTargetHelpers.dispatch(this, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get [Symbol.toStringTag](): string {
|
||||||
|
return "EventTarget";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventTargetHelpers = {
|
||||||
// https://dom.spec.whatwg.org/#concept-event-dispatch
|
// https://dom.spec.whatwg.org/#concept-event-dispatch
|
||||||
_dispatch(
|
dispatch(
|
||||||
|
targetImpl: EventTarget,
|
||||||
eventImpl: domTypes.Event,
|
eventImpl: domTypes.Event,
|
||||||
targetOverride?: domTypes.EventTarget
|
targetOverride?: domTypes.EventTarget
|
||||||
): boolean {
|
): boolean {
|
||||||
let targetImpl = this;
|
|
||||||
let clearTargets = false;
|
let clearTargets = false;
|
||||||
let activationTarget = null;
|
let activationTarget = null;
|
||||||
|
|
||||||
|
@ -224,7 +240,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
) {
|
) {
|
||||||
const touchTargets: domTypes.EventTarget[] = [];
|
const touchTargets: domTypes.EventTarget[] = [];
|
||||||
|
|
||||||
this._appendToEventPath(
|
eventTargetHelpers.appendToEventPath(
|
||||||
eventImpl,
|
eventImpl,
|
||||||
targetImpl,
|
targetImpl,
|
||||||
targetOverride,
|
targetOverride,
|
||||||
|
@ -235,13 +251,15 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
|
|
||||||
const isActivationEvent = eventImpl.type === "click";
|
const isActivationEvent = eventImpl.type === "click";
|
||||||
|
|
||||||
if (isActivationEvent && targetImpl._hasActivationBehavior) {
|
if (isActivationEvent && targetImpl[eventTargetHasActivationBehavior]) {
|
||||||
activationTarget = targetImpl;
|
activationTarget = targetImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
let slotInClosedTree = false;
|
let slotInClosedTree = false;
|
||||||
let slotable =
|
let slotable =
|
||||||
isSlotable(targetImpl) && targetImpl._assignedSlot ? targetImpl : null;
|
isSlotable(targetImpl) && targetImpl[eventTargetAssignedSlot]
|
||||||
|
? targetImpl
|
||||||
|
: null;
|
||||||
let parent = getEventTargetParent(targetImpl, eventImpl);
|
let parent = getEventTargetParent(targetImpl, eventImpl);
|
||||||
|
|
||||||
// Populate event path
|
// Populate event path
|
||||||
|
@ -254,7 +272,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
if (
|
if (
|
||||||
isShadowRoot(parentRoot) &&
|
isShadowRoot(parentRoot) &&
|
||||||
parentRoot &&
|
parentRoot &&
|
||||||
parentRoot.mode === "closed"
|
parentRoot[domTypes.eventTargetMode] === "closed"
|
||||||
) {
|
) {
|
||||||
slotInClosedTree = true;
|
slotInClosedTree = true;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +284,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
isNode(parent) &&
|
isNode(parent) &&
|
||||||
isShadowInclusiveAncestor(getRoot(targetImpl), parent)
|
isShadowInclusiveAncestor(getRoot(targetImpl), parent)
|
||||||
) {
|
) {
|
||||||
this._appendToEventPath(
|
eventTargetHelpers.appendToEventPath(
|
||||||
eventImpl,
|
eventImpl,
|
||||||
parent,
|
parent,
|
||||||
null,
|
null,
|
||||||
|
@ -282,12 +300,12 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
if (
|
if (
|
||||||
isActivationEvent &&
|
isActivationEvent &&
|
||||||
activationTarget === null &&
|
activationTarget === null &&
|
||||||
targetImpl._hasActivationBehavior
|
targetImpl[eventTargetHasActivationBehavior]
|
||||||
) {
|
) {
|
||||||
activationTarget = targetImpl;
|
activationTarget = targetImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._appendToEventPath(
|
eventTargetHelpers.appendToEventPath(
|
||||||
eventImpl,
|
eventImpl,
|
||||||
parent,
|
parent,
|
||||||
targetImpl,
|
targetImpl,
|
||||||
|
@ -328,7 +346,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
const tuple = eventImpl.path[i];
|
const tuple = eventImpl.path[i];
|
||||||
|
|
||||||
if (tuple.target === null) {
|
if (tuple.target === null) {
|
||||||
this._invokeEventListeners(tuple, eventImpl);
|
eventTargetHelpers.invokeEventListeners(targetImpl, tuple, eventImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +364,7 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
eventImpl.bubbles) ||
|
eventImpl.bubbles) ||
|
||||||
eventImpl.eventPhase === domTypes.EventPhase.AT_TARGET
|
eventImpl.eventPhase === domTypes.EventPhase.AT_TARGET
|
||||||
) {
|
) {
|
||||||
this._invokeEventListeners(tuple, eventImpl);
|
eventTargetHelpers.invokeEventListeners(targetImpl, tuple, eventImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,10 +390,11 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return !eventImpl.defaultPrevented;
|
return !eventImpl.defaultPrevented;
|
||||||
}
|
},
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-event-listener-invoke
|
// https://dom.spec.whatwg.org/#concept-event-listener-invoke
|
||||||
_invokeEventListeners(
|
invokeEventListeners(
|
||||||
|
targetImpl: EventTarget,
|
||||||
tuple: domTypes.EventPath,
|
tuple: domTypes.EventPath,
|
||||||
eventImpl: domTypes.Event
|
eventImpl: domTypes.Event
|
||||||
): void {
|
): void {
|
||||||
|
@ -396,11 +415,16 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
|
|
||||||
eventImpl.currentTarget = tuple.item;
|
eventImpl.currentTarget = tuple.item;
|
||||||
|
|
||||||
this._innerInvokeEventListeners(eventImpl, tuple.item.listeners);
|
eventTargetHelpers.innerInvokeEventListeners(
|
||||||
}
|
targetImpl,
|
||||||
|
eventImpl,
|
||||||
|
tuple.item[domTypes.eventTargetListeners]
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
|
// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
|
||||||
_innerInvokeEventListeners(
|
innerInvokeEventListeners(
|
||||||
|
targetImpl: EventTarget,
|
||||||
eventImpl: domTypes.Event,
|
eventImpl: domTypes.Event,
|
||||||
targetListeners: { [type in string]: domTypes.EventListener[] }
|
targetListeners: { [type in string]: domTypes.EventListener[] }
|
||||||
): boolean {
|
): boolean {
|
||||||
|
@ -471,9 +495,9 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
},
|
||||||
|
|
||||||
_normalizeAddEventHandlerOptions(
|
normalizeAddEventHandlerOptions(
|
||||||
options: boolean | domTypes.AddEventListenerOptions | undefined
|
options: boolean | domTypes.AddEventListenerOptions | undefined
|
||||||
): domTypes.AddEventListenerOptions {
|
): domTypes.AddEventListenerOptions {
|
||||||
if (typeof options === "boolean" || typeof options === "undefined") {
|
if (typeof options === "boolean" || typeof options === "undefined") {
|
||||||
|
@ -487,9 +511,9 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
} else {
|
} else {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
_normalizeEventHandlerOptions(
|
normalizeEventHandlerOptions(
|
||||||
options: boolean | domTypes.EventListenerOptions | undefined
|
options: boolean | domTypes.EventListenerOptions | undefined
|
||||||
): domTypes.EventListenerOptions {
|
): domTypes.EventListenerOptions {
|
||||||
if (typeof options === "boolean" || typeof options === "undefined") {
|
if (typeof options === "boolean" || typeof options === "undefined") {
|
||||||
|
@ -501,10 +525,10 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
} else {
|
} else {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-event-path-append
|
// https://dom.spec.whatwg.org/#concept-event-path-append
|
||||||
_appendToEventPath(
|
appendToEventPath(
|
||||||
eventImpl: domTypes.Event,
|
eventImpl: domTypes.Event,
|
||||||
target: domTypes.EventTarget,
|
target: domTypes.EventTarget,
|
||||||
targetOverride: domTypes.EventTarget | null,
|
targetOverride: domTypes.EventTarget | null,
|
||||||
|
@ -513,7 +537,8 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
slotInClosedTree: boolean
|
slotInClosedTree: boolean
|
||||||
): void {
|
): void {
|
||||||
const itemInShadowTree = isNode(target) && isShadowRoot(getRoot(target));
|
const itemInShadowTree = isNode(target) && isShadowRoot(getRoot(target));
|
||||||
const rootOfClosedTree = isShadowRoot(target) && target.mode === "closed";
|
const rootOfClosedTree =
|
||||||
|
isShadowRoot(target) && target[domTypes.eventTargetMode] === "closed";
|
||||||
|
|
||||||
eventImpl.path.push({
|
eventImpl.path.push({
|
||||||
item: target,
|
item: target,
|
||||||
|
@ -525,31 +550,11 @@ export class EventTarget implements domTypes.EventTarget {
|
||||||
slotInClosedTree
|
slotInClosedTree
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
get [Symbol.toStringTag](): string {
|
|
||||||
return "EventTarget";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Built-in objects providing `get` methods for our
|
/** Built-in objects providing `get` methods for our
|
||||||
* interceptable JavaScript operations.
|
* interceptable JavaScript operations.
|
||||||
*/
|
*/
|
||||||
Reflect.defineProperty(EventTarget.prototype, "host", {
|
|
||||||
enumerable: true,
|
|
||||||
writable: true
|
|
||||||
});
|
|
||||||
Reflect.defineProperty(EventTarget.prototype, "listeners", {
|
|
||||||
enumerable: true,
|
|
||||||
writable: true
|
|
||||||
});
|
|
||||||
Reflect.defineProperty(EventTarget.prototype, "mode", {
|
|
||||||
enumerable: true,
|
|
||||||
writable: true
|
|
||||||
});
|
|
||||||
Reflect.defineProperty(EventTarget.prototype, "nodeType", {
|
|
||||||
enumerable: true,
|
|
||||||
writable: true
|
|
||||||
});
|
|
||||||
Reflect.defineProperty(EventTarget.prototype, "addEventListener", {
|
Reflect.defineProperty(EventTarget.prototype, "addEventListener", {
|
||||||
enumerable: true
|
enumerable: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -69,6 +69,7 @@ window.console = console;
|
||||||
window.setTimeout = timers.setTimeout;
|
window.setTimeout = timers.setTimeout;
|
||||||
window.setInterval = timers.setInterval;
|
window.setInterval = timers.setInterval;
|
||||||
window.location = (undefined as unknown) as domTypes.Location;
|
window.location = (undefined as unknown) as domTypes.Location;
|
||||||
|
window.onload = undefined as undefined | Function;
|
||||||
// The following Crypto interface implementation is not up to par with the
|
// The following Crypto interface implementation is not up to par with the
|
||||||
// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
|
// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
|
||||||
// yet incorporate the SubtleCrypto interface as its "subtle" property.
|
// yet incorporate the SubtleCrypto interface as its "subtle" property.
|
||||||
|
@ -135,6 +136,28 @@ window.postMessage = workers.postMessage;
|
||||||
window.Worker = workers.WorkerImpl;
|
window.Worker = workers.WorkerImpl;
|
||||||
export type Worker = workers.Worker;
|
export type Worker = workers.Worker;
|
||||||
|
|
||||||
|
window[domTypes.eventTargetHost] = null;
|
||||||
|
window[domTypes.eventTargetListeners] = {};
|
||||||
|
window[domTypes.eventTargetMode] = "";
|
||||||
|
window[domTypes.eventTargetNodeType] = 0;
|
||||||
|
window[eventTarget.eventTargetAssignedSlot] = false;
|
||||||
|
window[eventTarget.eventTargetHasActivationBehavior] = false;
|
||||||
|
window.addEventListener = eventTarget.EventTarget.prototype.addEventListener;
|
||||||
|
window.dispatchEvent = eventTarget.EventTarget.prototype.dispatchEvent;
|
||||||
|
window.removeEventListener =
|
||||||
|
eventTarget.EventTarget.prototype.removeEventListener;
|
||||||
|
|
||||||
|
// Registers the handler for window.onload function.
|
||||||
|
window.addEventListener(
|
||||||
|
"load",
|
||||||
|
(e: domTypes.Event): void => {
|
||||||
|
const onload = window.onload;
|
||||||
|
if (typeof onload === "function") {
|
||||||
|
onload(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// below are interfaces that are available in TypeScript but
|
// below are interfaces that are available in TypeScript but
|
||||||
// have different signatures
|
// have different signatures
|
||||||
export interface ImportMeta {
|
export interface ImportMeta {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
// (0, eval) is indirect eval.
|
// (0, eval) is indirect eval.
|
||||||
// See the links below for details:
|
// See the links below for details:
|
||||||
// - https://stackoverflow.com/a/14120023
|
// - https://stackoverflow.com/a/14120023
|
||||||
|
|
7
tests/034_onload.out
Normal file
7
tests/034_onload.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
log from nest_imported script
|
||||||
|
log from imported script
|
||||||
|
log from main
|
||||||
|
got load event in onload function
|
||||||
|
got load event in event handler (nest_imported)
|
||||||
|
got load event in event handler (imported)
|
||||||
|
got load event in event handler (main)
|
2
tests/034_onload.test
Normal file
2
tests/034_onload.test
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
args: run --reload tests/034_onload/main.ts
|
||||||
|
output: tests/034_onload.out
|
8
tests/034_onload/imported.ts
Normal file
8
tests/034_onload/imported.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import "./nest_imported.ts";
|
||||||
|
window.addEventListener(
|
||||||
|
"load",
|
||||||
|
(e: Event): void => {
|
||||||
|
console.log(`got ${e.type} event in event handler (imported)`);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
console.log("log from imported script");
|
14
tests/034_onload/main.ts
Normal file
14
tests/034_onload/main.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import "./imported.ts";
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
"load",
|
||||||
|
(e: Event): void => {
|
||||||
|
console.log(`got ${e.type} event in event handler (main)`);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
window.onload = (e: Event): void => {
|
||||||
|
console.log(`got ${e.type} event in onload function`);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("log from main");
|
7
tests/034_onload/nest_imported.ts
Normal file
7
tests/034_onload/nest_imported.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
window.addEventListener(
|
||||||
|
"load",
|
||||||
|
(e: Event): void => {
|
||||||
|
console.log(`got ${e.type} event in event handler (nest_imported)`);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
console.log("log from nest_imported script");
|
1
tests/034_onload_imported.ts
Normal file
1
tests/034_onload_imported.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log("from imported script");
|
|
@ -425,7 +425,7 @@ $ deno run --allow-net=deno.land allow-net-whitelist-example.ts
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
async function main() {
|
window.onload = async function() {
|
||||||
// create subprocess
|
// create subprocess
|
||||||
const p = Deno.run({
|
const p = Deno.run({
|
||||||
args: ["echo", "hello"]
|
args: ["echo", "hello"]
|
||||||
|
@ -433,9 +433,7 @@ async function main() {
|
||||||
|
|
||||||
// await its completion
|
// await its completion
|
||||||
await p.status();
|
await p.status();
|
||||||
}
|
};
|
||||||
|
|
||||||
main();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it:
|
Run it:
|
||||||
|
@ -445,12 +443,17 @@ $ deno run --allow-run ./subprocess_simple.ts
|
||||||
hello
|
hello
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Here a function is assigned to `window.onload`. This function is called after
|
||||||
|
the main script is loaded. This is the same as
|
||||||
|
[onload](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload)
|
||||||
|
of the browsers, and it can be used as the main entrypoint.
|
||||||
|
|
||||||
By default when you use `Deno.run()` subprocess inherits `stdin`, `stdout` and
|
By default when you use `Deno.run()` subprocess inherits `stdin`, `stdout` and
|
||||||
`stderr` of parent process. If you want to communicate with started subprocess
|
`stderr` of parent process. If you want to communicate with started subprocess
|
||||||
you can use `"piped"` option.
|
you can use `"piped"` option.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
async function main() {
|
window.onload = async function() {
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
|
|
||||||
const fileNames = Deno.args.slice(1);
|
const fileNames = Deno.args.slice(1);
|
||||||
|
@ -479,9 +482,7 @@ async function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Deno.exit(code);
|
Deno.exit(code);
|
||||||
}
|
};
|
||||||
|
|
||||||
main();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
When you run it:
|
When you run it:
|
||||||
|
@ -833,14 +834,12 @@ Example:
|
||||||
|
|
||||||
import { serve } from "http/server.ts";
|
import { serve } from "http/server.ts";
|
||||||
|
|
||||||
async function main() {
|
window.onload = async function() {
|
||||||
const body = new TextEncoder().encode("Hello World\n");
|
const body = new TextEncoder().encode("Hello World\n");
|
||||||
for await (const req of serve(":8000")) {
|
for await (const req of serve(":8000")) {
|
||||||
req.respond({ body });
|
req.respond({ body });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
main();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
Loading…
Add table
Reference in a new issue