##// END OF EJS Templates
Corrected Scope.own() to cleanup the supplied object immediately when the scope is disposed already
Corrected Scope.own() to cleanup the supplied object immediately when the scope is disposed already

File last commit:

r109:4a375b9c654a default
r131:c7d9ad82b374 v1.8.1 default
Show More
dom-inject.ts
100 lines | 2.7 KiB | video/mp2t | TypeScriptLexer
/ djx / src / main / ts / dom-inject.ts
cin
Converted to subproject djx, removed dojo-typings
r65 import { id as mid } from "module";
import { TraceSource } from "@implab/core-amd/log/TraceSource";
import { MapOf } from "@implab/core-amd/interfaces";
import { mixin } from "@implab/core-amd/safe";
const trace = TraceSource.get(mid);
cin
linting
r109 function on<T extends keyof HTMLElementEventMap>(node: HTMLElement, eventName: T, handler: (this: HTMLElement, ev: HTMLElementEventMap[T]) => unknown): () => void {
cin
Converted to subproject djx, removed dojo-typings
r65 // Add an event listener to a DOM node
node.addEventListener(eventName, handler, false);
return () => node.removeEventListener(eventName, handler, false);
}
interface NodeLoadResult {
node: HTMLElement;
}
class DomInject {
injectionPoint?: HTMLElement;
injectAfter?: HTMLElement;
_map: MapOf<Promise<NodeLoadResult>> = {};
_inject<T extends keyof HTMLElementTagNameMap>(name: T, attr: Partial<HTMLElementTagNameMap[T]>) {
const node = document.createElement(name);
return new Promise<NodeLoadResult>((ok, fail) => {
const cleanup = () => {
noerr();
noload();
};
const noload = on(node, "load", () => {
ok({ node });
cleanup();
});
const noerr = on(node, "error", e => {
fail({
error: e,
node
});
cleanup();
});
mixin(node, attr);
const _injectionPoint = this.injectionPoint || document.head;
const _injectBefore = this.injectAfter ? this.injectAfter.nextSibling : null;
_injectionPoint.insertBefore(node, _injectBefore);
});
}
async injectScript(url: string) {
let d = this._map[url];
cin
linting
r109 if (d === undefined) {
cin
Converted to subproject djx, removed dojo-typings
r65 trace.log("js {0}", url);
d = this._inject("script", {
type: "text/javascript",
charset: "utf-8",
src: url
});
this._map[url] = d;
}
try {
await d;
trace.log("done {0}", url);
} catch (e) {
trace.error("failed {0}: {1}", url, e);
throw e;
}
}
async injectStylesheet(url: string) {
let d = this._map[url];
cin
linting
r109 if (d === undefined) {
cin
Converted to subproject djx, removed dojo-typings
r65 trace.log("js {0}", url);
d = this._inject("link", {
type: "text/css",
rel: "stylesheet",
href: url
});
this._map[url] = d;
}
try {
await d;
trace.log("done {0}", url);
} catch (e) {
trace.error("failed {0}: {1}", url, e);
throw e;
}
}
cin
fixed tslint errors, added support for private methods to @on() decorator
r79 }
cin
Converted to subproject djx, removed dojo-typings
r65
const instance = new DomInject();
export default instance;