##// 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 plugins {
1 plugins {
2 id "org.implab.gradle-typescript" version "1.3.1"
2 id "org.implab.gradle-typescript" version "1.3.2"
3 id "ivy-publish"
3 id "ivy-publish"
4 }
4 }
5
5
6 typescript {
6 typescript {
7 compilerOptions {
7 compilerOptions {
8 lib = ["es5", "dom", "scripthost", "es2015.promise", "es2015.symbol", "es2015.iterable"]
8 lib = ["es5", "dom", "scripthost", "es2015.promise", "es2015.symbol", "es2015.iterable"]
9 //listFiles = true
9 //listFiles = true
10 declaration = true
10 declaration = true
11 strict = true
11 strict = true
12 types = []
12 types = []
13 module = "amd"
13 module = "amd"
14 it.target = "es5"
14 it.target = "es5"
15 experimentalDecorators = true
15 experimentalDecorators = true
16 jsx = "react"
16 jsx = "react"
17 jsxFactory = "createElement"
17 jsxFactory = "createElement"
18 moduleResolution = "node"
18 moduleResolution = "node"
19 // dojo-typings are sick
19 // dojo-typings are sick
20 skipLibCheck = true
20 skipLibCheck = true
21 // traceResolution = true
21 // traceResolution = true
22 // baseUrl = "./"
22 // baseUrl = "./"
23 // paths = [ "*": [ "$projectDir/src/typings/*" ] ]
23 // paths = [ "*": [ "$projectDir/src/typings/*" ] ]
24 // baseUrl = "$projectDir/src/typings"
24 // baseUrl = "$projectDir/src/typings"
25 // typeRoots = ["$projectDir/src/typings"]
25 // typeRoots = ["$projectDir/src/typings"]
26 }
26 }
27
27
28 tscCmd = "$projectDir/node_modules/.bin/tsc"
28 tscCmd = "$projectDir/node_modules/.bin/tsc"
29 tsLintCmd = "$projectDir/node_modules/.bin/tslint"
29 tsLintCmd = "$projectDir/node_modules/.bin/tslint"
30 esLintCmd = "$projectDir/node_modules/.bin/eslint"
30 esLintCmd = "$projectDir/node_modules/.bin/eslint"
31 }
31 }
32
32
33 configureTsMain {
33 configureTsMain {
34 compilerOptions {
34 compilerOptions {
35 types = ["requirejs", "dojo-typings"]
35 types = ["requirejs", "dojo-typings"]
36 }
36 }
37 }
37 }
38
38
39 npmPackMeta {
39 npmPackMeta {
40 meta {
40 meta {
41 name = "@$npmScope/$project.name"
41 name = "@$npmScope/$project.name"
42 }
42 }
43 }
43 }
44
44
45 task npmPackTypings(type: Copy) {
45 task npmPackTypings(type: Copy) {
46 dependsOn sources.main.output
46 dependsOn typings
47
47
48 npmPackContents.dependsOn it
48 npmPackContents.dependsOn it
49
49
50 from sources.main.output.typingsDir
50 from typescript.typingsDir
51 into npm.packageDir
51 into npm.packageDir
52 }
52 }
53
53
54 task printVersion {
54 task printVersion {
55 doLast {
55 doLast {
56 println "packageName: ${npmPackMeta.metadata.get().name}";
56 println "packageName: ${npmPackMeta.metadata.get().name}";
57 println "version: $version";
57 println "version: $version";
58 println "target: $typescript.compilerOptions.target";
58 println "target: $typescript.compilerOptions.target";
59 println "module: $typescript.compilerOptions.module";
59 println "module: $typescript.compilerOptions.module";
60 println "symbols: $symbols";
60 println "symbols: $symbols";
61 }
61 }
62 } No newline at end of file
62 }
@@ -1,17 +1,17
1 import inject = require("./inject");
1 import inject = require("./dom-inject");
2 import { id as mid} from "module";
2 import { id as mid} from "module";
3 import { TraceSource } from "@implab/core-amd/log/TraceSource";
3 import { TraceSource } from "@implab/core-amd/log/TraceSource";
4 const log = TraceSource.get(mid);
4 const log = TraceSource.get(mid);
5
5
6 const plugin = {
6 const plugin = {
7 load: async (id: string, require: Require, cb: (param: any) => void) => {
7 load: async (id: string, require: Require, cb: (param: any) => void) => {
8 const url = require.toUrl(id);
8 const url = require.toUrl(id);
9 try {
9 try {
10 await inject.injectStylesheet(url);
10 await inject.injectStylesheet(url);
11 cb({ url });
11 cb({ url });
12 } catch (e) {
12 } catch (e) {
13 log.error("CSS plugin failed to load {0} ({1}): {2}", id, url, e);
13 log.error("CSS plugin failed to load {0} ({1}): {2}", id, url, e);
14 }
14 }
15 }
15 }
16 };
16 };
17 export = plugin;
17 export = plugin;
@@ -1,33 +1,33
1 import { Constructor } from "@implab/core-amd/interfaces";
1 import { Constructor } from "@implab/core-amd/interfaces";
2 import { HtmlElementContext } from "./djx/HtmlElementContext";
2 import { HtmlElementContext } from "./tsx/HtmlElementContext";
3 import { WidgetContext } from "./djx/WidgetContext";
3 import { WidgetContext } from "./tsx/WidgetContext";
4 import { isWidgetConstructor, BuildContext } from "./djx/traits";
4 import { isWidgetConstructor, BuildContext } from "./tsx/traits";
5
5
6 export function createElement<T extends Constructor>(elementType: string | T, ...args: any[]): BuildContext {
6 export function createElement<T extends Constructor>(elementType: string | T, ...args: any[]): BuildContext {
7 if (typeof elementType === "string") {
7 if (typeof elementType === "string") {
8 const ctx = new HtmlElementContext(elementType);
8 const ctx = new HtmlElementContext(elementType);
9 if (args)
9 if (args)
10 args.forEach(x => ctx.visitNext(x));
10 args.forEach(x => ctx.visitNext(x));
11
11
12 return ctx;
12 return ctx;
13 } else if (isWidgetConstructor(elementType)) {
13 } else if (isWidgetConstructor(elementType)) {
14 const ctx = new WidgetContext(elementType);
14 const ctx = new WidgetContext(elementType);
15 if (args)
15 if (args)
16 args.forEach(x => ctx.visitNext(x));
16 args.forEach(x => ctx.visitNext(x));
17
17
18 return ctx;
18 return ctx;
19 } else {
19 } else {
20 throw new Error(`The element type '${elementType}' is unsupported`);
20 throw new Error(`The element type '${elementType}' is unsupported`);
21 }
21 }
22 }
22 }
23
23
24 export interface EventDetails<T = any> {
24 export interface EventDetails<T = any> {
25 detail: T;
25 detail: T;
26 }
26 }
27
27
28 export interface EventSelector {
28 export interface EventSelector {
29 selectorTarget: HTMLElement;
29 selectorTarget: HTMLElement;
30 target: HTMLElement;
30 target: HTMLElement;
31 }
31 }
32
32
33 export type DojoMouseEvent<T = any> = MouseEvent & EventSelector & EventDetails<T>;
33 export type DojoMouseEvent<T = any> = MouseEvent & EventSelector & EventDetails<T>;
@@ -1,16 +1,18
1 import { test } from "./TestTraits";
1 import { test } from "./TestTraits";
2 import { delay } from "@implab/core-amd/safe";
2 import { delay } from "@implab/core-amd/safe";
3 import { assert } from "chai";
3 import { assert } from "chai";
4 import "@implab/djx";
5 import css = require("@implab/djx/css!my,css");
4
6
5 test("simple", (ok, fail, log) => {
7 test("simple", (ok, fail, log) => {
6 setTimeout(() => {
8 setTimeout(() => {
7 // end should be called after the last assertion
9 // end should be called after the last assertion
8 ok("async assert");
10 ok("async assert");
9 }, 100);
11 }, 100);
10 });
12 });
11
13
12 test("simple", async log => {
14 test("simple", async log => {
13 await delay(0);
15 await delay(0);
14
16
15 assert.ok(true); // everything is fine
17 assert.ok(true); // everything is fine
16 });
18 });
@@ -1,11 +1,18
1 {
1 {
2 "extends": "../tsconfig",
2 "extends": "../tsconfig",
3 "compilerOptions": {
3 "compilerOptions": {
4 "baseUrl": ".",
4 "rootDir": "ts",
5 "rootDir": "ts",
5 "rootDirs": [
6 "rootDirs": [
6 "ts",
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 "types": ["requirejs"]
16 "types": ["requirejs"]
10 }
17 }
11 } No newline at end of file
18 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
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