Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
95160c770f
8 changed files with 285 additions and 30 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
var version = "0.1.15"
|
var version = "0.1.16"
|
||||||
|
|
||||||
var inputFolder = "./docs"
|
var inputFolder = "./docs"
|
||||||
var tempFolder = "./temp"
|
var tempFolder = "./temp"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
## Change Log
|
## Change Log
|
||||||
|
|
||||||
|
[v0.1.16](/mithril/archive/v0.1.6) - maintenance
|
||||||
|
|
||||||
|
### Bug Fixes:
|
||||||
|
|
||||||
|
- prevent route change when only hash changes in non-hash mode [#107](https://github.com/lhorie/mithril.js/issues/107)
|
||||||
|
- fix null reference exception with Browserify [#110](https://github.com/lhorie/mithril.js/issues/110)
|
||||||
|
- fix nested array removal edge cases [#120](https://github.com/lhorie/mithril.js/issues/120)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
[v0.1.15](/mithril/archive/v0.1.15) - maintenance
|
[v0.1.15](/mithril/archive/v0.1.15) - maintenance
|
||||||
|
|
||||||
### Bug Fixes:
|
### Bug Fixes:
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ You can define a non-HTML-standard attribute called `config`. This special param
|
||||||
This is useful, for example, if you declare a `canvas` element and want to use the Javascript API to draw:
|
This is useful, for example, if you declare a `canvas` element and want to use the Javascript API to draw:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
function draw(element, isInitialized) {
|
function draw(element, isInitialized, context) {
|
||||||
//don't redraw if we did once already
|
//don't redraw if we did once already
|
||||||
if (isInitialized) return;
|
if (isInitialized) return;
|
||||||
|
|
||||||
|
|
@ -202,6 +202,21 @@ You can use this mechanism to attach custom event listeners to controller method
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
The third argument for `config` allows you to map data to a virtual DOM element in a way that persists across redraws. This is useful when a `config` instantiates 3rd party classes and accesses the instance on redraws.
|
||||||
|
|
||||||
|
The example below shows a contrived redraw counter. In it, the count is stored in the context object and re-accessed on each redraw.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function alertsRedrawCount(element, isInit, context) {
|
||||||
|
if (!isInit) context.count = 0
|
||||||
|
alert(++context.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
m("div", {config: alertsRedrawCount})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
You can use Mithril to create SVG documents (as long as you don't need to support browsers that don't support SVG natively).
|
You can use Mithril to create SVG documents (as long as you don't need to support browsers that don't support SVG natively).
|
||||||
|
|
||||||
Mithril automatically figures out the correct XML namespaces when it sees an SVG island in the virtual DOM tree.
|
Mithril automatically figures out the correct XML namespaces when it sees an SVG island in the virtual DOM tree.
|
||||||
|
|
@ -223,7 +238,7 @@ VirtualElement m(String selector [, Attributes attributes] [, Children children]
|
||||||
|
|
||||||
where:
|
where:
|
||||||
VirtualElement :: Object { String tag, Attributes attributes, Children children }
|
VirtualElement :: Object { String tag, Attributes attributes, Children children }
|
||||||
Attributes :: Object<any | void config(DOMElement element, Boolean isInitialized)>
|
Attributes :: Object<any | void config(DOMElement element, Boolean isInitialized, Object context)>
|
||||||
Children :: String text | VirtualElement virtualElement | SubtreeDirective directive | Array<Children children>
|
Children :: String text | VirtualElement virtualElement | SubtreeDirective directive | Array<Children children>
|
||||||
SubtreeDirective :: Object { String subtree }
|
SubtreeDirective :: Object { String subtree }
|
||||||
```
|
```
|
||||||
|
|
@ -286,7 +301,7 @@ where:
|
||||||
|
|
||||||
- #### The `config` attribute
|
- #### The `config` attribute
|
||||||
|
|
||||||
**void config(DOMElement element, Boolean isInitialized)** (optional)
|
**void config(DOMElement element, Boolean isInitialized, Object context)** (optional)
|
||||||
|
|
||||||
You can define a non-HTML-standard attribute called `config`. This special parameter allows you to call methods on the DOM element after it gets created.
|
You can define a non-HTML-standard attribute called `config`. This special parameter allows you to call methods on the DOM element after it gets created.
|
||||||
|
|
||||||
|
|
@ -339,6 +354,21 @@ where:
|
||||||
|
|
||||||
Whether this is the first time we are running this function on this element. This flag is false the first time it runs on an element, and true on redraws that happen after the element has been created.
|
Whether this is the first time we are running this function on this element. This flag is false the first time it runs on an element, and true on redraws that happen after the element has been created.
|
||||||
|
|
||||||
|
- **Object context**
|
||||||
|
|
||||||
|
An object that retains its state across redraws. It can be used to store instances of 3rd party classes that need to be accessed more than one time throughout the lifecycle of a page.
|
||||||
|
|
||||||
|
The example below shows a contrived redraw counter. In it, the count is stored in the context object and re-accessed on each redraw.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function alertsRedrawCount(element, isInit, context) {
|
||||||
|
if (!isInit) context.count = 0
|
||||||
|
alert(++context.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
m("div", {config: alertsRedrawCount})
|
||||||
|
```
|
||||||
|
|
||||||
- **Children children** (optional)
|
- **Children children** (optional)
|
||||||
|
|
||||||
If this argument is a string, it will be rendered as a text node. To render a string as HTML, see [`m.trust`](mithril.trust)
|
If this argument is a string, it will be rendered as a text node. To render a string as HTML, see [`m.trust`](mithril.trust)
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,23 @@ var file = m.request({
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Using variable data formats
|
||||||
|
|
||||||
|
By default, Mithril assumes both success and error responses are in JSON format, but some servers may not return JSON responses when returning HTTP error codes (e.g. 404)
|
||||||
|
|
||||||
|
You can get around this issue by using `extract`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var nonJsonErrors = function(xhr) {
|
||||||
|
return xhr.status > 200 ? JSON.stringify(xhr.responseText) : xhr.responseText
|
||||||
|
}
|
||||||
|
|
||||||
|
m.request({method: "GET", url: "/foo/bar.x", extract: nonJsonErrors})
|
||||||
|
.then(function(data) {}, function(error) {console.log(error)})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Extracting Metadata from the Response
|
### Extracting Metadata from the Response
|
||||||
|
|
||||||
The `extract` method can be used to read metadata from HTTP response headers or the status field of an XMLHttpRequest.
|
The `extract` method can be used to read metadata from HTTP response headers or the status field of an XMLHttpRequest.
|
||||||
|
|
|
||||||
|
|
@ -144,9 +144,9 @@ var users = m.request({method: "GET", url: "/user"})
|
||||||
return users.concat({name: "Jane"})
|
return users.concat({name: "Jane"})
|
||||||
})
|
})
|
||||||
|
|
||||||
function log(load) {
|
function log(value) {
|
||||||
console.log(load)
|
console.log(value)
|
||||||
return load
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
//assuming the response contains the following data: `[{name: "John"}, {name: "Mary"}]`
|
//assuming the response contains the following data: `[{name: "John"}, {name: "Mary"}]`
|
||||||
|
|
|
||||||
49
mithril.js
49
mithril.js
|
|
@ -32,13 +32,20 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
function build(parentElement, parentTag, data, cached, shouldReattach, index, editable, namespace) {
|
var configs = []
|
||||||
|
function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace) {
|
||||||
if (data === null || data === undefined) data = ""
|
if (data === null || data === undefined) data = ""
|
||||||
if (data.subtree === "retain") return
|
if (data.subtree === "retain") return
|
||||||
|
|
||||||
var cachedType = type.call(cached), dataType = type.call(data)
|
var cachedType = type.call(cached), dataType = type.call(data)
|
||||||
if (cachedType != dataType) {
|
if (cachedType != dataType) {
|
||||||
if (cached !== null && cached !== undefined) clear(cached.nodes)
|
if (cached !== null && cached !== undefined) {
|
||||||
|
if (parentCache && parentCache.nodes) {
|
||||||
|
var offset = index - parentIndex
|
||||||
|
clear(parentCache.nodes.slice(offset, offset + (dataType == "[object Array]" ? data : cached.nodes).length))
|
||||||
|
}
|
||||||
|
else clear(cached.nodes)
|
||||||
|
}
|
||||||
cached = new data.constructor
|
cached = new data.constructor
|
||||||
cached.nodes = []
|
cached.nodes = []
|
||||||
}
|
}
|
||||||
|
|
@ -46,18 +53,22 @@ Mithril = m = new function app(window) {
|
||||||
if (dataType == "[object Array]") {
|
if (dataType == "[object Array]") {
|
||||||
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
||||||
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
||||||
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
var item = build(parentElement, null, cached, index, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
||||||
if (item === undefined) continue
|
if (item === undefined) continue
|
||||||
if (!item.nodes.intact) intact = false
|
if (!item.nodes.intact) intact = false
|
||||||
subArrayCount += item instanceof Array ? item.length : 1
|
subArrayCount += item instanceof Array ? item.length : 1
|
||||||
cached[cacheCount++] = item
|
cached[cacheCount++] = item
|
||||||
}
|
}
|
||||||
if (!intact) {
|
if (!intact) {
|
||||||
for (var i = 0; i < data.length; i++) if (cached[i] !== undefined) nodes = nodes.concat(cached[i].nodes)
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
if (cached[i] !== undefined) nodes = nodes.concat(cached[i].nodes)
|
||||||
|
}
|
||||||
for (var i = nodes.length, node; node = cached.nodes[i]; i++) {
|
for (var i = nodes.length, node; node = cached.nodes[i]; i++) {
|
||||||
if (node.parentNode !== null && node.parentNode.childNodes.length != nodes.length) node.parentNode.removeChild(node)
|
if (node.parentNode !== null && node.parentNode.childNodes.length != nodes.length) node.parentNode.removeChild(node)
|
||||||
}
|
}
|
||||||
for (var i = cached.nodes.length, node; node = nodes[i]; i++) if (node.parentNode === null) parentElement.appendChild(node)
|
for (var i = cached.nodes.length, node; node = nodes[i]; i++) {
|
||||||
|
if (node.parentNode === null) parentElement.appendChild(node)
|
||||||
|
}
|
||||||
if (data.length < cached.length) cached.length = data.length
|
if (data.length < cached.length) cached.length = data.length
|
||||||
cached.nodes = nodes
|
cached.nodes = nodes
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +85,7 @@ Mithril = m = new function app(window) {
|
||||||
cached = {
|
cached = {
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
||||||
children: data.children !== undefined ? build(node, data.tag, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace) : undefined,
|
children: data.children !== undefined ? build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace) : undefined,
|
||||||
nodes: [node]
|
nodes: [node]
|
||||||
}
|
}
|
||||||
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
|
@ -82,11 +93,13 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
||||||
cached.children = build(node, data.tag, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
||||||
cached.nodes.intact = true
|
cached.nodes.intact = true
|
||||||
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
}
|
}
|
||||||
if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew)
|
if (type.call(data.attrs["config"]) == "[object Function]") {
|
||||||
|
configs.push(data.attrs["config"].bind(window, node, !isNew, cached.configContext = cached.configContext || {}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var node
|
var node
|
||||||
|
|
@ -213,7 +226,9 @@ Mithril = m = new function app(window) {
|
||||||
var index = nodeCache.indexOf(root)
|
var index = nodeCache.indexOf(root)
|
||||||
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
||||||
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
||||||
cellCache[id] = build(node, null, cell, cellCache[id], false, 0, null, undefined)
|
cellCache[id] = build(node, null, undefined, undefined, cell, cellCache[id], false, 0, null, undefined)
|
||||||
|
for (var i = 0; i < configs.length; i++) configs[i]()
|
||||||
|
configs.length = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
m.trust = function(value) {
|
m.trust = function(value) {
|
||||||
|
|
@ -273,21 +288,23 @@ Mithril = m = new function app(window) {
|
||||||
var redirect = function() {}, routeParams = {}, currentRoute
|
var redirect = function() {}, routeParams = {}, currentRoute
|
||||||
m.route = function() {
|
m.route = function() {
|
||||||
if (arguments.length === 0) return currentRoute
|
if (arguments.length === 0) return currentRoute
|
||||||
else if (arguments.length === 3) {
|
else if (arguments.length === 3 && typeof arguments[1] == "string") {
|
||||||
currentRoute = window.location[m.route.mode].slice(modes[m.route.mode].length)
|
|
||||||
var root = arguments[0], defaultRoute = arguments[1], router = arguments[2]
|
var root = arguments[0], defaultRoute = arguments[1], router = arguments[2]
|
||||||
redirect = function(source) {
|
redirect = function(source) {
|
||||||
var path = currentRoute = source.slice(modes[m.route.mode].length)
|
var path = currentRoute = normalizeRoute(source)
|
||||||
if (!routeByValue(root, router, path)) {
|
if (!routeByValue(root, router, path)) {
|
||||||
m.route(defaultRoute, true)
|
m.route(defaultRoute, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var listener = m.route.mode == "hash" ? "onhashchange" : "onpopstate"
|
var listener = m.route.mode == "hash" ? "onhashchange" : "onpopstate"
|
||||||
window[listener] = function() {
|
window[listener] = function() {
|
||||||
redirect(window.location[m.route.mode])
|
if (currentRoute != normalizeRoute(window.location[m.route.mode])) {
|
||||||
|
redirect(window.location[m.route.mode])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
computePostRedrawHook = scrollToHash
|
computePostRedrawHook = scrollToHash
|
||||||
window[listener]()
|
window[listener]()
|
||||||
|
currentRoute = normalizeRoute(window.location[m.route.mode])
|
||||||
}
|
}
|
||||||
else if (arguments[0].addEventListener) {
|
else if (arguments[0].addEventListener) {
|
||||||
var element = arguments[0]
|
var element = arguments[0]
|
||||||
|
|
@ -319,6 +336,7 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
m.route.param = function(key) {return routeParams[key]}
|
m.route.param = function(key) {return routeParams[key]}
|
||||||
m.route.mode = "search"
|
m.route.mode = "search"
|
||||||
|
function normalizeRoute(route) {return route.slice(modes[m.route.mode].length)}
|
||||||
function routeByValue(root, router, path) {
|
function routeByValue(root, router, path) {
|
||||||
routeParams = {}
|
routeParams = {}
|
||||||
|
|
||||||
|
|
@ -508,7 +526,8 @@ Mithril = m = new function app(window) {
|
||||||
deferred[e.type == "load" ? "resolve" : "reject"](response)
|
deferred[e.type == "load" ? "resolve" : "reject"](response)
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (e instanceof Error && e.constructor !== Error) throw 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 deferred.reject(e)
|
else deferred.reject(e)
|
||||||
}
|
}
|
||||||
if (xhrOptions.background !== true) m.endComputation()
|
if (xhrOptions.background !== true) m.endComputation()
|
||||||
|
|
@ -523,7 +542,7 @@ Mithril = m = new function app(window) {
|
||||||
m.deps.factory = app
|
m.deps.factory = app
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}(this)
|
}(typeof window != "undefined" ? window : {})
|
||||||
|
|
||||||
if (typeof module != "undefined" && module !== null) module.exports = m
|
if (typeof module != "undefined" && module !== null) module.exports = m
|
||||||
if (typeof define == "function" && define.amd) define(function() {return m})
|
if (typeof define == "function" && define.amd) define(function() {return m})
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,32 @@
|
||||||
|
//qunit doesn't support Function.prototype.bind...
|
||||||
|
if (!Function.prototype.bind) {
|
||||||
|
Function.prototype.bind = function (oThis) {
|
||||||
|
if (typeof this !== "function") {
|
||||||
|
// closest thing possible to the ECMAScript 5
|
||||||
|
// internal IsCallable function
|
||||||
|
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
|
||||||
|
}
|
||||||
|
|
||||||
|
var aArgs = Array.prototype.slice.call(arguments, 1),
|
||||||
|
fToBind = this,
|
||||||
|
fNOP = function () {},
|
||||||
|
fBound = function () {
|
||||||
|
return fToBind.apply(this instanceof fNOP && oThis
|
||||||
|
? this
|
||||||
|
: oThis,
|
||||||
|
aArgs.concat(Array.prototype.slice.call(arguments)));
|
||||||
|
};
|
||||||
|
|
||||||
|
fNOP.prototype = this.prototype;
|
||||||
|
fBound.prototype = new fNOP();
|
||||||
|
|
||||||
|
return fBound;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//tests
|
||||||
var dummyEl = document.getElementById('dummy')
|
var dummyEl = document.getElementById('dummy')
|
||||||
|
|
||||||
test('Mithril accessible as window.m', function() {
|
test('Mithril accessible as window.m', function() {
|
||||||
|
|
@ -45,3 +74,18 @@ test('issue99 regression', function() {
|
||||||
m.render(dummyEl, view2);
|
m.render(dummyEl, view2);
|
||||||
equal(dummyEl.innerHTML, '<div><span>0</span></div>', 'view2 should be rendered correctly');
|
equal(dummyEl.innerHTML, '<div><span>0</span></div>', 'view2 should be rendered correctly');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('config handler context', function() {
|
||||||
|
expect(3);
|
||||||
|
var view = m('div', {config: function(evt, isInitialized, context){
|
||||||
|
equal(context instanceof Object, true);
|
||||||
|
context.data = 1;
|
||||||
|
}})
|
||||||
|
m.render(dummyEl, view);
|
||||||
|
|
||||||
|
var view = m('div', {config: function(evt, isInitialized, context){
|
||||||
|
equal(context instanceof Object, true);
|
||||||
|
equal(context.data, 1);
|
||||||
|
}})
|
||||||
|
m.render(dummyEl, view);
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ function testMithril(mock) {
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
m.render(root, m("ul", [m("li"), m("li")]))
|
m.render(root, m("ul", [m("li"), m("li")]))
|
||||||
m.render(root, m("ul", [m("li"), undefined]))
|
m.render(root, m("ul", [m("li"), undefined]))
|
||||||
return root.childNodes[0].childNodes[1].nodeValue === ""
|
return root.childNodes[0].childNodes.length == 2 && root.childNodes[0].childNodes[1].nodeValue === ""
|
||||||
})
|
})
|
||||||
test(function() {
|
test(function() {
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
|
|
@ -398,6 +398,95 @@ function testMithril(mock) {
|
||||||
m.render(root, m("div", [m("a")]))
|
m.render(root, m("div", [m("a")]))
|
||||||
return root.childNodes[0].childNodes.length == 1 && root.childNodes[0].childNodes[0].nodeName == "A"
|
return root.childNodes[0].childNodes.length == 1 && root.childNodes[0].childNodes[0].nodeName == "A"
|
||||||
})
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", "b", "c", "d"]))
|
||||||
|
m.render(root, m("div", [["d", "e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", [["a", "b", "c", "d"]]))
|
||||||
|
m.render(root, m("div", ["d", "e"]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["x", [["a"], "b", "c", "d"]]))
|
||||||
|
m.render(root, m("div", ["d", ["e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["b"]))
|
||||||
|
m.render(root, m("div", [["e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 1 && children[0].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", ["b"]]))
|
||||||
|
m.render(root, m("div", ["d", [["e"]]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", [["b"]]]))
|
||||||
|
m.render(root, m("div", ["d", ["e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", [["b"], "c"]]))
|
||||||
|
m.render(root, m("div", ["d", [[["e"]], "x"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 3 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
|
||||||
|
var success = false
|
||||||
|
m.render(root, m("div", {config: function(elem, isInitialized, ctx) {ctx.data = 1}}))
|
||||||
|
m.render(root, m("div", {config: function(elem, isInitialized, ctx) {success = ctx.data === 1}}))
|
||||||
|
return success
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
var success = true;
|
||||||
|
var statefulConfig = function(elem, isInitialized, ctx) {ctx.data = index++}
|
||||||
|
var node = m("div", {config: statefulConfig});
|
||||||
|
m.render(root, [node, node]);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
var checkConfig = function(elem, isInitialized, ctx) {
|
||||||
|
success = success && (ctx.data === index++)
|
||||||
|
}
|
||||||
|
node = m("div", {config: checkConfig});
|
||||||
|
m.render(root, [node, node]);
|
||||||
|
return success;
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
var parent
|
||||||
|
m.render(root, m("div", m("a", {
|
||||||
|
config: function(el) {parent = el.parentNode.parentNode}
|
||||||
|
})));
|
||||||
|
return parent === root
|
||||||
|
})
|
||||||
//end m.render
|
//end m.render
|
||||||
|
|
||||||
//m.redraw
|
//m.redraw
|
||||||
|
|
@ -616,8 +705,8 @@ function testMithril(mock) {
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
m.route.mode = "search"
|
m.route.mode = "search"
|
||||||
m.route(root, "/", {
|
m.route(root, "/", {
|
||||||
"/": {controller: function() {}, view: function() {return;}},
|
"/": {controller: function() {}, view: function() {}},
|
||||||
"/test12": {controller: function() {}, view: function() {return;}}
|
"/test12": {controller: function() {}, view: function() {}}
|
||||||
})
|
})
|
||||||
mock.performance.$elapse(50)
|
mock.performance.$elapse(50)
|
||||||
m.route("/test12?a=foo&b=bar")
|
m.route("/test12?a=foo&b=bar")
|
||||||
|
|
@ -647,7 +736,7 @@ function testMithril(mock) {
|
||||||
m.route.mode = "search"
|
m.route.mode = "search"
|
||||||
m.route(root, "/", {
|
m.route(root, "/", {
|
||||||
"/": {controller: function() {}, view: function() {return "bar"}},
|
"/": {controller: function() {}, view: function() {return "bar"}},
|
||||||
"/test14": {controller: function() {}, view: function() {return "foo" }}
|
"/test14": {controller: function() {}, view: function() {return "foo"}}
|
||||||
})
|
})
|
||||||
mock.performance.$elapse(50)
|
mock.performance.$elapse(50)
|
||||||
m.route("/test14?test&test2=")
|
m.route("/test14?test&test2=")
|
||||||
|
|
@ -661,14 +750,30 @@ function testMithril(mock) {
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
m.route.mode = "search"
|
m.route.mode = "search"
|
||||||
m.route(root, "/", {
|
m.route(root, "/", {
|
||||||
"/": {controller: function() {}, view: function() {return;}},
|
"/": {controller: function() {}, view: function() {}},
|
||||||
"/test12": {controller: function() {}, view: function() {return;}}
|
"/test12": {controller: function() {}, view: function() {}}
|
||||||
})
|
})
|
||||||
mock.performance.$elapse(50)
|
mock.performance.$elapse(50)
|
||||||
m.route("/test12", {a: "foo", b: "bar"})
|
m.route("/test12", {a: "foo", b: "bar"})
|
||||||
mock.performance.$elapse(50) //teardown
|
mock.performance.$elapse(50) //teardown
|
||||||
return mock.location.search == "?/test12?a=foo&b=bar" && m.route.param("a") == "foo" && m.route.param("b") == "bar"
|
return mock.location.search == "?/test12?a=foo&b=bar" && m.route.param("a") == "foo" && m.route.param("b") == "bar"
|
||||||
})
|
})
|
||||||
|
test(function() {
|
||||||
|
mock.performance.$elapse(50) //setup
|
||||||
|
mock.location.search = "?"
|
||||||
|
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
var route1, route2
|
||||||
|
m.route.mode = "search"
|
||||||
|
m.route(root, "/", {
|
||||||
|
"/": {controller: function() {route1 = m.route()}, view: function() {}},
|
||||||
|
"/test13": {controller: function() {route2 = m.route()}, view: function() {}}
|
||||||
|
})
|
||||||
|
mock.performance.$elapse(50)
|
||||||
|
m.route("/test13")
|
||||||
|
mock.performance.$elapse(50) //teardown
|
||||||
|
return route1 == "/" && route2 == "/test13"
|
||||||
|
})
|
||||||
//end m.route
|
//end m.route
|
||||||
|
|
||||||
//m.prop
|
//m.prop
|
||||||
|
|
@ -719,7 +824,7 @@ function testMithril(mock) {
|
||||||
})
|
})
|
||||||
test(function() {
|
test(function() {
|
||||||
var error = m.prop("no error"), exception
|
var error = m.prop("no error"), exception
|
||||||
var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new SyntaxError("error occurred")}}).then(null, error)
|
var prop = m.request({method: "GET", url: "test", deserialize: function() {throw new TypeError("error occurred")}}).then(null, error)
|
||||||
try {mock.XMLHttpRequest.$instances.pop().onreadystatechange()}
|
try {mock.XMLHttpRequest.$instances.pop().onreadystatechange()}
|
||||||
catch (e) {exception = e}
|
catch (e) {exception = e}
|
||||||
m.endComputation()
|
m.endComputation()
|
||||||
|
|
@ -926,6 +1031,36 @@ function testMithril(mock) {
|
||||||
test(function() {
|
test(function() {
|
||||||
return m.deps.factory.toString().indexOf("console") < 0
|
return m.deps.factory.toString().indexOf("console") < 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// config context
|
||||||
|
test(function() {
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
|
||||||
|
var success = false;
|
||||||
|
m.render(root, m("div", {config: function(elem, isInitialized, ctx) {ctx.data=1}}));
|
||||||
|
m.render(root, m("div", {config: function(elem, isInitialized, ctx) {success = ctx.data===1}}));
|
||||||
|
return success;
|
||||||
|
})
|
||||||
|
|
||||||
|
// more complex config context
|
||||||
|
test(function() {
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
|
||||||
|
var idx = 0;
|
||||||
|
var success = true;
|
||||||
|
var statefulConfig = function(elem, isInitialized, ctx) {ctx.data=idx++}
|
||||||
|
var node = m("div", {config: statefulConfig});
|
||||||
|
m.render(root, [node, node]);
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
var checkConfig = function(elem, isInitialized, ctx) {
|
||||||
|
success = success && (ctx.data === idx++)
|
||||||
|
}
|
||||||
|
node = m("div", {config: checkConfig});
|
||||||
|
m.render(root, [node, node]);
|
||||||
|
return success;
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//mocks
|
//mocks
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue