##// END OF EJS Templates
fixes to css, nls to support requirejs optimizer
cin -
r36:a1a1ef050ecc 1.0.0-rc17 default
parent child
Show More
@@ -1,17 +1,18
1 import inject = require("./dom-inject");
2 import { id as mid} from "module";
3 import { TraceSource } from "@implab/core-amd/log/TraceSource";
4 const log = TraceSource.get(mid);
1 import inject from "./dom-inject";
2
3 interface OnLoad {
4 (result?: any): void;
5 error(err: any): void;
6 }
5 7
6 8 const plugin = {
7 load: async (id: string, require: Require, cb: (param: any) => void) => {
9 load: (id: string, require: Require, cb: OnLoad, config: { isBuild?: boolean }) => {
10 if (config.isBuild) {
11 cb();
12 } else {
8 13 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 inject.injectStylesheet(url).then(() => cb({ url }), e => cb.error(e));
14 15 }
15 16 }
16 17 };
17 18 export = plugin;
@@ -1,97 +1,100
1 1 import { id as mid } from "module";
2 2 import { TraceSource } from "@implab/core-amd/log/TraceSource";
3 3 import { MapOf } from "@implab/core-amd/interfaces";
4 4 import { mixin } from "@implab/core-amd/safe";
5 5
6 6 const trace = TraceSource.get(mid);
7 7
8 8
9 9 function on<T extends keyof HTMLElementEventMap>(node: HTMLElement, eventName: T, handler: (this: HTMLElement, ev: HTMLElementEventMap[T]) => any): () => void {
10 10 // Add an event listener to a DOM node
11 11 node.addEventListener(eventName, handler, false);
12 12
13 13 return () => node.removeEventListener(eventName, handler, false);
14 14 }
15 15
16 16 interface NodeLoadResult {
17 17 node: HTMLElement;
18 18 }
19 19
20 20 class DomInject {
21 injectionPoint = document.head;
22 injectBefore = document.head.firstChild;
21 injectionPoint?: HTMLElement;
22 injectBefore?: HTMLElement;
23 23
24 24 _map: MapOf<Promise<NodeLoadResult>> = {};
25 25
26 26 _inject<T extends keyof HTMLElementTagNameMap>(name: T, attr: Partial<HTMLElementTagNameMap[T]>) {
27 27 const node = document.createElement(name);
28 28
29 29 return new Promise<NodeLoadResult>((ok, fail) => {
30 30
31 31 const cleanup = () => {
32 32 noerr();
33 33 noload();
34 34 };
35 35
36 36 const noload = on(node, "load", () => {
37 37 ok({ node });
38 38 cleanup();
39 39 });
40 40
41 41 const noerr = on(node, "error", e => {
42 42 fail({
43 43 erorr: e,
44 44 node
45 45 });
46 46 cleanup();
47 47 });
48 48
49 49 mixin(node, attr);
50 50
51 this.injectionPoint.insertBefore(node, this.injectBefore);
51 const _injectionPoint = this.injectionPoint || document.head;
52 const _injectBefore = this.injectBefore || _injectionPoint.firstChild;
53
54 _injectionPoint.insertBefore(node, _injectBefore);
52 55 });
53 56 }
54 57
55 58 async injectScript(url: string) {
56 59 let d = this._map[url];
57 60 if (!d) {
58 61 trace.log("js {0}", url);
59 62 d = this._inject("script", {
60 63 type: "text/javascript",
61 64 charset: "utf-8",
62 65 src: url
63 66 });
64 67 this._map[url] = d;
65 68 }
66 69 try {
67 70 await d;
68 71 trace.log("done {0}", url);
69 72 } catch (e) {
70 73 trace.error("failed {0}: {1}", url, e);
71 74 throw e;
72 75 }
73 76 }
74 77
75 78 async injectStylesheet(url: string) {
76 79 let d = this._map[url];
77 80 if (!d) {
78 81 trace.log("js {0}", url);
79 82 d = this._inject("link", {
80 83 type: "text/css",
81 84 rel: "stylesheet",
82 85 href: url
83 86 });
84 87 this._map[url] = d;
85 88 }
86 89 try {
87 90 await d;
88 91 trace.log("done {0}", url);
89 92 } catch (e) {
90 93 trace.error("failed {0}: {1}", url, e);
91 94 throw e;
92 95 }
93 96 }
94 97 };
95 98
96 99 const instance = new DomInject();
97 export = instance; No newline at end of file
100 export default instance;
@@ -1,29 +1,38
1 1 import { MapOf } from "@implab/core-amd/interfaces";
2 2 import { NlsBundle } from "./NlsBundle";
3 3 import { isPromise } from "@implab/core-amd/safe";
4 4
5 interface OnLoad {
6 (result?: any): void;
7 error(err: any): void;
8 }
9
5 10 export function bundle<T extends object>(nls: T, locales?: MapOf<any>) {
6 11 const nlsBundle = new NlsBundle(nls, locales);
7 12
8 13 const fn = (locale?: string) => {
9 14 const result = locale ? nlsBundle.getLocale(locale) : nlsBundle.default;
10 15
11 16 if (isPromise(result))
12 17 throw new Error(`The bundle '${locale}' isn't loaded`);
13 18 else
14 19 return result;
15 20 };
16 21
17 22 fn.define = (pack: Partial<T>) => pack;
18 23 fn.default = nlsBundle.default;
19 fn.load = async (id: string, require: Require, cb: { (): void; error: (arg0: any) => void; }) => {
24 fn.load = async (id: string, require: Require, cb: OnLoad, config: any) => {
25 if (config.isBuild) {
26 cb();
27 } else {
20 28 try {
21 29 await nlsBundle.getLocale(id);
22 30 cb();
23 31 } catch (e) {
24 32 cb.error(e);
25 33 }
34 }
26 35 };
27 36
28 37 return fn;
29 38 }
General Comments 0
You need to be logged in to leave comments. Login now