INTRODUCTION ============ Development with MKWS consists primarily of defining new types of widgets. These can interact with the core functionality is several defined ways. You create a new widget type by calling the mkws.registerWidgetType function, passing in the widget name and a function. The name is used to recognise HTML elements as being widgets of this type -- for example, if you register a "Foo" widget, elements like
will be widgets of this type. The function promotes a bare widget object (passed as `this') into a widget of the appropriate type. MKWS doesn't use classes or explicit prototypes: it just makes objects that have the necessary behaviours. Widgets have *no* behaviours that they have to provide: you can make a doesn't-do-anything-at-all widget if you like: mkws.registerWidgetType('Sluggard', function() {}); More commonly, widgets will subscribe to one or more events, so that they're notified when something interesting happens. For example, the "Log" widget asks to be notified when a "log" event happens, and appends the logged message to its node, as follows: mkws.registerWidgetType('Log', function() { var that = this; this.team.queue("log").subscribe(function(teamName, timestamp, message) { $(that.node).append(teamName + ": " + timestamp + message + "
"); }); }); This simple widget illustrates several important points: * The base widget object (`this') has several baked-in properties and methods that are available to individual widgets. These include this.team (the team that this widget is a part of) and this.node (the DOM element of the widget). * The team object (`this.team') also has baked-in properties and methods. These include the queue function, which takes an event-name as its argument. It's possible to subscribe to an event's queue using this.team.queue("EVENT").subscribe. The argument is a function which is called whenever the event is published. The arguments to the function are different for different events. * The value of `this' is lost inside the subscribe callback, so it must be saved if it's to be used inside that callback (typically as a local variable named `that'). SPECIALISATION (INHERITANCE) ============================ Many widgets are simple specialisations of existing widgets. For example, the "Record" widget is the same as the "Records" widget except that it defaults to displaying a single record. It's defined as follows: mkws.registerWidgetType('Record', function() { mkws.promotionFunction('Records').call(this); if (!this.config.maxrecs) this.config.maxrecs = 1; }); Remember that when a promotion function is called, it's passed a base widget object that's not specialised for any particular task. To make a specialised widget, first promote that base widget into the type that you want to specialise from -- in this case, "Records" -- using the promotion function that's been registered for that type. Once this has been done, the specialisations can be introduced. In this case, it's a very matter of changing the "maxrecs" configuration setting to 1 unless it's already been given an explicit value. (That would occur if the HTML used an element like
, though it's not obvious why anyone would do that.