##// END OF EJS Templates
sync
cin -
r7:d14fb562b896 default
parent child
Show More
@@ -0,0 +1,64
1 import { isNull, mixin, argumentNotNull } from "@implab/core-amd/safe";
2 import { isPlainObject, isNode, isBuildContext } from "./traits";
3
4 export abstract class BuildContextBase {
5 _attrs = {};
6
7 _children = new Array();
8
9 _created: boolean = false;
10
11 visitNext(v: any) {
12 if (isNull(v))
13 return;
14
15 if (isPlainObject(v)) {
16
17 if (this._created)
18 this._setAttrs(v);
19 else
20 mixin(this._attrs, v);
21
22 } else {
23 if (this._created)
24 this._addChild(v);
25 else
26 this._children.push(v);
27 }
28 }
29
30 getChildDom(v: any) {
31 const tv = typeof v;
32 if (tv === "string" || tv === "number" || tv === "boolean" || v instanceof RegExp || v instanceof Date) {
33 return document.createTextNode(v.toString());
34 } else if (isNode(v)) {
35 return v;
36 } else if (isBuildContext(v)) {
37 return v.getDomElement();
38 } else {
39 throw new Error("Invalid parameter");
40 }
41 }
42
43 abstract _getDomElement(): HTMLElement;
44
45 ensureCreated() {
46 if (!this._created) {
47 this._create(this._attrs, this._children);
48 this._children = [];
49 this._attrs = {};
50 this._created = true;
51 }
52 }
53
54 getDomElement() {
55 this.ensureCreated();
56 return this._getDomElement();
57 }
58
59 abstract _addChild(child: any): void;
60
61 abstract _setAttrs(attrs: object): void;
62
63 abstract _create(attrs: object, children: any[]): void;
64 }
@@ -0,0 +1,51
1 import { djbase, djclass } from "../declare";
2 import _WidgetBase = require("dijit/_WidgetBase");
3 import _AttachMixin = require("dijit/_AttachMixin");
4 import { BuildContext, isNode } from "./traits";
5 import registry = require("dijit/registry");
6 // import { Handle } from "dojo/interfaces";
7 type Handle = dojo.Handle;
8
9 @djclass
10 export abstract class DjxWidgetBase extends djbase(_WidgetBase, _AttachMixin) {
11
12 buildRendering() {
13 this.domNode = this.render().getDomElement();
14 super.buildRendering();
15 }
16
17 abstract render(): BuildContext;
18
19 _processTemplateNode<T extends (Element | Node | _WidgetBase)>(
20 baseNode: T,
21 getAttrFunc: (baseNode: T, attr: string) => string,
22 // tslint:disable-next-line: ban-types
23 attachFunc: (node: T, type: string, func?: Function) => Handle
24 ): boolean {
25 if (isNode(baseNode)) {
26 const w = registry.byNode(baseNode);
27 if (w) {
28 // from dijit/_WidgetsInTemplateMixin
29 this._processTemplateNode(w,
30 (n, p) => n.get(p), // callback to get a property of a widget
31 (widget, type, callback) => {
32 if (!callback)
33 throw new Error("The callback must be specified");
34
35 // callback to do data-dojo-attach-event to a widget
36 if (type in widget) {
37 // back-compat, remove for 2.0
38 return widget.connect(widget, type, callback as EventListener);
39 } else {
40 // 1.x may never hit this branch, but it's the default for 2.0
41 return widget.on(type, callback);
42 }
43
44 });
45 // don't process widgets internals
46 return false;
47 }
48 }
49 return super._processTemplateNode(baseNode, getAttrFunc, attachFunc);
50 }
51 }
@@ -0,0 +1,45
1 import dom = require("dojo/dom-construct");
2 import attr = require("dojo/dom-attr");
3 import { argumentNotEmptyString } from "@implab/core-amd/safe";
4 import { BuildContextBase } from "./BuildContextBase";
5
6 export class HtmlElementContext extends BuildContextBase {
7 elementType: string;
8
9 _element: HTMLElement | undefined;
10
11 constructor(elementType: string) {
12 argumentNotEmptyString(elementType, "elementType");
13 super();
14
15 this.elementType = elementType;
16 }
17
18 _addChild(child: any): void {
19 if (!this._element)
20 throw new Error("The HTML element isn't created");
21 dom.place(this.getChildDom(child), this._element);
22 }
23
24 _setAttrs(attrs: object): void {
25 if (!this._element)
26 throw new Error("The HTML element isn't created");
27
28 attr.set(this._element, attrs);
29 }
30
31 _create(attrs: object, children: any[]) {
32 this._element = dom.create(this.elementType, attrs);
33
34 if (children)
35 children.forEach(v => this._addChild(v));
36 }
37
38 _getDomElement() {
39 if (!this._element)
40 throw new Error("The HTML element isn't created");
41
42 return this._element;
43 }
44
45 }
@@ -0,0 +1,43
1 import dom = require("dojo/dom-construct");
2 import { argumentNotNull } from "@implab/core-amd/safe";
3 import _WidgetBase = require("dijit/_WidgetBase");
4 import { BuildContextBase } from "./BuildContextBase";
5
6 type _WidgetBaseConstructor = typeof _WidgetBase;
7
8 export class WidgetContext extends BuildContextBase {
9 widgetClass: _WidgetBaseConstructor;
10
11 _instance: _WidgetBase | undefined;
12
13 constructor(widgetClass: _WidgetBaseConstructor) {
14 super();
15 argumentNotNull(widgetClass, "widgetClass");
16
17 this.widgetClass = widgetClass;
18 }
19
20 _addChild(child: any): void {
21 if (!this._instance || !this._instance.containerNode)
22 throw new Error("Widget doesn't support adding children");
23
24 dom.place(this.getChildDom(child), this._instance.containerNode);
25 }
26
27 _setAttrs(attrs: object): void {
28 this._instance?.set(attrs);
29 }
30
31 _create(attrs: object, children: any[]) {
32 this._instance = new this.widgetClass(this._attrs);
33 if (children)
34 children.forEach(x => this._addChild(x));
35 }
36
37 _getDomElement() {
38 if (!this._instance)
39 throw new Error("The instance of the widget isn't created");
40 return this._instance.domNode;
41 }
42
43 }
@@ -0,0 +1,32
1 import _WidgetBase = require("dijit/_WidgetBase");
2
3 type _WidgetBaseConstructor = typeof _WidgetBase;
4
5
6 export interface BuildContext {
7 getDomElement(): HTMLElement;
8 }
9
10 export function isNode(el: any): el is HTMLElement {
11 return el && el.nodeName && el.nodeType;
12 }
13
14 export function isWidget(v: any): v is _WidgetBase {
15 return v && "domNode" in v;
16 }
17
18 export function isBuildContext(v: any): v is BuildContext {
19 return typeof v === "object" && typeof v.getDomElement === "function";
20 }
21
22 export function isPlainObject(v: object) {
23 if (typeof v !== "object")
24 return false;
25
26 const vp = Object.getPrototypeOf(v);
27 return !vp || vp === Object.prototype;
28 }
29
30 export function isWidgetConstructor(v: any): v is _WidgetBaseConstructor {
31 return typeof v === "function" && v.prototype && "domNode" in v.prototype;
32 }
@@ -0,0 +1,4
1 declare module "@implab/djx/css!*" {
2 declare const result: { url: string };
3 export = result;
4 }
@@ -1,62 +1,62
1 1 plugins {
2 id "org.implab.gradle-typescript" version "1.3.1"
2 id "org.implab.gradle-typescript" version "1.3.2"
3 3 id "ivy-publish"
4 4 }
5 5
6 6 typescript {
7 7 compilerOptions {
8 8 lib = ["es5", "dom", "scripthost", "es2015.promise", "es2015.symbol", "es2015.iterable"]
9 9 //listFiles = true
10 10 declaration = true
11 11 strict = true
12 12 types = []
13 13 module = "amd"
14 14 it.target = "es5"
15 15 experimentalDecorators = true
16 16 jsx = "react"
17 17 jsxFactory = "createElement"
18 18 moduleResolution = "node"
19 19 // dojo-typings are sick
20 20 skipLibCheck = true
21 21 // traceResolution = true
22 22 // baseUrl = "./"
23 23 // paths = [ "*": [ "$projectDir/src/typings/*" ] ]
24 24 // baseUrl = "$projectDir/src/typings"
25 25 // typeRoots = ["$projectDir/src/typings"]
26 26 }
27 27
28 28 tscCmd = "$projectDir/node_modules/.bin/tsc"
29 29 tsLintCmd = "$projectDir/node_modules/.bin/tslint"
30 30 esLintCmd = "$projectDir/node_modules/.bin/eslint"
31 31 }
32 32
33 33 configureTsMain {
34 34 compilerOptions {
35 35 types = ["requirejs", "dojo-typings"]
36 36 }
37 37 }
38 38
39 39 npmPackMeta {
40 40 meta {
41 41 name = "@$npmScope/$project.name"
42 42 }
43 43 }
44 44
45 45 task npmPackTypings(type: Copy) {
46 dependsOn sources.main.output
46 dependsOn typings
47 47
48 48 npmPackContents.dependsOn it
49 49
50 from sources.main.output.typingsDir
50 from typescript.typingsDir
51 51 into npm.packageDir
52 52 }
53 53
54 54 task printVersion {
55 55 doLast {
56 56 println "packageName: ${npmPackMeta.metadata.get().name}";
57 57 println "version: $version";
58 58 println "target: $typescript.compilerOptions.target";
59 59 println "module: $typescript.compilerOptions.module";
60 60 println "symbols: $symbols";
61 61 }
62 62 } No newline at end of file
@@ -1,17 +1,17
1 import inject = require("./inject");
1 import inject = require("./dom-inject");
2 2 import { id as mid} from "module";
3 3 import { TraceSource } from "@implab/core-amd/log/TraceSource";
4 4 const log = TraceSource.get(mid);
5 5
6 6 const plugin = {
7 7 load: async (id: string, require: Require, cb: (param: any) => void) => {
8 8 const url = require.toUrl(id);
9 9 try {
10 10 await inject.injectStylesheet(url);
11 11 cb({ url });
12 12 } catch (e) {
13 13 log.error("CSS plugin failed to load {0} ({1}): {2}", id, url, e);
14 14 }
15 15 }
16 16 };
17 17 export = plugin;
@@ -1,33 +1,33
1 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";
2 import { HtmlElementContext } from "./tsx/HtmlElementContext";
3 import { WidgetContext } from "./tsx/WidgetContext";
4 import { isWidgetConstructor, BuildContext } from "./tsx/traits";
5 5
6 6 export function createElement<T extends Constructor>(elementType: string | T, ...args: any[]): BuildContext {
7 7 if (typeof elementType === "string") {
8 8 const ctx = new HtmlElementContext(elementType);
9 9 if (args)
10 10 args.forEach(x => ctx.visitNext(x));
11 11
12 12 return ctx;
13 13 } else if (isWidgetConstructor(elementType)) {
14 14 const ctx = new WidgetContext(elementType);
15 15 if (args)
16 16 args.forEach(x => ctx.visitNext(x));
17 17
18 18 return ctx;
19 19 } else {
20 20 throw new Error(`The element type '${elementType}' is unsupported`);
21 21 }
22 22 }
23 23
24 24 export interface EventDetails<T = any> {
25 25 detail: T;
26 26 }
27 27
28 28 export interface EventSelector {
29 29 selectorTarget: HTMLElement;
30 30 target: HTMLElement;
31 31 }
32 32
33 33 export type DojoMouseEvent<T = any> = MouseEvent & EventSelector & EventDetails<T>;
@@ -1,16 +1,18
1 1 import { test } from "./TestTraits";
2 2 import { delay } from "@implab/core-amd/safe";
3 3 import { assert } from "chai";
4 import "@implab/djx";
5 import css = require("@implab/djx/css!my,css");
4 6
5 7 test("simple", (ok, fail, log) => {
6 8 setTimeout(() => {
7 9 // end should be called after the last assertion
8 10 ok("async assert");
9 11 }, 100);
10 12 });
11 13
12 14 test("simple", async log => {
13 15 await delay(0);
14 16
15 17 assert.ok(true); // everything is fine
16 18 });
@@ -1,11 +1,18
1 1 {
2 2 "extends": "../tsconfig",
3 3 "compilerOptions": {
4 "baseUrl": ".",
4 5 "rootDir": "ts",
5 6 "rootDirs": [
6 7 "ts",
7 "../main/ts"
8 "typings",
9 "../main/ts",
10 "../main/typings"
8 11 ],
12 "paths": {
13 "@implab/djx" : ["../main/ts", "../main/typings"]
14 //"@implab/djx/*" : ["../main/ts/*", "../main/typings/*" ]
15 },
9 16 "types": ["requirejs"]
10 17 }
11 18 } No newline at end of file
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now