From ec502803a60754e3b205fc723a9f1234a6db94c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Fri, 25 Oct 2013 14:32:23 +0200 Subject: [PATCH 01/11] Added definitions for Twitter Flight. --- flight/flight.d.ts | 139 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 flight/flight.d.ts diff --git a/flight/flight.d.ts b/flight/flight.d.ts new file mode 100644 index 000000000..fd0b7d944 --- /dev/null +++ b/flight/flight.d.ts @@ -0,0 +1,139 @@ +/// + +// Type definitions for Flight 1.1.1 +// Project: http://flightjs.github.com/flight/ +// Definitions by: Jonathan Hedrén +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + +interface FlightAdvice { + after(method: string, fn: Function); + around(method: string, fn: Function); + before(method: string, fn: Function); +} + +interface FlightComponent { + node: Element; + $node: JQuery; +} + +interface FlightBase extends FlightAdvice, FlightComponent { + + defaultAttrs(obj: Object); + + select(attr: string) + + initialize(); + + on(eventType: string, handler: Function); + on(selector: string, eventType: string, handler: Function); + on(selector: Document, eventType: string, handler: Function); + on(selector: Element, eventType: string, handler: Function); + on(selector: Element[], eventType: string, handler: Function); + on(selector: string, eventType: string, handler: Object); + on(selector: Document, eventType: string, handler: Object); + on(selector: Element, eventType: string, handler: Object); + on(selector: Element[], eventType: string, handler: Object); + + off(eventType: string, handler?: Function); + off(selector: string, eventType: string, handler?: Function); + off(selector: Document, eventType: string, handler?: Function); + off(selector: Element, eventType: string, handler?: Function); + off(selector: Element[], eventType: string, handler?: Function); + off(selector: string, eventType: Object, handler?: Function); + off(selector: Document, eventType: Object, handler?: Function); + off(selector: Element, eventType: Object, handler?: Function); + off(selector: Element[], eventType: Object, handler?: Function); + off(selector: string, eventType: string, handler?: Object); + off(selector: Document, eventType: string, handler?: Object); + off(selector: Element, eventType: string, handler?: Object); + off(selector: Element[], eventType: string, handler?: Object); + off(selector: string, eventType: Object, handler?: Object); + off(selector: Document, eventType: Object, handler?: Object); + off(selector: Element, eventType: Object, handler?: Object); + off(selector: Element[], eventType: Object, handler?: Object); + + trigger(eventType: string); + trigger(selector: string, eventType: string, eventPayload?: Object); + trigger(selector: Document, eventType: string, eventPayload?: Object); + trigger(selector: Element, eventType: string, eventPayload?: Object); + trigger(selector: Element[], eventType: string, eventPayload?: Object); + trigger(eventType: Object); + trigger(selector: string, eventType: Object, eventPayload?: Object); + trigger(selector: Document, eventType: Object, eventPayload?: Object); + trigger(selector: Element, eventType: Object, eventPayload?: Object); + trigger(selector: Element[], eventType: Object, eventPayload?: Object); + + teardown(); +} + +interface FlightAdviceStatic { + withAdvice(); +} + +interface FlightComponentStatic { + (...fns: Function[]): FlightComponentStatic; + attachTo(selector: string, options?: Object); + attachTo(selector: Element, options?: Object); + attachTo(selector: JQuery, options?: Object); + teardownAll(); +} + +interface FlightComposeStatic { + mixin(base: Object, mixins: Function[]): void; + unlockProperty(obj, prop, op); +} +interface FlightLogger { + +} + +interface FlightRegistryStatic { + addInstance(instance); + allInstances: Object; + components: Array; + events: Array; + findComponentInfo(which); + findInstanceInfo(instance); + findInstanceInfoByNode(node); + off(el, type, callback); + on(componentOn); + removeComponentInfo(componentInfo); + removeInstance(instance); + reset(); + teardown(); + trigger(); + withRegistration(); +} + +interface FlightUtilsStatic { + compose(fn1: Function, fn2: Function, ...fns: Function[]): Function; + countThen(num: number, base: Function): Function; + debounce(func: Function, wait: number, immediate: boolean): Function; + delegate(rules: Object); + isDomObj(obj): boolean; + isEnumerable(obj: Object, property): boolean; + merge(obj1: Object, obj2: Object, deepClone?: boolean): Object; + merge(obj1: Object, obj2:Object, ...args: any[]): Object; + push(base: Object, extra: Object, protect?: boolean); + throttle(func: Function, wait: number): Function; + toArray(obj: Object, from?: number): Array; + uniqueArray(array: Array): Array; +} + +interface FlightEventData { + el: HTMLElement; +} + +interface FlightStatic { + advice: FlightAdviceStatic; + component: FlightComponentStatic; + compose: FlightComposeStatic; + logger: FlightLogger; + registry: FlightRegistryStatic; + utils: FlightUtilsStatic; +} + +declare module "flight" { + export = flight; +} +declare var flight: FlightStatic; \ No newline at end of file From 4e41decaa4ed60b3d803d3d32e680db548d525aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Fri, 25 Oct 2013 14:41:26 +0200 Subject: [PATCH 02/11] Added entry in definition list. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3484db60d..0b7baf4b2 100755 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ List of Definitions * [Firebase](https://www.firebase.com/docs/javascript/firebase) (by [Vincent Bortone](https://github.com/vbortone)) * [Firefox](https://developer.mozilla.org/en-US/docs/Web/API) (by [vvakame](https://github.com/vvakame)) * [FlexSlider](http://www.woothemes.com/flexslider/) (by [Diullei Gomes](https://github.com/Diullei)) +* [Flight by Twitter](http://flightjs.github.com/flight/) (by [Jonathan Hedrén](https://github.com/jonathanhedren)) * [Foundation](http://foundation.zurb.com/) (by [Boris Yankov](https://github.com/borisyankov)) * [FPSMeter](http://darsa.in/fpsmeter/) (by [Aaron Lampros](https://github.com/alampros)) * [FullCalendar](http://arshaw.com/fullcalendar/) (by [Neil Stalker](https://github.com/nestalk)) From ead810ac06e17f8907e5babec62ec3d8110b3715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Fri, 25 Oct 2013 14:43:12 +0200 Subject: [PATCH 03/11] Added test file for Flight. --- flight/flight-tests.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 flight/flight-tests.ts diff --git a/flight/flight-tests.ts b/flight/flight-tests.ts new file mode 100644 index 000000000..66f33c7ab --- /dev/null +++ b/flight/flight-tests.ts @@ -0,0 +1 @@ +/// \ No newline at end of file From d667e467f7963be20217e32e4b5ca0ee84f700dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Fri, 25 Oct 2013 16:21:40 +0200 Subject: [PATCH 04/11] Started adding JSDoc (copied from Flight docs) --- flight/flight.d.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/flight/flight.d.ts b/flight/flight.d.ts index fd0b7d944..37b6d06a0 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -19,12 +19,50 @@ interface FlightComponent { interface FlightBase extends FlightAdvice, FlightComponent { + /** + * Most Components and Mixins need to define attributes. In Flight, + * default values are assigned by passing an object to the defaultAttrs + * function. + */ defaultAttrs(obj: Object); + /** + * The select method takes an attr key as its argument. The value of the + * attr must be a CSS Selector. The method will return all matching + * elements within the component's node. + * + * This is a handy alternative to jQuery's this.$node.find() and prevents + * accidental access to elements outside of the component's node. + * + * @param attr + */ select(attr: string) + /** + * This method is attached to the prototype of every Component; it accepts + * the component's node and an options object as arguments. The core + * implementation, which is called every time an instance is created, will + * assign the node to the instance and override the default attrs with the + * options object. + * + * Components and Mixins will typically augment the core implementation by + * supplying a function as an argument to the after method (see the advice + * API for more information). This is a good place to set up event + * listeners that bind to callbacks. + */ initialize(); + /** + * This allows a component instance to listen to an event and register a + * callback to be invoked. Flight will automatically bind the context + * (this) of the callback to the component instance. + * + * @param selector Optional. Specify the DOM node(s) that should listen for the event. Defaults to the component instance's node value. + * + * @param eventType The event type to listen for. + * + * @param handler Either a function (callback) to be invoked, or a map of targets and callbacks. + */ on(eventType: string, handler: Function); on(selector: string, eventType: string, handler: Function); on(selector: Document, eventType: string, handler: Function); From dcfdf8ca90f5f266451cdf63000f11ddcde6ac03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Mon, 28 Oct 2013 12:26:32 +0100 Subject: [PATCH 05/11] Updated jsdocs for FlightBase. --- flight/flight.d.ts | 117 ++++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 38 deletions(-) diff --git a/flight/flight.d.ts b/flight/flight.d.ts index 37b6d06a0..eca08f46a 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -19,50 +19,52 @@ interface FlightComponent { interface FlightBase extends FlightAdvice, FlightComponent { - /** - * Most Components and Mixins need to define attributes. In Flight, - * default values are assigned by passing an object to the defaultAttrs - * function. - */ + /** + * Most Components and Mixins need to define attributes. In Flight, + * default values are assigned by passing an object to the defaultAttrs + * function. + */ defaultAttrs(obj: Object); - /** - * The select method takes an attr key as its argument. The value of the - * attr must be a CSS Selector. The method will return all matching - * elements within the component's node. - * - * This is a handy alternative to jQuery's this.$node.find() and prevents - * accidental access to elements outside of the component's node. - * - * @param attr - */ + /** + * The select method takes an attr key as its argument. The value of the + * attr must be a CSS Selector. The method will return all matching + * elements within the component's node. + * + * This is a handy alternative to jQuery's this.$node.find() and prevents + * accidental access to elements outside of the component's node. + * + * @param attr + */ select(attr: string) - /** - * This method is attached to the prototype of every Component; it accepts - * the component's node and an options object as arguments. The core - * implementation, which is called every time an instance is created, will - * assign the node to the instance and override the default attrs with the - * options object. - * - * Components and Mixins will typically augment the core implementation by - * supplying a function as an argument to the after method (see the advice - * API for more information). This is a good place to set up event - * listeners that bind to callbacks. - */ + /** + * This method is attached to the prototype of every Component; it accepts + * the component's node and an options object as arguments. The core + * implementation, which is called every time an instance is created, will + * assign the node to the instance and override the default attrs with the + * options object. + * + * Components and Mixins will typically augment the core implementation by + * supplying a function as an argument to the after method (see the advice + * API for more information). This is a good place to set up event + * listeners that bind to callbacks. + */ initialize(); - /** - * This allows a component instance to listen to an event and register a - * callback to be invoked. Flight will automatically bind the context - * (this) of the callback to the component instance. - * - * @param selector Optional. Specify the DOM node(s) that should listen for the event. Defaults to the component instance's node value. - * - * @param eventType The event type to listen for. - * - * @param handler Either a function (callback) to be invoked, or a map of targets and callbacks. - */ + /** + * This allows a component instance to listen to an event and register a + * callback to be invoked. Flight will automatically bind the context + * (this) of the callback to the component instance. + * + * @param selector Optional. Specify the DOM node(s) that should listen + * for the event. Defaults to the component instance's node value. + * + * @param eventType The event type to listen for. + * + * @param handler Either a function (callback) to be invoked, or a map of + * targets and callbacks. + */ on(eventType: string, handler: Function); on(selector: string, eventType: string, handler: Function); on(selector: Document, eventType: string, handler: Function); @@ -73,6 +75,18 @@ interface FlightBase extends FlightAdvice, FlightComponent { on(selector: Element, eventType: string, handler: Object); on(selector: Element[], eventType: string, handler: Object); + /** + * If we no longer want a component instance to listen to an event we can + * use the off method to unsubscribe. + * + * @param selector Optional. The DOM node(s) listening for the event. + * Defaults to the component instance's node value. + * + * @param eventType The event type being listened to. + * + * @param handler Optional. The function (callback) to detach from the + * component instance. Defaults to the detaching all callbacks for the event. + */ off(eventType: string, handler?: Function); off(selector: string, eventType: string, handler?: Function); off(selector: Document, eventType: string, handler?: Function); @@ -91,6 +105,25 @@ interface FlightBase extends FlightAdvice, FlightComponent { off(selector: Element, eventType: Object, handler?: Object); off(selector: Element[], eventType: Object, handler?: Object); + /** + * Trigger an event. + * + * @param selector Optional. The DOM node(s) that the event will be + * dispatched to. Defaults to the component instance's node value. + * + * @param eventType String. The event type to be triggered. + * + * You can also specify a default function that will be called by the + * component, providing that nothing in the event's bubble chain invokes + * preventDefault. Default functions in custom events are analagous to the + * default actions of native events. + * + * To define a default function, make the eventType argument an object + * that specifies the event's type and a defaultBehavior property. A + * common use case is defining default behavior for keyboard events. + * + * @param eventPayload This is the payload of data that accompanies the event. + */ trigger(eventType: string); trigger(selector: string, eventType: string, eventPayload?: Object); trigger(selector: Document, eventType: string, eventPayload?: Object); @@ -102,6 +135,14 @@ interface FlightBase extends FlightAdvice, FlightComponent { trigger(selector: Element, eventType: Object, eventPayload?: Object); trigger(selector: Element[], eventType: Object, eventPayload?: Object); + /** + * Remove a component instance and its event bindings. + * + * It's a good idea to teardown components after each unit test - and + * teardown is also good for unbinding event listeners when, for example, + * the user navigates away from a page. + * + */ teardown(); } From 385f229aa9e7cb7dd63eca9fd2f4b224801328ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Mon, 28 Oct 2013 12:47:58 +0100 Subject: [PATCH 06/11] Added som tests. Updated definitions. --- flight/flight-tests.ts | 49 +++++++++++++++++++++++++++++++++++++++++- flight/flight.d.ts | 5 +++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/flight/flight-tests.ts b/flight/flight-tests.ts index 66f33c7ab..7b48eb93f 100644 --- a/flight/flight-tests.ts +++ b/flight/flight-tests.ts @@ -1 +1,48 @@ -/// \ No newline at end of file +/// +declare var el: Element; +declare var els: Element[]; +declare var mixinFn: Function; + +function TestComponent() { + var self: FlightBase = this; + + self.defaultAttrs({ + fooSelector: '.bar' + }); + + this.onClick = function (ev: JQueryEventObject, data) { + self.select('fooSelector').addClass('bar'); + }; + + self.around('initialize', function () { }); + self.before('initialize', function () { }); + self.after("initialize", function () { + + var $node: JQuery = self.$node; + var node: Element = self.node; + + self.on(el, 'click', {}); + self.on(els, 'click', function () { }); + self.on(document, 'click', this.onClick); + self.on('click', function () { }); + self.on('click', { + fooSelector: this.onClick + }); + + self.off('click', function () { }); + self.off(document, 'click'); + self.off(el, 'click') + self.off(els, 'click'); + + self.teardown(); + }); +} + +flight.component(TestComponent, mixinFn).attachTo(el); +flight.component(TestComponent, mixinFn).attachTo($(els)); +flight.component(TestComponent, mixinFn).attachTo('.test'); +flight.component(TestComponent, mixinFn).attachTo('.test', { + some: 'data' +}); + +flight.component.teardownAll(); diff --git a/flight/flight.d.ts b/flight/flight.d.ts index eca08f46a..1fa49113f 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -36,7 +36,7 @@ interface FlightBase extends FlightAdvice, FlightComponent { * * @param attr */ - select(attr: string) + select(attr: string): JQuery; /** * This method is attached to the prototype of every Component; it accepts @@ -50,7 +50,7 @@ interface FlightBase extends FlightAdvice, FlightComponent { * API for more information). This is a good place to set up event * listeners that bind to callbacks. */ - initialize(); + initialize(node, options: Object); /** * This allows a component instance to listen to an event and register a @@ -66,6 +66,7 @@ interface FlightBase extends FlightAdvice, FlightComponent { * targets and callbacks. */ on(eventType: string, handler: Function); + on(eventType: string, handler: Object); on(selector: string, eventType: string, handler: Function); on(selector: Document, eventType: string, handler: Function); on(selector: Element, eventType: string, handler: Function); From 364abd4f0f313f576ce41b94efffdf64591e0d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Mon, 28 Oct 2013 12:58:18 +0100 Subject: [PATCH 07/11] Wrapped interfaces in module. Updated tests. --- flight/flight-tests.ts | 5 +++-- flight/flight.d.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/flight/flight-tests.ts b/flight/flight-tests.ts index 7b48eb93f..69daaaad2 100644 --- a/flight/flight-tests.ts +++ b/flight/flight-tests.ts @@ -4,13 +4,14 @@ declare var els: Element[]; declare var mixinFn: Function; function TestComponent() { - var self: FlightBase = this; + var self: Flight.Base = this; self.defaultAttrs({ fooSelector: '.bar' }); - this.onClick = function (ev: JQueryEventObject, data) { + this.onClick = function (ev: JQueryEventObject, data: Flight.EventData) { + var el: HTMLElement = data.el; self.select('fooSelector').addClass('bar'); }; diff --git a/flight/flight.d.ts b/flight/flight.d.ts index 1fa49113f..25a005b4e 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -7,8 +7,41 @@ interface FlightAdvice { + /** + * Run the customFunc function after the existingFunc function. + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * customFunc The function to be invoked after existingFunc. + */ after(method: string, fn: Function); + + /** + * Run the existingFunc function in the middle of the customFunc function. + * It's similar to underscore's _wrap function). + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * customFunc The function to wrap around existingFunc. The existingFunc + * function will be passed to customFunc as an argument. + * + * The existing function is passed to the custom function as an argument so + * that it can be referenced. If the custom function does not call the + * existing function then it will replace that function instead of + * surrounding it. + */ around(method: string, fn: Function); + + /** + * Run the customFunc function before the existingFunc function. + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * @param customFunc The function to be invoked before existingFunc. + */ before(method: string, fn: Function); } From a00779b366badda32485a00a65678ce488437ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Mon, 28 Oct 2013 12:59:41 +0100 Subject: [PATCH 08/11] Wrapped interfaces in module. --- flight/flight.d.ts | 484 ++++++++++++++++++++++----------------------- 1 file changed, 242 insertions(+), 242 deletions(-) diff --git a/flight/flight.d.ts b/flight/flight.d.ts index 25a005b4e..9e742d62e 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -5,248 +5,248 @@ // Definitions by: Jonathan Hedrén // Definitions: https://github.com/borisyankov/DefinitelyTyped +declare module Flight { -interface FlightAdvice { - /** - * Run the customFunc function after the existingFunc function. - * - * @param existingFuncName The name of the existing function (existingFunc) - * you want to augment. - * - * customFunc The function to be invoked after existingFunc. - */ - after(method: string, fn: Function); - - /** - * Run the existingFunc function in the middle of the customFunc function. - * It's similar to underscore's _wrap function). - * - * @param existingFuncName The name of the existing function (existingFunc) - * you want to augment. - * - * customFunc The function to wrap around existingFunc. The existingFunc - * function will be passed to customFunc as an argument. - * - * The existing function is passed to the custom function as an argument so - * that it can be referenced. If the custom function does not call the - * existing function then it will replace that function instead of - * surrounding it. - */ - around(method: string, fn: Function); - - /** - * Run the customFunc function before the existingFunc function. - * - * @param existingFuncName The name of the existing function (existingFunc) - * you want to augment. - * - * @param customFunc The function to be invoked before existingFunc. - */ - before(method: string, fn: Function); + export interface Advice { + /** + * Run the customFunc function after the existingFunc function. + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * customFunc The function to be invoked after existingFunc. + */ + after(method: string, fn: Function); + + /** + * Run the existingFunc function in the middle of the customFunc function. + * It's similar to underscore's _wrap function). + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * customFunc The function to wrap around existingFunc. The existingFunc + * function will be passed to customFunc as an argument. + * + * The existing function is passed to the custom function as an argument so + * that it can be referenced. If the custom function does not call the + * existing function then it will replace that function instead of + * surrounding it. + */ + around(method: string, fn: Function); + + /** + * Run the customFunc function before the existingFunc function. + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * @param customFunc The function to be invoked before existingFunc. + */ + before(method: string, fn: Function); + } + + export interface Component { + node: Element; + $node: JQuery; + } + + export interface Base extends Advice, Component { + + /** + * Most Components and Mixins need to define attributes. In Flight, + * default values are assigned by passing an object to the defaultAttrs + * function. + */ + defaultAttrs(obj: Object); + + /** + * The select method takes an attr key as its argument. The value of the + * attr must be a CSS Selector. The method will return all matching + * elements within the component's node. + * + * This is a handy alternative to jQuery's this.$node.find() and prevents + * accidental access to elements outside of the component's node. + * + * @param attr + */ + select(attr: string): JQuery; + + /** + * This method is attached to the prototype of every Component; it accepts + * the component's node and an options object as arguments. The core + * implementation, which is called every time an instance is created, will + * assign the node to the instance and override the default attrs with the + * options object. + * + * Components and Mixins will typically augment the core implementation by + * supplying a function as an argument to the after method (see the advice + * API for more information). This is a good place to set up event + * listeners that bind to callbacks. + */ + initialize(node, options: Object); + + /** + * This allows a component instance to listen to an event and register a + * callback to be invoked. Flight will automatically bind the context + * (this) of the callback to the component instance. + * + * @param selector Optional. Specify the DOM node(s) that should listen + * for the event. Defaults to the component instance's node value. + * + * @param eventType The event type to listen for. + * + * @param handler Either a function (callback) to be invoked, or a map of + * targets and callbacks. + */ + on(eventType: string, handler: Function); + on(eventType: string, handler: Object); + on(selector: string, eventType: string, handler: Function); + on(selector: Document, eventType: string, handler: Function); + on(selector: Element, eventType: string, handler: Function); + on(selector: Element[], eventType: string, handler: Function); + on(selector: string, eventType: string, handler: Object); + on(selector: Document, eventType: string, handler: Object); + on(selector: Element, eventType: string, handler: Object); + on(selector: Element[], eventType: string, handler: Object); + + /** + * If we no longer want a component instance to listen to an event we can + * use the off method to unsubscribe. + * + * @param selector Optional. The DOM node(s) listening for the event. + * Defaults to the component instance's node value. + * + * @param eventType The event type being listened to. + * + * @param handler Optional. The function (callback) to detach from the + * component instance. Defaults to the detaching all callbacks for the event. + */ + off(eventType: string, handler?: Function); + off(selector: string, eventType: string, handler?: Function); + off(selector: Document, eventType: string, handler?: Function); + off(selector: Element, eventType: string, handler?: Function); + off(selector: Element[], eventType: string, handler?: Function); + off(selector: string, eventType: Object, handler?: Function); + off(selector: Document, eventType: Object, handler?: Function); + off(selector: Element, eventType: Object, handler?: Function); + off(selector: Element[], eventType: Object, handler?: Function); + off(selector: string, eventType: string, handler?: Object); + off(selector: Document, eventType: string, handler?: Object); + off(selector: Element, eventType: string, handler?: Object); + off(selector: Element[], eventType: string, handler?: Object); + off(selector: string, eventType: Object, handler?: Object); + off(selector: Document, eventType: Object, handler?: Object); + off(selector: Element, eventType: Object, handler?: Object); + off(selector: Element[], eventType: Object, handler?: Object); + + /** + * Trigger an event. + * + * @param selector Optional. The DOM node(s) that the event will be + * dispatched to. Defaults to the component instance's node value. + * + * @param eventType String. The event type to be triggered. + * + * You can also specify a default function that will be called by the + * component, providing that nothing in the event's bubble chain invokes + * preventDefault. Default functions in custom events are analagous to the + * default actions of native events. + * + * To define a default function, make the eventType argument an object + * that specifies the event's type and a defaultBehavior property. A + * common use case is defining default behavior for keyboard events. + * + * @param eventPayload This is the payload of data that accompanies the event. + */ + trigger(eventType: string); + trigger(selector: string, eventType: string, eventPayload?: Object); + trigger(selector: Document, eventType: string, eventPayload?: Object); + trigger(selector: Element, eventType: string, eventPayload?: Object); + trigger(selector: Element[], eventType: string, eventPayload?: Object); + trigger(eventType: Object); + trigger(selector: string, eventType: Object, eventPayload?: Object); + trigger(selector: Document, eventType: Object, eventPayload?: Object); + trigger(selector: Element, eventType: Object, eventPayload?: Object); + trigger(selector: Element[], eventType: Object, eventPayload?: Object); + + /** + * Remove a component instance and its event bindings. + * + * It's a good idea to teardown components after each unit test - and + * teardown is also good for unbinding event listeners when, for example, + * the user navigates away from a page. + * + */ + teardown(); + } + + export interface AdviceStatic { + withAdvice(); + } + + export interface ComponentStatic { + (...fns: Function[]): ComponentStatic; + attachTo(selector: string, options?: Object); + attachTo(selector: Element, options?: Object); + attachTo(selector: JQuery, options?: Object); + teardownAll(); + } + + export interface ComposeStatic { + mixin(base: Object, mixins: Function[]): void; + unlockProperty(obj, prop, op); + } + + export interface LoggerStatic { + + } + + export interface RegistryStatic { + addInstance(instance); + allInstances: Object; + components: Array; + events: Array; + findComponentInfo(which); + findInstanceInfo(instance); + findInstanceInfoByNode(node); + off(el, type, callback); + on(componentOn); + removeComponentInfo(componentInfo); + removeInstance(instance); + reset(); + teardown(); + trigger(); + withRegistration(); + } + + export interface UtilsStatic { + compose(fn1: Function, fn2: Function, ...fns: Function[]): Function; + countThen(num: number, base: Function): Function; + debounce(func: Function, wait: number, immediate: boolean): Function; + delegate(rules: Object); + isDomObj(obj): boolean; + isEnumerable(obj: Object, property): boolean; + merge(obj1: Object, obj2: Object, deepClone?: boolean): Object; + merge(obj1: Object, obj2: Object, ...args: any[]): Object; + push(base: Object, extra: Object, protect?: boolean); + throttle(func: Function, wait: number): Function; + toArray(obj: Object, from?: number): Array; + uniqueArray(array: Array): Array; + } + + export interface EventData { + el: HTMLElement; + } + + export interface FlightStatic { + advice: AdviceStatic; + component: ComponentStatic; + compose: ComposeStatic; + logger: LoggerStatic; + registry: RegistryStatic; + utils: UtilsStatic; + } } -interface FlightComponent { - node: Element; - $node: JQuery; -} - -interface FlightBase extends FlightAdvice, FlightComponent { - - /** - * Most Components and Mixins need to define attributes. In Flight, - * default values are assigned by passing an object to the defaultAttrs - * function. - */ - defaultAttrs(obj: Object); - - /** - * The select method takes an attr key as its argument. The value of the - * attr must be a CSS Selector. The method will return all matching - * elements within the component's node. - * - * This is a handy alternative to jQuery's this.$node.find() and prevents - * accidental access to elements outside of the component's node. - * - * @param attr - */ - select(attr: string): JQuery; - - /** - * This method is attached to the prototype of every Component; it accepts - * the component's node and an options object as arguments. The core - * implementation, which is called every time an instance is created, will - * assign the node to the instance and override the default attrs with the - * options object. - * - * Components and Mixins will typically augment the core implementation by - * supplying a function as an argument to the after method (see the advice - * API for more information). This is a good place to set up event - * listeners that bind to callbacks. - */ - initialize(node, options: Object); - - /** - * This allows a component instance to listen to an event and register a - * callback to be invoked. Flight will automatically bind the context - * (this) of the callback to the component instance. - * - * @param selector Optional. Specify the DOM node(s) that should listen - * for the event. Defaults to the component instance's node value. - * - * @param eventType The event type to listen for. - * - * @param handler Either a function (callback) to be invoked, or a map of - * targets and callbacks. - */ - on(eventType: string, handler: Function); - on(eventType: string, handler: Object); - on(selector: string, eventType: string, handler: Function); - on(selector: Document, eventType: string, handler: Function); - on(selector: Element, eventType: string, handler: Function); - on(selector: Element[], eventType: string, handler: Function); - on(selector: string, eventType: string, handler: Object); - on(selector: Document, eventType: string, handler: Object); - on(selector: Element, eventType: string, handler: Object); - on(selector: Element[], eventType: string, handler: Object); - - /** - * If we no longer want a component instance to listen to an event we can - * use the off method to unsubscribe. - * - * @param selector Optional. The DOM node(s) listening for the event. - * Defaults to the component instance's node value. - * - * @param eventType The event type being listened to. - * - * @param handler Optional. The function (callback) to detach from the - * component instance. Defaults to the detaching all callbacks for the event. - */ - off(eventType: string, handler?: Function); - off(selector: string, eventType: string, handler?: Function); - off(selector: Document, eventType: string, handler?: Function); - off(selector: Element, eventType: string, handler?: Function); - off(selector: Element[], eventType: string, handler?: Function); - off(selector: string, eventType: Object, handler?: Function); - off(selector: Document, eventType: Object, handler?: Function); - off(selector: Element, eventType: Object, handler?: Function); - off(selector: Element[], eventType: Object, handler?: Function); - off(selector: string, eventType: string, handler?: Object); - off(selector: Document, eventType: string, handler?: Object); - off(selector: Element, eventType: string, handler?: Object); - off(selector: Element[], eventType: string, handler?: Object); - off(selector: string, eventType: Object, handler?: Object); - off(selector: Document, eventType: Object, handler?: Object); - off(selector: Element, eventType: Object, handler?: Object); - off(selector: Element[], eventType: Object, handler?: Object); - - /** - * Trigger an event. - * - * @param selector Optional. The DOM node(s) that the event will be - * dispatched to. Defaults to the component instance's node value. - * - * @param eventType String. The event type to be triggered. - * - * You can also specify a default function that will be called by the - * component, providing that nothing in the event's bubble chain invokes - * preventDefault. Default functions in custom events are analagous to the - * default actions of native events. - * - * To define a default function, make the eventType argument an object - * that specifies the event's type and a defaultBehavior property. A - * common use case is defining default behavior for keyboard events. - * - * @param eventPayload This is the payload of data that accompanies the event. - */ - trigger(eventType: string); - trigger(selector: string, eventType: string, eventPayload?: Object); - trigger(selector: Document, eventType: string, eventPayload?: Object); - trigger(selector: Element, eventType: string, eventPayload?: Object); - trigger(selector: Element[], eventType: string, eventPayload?: Object); - trigger(eventType: Object); - trigger(selector: string, eventType: Object, eventPayload?: Object); - trigger(selector: Document, eventType: Object, eventPayload?: Object); - trigger(selector: Element, eventType: Object, eventPayload?: Object); - trigger(selector: Element[], eventType: Object, eventPayload?: Object); - - /** - * Remove a component instance and its event bindings. - * - * It's a good idea to teardown components after each unit test - and - * teardown is also good for unbinding event listeners when, for example, - * the user navigates away from a page. - * - */ - teardown(); -} - -interface FlightAdviceStatic { - withAdvice(); -} - -interface FlightComponentStatic { - (...fns: Function[]): FlightComponentStatic; - attachTo(selector: string, options?: Object); - attachTo(selector: Element, options?: Object); - attachTo(selector: JQuery, options?: Object); - teardownAll(); -} - -interface FlightComposeStatic { - mixin(base: Object, mixins: Function[]): void; - unlockProperty(obj, prop, op); -} -interface FlightLogger { - -} - -interface FlightRegistryStatic { - addInstance(instance); - allInstances: Object; - components: Array; - events: Array; - findComponentInfo(which); - findInstanceInfo(instance); - findInstanceInfoByNode(node); - off(el, type, callback); - on(componentOn); - removeComponentInfo(componentInfo); - removeInstance(instance); - reset(); - teardown(); - trigger(); - withRegistration(); -} - -interface FlightUtilsStatic { - compose(fn1: Function, fn2: Function, ...fns: Function[]): Function; - countThen(num: number, base: Function): Function; - debounce(func: Function, wait: number, immediate: boolean): Function; - delegate(rules: Object); - isDomObj(obj): boolean; - isEnumerable(obj: Object, property): boolean; - merge(obj1: Object, obj2: Object, deepClone?: boolean): Object; - merge(obj1: Object, obj2:Object, ...args: any[]): Object; - push(base: Object, extra: Object, protect?: boolean); - throttle(func: Function, wait: number): Function; - toArray(obj: Object, from?: number): Array; - uniqueArray(array: Array): Array; -} - -interface FlightEventData { - el: HTMLElement; -} - -interface FlightStatic { - advice: FlightAdviceStatic; - component: FlightComponentStatic; - compose: FlightComposeStatic; - logger: FlightLogger; - registry: FlightRegistryStatic; - utils: FlightUtilsStatic; -} - -declare module "flight" { - export = flight; -} -declare var flight: FlightStatic; \ No newline at end of file +declare var flight: Flight.FlightStatic; \ No newline at end of file From d9ac108ab6321d3bf8dedc025f1e81139ec6818e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Mon, 28 Oct 2013 14:01:55 +0100 Subject: [PATCH 09/11] Added DEBUG interface. Fixed Advice/Component/Base inheritance. --- flight/flight-tests.ts | 2 +- flight/flight.d.ts | 101 +++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/flight/flight-tests.ts b/flight/flight-tests.ts index 69daaaad2..5e7b69393 100644 --- a/flight/flight-tests.ts +++ b/flight/flight-tests.ts @@ -4,7 +4,7 @@ declare var els: Element[]; declare var mixinFn: Function; function TestComponent() { - var self: Flight.Base = this; + var self: Flight.Component = this; self.defaultAttrs({ fooSelector: '.bar' diff --git a/flight/flight.d.ts b/flight/flight.d.ts index 9e742d62e..18df3ec6c 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -7,51 +7,7 @@ declare module Flight { - export interface Advice { - /** - * Run the customFunc function after the existingFunc function. - * - * @param existingFuncName The name of the existing function (existingFunc) - * you want to augment. - * - * customFunc The function to be invoked after existingFunc. - */ - after(method: string, fn: Function); - - /** - * Run the existingFunc function in the middle of the customFunc function. - * It's similar to underscore's _wrap function). - * - * @param existingFuncName The name of the existing function (existingFunc) - * you want to augment. - * - * customFunc The function to wrap around existingFunc. The existingFunc - * function will be passed to customFunc as an argument. - * - * The existing function is passed to the custom function as an argument so - * that it can be referenced. If the custom function does not call the - * existing function then it will replace that function instead of - * surrounding it. - */ - around(method: string, fn: Function); - - /** - * Run the customFunc function before the existingFunc function. - * - * @param existingFuncName The name of the existing function (existingFunc) - * you want to augment. - * - * @param customFunc The function to be invoked before existingFunc. - */ - before(method: string, fn: Function); - } - - export interface Component { - node: Element; - $node: JQuery; - } - - export interface Base extends Advice, Component { + export interface Base { /** * Most Components and Mixins need to define attributes. In Flight, @@ -181,6 +137,51 @@ declare module Flight { teardown(); } + export interface Advice extends Base { + /** + * Run the customFunc function after the existingFunc function. + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * customFunc The function to be invoked after existingFunc. + */ + after(method: string, fn: Function); + + /** + * Run the existingFunc function in the middle of the customFunc function. + * It's similar to underscore's _wrap function). + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * customFunc The function to wrap around existingFunc. The existingFunc + * function will be passed to customFunc as an argument. + * + * The existing function is passed to the custom function as an argument so + * that it can be referenced. If the custom function does not call the + * existing function then it will replace that function instead of + * surrounding it. + */ + around(method: string, fn: Function); + + /** + * Run the customFunc function before the existingFunc function. + * + * @param existingFuncName The name of the existing function (existingFunc) + * you want to augment. + * + * @param customFunc The function to be invoked before existingFunc. + */ + before(method: string, fn: Function); + } + + export interface Component extends Base, Advice { + node: Element; + $node: JQuery; + } + + export interface AdviceStatic { withAdvice(); } @@ -198,6 +199,15 @@ declare module Flight { unlockProperty(obj, prop, op); } + export interface DebugStatic { + events: { + logAll(); + logByAction(action: string); + logByName(name: string); + logNone(); + } + } + export interface LoggerStatic { } @@ -249,4 +259,5 @@ declare module Flight { } } +declare var DEBUG: Flight.DebugStatic; declare var flight: Flight.FlightStatic; \ No newline at end of file From baa58a4eb5cc341702a4cd70d0960266eed7e561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Wed, 30 Oct 2013 11:37:31 +0100 Subject: [PATCH 10/11] Changed encoding to UTF-8. --- flight/flight-tests.ts | 2 +- flight/flight.d.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flight/flight-tests.ts b/flight/flight-tests.ts index 5e7b69393..1bfe68d3a 100644 --- a/flight/flight-tests.ts +++ b/flight/flight-tests.ts @@ -1,4 +1,4 @@ -/// +/// declare var el: Element; declare var els: Element[]; declare var mixinFn: Function; diff --git a/flight/flight.d.ts b/flight/flight.d.ts index 18df3ec6c..8a89b6aff 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -1,8 +1,8 @@ -/// +/// // Type definitions for Flight 1.1.1 // Project: http://flightjs.github.com/flight/ -// Definitions by: Jonathan Hedrén +// Definitions by: Jonathan Hedrén // Definitions: https://github.com/borisyankov/DefinitelyTyped declare module Flight { From 380837b23ce55a05389e543356f7149d7d8664f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Hedr=C3=A9n?= Date: Wed, 30 Oct 2013 12:26:11 +0100 Subject: [PATCH 11/11] Added missing return/argument types. Removed undocumented API:s. --- flight/flight.d.ts | 137 ++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 81 deletions(-) diff --git a/flight/flight.d.ts b/flight/flight.d.ts index 8a89b6aff..a00f6d958 100644 --- a/flight/flight.d.ts +++ b/flight/flight.d.ts @@ -14,7 +14,7 @@ declare module Flight { * default values are assigned by passing an object to the defaultAttrs * function. */ - defaultAttrs(obj: Object); + defaultAttrs(obj: Object): void; /** * The select method takes an attr key as its argument. The value of the @@ -40,7 +40,7 @@ declare module Flight { * API for more information). This is a good place to set up event * listeners that bind to callbacks. */ - initialize(node, options: Object); + initialize(node: any, options: Object): void; /** * This allows a component instance to listen to an event and register a @@ -55,16 +55,16 @@ declare module Flight { * @param handler Either a function (callback) to be invoked, or a map of * targets and callbacks. */ - on(eventType: string, handler: Function); - on(eventType: string, handler: Object); - on(selector: string, eventType: string, handler: Function); - on(selector: Document, eventType: string, handler: Function); - on(selector: Element, eventType: string, handler: Function); - on(selector: Element[], eventType: string, handler: Function); - on(selector: string, eventType: string, handler: Object); - on(selector: Document, eventType: string, handler: Object); - on(selector: Element, eventType: string, handler: Object); - on(selector: Element[], eventType: string, handler: Object); + on(eventType: string, handler: Function): void; + on(eventType: string, handler: Object): void; + on(selector: string, eventType: string, handler: Function): void; + on(selector: Document, eventType: string, handler: Function): void; + on(selector: Element, eventType: string, handler: Function): void; + on(selector: Element[], eventType: string, handler: Function): void; + on(selector: string, eventType: string, handler: Object): void; + on(selector: Document, eventType: string, handler: Object): void; + on(selector: Element, eventType: string, handler: Object): void; + on(selector: Element[], eventType: string, handler: Object): void; /** * If we no longer want a component instance to listen to an event we can @@ -78,23 +78,23 @@ declare module Flight { * @param handler Optional. The function (callback) to detach from the * component instance. Defaults to the detaching all callbacks for the event. */ - off(eventType: string, handler?: Function); - off(selector: string, eventType: string, handler?: Function); - off(selector: Document, eventType: string, handler?: Function); - off(selector: Element, eventType: string, handler?: Function); - off(selector: Element[], eventType: string, handler?: Function); - off(selector: string, eventType: Object, handler?: Function); - off(selector: Document, eventType: Object, handler?: Function); - off(selector: Element, eventType: Object, handler?: Function); - off(selector: Element[], eventType: Object, handler?: Function); - off(selector: string, eventType: string, handler?: Object); - off(selector: Document, eventType: string, handler?: Object); - off(selector: Element, eventType: string, handler?: Object); - off(selector: Element[], eventType: string, handler?: Object); - off(selector: string, eventType: Object, handler?: Object); - off(selector: Document, eventType: Object, handler?: Object); - off(selector: Element, eventType: Object, handler?: Object); - off(selector: Element[], eventType: Object, handler?: Object); + off(eventType: string, handler?: Function): void; + off(selector: string, eventType: string, handler?: Function): void; + off(selector: Document, eventType: string, handler?: Function): void; + off(selector: Element, eventType: string, handler?: Function): void; + off(selector: Element[], eventType: string, handler?: Function): void; + off(selector: string, eventType: Object, handler?: Function): void; + off(selector: Document, eventType: Object, handler?: Function): void; + off(selector: Element, eventType: Object, handler?: Function): void; + off(selector: Element[], eventType: Object, handler?: Function): void; + off(selector: string, eventType: string, handler?: Object): void; + off(selector: Document, eventType: string, handler?: Object): void; + off(selector: Element, eventType: string, handler?: Object): void; + off(selector: Element[], eventType: string, handler?: Object): void; + off(selector: string, eventType: Object, handler?: Object): void; + off(selector: Document, eventType: Object, handler?: Object): void; + off(selector: Element, eventType: Object, handler?: Object): void; + off(selector: Element[], eventType: Object, handler?: Object): void; /** * Trigger an event. @@ -115,16 +115,16 @@ declare module Flight { * * @param eventPayload This is the payload of data that accompanies the event. */ - trigger(eventType: string); - trigger(selector: string, eventType: string, eventPayload?: Object); - trigger(selector: Document, eventType: string, eventPayload?: Object); - trigger(selector: Element, eventType: string, eventPayload?: Object); - trigger(selector: Element[], eventType: string, eventPayload?: Object); - trigger(eventType: Object); - trigger(selector: string, eventType: Object, eventPayload?: Object); - trigger(selector: Document, eventType: Object, eventPayload?: Object); - trigger(selector: Element, eventType: Object, eventPayload?: Object); - trigger(selector: Element[], eventType: Object, eventPayload?: Object); + trigger(eventType: string): void; + trigger(selector: string, eventType: string, eventPayload?: Object): void; + trigger(selector: Document, eventType: string, eventPayload?: Object): void; + trigger(selector: Element, eventType: string, eventPayload?: Object): void; + trigger(selector: Element[], eventType: string, eventPayload?: Object): void; + trigger(eventType: Object): void; + trigger(selector: string, eventType: Object, eventPayload?: Object): void; + trigger(selector: Document, eventType: Object, eventPayload?: Object): void; + trigger(selector: Element, eventType: Object, eventPayload?: Object): void; + trigger(selector: Element[], eventType: Object, eventPayload?: Object): void; /** * Remove a component instance and its event bindings. @@ -134,7 +134,7 @@ declare module Flight { * the user navigates away from a page. * */ - teardown(); + teardown(): void; } export interface Advice extends Base { @@ -146,7 +146,7 @@ declare module Flight { * * customFunc The function to be invoked after existingFunc. */ - after(method: string, fn: Function); + after(method: string, fn: Function): void; /** * Run the existingFunc function in the middle of the customFunc function. @@ -163,7 +163,7 @@ declare module Flight { * existing function then it will replace that function instead of * surrounding it. */ - around(method: string, fn: Function); + around(method: string, fn: Function): void; /** * Run the customFunc function before the existingFunc function. @@ -173,7 +173,7 @@ declare module Flight { * * @param customFunc The function to be invoked before existingFunc. */ - before(method: string, fn: Function); + before(method: string, fn: Function): void; } export interface Component extends Base, Advice { @@ -183,63 +183,40 @@ declare module Flight { export interface AdviceStatic { - withAdvice(); + withAdvice(): Function; } export interface ComponentStatic { (...fns: Function[]): ComponentStatic; - attachTo(selector: string, options?: Object); - attachTo(selector: Element, options?: Object); - attachTo(selector: JQuery, options?: Object); - teardownAll(); + attachTo(selector: string, options?: Object): void; + attachTo(selector: Element, options?: Object): void; + attachTo(selector: JQuery, options?: Object): void; + teardownAll(): void; } export interface ComposeStatic { mixin(base: Object, mixins: Function[]): void; - unlockProperty(obj, prop, op); } export interface DebugStatic { events: { - logAll(); - logByAction(action: string); - logByName(name: string); - logNone(); + logAll(): void; + logByAction(action: string): void; + logByName(name: string): void; + logNone(): void; } } - export interface LoggerStatic { - - } - - export interface RegistryStatic { - addInstance(instance); - allInstances: Object; - components: Array; - events: Array; - findComponentInfo(which); - findInstanceInfo(instance); - findInstanceInfoByNode(node); - off(el, type, callback); - on(componentOn); - removeComponentInfo(componentInfo); - removeInstance(instance); - reset(); - teardown(); - trigger(); - withRegistration(); - } - export interface UtilsStatic { compose(fn1: Function, fn2: Function, ...fns: Function[]): Function; countThen(num: number, base: Function): Function; debounce(func: Function, wait: number, immediate: boolean): Function; - delegate(rules: Object); - isDomObj(obj): boolean; - isEnumerable(obj: Object, property): boolean; + delegate(rules: Object): void; + isDomObj(obj: Object): boolean; + isEnumerable(obj: Object, property: string): boolean; merge(obj1: Object, obj2: Object, deepClone?: boolean): Object; merge(obj1: Object, obj2: Object, ...args: any[]): Object; - push(base: Object, extra: Object, protect?: boolean); + push(base: Object, extra: Object, protect?: boolean): void; throttle(func: Function, wait: number): Function; toArray(obj: Object, from?: number): Array; uniqueArray(array: Array): Array; @@ -253,8 +230,6 @@ declare module Flight { advice: AdviceStatic; component: ComponentStatic; compose: ComposeStatic; - logger: LoggerStatic; - registry: RegistryStatic; utils: UtilsStatic; } }