From e66bc8ca54d2eb7f3b133e8be05d6762b3df44ce Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Mon, 21 Jul 2014 22:48:24 -0400 Subject: [PATCH 1/8] externs for closure compiler --- mithril.closure-compiler-externs.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 mithril.closure-compiler-externs.js diff --git a/mithril.closure-compiler-externs.js b/mithril.closure-compiler-externs.js new file mode 100644 index 00000000..ed3575ca --- /dev/null +++ b/mithril.closure-compiler-externs.js @@ -0,0 +1,15 @@ +var m = { + "render": function () {}, + "trust": function () {}, + "module": function () {}, + "redraw": function () {}, + "startComputation": function () {}, + "endComputation": function () {}, + "withAttr": function () {}, + "route": function () {}, + "prop": function () {}, + "deferred": function () {}, + "sync": function () {}, + "request": function () {}, + "deps": function () {} +} From d3c9a28c25252948e678e16400efab73d30266ba Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Tue, 22 Jul 2014 16:25:36 -0400 Subject: [PATCH 2/8] fix console.log calling for non-firebug environments --- tests/mithril-tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 1a61a1b6..c4fe3127 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1578,4 +1578,4 @@ function testMithril(mock) { //mocks testMithril(mock.window) -test.print(console.log) +test.print(function(value) {console.log(value)}) From 9a00707eeb25cdb0d0af8c21d2516ebb103a5304 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Tue, 22 Jul 2014 16:39:35 -0400 Subject: [PATCH 3/8] fix console.log higher-order calls in docs --- docs/components.md | 4 +++- docs/mithril.deferred.md | 11 ++++++++--- docs/mithril.request.md | 7 ++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/components.md b/docs/components.md index be796464..712cfe5e 100644 --- a/docs/components.md +++ b/docs/components.md @@ -137,10 +137,12 @@ dashboard.controller = function() { dashboard.view = function(ctrl) { return m("#example", [ - new autocompleter.view(ctrl.autocompleter, {onchange: m.withAttr("value", console.log)}), + new autocompleter.view(ctrl.autocompleter, {onchange: m.withAttr("value", log)}), ]); }; +//an FP-friendly console.log +var log = function(value) {console.log(value)} //initialize diff --git a/docs/mithril.deferred.md b/docs/mithril.deferred.md index e4b19d9c..48617e3c 100644 --- a/docs/mithril.deferred.md +++ b/docs/mithril.deferred.md @@ -136,14 +136,19 @@ For the most part, Mithril promises behave as you'd expect a [Promise/A+](http:/ Mithril promises forward a value downstream if a resolution callback returns `undefined`. This allows simpler debugging of promise chains: ```javascript +//a FP-friendly console.log +var log = function(value) { + console.log(value) +} + var data = m.request({method: "GET", url: "/data"}) - .then(console.log) //Mithril promises let us debug like this + .then(log) //Mithril promises let us debug like this .then(doStuff) var data = m.request({method: "GET", url: "/data"}) - .then(function(value) { // Promises/A+ would require us to declare an anonymous function + .then(function(value) { console.log(value) // here's the debugging snippet - return value // and we need to remember to return the value as well + return value // Promises/A+ requires us to return a value }) .then(doStuff) // or else `doStuff` will break diff --git a/docs/mithril.request.md b/docs/mithril.request.md index 10230361..c1232418 100644 --- a/docs/mithril.request.md +++ b/docs/mithril.request.md @@ -139,8 +139,13 @@ As you saw, you can chain operations that act on the response data. Typically th In the example below, we take advantage of queuing to debug the AJAX response data prior to doing further processing on the user list ```javascript +//a FP-friendly console.log +var log = function(value) { + console.log(value) +} + var users = m.request({method: "GET", url: "/user"}) - .then(console.log); + .then(log); .then(function(users) { //add one more user to the response return users.concat({name: "Jane"}) From 13967ad8083525477c43cee18c5e192849faffae Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Sat, 2 Aug 2014 21:30:15 -0400 Subject: [PATCH 4/8] rethrow errors from other contexts --- mithril.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mithril.js b/mithril.js index 688c187b..c3380cc2 100644 --- a/mithril.js +++ b/mithril.js @@ -553,7 +553,7 @@ Mithril = m = new function app(window) { else next[method](result !== undefined ? result : value) } catch (e) { - if (e instanceof Error && e.constructor !== Error) throw e + if (type.call(e) == "[object Error]" && e.constructor !== Error) throw e else next.reject(e) } } @@ -657,7 +657,7 @@ Mithril = m = new function app(window) { } catch (e) { if (e instanceof SyntaxError) throw new SyntaxError("Could not parse HTTP response. See http://lhorie.github.io/mithril/mithril.request.html#using-variable-data-formats") - else if (e instanceof Error && e.constructor !== Error) throw e + else if (type.call(e) == "[object Error]" && e.constructor !== Error) throw e else deferred.reject(e) } if (xhrOptions.background !== true) m.endComputation() From 7b535f9419ae01594c5c2e35ce1e56eca3082846 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Fri, 8 Aug 2014 18:13:28 -0400 Subject: [PATCH 5/8] add docs for nullables --- docs/how-to-read-signatures.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/how-to-read-signatures.md b/docs/how-to-read-signatures.md index 785bb6c6..fc794466 100644 --- a/docs/how-to-read-signatures.md +++ b/docs/how-to-read-signatures.md @@ -164,3 +164,13 @@ void test(Object { any | void config(DOMElement) } value) //example of a valid function call test({ first: "first", config: function(element) { /*do stuff*/ } }) ``` + +### Nullable Types + +A question mark `?` after a type denotes that a value can be either of that type or `undefined`. + +```clink +XMLHttpRequest? config() +``` + +In the example above, the `config` function is expected to return either an instance of the XMLHttpRequest object or `undefined` From e08c626abfe522f809d616ef03bbacec558fa9e1 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Sun, 10 Aug 2014 21:36:52 -0400 Subject: [PATCH 6/8] fix IE8 null ref --- mithril.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mithril.js b/mithril.js index 06c5d5b0..290d0232 100644 --- a/mithril.js +++ b/mithril.js @@ -4,7 +4,7 @@ Mithril = m = new function app(window, undefined) { function m() { var args = arguments - var hasAttrs = type.call(args[1]) == "[object Object]" && !("tag" in args[1]) && !("subtree" in args[1]) + var hasAttrs = args[1] !== undefined && type.call(args[1]) == "[object Object]" && !("tag" in args[1]) && !("subtree" in args[1]) var attrs = hasAttrs ? args[1] : {} var classAttrName = "class" in attrs ? "class" : "className" var cell = {tag: "div", attrs: {}} @@ -29,8 +29,7 @@ Mithril = m = new function app(window, undefined) { return cell } function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace, configs) { - if (data === undefined) return undefined - if (data === null) data = "" + if (data === undefined || data === null) data = "" if (data.subtree === "retain") return cached var cachedType = type.call(cached), dataType = type.call(data) From 3fc0165c983be561d58fcb3fa1e22ba6eafbfddc Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Sun, 10 Aug 2014 21:37:13 -0400 Subject: [PATCH 7/8] update docs about Function::bind requirement --- docs/tools.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tools.md b/docs/tools.md index ce2fe847..cd325b63 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -57,11 +57,11 @@ You can use it by adding a reference to your Typescript files. This will allow t ### Internet Explorer Compatibility -Mithril relies on some Ecmascript 5 features, namely: `Array::indexOf` and `Object::keys`, as well as the `JSON` object. +Mithril relies on some Ecmascript 5 features, namely: `Array::indexOf`, `Object::keys` and `Function::bind`, as well as the `JSON` object. You can use polyfill libraries to support these features in IE7. -- [ES5 Shim](https://github.com/es-shims/es5-shim) or Mozilla.org's [Array::indexOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) and [Object::keys](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) polyfills +- [ES5 Shim](https://github.com/es-shims/es5-shim) or Mozilla.org's [Array::indexOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf), [Object::keys](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) and [Function::bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfills - [JSON2.js](https://github.com/douglascrockford/JSON-js/blob/master/json2.js) From b86c4cec3f6acdde0030a76b56de4a71441bdcfc Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Sun, 10 Aug 2014 21:37:35 -0400 Subject: [PATCH 8/8] fix m.sync resolution when empty array --- mithril.js | 8 ++++++-- tests/mithril-tests.js | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mithril.js b/mithril.js index 290d0232..f429a659 100644 --- a/mithril.js +++ b/mithril.js @@ -586,9 +586,13 @@ Mithril = m = new function app(window, undefined) { var deferred = m.deferred() var outstanding = args.length var results = new Array(outstanding) - for (var i = 0; i < args.length; i++) { - args[i].then(synchronizer(i, true), synchronizer(i, false)) + if (args.length > 0) { + for (var i = 0; i < args.length; i++) { + args[i].then(synchronizer(i, true), synchronizer(i, false)) + } } + else deferred.resolve() + return deferred.promise } function identity(value) {return value} diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 53323b88..7e6ebbda 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1517,6 +1517,11 @@ function testMithril(mock) { deferred1.resolve("test") return value[0] === "test" && value[1] === "foo" }) + test(function() { + var value = 1 + m.sync([]).then(function() {value = 2}) + return value == 2 + }) //m.startComputation/m.endComputation test(function() {