From 577d0f70396f15caa76c18038b7845597bd94821 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Tue, 24 Mar 2015 20:45:43 -0400 Subject: [PATCH 1/3] #506 allow AMD modules to load from typescript --- mithril.d.ts | 287 ++++++++++++++++++++++++++------------------------- 1 file changed, 144 insertions(+), 143 deletions(-) diff --git a/mithril.d.ts b/mithril.d.ts index 06264c71..0c489880 100644 --- a/mithril.d.ts +++ b/mithril.d.ts @@ -1,165 +1,166 @@ //Mithril type definitions for Typescript +declare module _mithril { + interface MithrilStatic { -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[]; + } + + // Configuration function for an element + interface MithrilElementConfig { + (element: Element, isInitialized: boolean, context?: any): void; + } + + // Attributes on a virtual element + interface MithrilAttributes { + title?: string; + className?: string; + class?: string; + config?: MithrilElementConfig; + } + + // 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; + dataType?: string; + } } -interface MithrilVirtualElement { - key?: number; - tag?: string; - attrs?: MithrilAttributes; - children?: any[]; -} +declare var Mithril: _mithril.MithrilStatic; +declare var m: _mithril.MithrilStatic; -// Configuration function for an element -interface MithrilElementConfig { - (element: Element, isInitialized: boolean, context?: any): void; -} - -// Attributes on a virtual element -interface MithrilAttributes { - title?: string; - className?: string; - class?: string; - config?: MithrilElementConfig; -} - -// 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; - dataType?: string; -} - -declare var Mithril: MithrilStatic; -declare var m: MithrilStatic; - -declare module 'mithril' { +declare module "mithril" { export = m; -} +} \ No newline at end of file From 30a00cde8ba162da4a598561771185d262338f10 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Tue, 24 Mar 2015 23:56:22 -0400 Subject: [PATCH 2/3] change order in community page --- docs/community.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/community.md b/docs/community.md index 79f30f69..e658106e 100644 --- a/docs/community.md +++ b/docs/community.md @@ -8,6 +8,14 @@ Go to the [Learn Mithril site](http://lhorie.github.io/mithril-blog) --- +### Gitter + +There's a [Gitter chat room](https://gitter.im/lhorie/mithril.js). This is a great place to ask questions, discuss ideas and connect with Mithril users. + +You can sign in with your Github credentials. + +--- + ### Mailing List Looking for a place to talk about Mithril? Suggestions? @@ -27,11 +35,6 @@ Want to help fellow Mithril developers and gain karma while at it? [Keep an eye ### IRC Join the #mithriljs IRC channel on [Freenode](http://webchat.freenode.net). ---- - -### Gitter - -There's also a [Gitter chat room](https://gitter.im/lhorie/mithril.js). --- From 6f832a7040534961fb96bb6764dd421379d3b8b0 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Wed, 25 Mar 2015 21:54:36 -0400 Subject: [PATCH 3/3] #501,#502,#504 buildQueryString and parseQueryString fixes and tests --- mithril.js | 38 +++++++++++++++++++++++++++----------- tests/mithril-tests.js | 29 +++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/mithril.js b/mithril.js index 8cd2181b..de3c06e7 100644 --- a/mithril.js +++ b/mithril.js @@ -715,28 +715,44 @@ var m = (function app(window, undefined) { else window.scrollTo(0, 0) } function buildQueryString(object, prefix) { - var str = []; - for(var prop in object) { - var key = prefix ? prefix + "[" + prop + "]" : prop, value = object[prop]; + var duplicates = {} + var str = [] + for (var prop in object) { + var key = prefix ? prefix + "[" + prop + "]" : prop + var value = object[prop] var valueType = type.call(value) - var pair = value != null && (valueType === OBJECT) ? - buildQueryString(value, key) : - valueType === ARRAY ? - value.map(function(item) {return encodeURIComponent(key + "[]") + "=" + encodeURIComponent(item)}).join("&") : - encodeURIComponent(key) + "=" + encodeURIComponent(value) - str.push(pair) + var pair = (value === null) ? encodeURIComponent(key) : + valueType === OBJECT ? buildQueryString(value, key) : + valueType === ARRAY ? value.reduce(function(memo, item) { + if (!duplicates[key]) duplicates[key] = {} + if (!duplicates[key][item]) { + duplicates[key][item] = true + return memo.concat(encodeURIComponent(key) + "=" + encodeURIComponent(item)) + } + return memo + }, []).join("&") : + encodeURIComponent(key) + "=" + encodeURIComponent(value) + if (value !== undefined) str.push(pair) } return str.join("&") } - function parseQueryString(str) { var pairs = str.split("&"), params = {}; for (var i = 0, len = pairs.length; i < len; i++) { var pair = pairs[i].split("="); - params[decodeURIComponent(pair[0])] = pair[1] ? decodeURIComponent(pair[1]) : "" + var key = decodeURIComponent(pair[0]) + var value = pair.length == 2 ? decodeURIComponent(pair[1]) : null + if (params[key] != null) { + if (type.call(params[key]) !== ARRAY) params[key] = [params[key]] + params[key].push(value) + } + else params[key] = value } return params } + m.route.buildQueryString = buildQueryString + m.route.parseQueryString = parseQueryString + function reset(root) { var cacheKey = getCellCacheKey(root); clear(root.childNodes, cellCache[cacheKey]); diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 2bd3de83..f339f554 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1200,7 +1200,7 @@ function testMithril(mock) { mock.requestAnimationFrame.$resolve() m.route("/test14?test&test2=") mock.requestAnimationFrame.$resolve() //teardown - return mock.location.search == "?/test14?test=&test2=" && m.route.param("test") === "" && m.route.param("test2") === "" + return mock.location.search == "?/test14?test&test2=" && m.route.param("test") === null && m.route.param("test2") === "" }) test(function() { mock.requestAnimationFrame.$resolve() //setup @@ -2264,6 +2264,31 @@ function testMithril(mock) { }) //end m.route + //m.route.parseQueryString + test(function() { + var args = m.route.parseQueryString("foo=bar&hello%5B%5D=world&hello%5B%5D=mars&hello%5B%5D=pluto") + return args["hello[]"] instanceof Array && args["hello[]"].indexOf("world") > -1 && args["hello[]"].indexOf("mars") > -1 && args["hello[]"].indexOf("pluto") > -1 + }) + test(function() { + var args = m.route.parseQueryString("foo=bar&hello=world&hello=mars&bam=&yup") + return args.foo === "bar" && args.hello[0] === "world" && args.hello[1] === "mars" && args.bam === "" && args.yup === null + }) + + //m.route.buildQueryString + test(function() { + var string = m.route.buildQueryString({ + foo: "bar", + hello: ["world", "mars", "mars"], + world: { + test:3 + }, + bam: "", + yup: null, + removed: undefined + }) + return string === "foo=bar&hello=world&hello=mars&world%5Btest%5D=3&bam=&yup" + }) + //m.prop test(function() { var prop = m.prop("test") @@ -2384,7 +2409,7 @@ function testMithril(mock) { test(function() { var prop = m.request({method: "GET", url: "test", data: {foo: [1, 2]}}) mock.XMLHttpRequest.$instances.pop().onreadystatechange() - return prop().url === "test?foo%5B%5D=1&foo%5B%5D=2" + return prop().url === "test?foo=1&foo=2" }) // m.request over jsonp