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