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..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"})
@@ -507,7 +508,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 +524,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.
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.
diff --git a/mithril.d.ts b/mithril.d.ts
index 5bdcff5b..06264c71 100644
--- a/mithril.d.ts
+++ b/mithril.d.ts
@@ -1,76 +1,165 @@
//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 {
+ onunload?(evt: Event): any;
+}
+
+interface MithrilControllerFunction extends MithrilController {
+ (): any;
+}
+
+interface MithrilView {
+ (ctrl: T): string|MithrilVirtualElement;
+}
+
+interface MithrilModule {
+ controller: MithrilControllerFunction|{ new(): 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;
}
diff --git a/mithril.js b/mithril.js
index 2dead416..1c8f7e5e 100644
--- a/mithril.js
+++ b/mithril.js
@@ -648,13 +648,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) {
@@ -677,7 +683,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) {
@@ -730,8 +739,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() {