##// END OF EJS Templates
added 'dom-inject' and 'css' modules
cin -
r6:5cc84d1fc7c0 default
parent child
Show More
@@ -0,0 +1,17
1 import inject = require("./inject");
2 import { id as mid} from "module";
3 import { TraceSource } from "@implab/core-amd/log/TraceSource";
4 const log = TraceSource.get(mid);
5
6 const plugin = {
7 load: async (id: string, require: Require, cb: (param: any) => void) => {
8 const url = require.toUrl(id);
9 try {
10 await inject.injectStylesheet(url);
11 cb({ url });
12 } catch (e) {
13 log.error("CSS plugin failed to load {0} ({1}): {2}", id, url, e);
14 }
15 }
16 };
17 export = plugin;
@@ -0,0 +1,95
1 import { id as mid } from "module";
2 import { TraceSource } from "@implab/core-amd/log/TraceSource";
3 import { MapOf } from "@implab/core-amd/interfaces";
4 import { mixin } from "@implab/core-amd/safe";
5
6 const trace = TraceSource.get(mid);
7
8
9 function on<T extends keyof HTMLElementEventMap>(node: HTMLElement, eventName: T, handler: (this: HTMLElement, ev: HTMLElementEventMap[T]) => any): () => void {
10 // Add an event listener to a DOM node
11 node.addEventListener(eventName, handler, false);
12
13 return () => node.removeEventListener(eventName, handler, false);
14 }
15
16 interface NodeLoadResult {
17 node: HTMLElement;
18 }
19
20 class DomInject {
21 injectionPoint = document.head;
22 injectBefore = document.head.firstChild;
23
24 _map: MapOf<Promise<NodeLoadResult>> = {};
25
26 _inject<T extends keyof HTMLElementTagNameMap>(name: T, attr: Partial<HTMLElementTagNameMap[T]>) {
27 const node = document.createElement(name);
28
29 return new Promise<NodeLoadResult>((ok, fail) => {
30
31 const cleanup = () => {
32 noerr();
33 noload();
34 };
35
36 const noload = on(node, "load", () => {
37 ok({ node });
38 cleanup();
39 });
40
41 const noerr = on(node, "error", e => {
42 fail({
43 erorr: e,
44 node
45 });
46 cleanup();
47 });
48
49 mixin(node, attr);
50
51 this.injectionPoint.insertBefore(node, this.injectBefore);
52 });
53 }
54
55 async injectScript(url: string) {
56 let d = this._map[url];
57 if (!d) {
58 trace.log("js {0}", url);
59 d = this._inject("script", {
60 type: "text/javascript",
61 charset: "utf-8",
62 src: url
63 });
64 this._map[url] = d;
65 }
66 try {
67 await d;
68 trace.log("done {0}", url);
69 } catch (e) {
70 trace.error("failed {0}: {1}", url, e);
71 }
72 }
73
74 async injectStylesheet(url: string) {
75 let d = this._map[url];
76 if (!d) {
77 trace.log("js {0}", url);
78 d = this._inject("link", {
79 type: "text/css",
80 rel: "stylesheet",
81 href: url
82 });
83 this._map[url] = d;
84 }
85 try {
86 await d;
87 trace.log("done {0}", url);
88 } catch (e) {
89 trace.error("failed {0}: {1}", url, e);
90 }
91 }
92 };
93
94 const instance = new DomInject();
95 export = instance; No newline at end of file
@@ -0,0 +1,33
1 import { Constructor } from "@implab/core-amd/interfaces";
2 import { HtmlElementContext } from "./djx/HtmlElementContext";
3 import { WidgetContext } from "./djx/WidgetContext";
4 import { isWidgetConstructor, BuildContext } from "./djx/traits";
5
6 export function createElement<T extends Constructor>(elementType: string | T, ...args: any[]): BuildContext {
7 if (typeof elementType === "string") {
8 const ctx = new HtmlElementContext(elementType);
9 if (args)
10 args.forEach(x => ctx.visitNext(x));
11
12 return ctx;
13 } else if (isWidgetConstructor(elementType)) {
14 const ctx = new WidgetContext(elementType);
15 if (args)
16 args.forEach(x => ctx.visitNext(x));
17
18 return ctx;
19 } else {
20 throw new Error(`The element type '${elementType}' is unsupported`);
21 }
22 }
23
24 export interface EventDetails<T = any> {
25 detail: T;
26 }
27
28 export interface EventSelector {
29 selectorTarget: HTMLElement;
30 target: HTMLElement;
31 }
32
33 export type DojoMouseEvent<T = any> = MouseEvent & EventSelector & EventDetails<T>;
@@ -45,7 +45,7 npmPackMeta {
45 task npmPackTypings(type: Copy) {
45 task npmPackTypings(type: Copy) {
46 dependsOn sources.main.output
46 dependsOn sources.main.output
47
47
48 npmPack.dependsOn it
48 npmPackContents.dependsOn it
49
49
50 from sources.main.output.typingsDir
50 from sources.main.output.typingsDir
51 into npm.packageDir
51 into npm.packageDir
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now