##// END OF EJS Templates
temp commit, working on @on() decorator
cin -
r72:3ef812269f4f default
parent child
Show More
@@ -23,9 +23,8
23 "@types/chai": "4.1.3",
23 "@types/chai": "4.1.3",
24 "@types/requirejs": "2.1.31",
24 "@types/requirejs": "2.1.31",
25 "@types/yaml": "1.2.0",
25 "@types/yaml": "1.2.0",
26 "chai": "4.2.0",
27 "dojo": "1.16.0",
26 "dojo": "1.16.0",
28 "@implab/dojo-typings": "/home/sergey/projects/implabjs-dojo-typings/dojo-typings/build/npm/package/implab-dojo-typings-v1.0.0-rc4.tgz",
27 "@implab/dojo-typings": "1.0.0",
29 "eslint": "6.8.0",
28 "eslint": "6.8.0",
30 "requirejs": "2.3.6",
29 "requirejs": "2.3.6",
31 "tslint": "^6.1.3",
30 "tslint": "^6.1.3",
@@ -16,6 +16,8 export interface EventArgs {
16
16
17 export interface DjxWidgetBase<Attrs = {}, Events extends { [name in keyof Events]: Event } = {}> extends
17 export interface DjxWidgetBase<Attrs = {}, Events extends { [name in keyof Events]: Event } = {}> extends
18 _WidgetBase<Events> {
18 _WidgetBase<Events> {
19
20 readonly _eventMap: Events & GlobalEventHandlersEventMap;
19 }
21 }
20
22
21 type _super = {
23 type _super = {
@@ -25,6 +27,11 type _super = {
25 @djclass
27 @djclass
26 export abstract class DjxWidgetBase<Attrs = {}, Events = {}> extends djbase<_super, _AttachMixin>(_WidgetBase, _AttachMixin) {
28 export abstract class DjxWidgetBase<Attrs = {}, Events = {}> extends djbase<_super, _AttachMixin>(_WidgetBase, _AttachMixin) {
27
29
30 _eventHandlers: Array<{
31 eventName: keyof Events,
32 handlerMethod: string;
33 }> = [];
34
28 buildRendering() {
35 buildRendering() {
29 this.domNode = this.render().getDomNode();
36 this.domNode = this.render().getDomNode();
30 super.buildRendering();
37 super.buildRendering();
@@ -42,6 +49,13 export abstract class DjxWidgetBase<Attr
42
49
43 abstract render(): Rendition<HTMLElement>;
50 abstract render(): Rendition<HTMLElement>;
44
51
52 private _connectEventHandlers() {
53 this._eventHandlers.forEach(({eventName, handlerMethod}) => {
54 if (typeof this[handlerMethod as keyof this] === "function")
55 this.on(eventName, this[handlerMethod] as Function);
56 });
57 }
58
45 _processTemplateNode<T extends (Element | Node | _WidgetBase)>(
59 _processTemplateNode<T extends (Element | Node | _WidgetBase)>(
46 baseNode: T,
60 baseNode: T,
47 getAttrFunc: (baseNode: T, attr: string) => any,
61 getAttrFunc: (baseNode: T, attr: string) => any,
@@ -5,6 +5,7 import registry = require("dijit/registr
5 import dom = require("dojo/dom-construct");
5 import dom = require("dojo/dom-construct");
6 import Stateful = require("dojo/Stateful");
6 import Stateful = require("dojo/Stateful");
7 import { FunctionRendition } from "./FunctionRendition";
7 import { FunctionRendition } from "./FunctionRendition";
8 import { DjxWidgetBase } from "./DjxWidgetBase";
8
9
9 type _WidgetBaseConstructor = typeof _WidgetBase;
10 type _WidgetBaseConstructor = typeof _WidgetBase;
10
11
@@ -16,7 +17,7 export interface Rendition<TNode extends
16 placeAt(refNode: string | Node, position?: DojoNodePosition): void;
17 placeAt(refNode: string | Node, position?: DojoNodePosition): void;
17 }
18 }
18
19
19 /**
20 /**
20 * @deprecated use Rendition
21 * @deprecated use Rendition
21 */
22 */
22 export type BuildContext<TNode extends Node = Node> = Rendition<TNode>;
23 export type BuildContext<TNode extends Node = Node> = Rendition<TNode>;
@@ -131,7 +132,7 export function emptyNode(target: Node)
131 /** This function starts all widgets inside the DOM node if the target is a node
132 /** This function starts all widgets inside the DOM node if the target is a node
132 * or starts widget itself if the target is the widget. If the specified node
133 * or starts widget itself if the target is the widget. If the specified node
133 * associated with the widget that widget will be started.
134 * associated with the widget that widget will be started.
134 *
135 *
135 * @param target DOM node to find and start widgets or the widget itself.
136 * @param target DOM node to find and start widgets or the widget itself.
136 */
137 */
137 export function startupWidgets(target: Node | _WidgetBase, skipNode?: Node) {
138 export function startupWidgets(target: Node | _WidgetBase, skipNode?: Node) {
@@ -144,7 +145,7 export function startupWidgets(target: N
144 registry.findWidgets(target, skipNode).forEach(x => x.startup());
145 registry.findWidgets(target, skipNode).forEach(x => x.startup());
145 }
146 }
146 } else {
147 } else {
147 if(target.startup)
148 if (target.startup)
148 target.startup();
149 target.startup();
149 }
150 }
150 }
151 }
@@ -163,11 +164,11 type CleanFn = (instance: IRemovable | I
163 * @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
164 * @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
164 * @returns Rendition which is created instantly
165 * @returns Rendition which is created instantly
165 */
166 */
166 export function watch<W extends _WidgetBase, K extends keyof W> (
167 export function watch<W extends _WidgetBase, K extends keyof W>(
167 target: W,
168 target: W,
168 prop: K,
169 prop: K,
169 render: (model: W[K]) => any,
170 render: (model: W[K]) => any,
170 cleanupOrOwner?: {own: CleanFn} | CleanFn
171 cleanupOrOwner?: { own: CleanFn } | CleanFn
171 ): Rendition;
172 ): Rendition;
172 /**
173 /**
173 * Observers the property and calls render callback each change.
174 * Observers the property and calls render callback each change.
@@ -182,13 +183,13 export function watch<T extends Stateful
182 target: T,
183 target: T,
183 prop: K,
184 prop: K,
184 render: (model: StatefulProps<T>[K]) => any,
185 render: (model: StatefulProps<T>[K]) => any,
185 cleanupOrOwner?: {own: CleanFn} | CleanFn
186 cleanupOrOwner?: { own: CleanFn } | CleanFn
186 ): Rendition;
187 ): Rendition;
187 export function watch<T extends Stateful, K extends keyof StatefulProps<T> & string>(
188 export function watch<T extends Stateful, K extends keyof StatefulProps<T> & string>(
188 target: T,
189 target: T,
189 prop: K,
190 prop: K,
190 render: (model: StatefulProps<T>[K]) => any,
191 render: (model: StatefulProps<T>[K]) => any,
191 cleanupOrOwner: {own: CleanFn} | CleanFn = () => {}
192 cleanupOrOwner: { own: CleanFn } | CleanFn = () => { }
192 ) {
193 ) {
193 let rendition = new FunctionRendition(() => render(target.get(prop)));
194 let rendition = new FunctionRendition(() => render(target.get(prop)));
194 const _own = cleanupOrOwner instanceof Function ? cleanupOrOwner : (x: IRemovable) => cleanupOrOwner.own(x)
195 const _own = cleanupOrOwner instanceof Function ? cleanupOrOwner : (x: IRemovable) => cleanupOrOwner.own(x)
@@ -202,3 +203,20 export function watch<T extends Stateful
202 }));
203 }));
203 return rendition;
204 return rendition;
204 }
205 }
206
207 export type WidgetEvents<W> = W extends DjxWidgetBase<any, infer EM> ? EM : never;
208
209 export type HandlerType<W, E extends keyof any> = W extends {
210 on(eventName: E, handler: infer H): any;
211 } ? H : never;
212
213 export const on = <E extends keyof any>(eventName: E) =>
214 <K extends keyof T,
215 T extends DjxWidgetBase
216 >(
217 target: T,
218 key: K,
219 descriptor: PropertyDescriptor
220 ): any => {
221 target.
222 };
@@ -2,6 +2,7 import { djbase, djclass, bind, prototyp
2
2
3 import { DjxWidgetBase } from "../tsx/DjxWidgetBase";
3 import { DjxWidgetBase } from "../tsx/DjxWidgetBase";
4 import { createElement } from "../tsx";
4 import { createElement } from "../tsx";
5 import { HandlerType, on, WidgetEvents } from "../tsx/traits";
5
6
6 interface MyWidgetAttrs {
7 interface MyWidgetAttrs {
7 title: string;
8 title: string;
@@ -40,11 +41,17 export class MyWidget extends djbase(Djx
40 </div>;
41 </div>;
41 }
42 }
42
43
44 postCreate() {
45 super.postCreate();
46
47 this.on("click", () => {});
48 }
49
43 _onSubmit(e: Event) {
50 _onSubmit(e: Event) {
44 }
51 }
45
52
46 _onIncClick(e: MouseEvent) {
53 _onIncClick(e: MouseEvent) {
47 this.set("counter", this.counter+1);
54 this.set("counter", this.counter + 1);
48
55
49 this.emit("count-inc", { bubbles: false });
56 this.emit("count-inc", { bubbles: false });
50 }
57 }
@@ -52,4 +59,15 export class MyWidget extends djbase(Djx
52 _onDecClick() {
59 _onDecClick() {
53 this.emit("count-dec", { bubbles: false, detail: this.counter });
60 this.emit("count-dec", { bubbles: false, detail: this.counter });
54 }
61 }
62
63 @on("count-inc")
64 _onCounterInc(evt: Event & { detail: number; }) {
65
66 }
55 }
67 }
68
69 declare const w: MyWidget;
70 w.on("click", () => {});
71
72 declare const ev: WidgetEvents<MyWidget>;
73 ev["count-inc"];
@@ -6,6 +6,7
6 "types": [],
6 "types": [],
7 "experimentalDecorators": true,
7 "experimentalDecorators": true,
8 "jsxFactory": "createElement",
8 "jsxFactory": "createElement",
9 "target": "ES5",
9 //"skipLibCheck": true,
10 //"skipLibCheck": true,
10 "jsx": "react",
11 "jsx": "react",
11 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
12 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
General Comments 0
You need to be logged in to leave comments. Login now