##// END OF EJS Templates
corrected i18n, css modules to support requirejs optimizer...
corrected i18n, css modules to support requirejs optimizer i18n bundles now conforms js modules with default exports (breaking change!)

File last commit:

r52:0b9593714536 default
r53:deb0ed6fb680 v1.0.7 default
Show More
dom-inject.ts
100 lines | 2.7 KiB | video/mp2t | TypeScriptLexer
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);
function on<T extends keyof HTMLElementEventMap>(node: HTMLElement, eventName: T, handler: (this: HTMLElement, ev: HTMLElementEventMap[T]) => any): () => void {
// 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];
if (!d) {
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];
if (!d) {
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;
}
}
};
const instance = new DomInject();
export default instance;