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