##// END OF EJS Templates
bind event handler methods marked with `@on` before subscribing the event
cin -
r77:bc7556143fe5 v1.2.2 default
parent child
Show More
@@ -1,110 +1,110
1 import { AbstractConstructor, djbase, djclass } from "../declare";
1 import { AbstractConstructor, djbase, djclass } from "../declare";
2 import _WidgetBase = require("dijit/_WidgetBase");
2 import _WidgetBase = require("dijit/_WidgetBase");
3 import _AttachMixin = require("dijit/_AttachMixin");
3 import _AttachMixin = require("dijit/_AttachMixin");
4 import { Rendition, isNode, startupWidgets } from "./traits";
4 import { Rendition, isNode, startupWidgets } from "./traits";
5 import registry = require("dijit/registry");
5 import registry = require("dijit/registry");
6
6
7 // type Handle = dojo.Handle;
7 // type Handle = dojo.Handle;
8
8
9 export interface EventArgs {
9 export interface EventArgs {
10 bubbles?: boolean;
10 bubbles?: boolean;
11
11
12 cancelable?: boolean;
12 cancelable?: boolean;
13
13
14 composed?: boolean;
14 composed?: boolean;
15 }
15 }
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
19
20 /** This property is declared only for type inference to work, it is never assigned
20 /** This property is declared only for type inference to work, it is never assigned
21 * and should not be used.
21 * and should not be used.
22 */
22 */
23 readonly _eventMap: Events & GlobalEventHandlersEventMap;
23 readonly _eventMap: Events & GlobalEventHandlersEventMap;
24 }
24 }
25
25
26 type _super = {
26 type _super = {
27 startup(): void;
27 startup(): void;
28 }
28 }
29
29
30 @djclass
30 @djclass
31 export abstract class DjxWidgetBase<Attrs = {}, Events = {}> extends djbase<_super, _AttachMixin>(_WidgetBase, _AttachMixin) {
31 export abstract class DjxWidgetBase<Attrs = {}, Events = {}> extends djbase<_super, _AttachMixin>(_WidgetBase, _AttachMixin) {
32
32
33 /** The list of pairs of event and method names. When the widget is created all methods from
33 /** The list of pairs of event and method names. When the widget is created all methods from
34 * this list will be connected to corresponding events.
34 * this list will be connected to corresponding events.
35 */
35 */
36 _eventHandlers: Array<{
36 _eventHandlers: Array<{
37 eventName: string,
37 eventName: string,
38 handlerMethod: keyof any;
38 handlerMethod: keyof any;
39 }> = [];
39 }> = [];
40
40
41 buildRendering() {
41 buildRendering() {
42 this.domNode = this.render().getDomNode();
42 this.domNode = this.render().getDomNode();
43 super.buildRendering();
43 super.buildRendering();
44
44
45 // now we should get assigned data-dojo-attach-points
45 // now we should get assigned data-dojo-attach-points
46 // place the contents of the original srcNode to the containerNode
46 // place the contents of the original srcNode to the containerNode
47 const src = this.srcNodeRef;
47 const src = this.srcNodeRef;
48 const dest = this.containerNode;
48 const dest = this.containerNode;
49
49
50 // the donNode is constructed now we need to connect event handlers
50 // the donNode is constructed now we need to connect event handlers
51 this._connectEventHandlers();
51 this._connectEventHandlers();
52
52
53 if (src && dest) {
53 if (src && dest) {
54 while (src.firstChild)
54 while (src.firstChild)
55 dest.appendChild(src.firstChild);
55 dest.appendChild(src.firstChild);
56 }
56 }
57 }
57 }
58
58
59 abstract render(): Rendition<HTMLElement>;
59 abstract render(): Rendition<HTMLElement>;
60
60
61 private _connectEventHandlers() {
61 private _connectEventHandlers() {
62 this._eventHandlers.forEach(({eventName, handlerMethod}) => {
62 this._eventHandlers.forEach(({eventName, handlerMethod}) => {
63 const handler = this[handlerMethod as keyof this];
63 const handler = this[handlerMethod as keyof this];
64 if (typeof handler === "function")
64 if (typeof handler === "function")
65 this.on(eventName, handler);
65 this.on(eventName, handler.bind(this));
66 });
66 });
67 }
67 }
68
68
69 _processTemplateNode<T extends (Element | Node | _WidgetBase)>(
69 _processTemplateNode<T extends (Element | Node | _WidgetBase)>(
70 baseNode: T,
70 baseNode: T,
71 getAttrFunc: (baseNode: T, attr: string) => any,
71 getAttrFunc: (baseNode: T, attr: string) => any,
72 // tslint:disable-next-line: ban-types
72 // tslint:disable-next-line: ban-types
73 attachFunc: (node: T, type: string, func?: Function) => dojo.Handle
73 attachFunc: (node: T, type: string, func?: Function) => dojo.Handle
74 ): boolean {
74 ): boolean {
75 if (isNode(baseNode)) {
75 if (isNode(baseNode)) {
76 const w = registry.byNode(baseNode);
76 const w = registry.byNode(baseNode);
77 if (w) {
77 if (w) {
78 // from dijit/_WidgetsInTemplateMixin
78 // from dijit/_WidgetsInTemplateMixin
79 this._processTemplateNode(w,
79 this._processTemplateNode(w,
80 (n, p) => n.get(p as any), // callback to get a property of a widget
80 (n, p) => n.get(p as any), // callback to get a property of a widget
81 (widget, type, callback) => {
81 (widget, type, callback) => {
82 if (!callback)
82 if (!callback)
83 throw new Error("The callback must be specified");
83 throw new Error("The callback must be specified");
84
84
85 // callback to do data-dojo-attach-event to a widget
85 // callback to do data-dojo-attach-event to a widget
86 if (type in widget) {
86 if (type in widget) {
87 // back-compat, remove for 2.0
87 // back-compat, remove for 2.0
88 return widget.connect(widget, type, callback as EventListener);
88 return widget.connect(widget, type, callback as EventListener);
89 } else {
89 } else {
90 // 1.x may never hit this branch, but it's the default for 2.0
90 // 1.x may never hit this branch, but it's the default for 2.0
91 return widget.on(type, callback);
91 return widget.on(type, callback);
92 }
92 }
93
93
94 });
94 });
95 // don't process widgets internals
95 // don't process widgets internals
96 return false;
96 return false;
97 }
97 }
98 }
98 }
99 return super._processTemplateNode(baseNode, getAttrFunc, attachFunc);
99 return super._processTemplateNode(baseNode, getAttrFunc, attachFunc);
100 }
100 }
101
101
102 /** Starts current widget and all its supporting widgets (placed outside
102 /** Starts current widget and all its supporting widgets (placed outside
103 * `containerNode`) and child widgets (placed inside `containerNode`)
103 * `containerNode`) and child widgets (placed inside `containerNode`)
104 */
104 */
105 startup() {
105 startup() {
106 // startup supporting widgets
106 // startup supporting widgets
107 registry.findWidgets(this.domNode, this.containerNode).forEach(w => w.startup());
107 registry.findWidgets(this.domNode, this.containerNode).forEach(w => w.startup());
108 super.startup();
108 super.startup();
109 }
109 }
110 }
110 }
General Comments 0
You need to be logged in to leave comments. Login now