From 492eb2ed67adb59b76f5cb9f6c5ad652c91cbff5 Mon Sep 17 00:00:00 2001 From: Chris Bowdon Date: Wed, 11 Feb 2015 20:51:48 +0000 Subject: [PATCH 1/7] Stricter TypeScript definitions --- mithril.d.ts | 194 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 140 insertions(+), 54 deletions(-) diff --git a/mithril.d.ts b/mithril.d.ts index 5bdcff5b..3279b8cc 100644 --- a/mithril.d.ts +++ b/mithril.d.ts @@ -1,76 +1,162 @@ //Mithril type definitions for Typescript interface MithrilStatic { - (selector: string, attributes: Object, children?: any): MithrilVirtualElement; - (selector: string, children?: any): MithrilVirtualElement; - prop(value?: any): (value?: any) => any; - withAttr(property: string, callback: (value: any) => void): (e: Event) => any; - module(rootElement: Node, module?: MithrilModule): Object; - trust(html: string): String; - render(rootElement: Element, children?: any): void; - render(rootElement: HTMLDocument, children?: any): void; - redraw: { - (): void; - strategy(key: string); - }; - route: { - (rootElement:Element, defaultRoute:string, routes:{ [key: string]: MithrilModule }): void - (element: Element, isInitialized: boolean): void; - (rootElement:HTMLDocument, defaultRoute:string, routes:{ [key: string]: MithrilModule }): void; - (path:string, params?:any, shouldReplaceHistory?:boolean): void; - (): string; - param(key:string): string; - mode: string; - }; - request(options: MithrilXHROptions): MithrilPromise; - deferred(): MithrilDeferred; - sync(promises: MithrilPromise[]): MithrilPromise; - startComputation(): void; - endComputation(): void; - deps(Object: any): Object; + + (selector: string, attributes: MithrilAttributes, ...children: Array): MithrilVirtualElement; + (selector: string, ...children: Array): MithrilVirtualElement; + + prop(promise: MithrilPromise) : MithrilPromiseProperty; + prop(value: T): MithrilProperty; + prop(): MithrilProperty; // might be that this should be Property + + withAttr(property: string, callback: (value: any) => void): (e: MithrilEvent) => any; + + module(rootElement: Node, module: MithrilModule): T; + module(rootElement: Node): T; + + trust(html: string): string; + + render(rootElement: Element|HTMLDocument): void; + render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement, forceRecreation?: boolean): void; + render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement[], forceRecreation?: boolean): void; + + redraw: { + (force?: boolean): void; + strategy: MithrilProperty; + } + + route: { + (rootElement: HTMLDocument, defaultRoute: string, routes: MithrilRoutes): void; + (rootElement: Element, defaultRoute: string, routes: MithrilRoutes): void; + + (element: Element, isInitialized: boolean): void; + (path: string, params?: any, shouldReplaceHistory?: boolean): void; + (): string; + + param(key: string): string; + mode: string; + } + + request(options: MithrilXHROptions): MithrilPromise; + + deferred: { + onerror(e: Error): void; + (): MithrilDeferred; + } + + sync(promises: MithrilPromise[]): MithrilPromise; + + startComputation(): void; + endComputation(): void; + + // For test suite + deps: { + (mockWindow: Window): Window; + factory: Object; + } + } interface MithrilVirtualElement { - tag: string; - attrs: Object; - children: any; + key?: number; + tag?: string; + attrs?: MithrilAttributes; + children?: any[]; } -interface MithrilModule { - controller: Function; - view: Function; +// Configuration function for an element +interface MithrilElementConfig { + (element: Element, isInitialized: boolean, context?: any): void; } -interface MithrilDeferred { - resolve(value?: any): void; - reject(value?: any): void; - promise: MithrilPromise; +// Attributes on a virtual element +interface MithrilAttributes { + title?: string; + className?: string; + class?: string; + config?: MithrilElementConfig; } -interface MithrilPromise { - (value?: any): any; - then(successCallback?: (value: any) => any, errorCallback?: (value: any) => any): MithrilPromise; +// Defines the subset of Event that Mithril needs +interface MithrilEvent { + currentTarget: Element; } +interface MithrilController { + (): any; + onunload?(evt: Event): any; +} + +interface MithrilView { + (ctrl: T): string|MithrilVirtualElement; +} + +interface MithrilModule { + controller: T; + view: MithrilView; +} + +interface MithrilProperty { + (): T; + (value: T): T; + toJSON(): T; +} + +interface MithrilPromiseProperty extends MithrilPromise { + (): T; + (value: T): T; + toJSON(): T; +} + +interface MithrilRoutes { + [key: string]: MithrilModule; +} + + +interface MithrilDeferred { + resolve(value?: T): void; + reject(value?: any): void; + promise: MithrilPromise; +} + +interface MithrilSuccessCallback { + (value: T): U; + (value: T): MithrilPromise; +} + +interface MithrilErrorCallback { + (value: Error): U; + (value: string): U; +} + +interface MithrilPromise { + (): T; + (value: T): T; + then(success: (value: T) => U): MithrilPromise; + then(success: (value: T) => MithrilPromise): MithrilPromise; + then(success: (value: T) => U, error: (value: Error) => V): MithrilPromise|MithrilPromise; + then(success: (value: T) => MithrilPromise, error: (value: Error) => V): MithrilPromise|MithrilPromise; +} interface MithrilXHROptions { - method: string; - url: string; - user?: string; - password?: string; - data?: any; - background?: boolean; - unwrapSuccess?(data: any): any; - unwrapError?(data: any): any; - serialize?(dataToSerialize: any): string; - deserialize?(dataToDeserialize: string): any; - extract?(xhr: XMLHttpRequest, options: MithrilXHROptions): string; - type?(data: Object): void; - config?(xhr: XMLHttpRequest, options: MithrilXHROptions): XMLHttpRequest; + method?: string; + url: string; + user?: string; + password?: string; + data?: any; + background?: boolean; + unwrapSuccess?(data: any): any; + unwrapError?(data: any): any; + serialize?(dataToSerialize: any): string; + deserialize?(dataToDeserialize: string): any; + extract?(xhr: XMLHttpRequest, options: MithrilXHROptions): string; + type?(data: Object): void; + config?(xhr: XMLHttpRequest, options: MithrilXHROptions): XMLHttpRequest; + dataType?: string; } declare var Mithril: MithrilStatic; declare var m: MithrilStatic; declare module 'mithril' { - export = MithrilStatic; + export = m; } From e9eb03285a480c379de0bafc4519f4fd3ed5a08e Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Thu, 12 Feb 2015 20:56:28 -0500 Subject: [PATCH 2/7] fix docs typo --- docs/mithril.route.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mithril.route.md b/docs/mithril.route.md index b32abdf6..fb3b50ee 100644 --- a/docs/mithril.route.md +++ b/docs/mithril.route.md @@ -73,7 +73,7 @@ m.route(document.body, "/dashboard/johndoe", { This redirects to the URL `http://server/#/dashboard/johndoe` and yields: ```markup -johndoe +
johndoe
``` Above, `dashboard` is a module. It contains a `controller` and a `view` properties. When the URL matches a route, the respective module's controller is instantiated and passed as a parameter to the view. From 105a936a06e7dafacb36e0aa1e2be77d7cb06a1e Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Thu, 12 Feb 2015 22:02:44 -0500 Subject: [PATCH 3/7] #320 fix routing bug in IE9 --- mithril.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/mithril.js b/mithril.js index 3dcfb4b4..5e8e7a44 100644 --- a/mithril.js +++ b/mithril.js @@ -605,13 +605,19 @@ var m = (function app(window, undefined) { window[listener]() } //config: m.route - else if (arguments[0].addEventListener) { + else if (arguments[0].addEventListener || arguments[0].attachEvent) { var element = arguments[0]; var isInitialized = arguments[1]; var context = arguments[2]; element.href = (m.route.mode !== 'pathname' ? $location.pathname : '') + modes[m.route.mode] + this.attrs.href; - element.removeEventListener("click", routeUnobtrusive); - element.addEventListener("click", routeUnobtrusive) + if (element.addEventListener) { + element.removeEventListener("click", routeUnobtrusive); + element.addEventListener("click", routeUnobtrusive) + } + else { + element.detachEvent("onclick", routeUnobtrusive); + element.attachEvent("onclick", routeUnobtrusive) + } } //m.route(route, params) else if (type.call(arguments[0]) === STRING) { @@ -634,7 +640,10 @@ var m = (function app(window, undefined) { }; redirect(modes[m.route.mode] + currentRoute) } - else $location[m.route.mode] = currentRoute + else { + $location[m.route.mode] = currentRoute + redirect(modes[m.route.mode] + currentRoute) + } } }; m.route.param = function(key) { @@ -687,8 +696,9 @@ var m = (function app(window, undefined) { if (e.ctrlKey || e.metaKey || e.which === 2) return; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; - var currentTarget = e.currentTarget || this; + var currentTarget = e.currentTarget || e.srcElement; var args = m.route.mode === "pathname" && currentTarget.search ? parseQueryString(currentTarget.search.slice(1)) : {}; + while (currentTarget && currentTarget.nodeName.toUpperCase() != "A") currentTarget = currentTarget.parentNode m.route(currentTarget[m.route.mode].slice(modes[m.route.mode].length), args) } function setScroll() { From 8ac72911a83e6178d3acda07dcdc923865a61e3d Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Thu, 12 Feb 2015 22:15:42 -0500 Subject: [PATCH 4/7] update docs and change log --- docs/change-log.md | 18 ++++++++++++++++++ docs/mithril.request.md | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/change-log.md b/docs/change-log.md index 3a281aa0..8fb182f8 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -1,5 +1,21 @@ ## Change Log +[v0.1.31](/mithril/archive/v0.1.31) - maintenance + +### News: + +- Typescript definitions are more strongly typed +- m.request's `unwrapSuccess` and `unwrapError` callbacks now receive the XMLHttpRequest instance as a second parameter +- 3rd parameter for `m.route(route, params, shouldReplaceHistory)` is now public +- exact routes now have higher precedence than routes w/ variables [#452](https://github.com/lhorie/mithril.js/issues/452) + +### Bug Fixes: + +- fix routing bug in IE9 [#320](https://github.com/lhorie/mithril.js/issues/320) +- fix ordering bug in m.trust when using HTML entities [#453](https://github.com/lhorie/mithril.js/issues/453) + +--- + [v0.1.30](/mithril/archive/v0.1.30) - maintenance ### Bug Fixes: @@ -8,6 +24,8 @@ - fix module.view's `this` association regression in Haxe environment [#434](https://github.com/lhorie/mithril.js/issues/434) - fix array serialization syntax in querystrings [#440](https://github.com/lhorie/mithril.js/issues/440) +--- + [v0.1.29](/mithril/archive/v0.1.29) - maintenance ### News: diff --git a/docs/mithril.request.md b/docs/mithril.request.md index 1f45ccdb..c133a0b3 100644 --- a/docs/mithril.request.md +++ b/docs/mithril.request.md @@ -507,7 +507,7 @@ where: The value that populates the returned getter-setter before the request completes. This is useful when using the `background` option, in order to avoid the need for null checks in views that may be attempting to access the returned getter-setter before the asynchronous request resolves. - - **any unwrapSuccess(any data)** (optional) + - **any unwrapSuccess(any data, XMLHttpRequest xhr)** (optional) A preprocessor function to unwrap the data from a success response in case the response contains metadata wrapping the data. @@ -523,7 +523,7 @@ where: The unwrapped data - - **any unwrapError(any data)** (optional) + - **any unwrapError(any data, XMLHttpRequest xhr)** (optional) A preprocessor function to unwrap the data from an error response in case the response contains metadata wrapping the data. From a48cf080f497df47f843b38b0307d7eed0e7b51c Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Fri, 13 Feb 2015 13:42:04 -0500 Subject: [PATCH 5/7] fix return value in doc --- docs/mithril.request.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/mithril.request.md b/docs/mithril.request.md index c133a0b3..ad89a482 100644 --- a/docs/mithril.request.md +++ b/docs/mithril.request.md @@ -164,6 +164,7 @@ In the example below, we take advantage of queuing to debug the AJAX response da //a FP-friendly console.log var log = function(value) { console.log(value) + return value } var users = m.request({method: "GET", url: "/user"}) From a5667ff3413c3ca25541b1f8167e931579d5573b Mon Sep 17 00:00:00 2001 From: Chris Bowdon Date: Sat, 14 Feb 2015 13:31:50 +0000 Subject: [PATCH 6/7] Made it possible to use TypeScript class as a controller --- mithril.d.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mithril.d.ts b/mithril.d.ts index 3279b8cc..43575f08 100644 --- a/mithril.d.ts +++ b/mithril.d.ts @@ -83,16 +83,19 @@ interface MithrilEvent { } interface MithrilController { - (): any; onunload?(evt: Event): any; } +interface MithrilControllerFunction extends MithrilController { + (): any; +} + interface MithrilView { (ctrl: T): string|MithrilVirtualElement; } interface MithrilModule { - controller: T; + controller: MithrilControllerFunction|{ new(): T }; view: MithrilView; } From 130a075a919bb413fa0499031f9f9f9f5a7217b5 Mon Sep 17 00:00:00 2001 From: Chris Bowdon Date: Sat, 14 Feb 2015 13:32:34 +0000 Subject: [PATCH 7/7] Fixed weird 7-space indentation in d.ts (now 4) --- mithril.d.ts | 176 +++++++++++++++++++++++++-------------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/mithril.d.ts b/mithril.d.ts index 43575f08..06264c71 100644 --- a/mithril.d.ts +++ b/mithril.d.ts @@ -2,164 +2,164 @@ interface MithrilStatic { - (selector: string, attributes: MithrilAttributes, ...children: Array): MithrilVirtualElement; - (selector: string, ...children: Array): MithrilVirtualElement; + (selector: string, attributes: MithrilAttributes, ...children: Array): MithrilVirtualElement; + (selector: string, ...children: Array): MithrilVirtualElement; - prop(promise: MithrilPromise) : MithrilPromiseProperty; - prop(value: T): MithrilProperty; - prop(): MithrilProperty; // might be that this should be Property + prop(promise: MithrilPromise) : MithrilPromiseProperty; + prop(value: T): MithrilProperty; + prop(): MithrilProperty; // might be that this should be Property - withAttr(property: string, callback: (value: any) => void): (e: MithrilEvent) => any; + withAttr(property: string, callback: (value: any) => void): (e: MithrilEvent) => any; - module(rootElement: Node, module: MithrilModule): T; - module(rootElement: Node): T; + module(rootElement: Node, module: MithrilModule): T; + module(rootElement: Node): T; - trust(html: string): string; + trust(html: string): string; - render(rootElement: Element|HTMLDocument): void; - render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement, forceRecreation?: boolean): void; - render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement[], forceRecreation?: boolean): void; + render(rootElement: Element|HTMLDocument): void; + render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement, forceRecreation?: boolean): void; + render(rootElement: Element|HTMLDocument, children: MithrilVirtualElement[], forceRecreation?: boolean): void; - redraw: { - (force?: boolean): void; - strategy: MithrilProperty; - } + redraw: { + (force?: boolean): void; + strategy: MithrilProperty; + } - route: { - (rootElement: HTMLDocument, defaultRoute: string, routes: MithrilRoutes): void; - (rootElement: Element, defaultRoute: string, routes: MithrilRoutes): void; + route: { + (rootElement: HTMLDocument, defaultRoute: string, routes: MithrilRoutes): void; + (rootElement: Element, defaultRoute: string, routes: MithrilRoutes): void; - (element: Element, isInitialized: boolean): void; - (path: string, params?: any, shouldReplaceHistory?: boolean): void; - (): string; + (element: Element, isInitialized: boolean): void; + (path: string, params?: any, shouldReplaceHistory?: boolean): void; + (): string; - param(key: string): string; - mode: string; - } + param(key: string): string; + mode: string; + } - request(options: MithrilXHROptions): MithrilPromise; + request(options: MithrilXHROptions): MithrilPromise; - deferred: { - onerror(e: Error): void; - (): MithrilDeferred; - } + deferred: { + onerror(e: Error): void; + (): MithrilDeferred; + } - sync(promises: MithrilPromise[]): MithrilPromise; + sync(promises: MithrilPromise[]): MithrilPromise; - startComputation(): void; - endComputation(): void; + startComputation(): void; + endComputation(): void; - // For test suite - deps: { - (mockWindow: Window): Window; - factory: Object; - } + // For test suite + deps: { + (mockWindow: Window): Window; + factory: Object; + } } interface MithrilVirtualElement { - key?: number; - tag?: string; - attrs?: MithrilAttributes; - children?: any[]; + key?: number; + tag?: string; + attrs?: MithrilAttributes; + children?: any[]; } // Configuration function for an element interface MithrilElementConfig { - (element: Element, isInitialized: boolean, context?: any): void; + (element: Element, isInitialized: boolean, context?: any): void; } // Attributes on a virtual element interface MithrilAttributes { - title?: string; - className?: string; - class?: string; - config?: MithrilElementConfig; + title?: string; + className?: string; + class?: string; + config?: MithrilElementConfig; } // Defines the subset of Event that Mithril needs interface MithrilEvent { - currentTarget: Element; + currentTarget: Element; } interface MithrilController { - onunload?(evt: Event): any; + onunload?(evt: Event): any; } interface MithrilControllerFunction extends MithrilController { - (): any; + (): any; } interface MithrilView { - (ctrl: T): string|MithrilVirtualElement; + (ctrl: T): string|MithrilVirtualElement; } interface MithrilModule { - controller: MithrilControllerFunction|{ new(): T }; - view: MithrilView; + controller: MithrilControllerFunction|{ new(): T }; + view: MithrilView; } interface MithrilProperty { - (): T; - (value: T): T; - toJSON(): T; + (): T; + (value: T): T; + toJSON(): T; } interface MithrilPromiseProperty extends MithrilPromise { - (): T; - (value: T): T; - toJSON(): T; + (): T; + (value: T): T; + toJSON(): T; } interface MithrilRoutes { - [key: string]: MithrilModule; + [key: string]: MithrilModule; } interface MithrilDeferred { - resolve(value?: T): void; - reject(value?: any): void; - promise: MithrilPromise; + resolve(value?: T): void; + reject(value?: any): void; + promise: MithrilPromise; } interface MithrilSuccessCallback { - (value: T): U; - (value: T): MithrilPromise; + (value: T): U; + (value: T): MithrilPromise; } interface MithrilErrorCallback { - (value: Error): U; - (value: string): U; + (value: Error): U; + (value: string): U; } interface MithrilPromise { - (): T; - (value: T): T; - then(success: (value: T) => U): MithrilPromise; - then(success: (value: T) => MithrilPromise): MithrilPromise; - then(success: (value: T) => U, error: (value: Error) => V): MithrilPromise|MithrilPromise; - then(success: (value: T) => MithrilPromise, error: (value: Error) => V): MithrilPromise|MithrilPromise; + (): T; + (value: T): T; + then(success: (value: T) => U): MithrilPromise; + then(success: (value: T) => MithrilPromise): MithrilPromise; + then(success: (value: T) => U, error: (value: Error) => V): MithrilPromise|MithrilPromise; + then(success: (value: T) => MithrilPromise, error: (value: Error) => V): MithrilPromise|MithrilPromise; } interface MithrilXHROptions { - method?: string; - url: string; - user?: string; - password?: string; - data?: any; - background?: boolean; - unwrapSuccess?(data: any): any; - unwrapError?(data: any): any; - serialize?(dataToSerialize: any): string; - deserialize?(dataToDeserialize: string): any; - extract?(xhr: XMLHttpRequest, options: MithrilXHROptions): string; - type?(data: Object): void; - config?(xhr: XMLHttpRequest, options: MithrilXHROptions): XMLHttpRequest; - dataType?: string; + method?: string; + url: string; + user?: string; + password?: string; + data?: any; + background?: boolean; + unwrapSuccess?(data: any): any; + unwrapError?(data: any): any; + serialize?(dataToSerialize: any): string; + deserialize?(dataToDeserialize: string): any; + extract?(xhr: XMLHttpRequest, options: MithrilXHROptions): string; + type?(data: Object): void; + config?(xhr: XMLHttpRequest, options: MithrilXHROptions): XMLHttpRequest; + dataType?: string; } declare var Mithril: MithrilStatic; declare var m: MithrilStatic; declare module 'mithril' { - export = m; + export = m; }