Merge remote-tracking branch 'origin/rewrite' into rewrite

This commit is contained in:
Leo Horie 2016-08-10 09:13:19 -04:00
commit 7f8363560e
18 changed files with 289 additions and 69 deletions

BIN
.deploy.enc Normal file

Binary file not shown.

View file

@ -1,5 +1,43 @@
sudo: false
language: node_js
node_js:
- stable
- node
sudo: false
cache:
directories:
- node_modules
# Custom install step so the travis scripts don't need to be in package.json
install:
- npm install
- npm install @alrra/travis-scripts@^3.0.1
# After a successful build create bundles & commit back to the repo
after_success:
- |
# Only want to commit things on commits to $BRANCH
if [ "$TRAVIS_EVENT_TYPE" == "pull_request" ] || [ "$TRAVIS_BRANCH" != "$BRANCH" ]; then
echo "Artifacts only built on $BRANCH"
exit 0
fi
# Set up SSH environment
$(npm bin)/set-up-ssh --key "$encrypted_8b86e0359d64_key" \
--iv "$encrypted_8b86e0359d64_iv" \
--path-encrypted-key "./.deploy.enc"
# Build & commit changes
$(npm bin)/commit-changes --commands "npm run build" \
--commit-message "Bundled output for commit $TRAVIS_COMMIT [skip ci]" \
--branch "$BRANCH"
env:
global:
# Restrict the branch this will activate on
- BRANCH=rewrite
# Set up GH_USER_EMAIL & GH_USER_NAME env variables used by travis-scripts package
- secure: Xvqvm3+PvJu/rs3jl/NNn0RWLkkLkIoPHiL0GCfVRaywgjCYVN02g54NVvIDaOfybqPmu9E6PJFVs92vhF34NMFQHf4EWskynusIGV271R2BV0i+OJBfLMuLgiwm6zRn7/Zw4JvWIUGEwcnlz0qxbqdHsS0SOR3fIkFzePickW0=
- secure: Rf/ldEO9d4vItJhe6EmqWpFAyCARzoCb422nHnjr1hYJknnwIXpgyZ1C/7On/9o7rWPPf+8WcHC/rgjK2rthKCldzdG5I60LfWSNzap9lk3Aa4TpSCoDBuEp7JVvDr5tc3rKnBXVT71hOay7RSx1StWzXiJs9mjaeVMJzYzRT78=

View file

@ -1,14 +1,25 @@
"use strict"
var coreRenderer = require("../render/render")
var Vnode = require("../render/vnode")
var autoredraw = require("../api/autoredraw")
var dummy = {view: function() {}}
module.exports = function(renderer, pubsub) {
return function(root, component) {
pubsub.unsubscribe(root.redraw)
var run = autoredraw(root, renderer, pubsub, function() {
renderer.render(root, {tag: component})
renderer.render(
root,
Vnode(component === null ? dummy : component, undefined, undefined, undefined, undefined, undefined)
)
})
run()
if (component === null) {
pubsub.unsubscribe(root.redraw)
delete root.redraw
}
}
}

View file

@ -32,6 +32,20 @@ o.spec("mount", function() {
o(root.firstChild.nodeName).equals("DIV")
})
o("mounting null deletes `redraw` from `root`", function() {
mount(root, {
view : function() {
return m("div")
}
})
o(typeof root.redraw).equals('function')
mount(root, null)
o(typeof root.redraw).equals('undefined')
})
o("redraws on events", function(done) {
var onupdate = o.spy()
var oninit = o.spy()

View file

@ -2,6 +2,7 @@
- [API](#api)
- [How it works](#how-it-works)
- [Performance considerations](#performance-considerations)
- [Differences from m.render](#differences-from-m-render)
---
@ -13,7 +14,7 @@
Argument | Type | Required | Description
----------- | -------------------- | -------- | ---
`element` | `Element` | Yes | A DOM element that will be the parent node to the subtree
`component` | `Component` | Yes | The [component](components.md) to be rendered
`component` | `Component|null` | Yes | The [component](components.md) to be rendered. `null` unmounts the tree and cleans up internal state.
**returns** | | | Returns nothing
[How to read signatures](signatures.md)
@ -24,6 +25,18 @@ Argument | Type | Required | Description
Similar to [`m.render()`](render.md), the `m.mount()` method takes a component and mounts a corresponding DOM tree into `element`. If `element` already has a DOM tree mounted via a previous `m.mount()` call, the component is diffed against the previous vnode tree and the existing DOM tree is modified only where needed to reflect the changes. Unchanged DOM nodes are not touched at all.
#### Replace a component
Running `mount(element, OtherComponent)` where `element` is a current mount point replaces the component previously mounted with `OtherComponent`.
#### Unmount
Using `m.mount(element, null)` on an element with a previously mounted component unmounts it and cleans up Mithril internal state. This can be useful to prevent memory leaks when removing the `root` node manually from the DOM.
---
### Performance considerations
It may seem wasteful to generate a vnode tree on every redraw, but as it turns out, creating and comparing Javascript data structures is surprisingly cheap compared to reading and modifying the DOM.
Touching the DOM can be extremely expensive for a couple of reasons. Alternating reads and writes can adversely affect performance by causing several browser repaints to occur in quick succession, whereas comparing virtual dom trees allows writes to be batched into a single repaint. Also, the performance characteristics of various DOM operations vary between implementations and can be difficult to learn and optimize for all browsers. For example, in some implementations, reading `childNodes.length` has a complexity of O(n); in some, reading `parentNode` causes a repaint, etc.

View file

@ -35,7 +35,7 @@ In contrast, traversing a javascript data structure has a much more predictable
### Differences from other API methods
`m.render()` method is internally called by [`m.mount()`](mount.md), [`m.route()`](route.md), [`m.redraw()`](redraw.md) and `[m.request()](request.md)`. It is not called by [`m.prop()`](prop.md)
`m.render()` method is internally called by [`m.mount()`](mount.md), [`m.route()`](route.md), [`m.redraw()`](redraw.md) and [`m.request()`](request.md). It is not called by [`m.prop()`](prop.md)
Unlike with `m.mount()` and `m.route()`, a vnode tree rendered via `m.render()` does not auto-redraw in response to view events, `m.redraw()` calls or `m.request()` calls. It is a low level mechanism suitable for library authors who wish to manually control rendering instead of relying on Mithril's built-in auto-redrawing system.

View file

@ -32,7 +32,7 @@ Argument | Type | Required | Descript
`options.type` | `any = Function(any)` | No | A constructor to be applied to each object in the response. Defaults to the [identity function](https://en.wikipedia.org/wiki/Identity_function).
`options.serialize` | `string = Function(any)` | No | A serialization method to be applied to `data`. Defaults to `JSON.stringify`, or if `options.data` is an instance of [`FormData`](https://developer.mozilla.org/en/docs/Web/API/FormData), defaults to the [identity function](https://en.wikipedia.org/wiki/Identity_function) (i.e. `function(value) {return value}`).
`options.deserialize` | `any = Function(string)` | No | A deserialization method to be applied to the response. Defaults to a small wrapper around `JSON.parse` that returns `null` for empty responses.
`options.extract` | `string = Function(xhr, options)` | No | A hook to specify how the XMLHttpRequest response should be read. Useful for reading response headers and cookies. Defaults to a function that returns `xhr.responseText`
`options.extract` | `string = Function(xhr, options)` | No | A hook to specify how the XMLHttpRequest response should be read. Useful for reading response headers and cookies. Defaults to a function that returns `xhr.responseText`. If defined, `options.deserialize` is ignored.
`options.initialValue` | `any` | No | A value to populate the returned stream before the request completes
`options.useBody` | `Boolean` | No | Force the use of the HTTP body section for `data` in `GET` requests when set to `true`, or the use of querystring for other HTTP methods when set to `false`. Defaults to `false` for `GET` requests and `true` for other methods.
**returns** | `Stream` | | A stream that resolves to the response data, after it has been piped through the `extract`, `deserialize` and `type` methods
@ -378,6 +378,26 @@ Ignoring the fact that the parseCSV function above doesn't handle a lot of cases
---
### Retrieving response details
By default Mithril attempts to parse a response as JSON and returns `xhr.responseText`. It may be useful to inspect a server response in more detail, this can be accomplished by passing a custom `options.extract` function:
```javascript
m.request({
method: "GET",
url: "/api/v1/users",
extract: function(xhr) {return {status: xhr.status, body: xhr.responseText}}
})
.run(function(response) {
console.log(response.status, response.body)
})
```
The parameter to `options.extract` is the XMLHttpRequest object once its operation is completed, but before it has been passed to the resulting [stream](prop.md), so the stream may still end up in an errored state if processing throws an exception.
---
### Why JSON instead of HTML
Many server-side frameworks provide a view engine that interpolates database data into a template before serving HTML (on page load or via AJAX) and then employ jQuery to handle user interactions.

View file

@ -7,6 +7,7 @@
- [Component `controller` function](#component-controller-function)
- [Component arguments](#component-arguments)
- [Passing components to `m()`](#passing-components-to-m)
- [Passing vnodes to `m.mount()` and `m.route()`](#passing-vnodes-to-mmount-and-mroute)
- [`m.route` mode](#mroute-mode)
- [`m.route` and anchor tags](#mroute-and-anchor-tags)
- [Reading/writing the current route](#readingwriting-the-current-route)
@ -178,6 +179,34 @@ m("div", component);
m("div", m(component));
```
## Passing vnodes to `m.mount()` and `m.route()`
In `v0.2.x`, `m.mount(element, component)` tolerated [vnodes](vnodes.md) as second arguments instead of [components](components.md) (even though it wasn't documented). Likewise, `m.route(element, defaultRoute, routes)` accepted vnodes as values in the `routes` object.
In `v1.x`, components are required instead in both cases.
### `v0.2.x`
```javascript
m.mount(element, m('i', 'hello'));
m.mount(element, m(Component, attrs));
m.route(element, '/', {
'/': m('b', 'bye')
})
```
### `v1.x`
```javascript
m.mount(element, {view: function () {return m('i', 'hello')}});
m.mount(element, {view: function () {return m(Component, attrs)}});
m.route(element, '/', {
'/': {view: function () {return m('b', 'bye')}}
})
```
## `m.route` mode
`m.route.mode` was replaced by `m.route.prefix(prefix)` where `prefix` can be `#`, `?`, `` (for "pathname" mode). The new API also supports hashbang (`#!`), which is the default, and it supports non-root pathnames and arbitrary mode variations such as querybang (`?!`)
@ -330,3 +359,5 @@ m.prop.merge([
console.log("Contributors:", users[0].name, "and", users[1].name);
});
```
Additionally, if the `extract` option is passed to `m.request` the return value of the provided function will be passed to the [m.prop stream](prop.md) directly, and any `deserialize` callback is ignored.

View file

@ -348,7 +348,7 @@ var renderService = function($window) {
}
//update
function updateNodes(parent, old, vnodes, hooks, nextSibling, ns) {
if (old == null && vnodes == null) return
if (old === vnodes || old == null && vnodes == null) return
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined)
else if (vnodes == null) removeNodes(parent, old, 0, old.length, vnodes)
else {
@ -357,7 +357,7 @@ var renderService = function($window) {
if (old.length === vnodes.length && vnodes[0] != null && vnodes[0].key == null) {
for (var i = 0; i < old.length; i++) {
if (old[i] == null && vnodes[i] == null) continue
if (old[i] === vnodes[i] || old[i] == null && vnodes[i] == null) continue
else if (old[i] == null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling))
else if (vnodes[i] == null) removeNodes(parent, old, i, i + 1, vnodes)
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), recycling, ns)
@ -675,11 +675,11 @@ var renderService = function($window) {
}
//style
function updateStyle(element, old, style) {
if (old === style) element.style = "", old = null
if (style == null) element.style = ""
else if (typeof style === "string") element.style = style
if (old === style) element.cssText = "", old = null
if (style == null) element.cssText = ""
else if (typeof style === "string") element.cssText = style
else {
if (typeof old === "string") element.style = ""
if (typeof old === "string") element.cssText = ""
for (var key in style) {
element.style[key] = style[key]
}
@ -744,7 +744,12 @@ var renderService = function($window) {
function render(dom, vnodes) {
var hooks = []
var active = $doc.activeElement
if (dom.vnodes == null) dom.vnodes = []
// First time rendering into a node clears it out
if (dom.vnodes == null) {
dom.vnodes = []
dom.textContent = "";
}
if (!(vnodes instanceof Array)) vnodes = [vnodes]
updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), hooks, null, undefined)
dom.vnodes = vnodes
@ -808,7 +813,7 @@ var requestService = function($window) {
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
try {
var response = args.deserialize(args.extract(xhr, args))
var response = (args.extract !== extract) ? args.extract(xhr, args) : args.deserialize(args.extract(xhr, args))
if (xhr.status >= 200 && xhr.status < 300) {
stream(cast(args.type, response))
}
@ -1103,12 +1108,21 @@ m.route = function($window, renderer, pubsub) {
return route
}(window, renderService, redrawService)
var dummy = {view: function() {}}
m.mount = function(renderer, pubsub) {
return function(root, component) {
pubsub.unsubscribe(root.redraw)
var run = autoredraw(root, renderer, pubsub, function() {
renderer.render(root, {tag: component})
renderer.render(
root,
Vnode(component === null ? dummy : component, undefined, undefined, undefined, undefined, undefined)
)
})
run()
if (component === null) {
pubsub.unsubscribe(root.redraw)
delete root.redraw
}
}
}(renderService, redrawService)
m.trust = function(html) {

74
mithril.min.js vendored
View file

@ -1,40 +1,40 @@
new function(){(function(){function y(){function a(){0<arguments.length&&I(a,arguments[0],void 0);return a._state.value}N(a,arguments);0<arguments.length&&I(a,arguments[0],void 0);return a}function N(a,b){a.constructor=y;a._state={id:aa++,value:void 0,error:void 0,state:0,derive:void 0,recover:void 0,deps:{},parents:[],errorStream:void 0,endStream:void 0};a.map=ba;a.ap=ca;a.of=y;a.valueOf=O;a.toJSON=da;a.toString=O;a.run=ea;a["catch"]=fa;Object.defineProperties(a,{error:{get:function(){if(!a._state.errorStream){var b=
new function(){function y(){function a(){0<arguments.length&&I(a,arguments[0],void 0);return a._state.value}N(a,arguments);0<arguments.length&&I(a,arguments[0],void 0);return a}function N(a,b){a.constructor=y;a._state={id:aa++,value:void 0,error:void 0,state:0,derive:void 0,recover:void 0,deps:{},parents:[],errorStream:void 0,endStream:void 0};a.map=ba;a.ap=ca;a.of=y;a.valueOf=O;a.toJSON=da;a.toString=O;a.run=ea;a["catch"]=fa;Object.defineProperties(a,{error:{get:function(){if(!a._state.errorStream){var b=
function(){0<arguments.length&&I(a,void 0,arguments[0]);return a._state.error};N(b,[]);D(b,[a],P,P);a._state.errorStream=b}return a._state.errorStream}},end:{get:function(){if(!a._state.endStream){var b=y();b.map(function(d){!0===d&&(Q(a),Q(b));return d});a._state.endStream=b}return a._state.endStream}}})}function I(a,b,h){E(a,b,h);for(var d in a._state.deps)R(a._state.deps[d],!1);a._state.changed=!1;for(var g in a._state.deps)a._state.deps[g]._state.changed=!1}function E(a,b,h){h=S(b,h);if(void 0!==
h&&"function"===typeof a._state.recover)try{var d=a._state.recover();if(d===F)return;a._state.value=d;a._state.error=void 0}catch(g){a._state.value=void 0,a._state.error=g,T(a,g)}else a._state.value=b,a._state.error=h;a._state.changed=!0;2!==a._state.state&&(a._state.state=1)}function R(a,b){var h=a._state,d=h.parents;if(0<d.length&&d.filter(ga).length===d.length&&(b||0<d.filter(U).length))if(d=d.filter(V),0<d.length)E(a,void 0,d[0]._state.error);else try{var g=h.derive();g!==F&&E(a,g,void 0)}catch(k){E(a,
void 0,k),T(a,k)}}function S(a,b){null!=a&&a.constructor===y&&(b=void 0!==a._state.error?a._state.error:S(a._state.value,a._state.error));return b}function T(a,b){0===Object.keys(a._state.deps).length&&setTimeout(function(){0===Object.keys(a._state.deps).length&&console.error(b)},0)}function ea(a){var b=y(),h=this;return D(b,[h],function(){return W(b,a(h()))},void 0)}function fa(a){var b=y(),h=this;return D(b,[h],function(){return h._state.value},function(){return W(b,a(h._state.error))})}function G(a,
h&&"function"===typeof a._state.recover)try{var d=a._state.recover();if(d===F)return;a._state.value=d;a._state.error=void 0}catch(g){a._state.value=void 0,a._state.error=g,T(a,g)}else a._state.value=b,a._state.error=h;a._state.changed=!0;2!==a._state.state&&(a._state.state=1)}function R(a,b){var h=a._state,d=h.parents;if(0<d.length&&d.filter(ga).length===d.length&&(b||0<d.filter(U).length))if(d=d.filter(V),0<d.length)E(a,void 0,d[0]._state.error);else try{var g=h.derive();g!==F&&E(a,g,void 0)}catch(p){E(a,
void 0,p),T(a,p)}}function S(a,b){null!=a&&a.constructor===y&&(b=void 0!==a._state.error?a._state.error:S(a._state.value,a._state.error));return b}function T(a,b){0===Object.keys(a._state.deps).length&&setTimeout(function(){0===Object.keys(a._state.deps).length&&console.error(b)},0)}function ea(a){var b=y(),h=this;return D(b,[h],function(){return W(b,a(h()))},void 0)}function fa(a){var b=y(),h=this;return D(b,[h],function(){return h._state.value},function(){return W(b,a(h._state.error))})}function G(a,
b){return D(y(),b,function(){var h=b.filter(V);if(0<h.length)throw h[0]._state.error;return a.apply(this,b.concat([b.filter(U)]))},void 0)}function W(a,b){if(null!=b&&b.constructor===y){b.error.map(a.error);b.map(a);if(0===b._state.state)return F;if(b._state.error)throw b._state.error;b=b._state.value}return b}function D(a,b,h,d){var g=a._state;g.derive=h;g.recover=d;g.parents=b.filter(ha);X(a,g.parents);R(a,!0);return a}function X(a,b){for(var h=0;h<b.length;h++)b[h]._state.deps[a._state.id]=a,X(a,
b[h]._state.parents)}function Q(a){for(var b=0;b<a._state.parents.length;b++)delete a._state.parents[b]._state.deps[a._state.id];for(var h in a._state.deps){var b=a._state.deps[h],d=b._state.parents.indexOf(a);-1<d&&b._state.parents.splice(d,1)}a._state.state=2;a._state.deps={}}function ba(a){return G(function(b){return a(b())},[this])}function ca(a){return G(function(a,h){return a()(h())},[this,a])}function O(){return this._state.value}function da(){return JSON.stringify(this._state.value)}function ga(a){return 1===
a._state.state}function U(a){return a._state.changed}function ha(a){return 2!==a._state.state}function V(a){return a._state.error}function u(a,b,h,d,g,k){return{tag:a,key:b,attrs:h,children:d,text:g,dom:k,domSize:void 0,state:{},events:void 0,instance:void 0}}var aa=0,P=function(){},F={},C={stream:y,merge:function(a){return G(function(){return a.map(function(a){return a()})},a)},combine:G,reject:function(a){var b=y();b.error(a);return b},HALT:F};u.normalize=function(a){return a instanceof Array?u("[",
void 0,void 0,u.normalizeChildren(a),void 0,void 0):null!=a&&"object"!==typeof a?u("#",void 0,void 0,a,void 0,void 0):a};u.normalizeChildren=function(a){for(var b=0;b<a.length;b++)a[b]=u.normalize(a[b]);return a};var ia=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,J={},l=function(a){if("string"===typeof a&&void 0===J[a]){for(var b,h,d=[],g={};b=ia.exec(a);){var k=b[1],m=b[2];""===k&&""!==m?h=m:"#"===k?g.id=m:"."===k?d.push(m):"["===b[3][0]&&((k=b[6])&&(k=k.replace(/\\(["'])/g,
"$1").replace(/\\\\/g,"\\")),g[b[4]]=k||!0)}0<d.length&&(g.className=d.join(" "));J[a]=function(a,b){var e=!1,d,k,m=a.className||a["class"],r;for(r in g)a[r]=g[r];void 0!==m&&(void 0!==a["class"]&&(a["class"]=void 0,a.className=m),void 0!==g.className&&(a.className=g.className+" "+m));for(r in a)if("key"!==r){e=!0;break}b instanceof Array&&1==b.length&&null!=b[0]&&"#"===b[0].tag?k=b[0].children:d=b;return u(h||"div",a.key,e?a:void 0,d,k,void 0)}}var e;null!=arguments[1]&&("object"!==typeof arguments[1]||
void 0!==arguments[1].tag||arguments[1]instanceof Array)?d=1:(e=arguments[1],d=2);if(arguments.length===d+1)b=arguments[d]instanceof Array?arguments[d]:[arguments[d]];else for(b=[];d<arguments.length;d++)b.push(arguments[d]);return"string"===typeof a?J[a](e||{},u.normalizeChildren(b)):u(a,e&&e.key,e||{},u.normalizeChildren(b),void 0,void 0)},K=function(a){function b(a,c,f,b,e,d,g){for(;f<b;f++){var k=c[f];null!=k&&n(a,h(k,e,g),d)}}function h(a,c,f){var e=a.tag;null!=a.attrs&&l(a.attrs,a,c);if("string"===
typeof e)switch(e){case "#":return a.dom=x.createTextNode(a.children);case "<":return d(a);case "[":var n=x.createDocumentFragment();null!=a.children&&(e=a.children,b(n,e,0,e.length,c,null,f));a.dom=n.firstChild;a.domSize=n.childNodes.length;return n;default:var g=a.tag;switch(a.tag){case "svg":f="http://www.w3.org/2000/svg";break;case "math":f="http://www.w3.org/1998/Math/MathML"}var k=(e=a.attrs)&&e.is,g=f?k?x.createElementNS(f,g,k):x.createElementNS(f,g):k?x.createElement(g,k):x.createElement(g);
a.dom=g;if(null!=e)for(n in k=f,e)A(a,n,null,e[n],k);null!=a.text&&(""!==a.text?g.textContent=a.text:a.children=[u("#",void 0,void 0,a.text,void 0,void 0)]);null!=a.children&&(n=a.children,b(g,n,0,n.length,c,null,f),c=a.attrs,"select"===a.tag&&null!=c&&("value"in c&&A(a,"value",null,c.value,void 0),"selectedIndex"in c&&A(a,"selectedIndex",null,c.selectedIndex,void 0)));return g}else return a.state=C(a.tag),l(a.tag,a,c),a.instance=u.normalize(a.tag.view.call(a.state,a)),null!=a.instance?(c=h(a.instance,
c,f),a.dom=a.instance.dom,a.domSize=null!=a.dom?a.instance.domSize:0,a=c):(a.domSize=0,a=ja),a}function d(a){var c={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(a.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",c=x.createElement(c);c.innerHTML=a.children;a.dom=c.firstChild;a.domSize=c.childNodes.length;a=x.createDocumentFragment();for(var f;f=c.firstChild;)a.appendChild(f);return a}function g(a,c,f,d,g,B){if(null!=c||null!=
f)if(null==c)b(a,f,0,f.length,d,g,void 0);else if(null==f)v(a,c,0,c.length,f);else{var p;a:{if(null!=c.pool&&Math.abs(c.pool.length-f.length)<=Math.abs(c.length-f.length)&&(p=f[0]&&f[0].children&&f[0].children.length||0,Math.abs((c.pool[0]&&c.pool[0].children&&c.pool[0].children.length||0)-p)<=Math.abs((c[0]&&c[0].children&&c[0].children.length||0)-p))){p=!0;break a}p=!1}p&&(c=c.concat(c.pool));if(c.length===f.length&&null!=f[0]&&null==f[0].key)for(var q=0;q<c.length;q++){if(null!=c[q]||null!=f[q])null==
c[q]?n(a,h(f[q],d,B),e(c,q+1,g)):null==f[q]?v(a,c,q,q+1,f):k(a,c[q],f[q],d,e(c,q+1,g),p,B),p&&c[q].tag===f[q].tag&&n(a,m(c[q]),e(c,q+1,g))}else{for(var A=q=0,r=c.length-1,z=f.length-1,u;r>=q&&z>=A;){var t=c[q],w=f[A];if(t===w)q++,A++;else if(null!=t&&null!=w&&t.key===w.key)q++,A++,k(a,t,w,d,e(c,q,g),p,B),p&&t.tag===w.tag&&n(a,m(t),g);else if(t=c[r],t===w)r--,A++;else if(null!=t&&null!=w&&t.key===w.key)k(a,t,w,d,e(c,r+1,g),p,B),n(a,m(t),e(c,q,g)),r--,A++;else break}for(;r>=q&&z>=A;){t=c[r];w=f[z];
if(t===w)r--;else if(null!=t&&null!=w&&t.key===w.key)k(a,t,w,d,e(c,r+1,g),p,B),p&&t.tag===w.tag&&n(a,m(t),g),null!=t.dom&&(g=t.dom),r--;else{if(!u){u=c;var t=r,l={},x;for(x=0;x<t;x++){var y=u[x];null!=y&&(y=y.key,null!=y&&(l[y]=x))}u=l}null!=w&&(t=u[w.key],null!=t?(l=c[t],k(a,l,w,d,e(c,r+1,g),p,B),n(a,m(l),g),c[t].skip=!0,null!=l.dom&&(g=l.dom)):(w=h(w,d,void 0),n(a,w,g),g=w))}z--;if(z<A)break}b(a,f,A,z+1,d,g,B);v(a,c,q,r+1,f)}}}function k(a,c,f,b,e,p,v){var q=c.tag;if(q===f.tag){f.state=c.state;
f.events=c.events;var r;var z;null!=f.attrs&&"function"===typeof f.attrs.onbeforeupdate&&(r=f.attrs.onbeforeupdate.call(f.state,f,c));"string"!==typeof f.tag&&"function"===typeof f.tag.onbeforeupdate&&(z=f.tag.onbeforeupdate.call(f.state,f,c));void 0===r&&void 0===z||r||z?r=!1:(f.dom=c.dom,f.domSize=c.domSize,f.instance=c.instance,r=!0);if(!r)if(null!=f.attrs&&y(f.attrs,f,b,p),"string"===typeof q)switch(q){case "#":c.children.toString()!==f.children.toString()&&(c.dom.nodeValue=f.children);f.dom=
c.dom;break;case "<":c.children!==f.children?(m(c),n(a,d(f),e)):(f.dom=c.dom,f.domSize=c.domSize);break;case "[":g(a,c.children,f.children,b,e,v);c=0;b=f.children;f.dom=null;if(null!=b){for(var l=0;l<b.length;l++)a=b[l],null!=a&&null!=a.dom&&(null==f.dom&&(f.dom=a.dom),c+=a.domSize||1);1!==c&&(f.domSize=c)}break;default:a=v;e=f.dom=c.dom;switch(f.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}"textarea"===f.tag&&(null==f.attrs&&(f.attrs={}),
null!=f.text&&(f.attrs.value=f.text));p=c.attrs;v=f.attrs;q=a;if(null!=v)for(l in v)A(f,l,p&&p[l],v[l],q);if(null!=p)for(l in p)null!=v&&l in v||"key"!==l&&f.dom.removeAttribute(l);null!=c.text&&null!=f.text&&""!==f.text?c.text.toString()!==f.text.toString()&&(c.dom.firstChild.nodeValue=f.text):(null!=c.text&&(c.children=[u("#",void 0,void 0,c.text,void 0,c.dom.firstChild)]),null!=f.text&&(f.children=[u("#",void 0,void 0,f.text,void 0,void 0)]),g(e,c.children,f.children,b,null,a))}else f.instance=
u.normalize(f.tag.view.call(f.state,f)),y(f.tag,f,b,p),null!=f.instance?(null==c.instance?n(a,h(f.instance,b,v),e):k(a,c.instance,f.instance,b,e,p,v),f.dom=f.instance.dom,f.domSize=f.instance.domSize):null!=c.instance?(B(a,c.instance,null,!1),f.dom=void 0,f.domSize=0):(f.dom=c.dom,f.domSize=c.domSize)}else B(a,c,null,!1),n(a,h(f,b,void 0),e)}function m(a){var c=a.domSize;if(null!=c||null==a.dom){var f=x.createDocumentFragment();if(0<c){for(a=a.dom;--c;)f.appendChild(a.nextSibling);f.insertBefore(a,
f.firstChild)}return f}return a.dom}function e(a,c,f){for(;c<a.length;c++)if(null!=a[c]&&null!=a[c].dom)return a[c].dom;return f}function n(a,c,f){f&&f.parentNode?a.insertBefore(c,f):a.appendChild(c)}function v(a,c,f,b,e){for(;f<b;f++){var g=c[f];null!=g&&(g.skip?g.skip=void 0:B(a,g,e,!1))}}function B(a,c,f,b){if(!1===b){var e=0,g=0;b=function(){++g===e&&B(a,c,f,!0)};c.attrs&&c.attrs.onbeforeremove&&(e++,c.attrs.onbeforeremove.call(c.state,c,b));"string"!==typeof c.tag&&c.tag.onbeforeremove&&(e++,
c.tag.onbeforeremove.call(c.state,c,b));if(0<e)return}p(c);if(c.dom){b=c.domSize||1;if(1<b)for(var d=c.dom;--b;)a.removeChild(d.nextSibling);null!=c.dom.parentNode&&a.removeChild(c.dom);null==f||null!=c.domSize||z(c.attrs)||"string"!==typeof c.tag||(f.pool?f.pool.push(c):f.pool=[c])}}function p(a){a.attrs&&a.attrs.onremove&&a.attrs.onremove.call(a.state,a);"string"!==typeof a.tag&&a.tag.onremove&&a.tag.onremove.call(a.state,a);if(null!=a.instance)p(a.instance);else if(a=a.children,a instanceof Array)for(var c=
0;c<a.length;c++){var b=a[c];null!=b&&p(b)}}function A(a,c,b,e,g){var d=a.dom;if("key"!==c&&(b!==e||"value"===c||"checked"===c||"selectedIndex"===c||"selected"===c&&a.dom===x.activeElement||"object"===typeof e)&&"undefined"!==typeof e&&"oninit"!==c&&"oncreate"!==c&&"onupdate"!==c&&"onremove"!==c&&"onbeforeremove"!==c&&"onbeforeupdate"!==c){var n=c.indexOf(":");if(-1<n&&"xlink"===c.substr(0,n))d.setAttributeNS("http://www.w3.org/1999/xlink",c.slice(n+1),e);else if("o"===c[0]&&"n"===c[1]&&"function"===
typeof e)r(a,c,e);else if("style"===c)if(a=b,a===e&&(d.style="",a=null),null==e)d.style="";else if("string"===typeof e)d.style=e;else{"string"===typeof a&&(d.style="");for(var h in e)d.style[h]=e[h];if(null!=a&&"string"!==typeof a)for(h in a)h in e||(d.style[h]="")}else if(c in d&&"href"!==c&&"list"!==c&&"form"!==c&&void 0===g){if("input"!==a.tag||"value"!==c||a.dom.value!==e||a.dom!==x.activeElement)d[c]=e}else"boolean"===typeof e?e?d.setAttribute(c,""):d.removeAttribute(c):d.setAttribute("className"===
c?"class":c,e)}}function z(a){return null!=a&&(a.oncreate||a.onupdate||a.onbeforeremove||a.onremove)}function r(a,c,b){var e=a.dom,d=function(a){var c=b.call(e,a);"function"===typeof D&&D.call(e,a);return c};if(c in e)e[c]=d;else{var g=c.slice(2);void 0===a.events&&(a.events={});null!=a.events[c]&&e.removeEventListener(g,a.events[c],!1);a.events[c]=d;e.addEventListener(g,a.events[c],!1)}}function l(a,c,b){"function"===typeof a.oninit&&a.oninit.call(c.state,c);"function"===typeof a.oncreate&&b.push(a.oncreate.bind(c.state,
c))}function y(a,c,b,e){e?l(a,c,b):"function"===typeof a.onupdate&&b.push(a.onupdate.bind(c.state,c))}function C(a){if(a instanceof Array){for(var c=[],b=0;b<a.length;b++)c[b]=a[b];return c}if("object"===typeof a){c={};for(b in a)c[b]=a[b];return c}return a}var x=a.document,ja=x.createDocumentFragment(),D;return{render:function(a,c){var b=[],e=x.activeElement;null==a.vnodes&&(a.vnodes=[]);c instanceof Array||(c=[c]);g(a,a.vnodes,u.normalizeChildren(c),b,null,void 0);a.vnodes=c;for(var d=0;d<b.length;d++)b[d]();
x.activeElement!==e&&e.focus()},setEventCallback:function(a){return D=a}}}(window),L=function(a){function b(a,d){if(d instanceof Array)for(var m=0;m<d.length;m++)b(a+"["+m+"]",d[m]);else if("[object Object]"===Object.prototype.toString.call(d))for(m in d)b(a+"["+m+"]",d[m]);else h.push(encodeURIComponent(a)+(null!=d&&""!==d?"="+encodeURIComponent(d):""))}if("[object Object]"!==Object.prototype.toString.call(a))return"";var h=[],d;for(d in a)b(d,a[d]);return h.join("&")},M=function(a){function b(a,
b){if(null==b)return a;for(var d=a.match(/:[^\/]+/gi)||[],g=0;g<d.length;g++){var h=d[g].slice(1);null!=b[h]&&(a=a.replace(d[g],b[h]),delete b[h])}return a}function h(a,b){var d=L(b);if(""!==d){var g=0>a.indexOf("?")?"?":"&";a+=g+d}return a}function d(a){try{return""!==a?JSON.parse(a):null}catch(b){throw Error(a);}}function g(a){return a.responseText}var k=0,m;return{xhr:function(e){var n=C.stream();void 0!==e.initialValue&&n(e.initialValue);var v="boolean"===typeof e.useBody?e.useBody:"GET"!==e.method&&
"TRACE"!==e.method;"function"!==typeof e.serialize&&(e.serialize="undefined"!==typeof FormData&&e.data instanceof FormData?function(a){return a}:JSON.stringify);"function"!==typeof e.deserialize&&(e.deserialize=d);"function"!==typeof e.extract&&(e.extract=g);e.url=b(e.url,e.data);v?e.data=e.serialize(e.data):e.url=h(e.url,e.data);var k=new a.XMLHttpRequest;k.open(e.method,e.url,"boolean"===typeof e.async?e.async:!0,"string"===typeof e.user?e.user:void 0,"string"===typeof e.password?e.password:void 0);
e.serialize===JSON.stringify&&v&&k.setRequestHeader("Content-Type","application/json; charset=utf-8");e.deserialize===d&&k.setRequestHeader("Accept","application/json, text/*");"function"===typeof e.config&&(k=e.config(k,e)||k);k.onreadystatechange=function(){if(4===k.readyState){try{var a=e.deserialize(e.extract(k,e));if(200<=k.status&&300>k.status){if("function"===typeof e.type)if(a instanceof Array)for(var b=0;b<a.length;b++)a[b]=new e.type(a[b]);else a=new e.type(a);n(a)}else{var b=Error(k.responseText),
d;for(d in a)b[d]=a[d];n.error(b)}}catch(g){n.error(g)}"function"===typeof m&&m()}};v?k.send(e.data):k.send();return n},jsonp:function(e){var d=C.stream(),g=e.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+k++,l=a.document.createElement("script");a[g]=function(b){l.parentNode.removeChild(l);d(b);"function"===typeof m&&m();delete a[g]};l.onerror=function(){l.parentNode.removeChild(l);d.error(Error("JSONP request failed"));"function"===typeof m&&m();delete a[g]};null==e.data&&(e.data=
{});e.url=b(e.url,e.data);e.data[e.callbackKey||"callback"]=g;l.src=h(e.url,e.data);a.document.documentElement.appendChild(l);return d},setCompletionCallback:function(a){m=a}}}(window),H=function(){var a=[];return{subscribe:a.push.bind(a),unsubscribe:function(b){b=a.indexOf(b);-1<b&&a.splice(b,1)},publish:function(){for(var b=0;b<a.length;b++)a[b].apply(this,arguments)}}}();M.setCompletionCallback(H.publish);var Y=function(a){if(""===a||null==a)return{};"?"===a.charAt(0)&&(a=a.slice(1));a=a.split("&");
for(var b={},h={},d=0;d<a.length;d++){var g=a[d].split("="),k=decodeURIComponent(g[0]),g=2===g.length?decodeURIComponent(g[1]):"",m=Number(g);""!==g&&!isNaN(m)||"NaN"===g?g=m:"true"===g?g=!0:"false"===g?g=!1:(m=new Date(g),isNaN(m.getTime())||(g=m));var m=k.split(/\]\[?|\[/),e=b;-1<k.indexOf("[")&&m.pop();for(var n=0;n<m.length;n++){var k=m[n],v=m[n+1],v=""==v||!isNaN(parseInt(v,10)),l=n===m.length-1;""===k&&(k=m.slice(0,n).join(),null==h[k]&&(h[k]=0),k=h[k]++);null==e[k]&&(e[k]=l?g:v?[]:{});e=e[k]}}return b},
ka=function(a){function b(b){var e=a.location[b].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===b&&"/"!==e[0]&&(e="/"+e);return e}function h(a,b,e){var d=a.indexOf("?"),g=a.indexOf("#"),h=-1<d?d:-1<g?g:a.length;if(-1<d){var d=Y(a.slice(d+1,-1<g?g:a.length)),k;for(k in d)b[k]=d[k]}if(-1<g)for(k in b=Y(a.slice(g+1)),b)e[k]=b[k];return a.slice(0,h)}function d(){switch(e.charAt(0)){case "#":return b("hash").slice(e.length);case "?":return b("search").slice(e.length)+b("hash");default:return b("pathname").slice(e.length)+
b("search")+b("hash")}}function g(b,d,g){var m={},l={};b=h(b,m,l);if(null!=d){for(var z in d)m[z]=d[z];b=b.replace(/:([^\/]+)/g,function(a,b){delete m[b];return d[b]})}(z=L(m))&&(b+="?"+z);(l=L(l))&&(b+="#"+l);k?(g&&g.replace?a.history.replaceState(null,null,e+b):a.history.pushState(null,null,e+b),a.onpopstate()):a.location.href=e+b}var k="function"===typeof a.history.pushState&&"file:"!==a.location.protocol,m="function"===typeof setImmediate?setImmediate:setTimeout,e="#!";return{setPrefix:function(a){e=
a},getPath:d,setPath:g,defineRoutes:function(b,g,l){function p(){var a=d(),e={},k=h(a,e,e);m(function(){for(var d in b){var h=new RegExp("^"+d.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(h.test(k)){k.replace(h,function(){for(var h=d.match(/:[^\/]+/g)||[],k=[].slice.call(arguments,1,-2),l=0;l<h.length;l++)e[h[l].replace(/:|\./g,"")]=decodeURIComponent(k[l]);g(b[d],e,a,d)});return}}l(a,e)})}k?a.onpopstate=p:"#"===e.charAt(0)&&(a.onhashchange=p);p();return p},link:function(a){a.dom.setAttribute("href",
e+a.attrs.href);a.dom.onclick=function(b){b.preventDefault();b.redraw=!1;g(a.attrs.href,void 0,void 0)}}}},la=function(a){var b=0,h=null,d="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(g){var k=Date.now();!0===g||0===b||16<=k-b?(b=k,a()):null===h&&(h=d(function(){h=null;a();b=Date.now()},16-(k-b)))}},Z=function(a,b,h,d){d=la(d);null!=b&&b.setEventCallback(function(a){!1!==a.redraw&&h.publish()});null!=h&&(a.redraw&&h.unsubscribe(a.redraw),h.subscribe(d));
return a.redraw=d};l.route=function(a,b,h){var d=ka(a);a=function(a,k,l){var e=null,n=null;l=d.defineRoutes(l,function(d,h,k,l){if("function"!==typeof d.view){"function"!==typeof d.render&&(d.render=function(a){return a});var m=function(l){e=k;n=l;b.render(a,d.render(u(l,null,h,void 0,void 0,void 0)))};"function"!==typeof d.resolve&&(d.resolve=function(){m(n)});k!==e?d.resolve(m,h,k,l):m(n)}else b.render(a,u(d,null,h,void 0,void 0,void 0))},function(){d.setPath(k,null,{replace:!0})});Z(a,b,h,l)};
a.link=d.link;a.prefix=d.setPrefix;a.set=d.setPath;a.get=d.getPath;return a}(window,K,H);l.mount=function(a,b){return function(h,d){Z(h,a,b,function(){a.render(h,{tag:d})})()}}(K,H);l.trust=function(a){return u("<",void 0,void 0,a,void 0,void 0)};l.withAttr=function(a,b,h){return function(d){return b.call(h||this,a in d.currentTarget?d.currentTarget[a]:d.currentTarget.getAttribute(a))}};l.prop=C.stream;l.prop.combine=C.combine;l.prop.reject=C.reject;l.prop.merge=C.merge;l.prop.HALT=C.HALT;l.render=
K.render;l.redraw=H.publish;l.request=M.xhr;l.jsonp=M.jsonp;l.version="1.0.0";window.m=l})()};
a._state.state}function U(a){return a._state.changed}function ha(a){return 2!==a._state.state}function V(a){return a._state.error}function u(a,b,h,d,g,p){return{tag:a,key:b,attrs:h,children:d,text:g,dom:p,domSize:void 0,state:{},events:void 0,instance:void 0}}var aa=0,P=function(){},F={},C={stream:y,merge:function(a){return G(function(){return a.map(function(a){return a()})},a)},combine:G,reject:function(a){var b=y();b.error(a);return b},HALT:F};u.normalize=function(a){return a instanceof Array?u("[",
void 0,void 0,u.normalizeChildren(a),void 0,void 0):null!=a&&"object"!==typeof a?u("#",void 0,void 0,a,void 0,void 0):a};u.normalizeChildren=function(a){for(var b=0;b<a.length;b++)a[b]=u.normalize(a[b]);return a};var ia=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,J={},n=function(a){if("string"===typeof a&&void 0===J[a]){for(var b,h,d=[],g={};b=ia.exec(a);){var p=b[1],l=b[2];""===p&&""!==l?h=l:"#"===p?g.id=l:"."===p?d.push(l):"["===b[3][0]&&((p=b[6])&&(p=p.replace(/\\(["'])/g,
"$1").replace(/\\\\/g,"\\")),g[b[4]]=p||!0)}0<d.length&&(g.className=d.join(" "));J[a]=function(a,b){var d=!1,k,p,m=a.className||a["class"],l;for(l in g)a[l]=g[l];void 0!==m&&(void 0!==a["class"]&&(a["class"]=void 0,a.className=m),void 0!==g.className&&(a.className=g.className+" "+m));for(l in a)if("key"!==l){d=!0;break}b instanceof Array&&1==b.length&&null!=b[0]&&"#"===b[0].tag?p=b[0].children:k=b;return u(h||"div",a.key,d?a:void 0,k,p,void 0)}}var m;null!=arguments[1]&&("object"!==typeof arguments[1]||
void 0!==arguments[1].tag||arguments[1]instanceof Array)?d=1:(m=arguments[1],d=2);if(arguments.length===d+1)b=arguments[d]instanceof Array?arguments[d]:[arguments[d]];else for(b=[];d<arguments.length;d++)b.push(arguments[d]);return"string"===typeof a?J[a](m||{},u.normalizeChildren(b)):u(a,m&&m.key,m||{},u.normalizeChildren(b),void 0,void 0)},K=function(a){function b(a,c,e,b,d,q,g){for(;e<b;e++){var k=c[e];null!=k&&f(a,h(k,d,g),q)}}function h(a,c,e){var f=a.tag;null!=a.attrs&&n(a.attrs,a,c);if("string"===
typeof f)switch(f){case "#":return a.dom=x.createTextNode(a.children);case "<":return d(a);case "[":var q=x.createDocumentFragment();null!=a.children&&(f=a.children,b(q,f,0,f.length,c,null,e));a.dom=q.firstChild;a.domSize=q.childNodes.length;return q;default:var g=a.tag;switch(a.tag){case "svg":e="http://www.w3.org/2000/svg";break;case "math":e="http://www.w3.org/1998/Math/MathML"}var k=(f=a.attrs)&&f.is,g=e?k?x.createElementNS(e,g,k):x.createElementNS(e,g):k?x.createElement(g,k):x.createElement(g);
a.dom=g;if(null!=f)for(q in k=e,f)A(a,q,null,f[q],k);null!=a.text&&(""!==a.text?g.textContent=a.text:a.children=[u("#",void 0,void 0,a.text,void 0,void 0)]);null!=a.children&&(q=a.children,b(g,q,0,q.length,c,null,e),c=a.attrs,"select"===a.tag&&null!=c&&("value"in c&&A(a,"value",null,c.value,void 0),"selectedIndex"in c&&A(a,"selectedIndex",null,c.selectedIndex,void 0)));return g}else return a.state=C(a.tag),n(a.tag,a,c),a.instance=u.normalize(a.tag.view.call(a.state,a)),null!=a.instance?(c=h(a.instance,
c,e),a.dom=a.instance.dom,a.domSize=null!=a.dom?a.instance.domSize:0,a=c):(a.domSize=0,a=ja),a}function d(a){var c={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(a.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",c=x.createElement(c);c.innerHTML=a.children;a.dom=c.firstChild;a.domSize=c.childNodes.length;a=x.createDocumentFragment();for(var e;e=c.firstChild;)a.appendChild(e);return a}function g(a,c,e,d,g,k){if(c!==e&&(null!=c||
null!=e))if(null==c)b(a,e,0,e.length,d,g,void 0);else if(null==e)q(a,c,0,c.length,e);else{var z;a:{if(null!=c.pool&&Math.abs(c.pool.length-e.length)<=Math.abs(c.length-e.length)&&(z=e[0]&&e[0].children&&e[0].children.length||0,Math.abs((c.pool[0]&&c.pool[0].children&&c.pool[0].children.length||0)-z)<=Math.abs((c[0]&&c[0].children&&c[0].children.length||0)-z))){z=!0;break a}z=!1}z&&(c=c.concat(c.pool));if(c.length===e.length&&null!=e[0]&&null==e[0].key)for(var r=0;r<c.length;r++)c[r]===e[r]||null==
c[r]&&null==e[r]||(null==c[r]?f(a,h(e[r],d,k),m(c,r+1,g)):null==e[r]?q(a,c,r,r+1,e):p(a,c[r],e[r],d,m(c,r+1,g),z,k),z&&c[r].tag===e[r].tag&&f(a,l(c[r]),m(c,r+1,g)));else{for(var A=r=0,v=c.length-1,B=e.length-1,u;v>=r&&B>=A;){var t=c[r],w=e[A];if(t===w)r++,A++;else if(null!=t&&null!=w&&t.key===w.key)r++,A++,p(a,t,w,d,m(c,r,g),z,k),z&&t.tag===w.tag&&f(a,l(t),g);else if(t=c[v],t===w)v--,A++;else if(null!=t&&null!=w&&t.key===w.key)p(a,t,w,d,m(c,v+1,g),z,k),f(a,l(t),m(c,r,g)),v--,A++;else break}for(;v>=
r&&B>=A;){t=c[v];w=e[B];if(t===w)v--;else if(null!=t&&null!=w&&t.key===w.key)p(a,t,w,d,m(c,v+1,g),z,k),z&&t.tag===w.tag&&f(a,l(t),g),null!=t.dom&&(g=t.dom),v--;else{if(!u){u=c;var t=v,n={},x;for(x=0;x<t;x++){var y=u[x];null!=y&&(y=y.key,null!=y&&(n[y]=x))}u=n}null!=w&&(t=u[w.key],null!=t?(n=c[t],p(a,n,w,d,m(c,v+1,g),z,k),f(a,l(n),g),c[t].skip=!0,null!=n.dom&&(g=n.dom)):(w=h(w,d,void 0),f(a,w,g),g=w))}B--;if(B<A)break}b(a,e,A,B+1,d,g,k);q(a,c,r,v+1,e)}}}function p(a,c,e,b,k,q,m){var r=c.tag;if(r===
e.tag){e.state=c.state;e.events=c.events;var v;var B;null!=e.attrs&&"function"===typeof e.attrs.onbeforeupdate&&(v=e.attrs.onbeforeupdate.call(e.state,e,c));"string"!==typeof e.tag&&"function"===typeof e.tag.onbeforeupdate&&(B=e.tag.onbeforeupdate.call(e.state,e,c));void 0===v&&void 0===B||v||B?v=!1:(e.dom=c.dom,e.domSize=c.domSize,e.instance=c.instance,v=!0);if(!v)if(null!=e.attrs&&y(e.attrs,e,b,q),"string"===typeof r)switch(r){case "#":c.children.toString()!==e.children.toString()&&(c.dom.nodeValue=
e.children);e.dom=c.dom;break;case "<":c.children!==e.children?(l(c),f(a,d(e),k)):(e.dom=c.dom,e.domSize=c.domSize);break;case "[":g(a,c.children,e.children,b,k,m);c=0;b=e.children;e.dom=null;if(null!=b){for(var n=0;n<b.length;n++)a=b[n],null!=a&&null!=a.dom&&(null==e.dom&&(e.dom=a.dom),c+=a.domSize||1);1!==c&&(e.domSize=c)}break;default:a=m;k=e.dom=c.dom;switch(e.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}"textarea"===e.tag&&(null==e.attrs&&
(e.attrs={}),null!=e.text&&(e.attrs.value=e.text));q=c.attrs;m=e.attrs;r=a;if(null!=m)for(n in m)A(e,n,q&&q[n],m[n],r);if(null!=q)for(n in q)null!=m&&n in m||"key"!==n&&e.dom.removeAttribute(n);null!=c.text&&null!=e.text&&""!==e.text?c.text.toString()!==e.text.toString()&&(c.dom.firstChild.nodeValue=e.text):(null!=c.text&&(c.children=[u("#",void 0,void 0,c.text,void 0,c.dom.firstChild)]),null!=e.text&&(e.children=[u("#",void 0,void 0,e.text,void 0,void 0)]),g(k,c.children,e.children,b,null,a))}else e.instance=
u.normalize(e.tag.view.call(e.state,e)),y(e.tag,e,b,q),null!=e.instance?(null==c.instance?f(a,h(e.instance,b,m),k):p(a,c.instance,e.instance,b,k,q,m),e.dom=e.instance.dom,e.domSize=e.instance.domSize):null!=c.instance?(z(a,c.instance,null,!1),e.dom=void 0,e.domSize=0):(e.dom=c.dom,e.domSize=c.domSize)}else z(a,c,null,!1),f(a,h(e,b,void 0),k)}function l(a){var c=a.domSize;if(null!=c||null==a.dom){var e=x.createDocumentFragment();if(0<c){for(a=a.dom;--c;)e.appendChild(a.nextSibling);e.insertBefore(a,
e.firstChild)}return e}return a.dom}function m(a,c,e){for(;c<a.length;c++)if(null!=a[c]&&null!=a[c].dom)return a[c].dom;return e}function f(a,c,e){e&&e.parentNode?a.insertBefore(c,e):a.appendChild(c)}function q(a,c,e,b,f){for(;e<b;e++){var d=c[e];null!=d&&(d.skip?d.skip=void 0:z(a,d,f,!1))}}function z(a,c,e,b){if(!1===b){var f=0,d=0;b=function(){++d===f&&z(a,c,e,!0)};c.attrs&&c.attrs.onbeforeremove&&(f++,c.attrs.onbeforeremove.call(c.state,c,b));"string"!==typeof c.tag&&c.tag.onbeforeremove&&(f++,
c.tag.onbeforeremove.call(c.state,c,b));if(0<f)return}k(c);if(c.dom){b=c.domSize||1;if(1<b)for(var g=c.dom;--b;)a.removeChild(g.nextSibling);null!=c.dom.parentNode&&a.removeChild(c.dom);null==e||null!=c.domSize||v(c.attrs)||"string"!==typeof c.tag||(e.pool?e.pool.push(c):e.pool=[c])}}function k(a){a.attrs&&a.attrs.onremove&&a.attrs.onremove.call(a.state,a);"string"!==typeof a.tag&&a.tag.onremove&&a.tag.onremove.call(a.state,a);if(null!=a.instance)k(a.instance);else if(a=a.children,a instanceof Array)for(var c=
0;c<a.length;c++){var b=a[c];null!=b&&k(b)}}function A(a,c,b,f,d){var g=a.dom;if("key"!==c&&(b!==f||"value"===c||"checked"===c||"selectedIndex"===c||"selected"===c&&a.dom===x.activeElement||"object"===typeof f)&&"undefined"!==typeof f&&"oninit"!==c&&"oncreate"!==c&&"onupdate"!==c&&"onremove"!==c&&"onbeforeremove"!==c&&"onbeforeupdate"!==c){var q=c.indexOf(":");if(-1<q&&"xlink"===c.substr(0,q))g.setAttributeNS("http://www.w3.org/1999/xlink",c.slice(q+1),f);else if("o"===c[0]&&"n"===c[1]&&"function"===
typeof f)B(a,c,f);else if("style"===c)if(a=b,a===f&&(g.cssText="",a=null),null==f)g.cssText="";else if("string"===typeof f)g.cssText=f;else{"string"===typeof a&&(g.cssText="");for(var k in f)g.style[k]=f[k];if(null!=a&&"string"!==typeof a)for(k in a)k in f||(g.style[k]="")}else if(c in g&&"href"!==c&&"list"!==c&&"form"!==c&&void 0===d){if("input"!==a.tag||"value"!==c||a.dom.value!==f||a.dom!==x.activeElement)g[c]=f}else"boolean"===typeof f?f?g.setAttribute(c,""):g.removeAttribute(c):g.setAttribute("className"===
c?"class":c,f)}}function v(a){return null!=a&&(a.oncreate||a.onupdate||a.onbeforeremove||a.onremove)}function B(a,c,f){var b=a.dom,g=function(a){var c=f.call(b,a);"function"===typeof D&&D.call(b,a);return c};if(c in b)b[c]=g;else{var d=c.slice(2);void 0===a.events&&(a.events={});null!=a.events[c]&&b.removeEventListener(d,a.events[c],!1);a.events[c]=g;b.addEventListener(d,a.events[c],!1)}}function n(a,c,b){"function"===typeof a.oninit&&a.oninit.call(c.state,c);"function"===typeof a.oncreate&&b.push(a.oncreate.bind(c.state,
c))}function y(a,c,b,f){f?n(a,c,b):"function"===typeof a.onupdate&&b.push(a.onupdate.bind(c.state,c))}function C(a){if(a instanceof Array){for(var c=[],b=0;b<a.length;b++)c[b]=a[b];return c}if("object"===typeof a){c={};for(b in a)c[b]=a[b];return c}return a}var x=a.document,ja=x.createDocumentFragment(),D;return{render:function(a,c){var b=[],f=x.activeElement;null==a.vnodes&&(a.vnodes=[],a.textContent="");c instanceof Array||(c=[c]);g(a,a.vnodes,u.normalizeChildren(c),b,null,void 0);a.vnodes=c;for(var d=
0;d<b.length;d++)b[d]();x.activeElement!==f&&f.focus()},setEventCallback:function(a){return D=a}}}(window),L=function(a){function b(a,d){if(d instanceof Array)for(var l=0;l<d.length;l++)b(a+"["+l+"]",d[l]);else if("[object Object]"===Object.prototype.toString.call(d))for(l in d)b(a+"["+l+"]",d[l]);else h.push(encodeURIComponent(a)+(null!=d&&""!==d?"="+encodeURIComponent(d):""))}if("[object Object]"!==Object.prototype.toString.call(a))return"";var h=[],d;for(d in a)b(d,a[d]);return h.join("&")},M=
function(a){function b(a,b){if(null==b)return a;for(var d=a.match(/:[^\/]+/gi)||[],g=0;g<d.length;g++){var h=d[g].slice(1);null!=b[h]&&(a=a.replace(d[g],b[h]),delete b[h])}return a}function h(a,b){var d=L(b);if(""!==d){var g=0>a.indexOf("?")?"?":"&";a+=g+d}return a}function d(a){try{return""!==a?JSON.parse(a):null}catch(b){throw Error(a);}}function g(a){return a.responseText}function p(a,b){if("function"===typeof a)if(b instanceof Array)for(var d=0;d<b.length;d++)b[d]=new a(b[d]);else return new a(b);
return b}var l=0,m;return{xhr:function(f){var q=C.stream();void 0!==f.initialValue&&q(f.initialValue);var l="boolean"===typeof f.useBody?f.useBody:"GET"!==f.method&&"TRACE"!==f.method;"function"!==typeof f.serialize&&(f.serialize="undefined"!==typeof FormData&&f.data instanceof FormData?function(a){return a}:JSON.stringify);"function"!==typeof f.deserialize&&(f.deserialize=d);"function"!==typeof f.extract&&(f.extract=g);f.url=b(f.url,f.data);l?f.data=f.serialize(f.data):f.url=h(f.url,f.data);var k=
new a.XMLHttpRequest;k.open(f.method,f.url,"boolean"===typeof f.async?f.async:!0,"string"===typeof f.user?f.user:void 0,"string"===typeof f.password?f.password:void 0);f.serialize===JSON.stringify&&l&&k.setRequestHeader("Content-Type","application/json; charset=utf-8");f.deserialize===d&&k.setRequestHeader("Accept","application/json, text/*");"function"===typeof f.config&&(k=f.config(k,f)||k);k.onreadystatechange=function(){if(4===k.readyState){try{var a=f.extract!==g?f.extract(k,f):f.deserialize(f.extract(k,
f));if(200<=k.status&&300>k.status)q(p(f.type,a));else{var b=Error(k.responseText),d;for(d in a)b[d]=a[d];q.error(b)}}catch(h){q.error(h)}"function"===typeof m&&m()}};l?k.send(f.data):k.send();return q},jsonp:function(f){var d=C.stream();void 0!==f.initialValue&&d(f.initialValue);var g=f.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+l++,k=a.document.createElement("script");a[g]=function(b){k.parentNode.removeChild(k);d(p(f.type,b));"function"===typeof m&&m();delete a[g]};k.onerror=
function(){k.parentNode.removeChild(k);d.error(Error("JSONP request failed"));"function"===typeof m&&m();delete a[g]};null==f.data&&(f.data={});f.url=b(f.url,f.data);f.data[f.callbackKey||"callback"]=g;k.src=h(f.url,f.data);a.document.documentElement.appendChild(k);return d},setCompletionCallback:function(a){m=a}}}(window),H=function(){var a=[];return{subscribe:a.push.bind(a),unsubscribe:function(b){b=a.indexOf(b);-1<b&&a.splice(b,1)},publish:function(){for(var b=0;b<a.length;b++)a[b].apply(this,
arguments)}}}();M.setCompletionCallback(H.publish);var Y=function(a){if(""===a||null==a)return{};"?"===a.charAt(0)&&(a=a.slice(1));a=a.split("&");for(var b={},h={},d=0;d<a.length;d++){var g=a[d].split("="),p=decodeURIComponent(g[0]),g=2===g.length?decodeURIComponent(g[1]):"",l=Number(g);""!==g&&!isNaN(l)||"NaN"===g?g=l:"true"===g?g=!0:"false"===g?g=!1:(l=new Date(g),isNaN(l.getTime())||(g=l));var l=p.split(/\]\[?|\[/),m=b;-1<p.indexOf("[")&&l.pop();for(var f=0;f<l.length;f++){var p=l[f],q=l[f+1],
q=""==q||!isNaN(parseInt(q,10)),n=f===l.length-1;""===p&&(p=l.slice(0,f).join(),null==h[p]&&(h[p]=0),p=h[p]++);null==m[p]&&(m[p]=n?g:q?[]:{});m=m[p]}}return b},ka=function(a){function b(b){var d=a.location[b].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===b&&"/"!==d[0]&&(d="/"+d);return d}function h(a,b,d){var g=a.indexOf("?"),h=a.indexOf("#"),m=-1<g?g:-1<h?h:a.length;if(-1<g){var g=Y(a.slice(g+1,-1<h?h:a.length)),l;for(l in g)b[l]=g[l]}if(-1<h)for(l in b=Y(a.slice(h+1)),b)d[l]=
b[l];return a.slice(0,m)}function d(){switch(m.charAt(0)){case "#":return b("hash").slice(m.length);case "?":return b("search").slice(m.length)+b("hash");default:return b("pathname").slice(m.length)+b("search")+b("hash")}}function g(b,d,g){var k={},l={};b=h(b,k,l);if(null!=d){for(var n in d)k[n]=d[n];b=b.replace(/:([^\/]+)/g,function(a,b){delete k[b];return d[b]})}(n=L(k))&&(b+="?"+n);(l=L(l))&&(b+="#"+l);p?(g&&g.replace?a.history.replaceState(null,null,m+b):a.history.pushState(null,null,m+b),a.onpopstate()):
a.location.href=m+b}var p="function"===typeof a.history.pushState,l="function"===typeof setImmediate?setImmediate:setTimeout,m="#!";return{setPrefix:function(a){m=a},getPath:d,setPath:g,defineRoutes:function(b,g,n){function k(){var a=d(),k={},m=h(a,k,k);l(function(){for(var d in b){var h=new RegExp("^"+d.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(h.test(m)){m.replace(h,function(){for(var h=d.match(/:[^\/]+/g)||[],l=[].slice.call(arguments,1,-2),m=0;m<h.length;m++)k[h[m].replace(/:|\./g,
"")]=decodeURIComponent(l[m]);g(b[d],k,a,d)});return}}n(a,k)})}p?a.onpopstate=k:"#"===m.charAt(0)&&(a.onhashchange=k);k();return k},link:function(a){a.dom.setAttribute("href",m+a.attrs.href);a.dom.onclick=function(b){b.preventDefault();b.redraw=!1;g(a.attrs.href,void 0,void 0)}}}},la=function(a){var b=0,h=null,d="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(g){var n=Date.now();!0===g||0===b||16<=n-b?(b=n,a()):null===h&&(h=d(function(){h=null;a();b=Date.now()},
16-(n-b)))}},Z=function(a,b,h,d){d=la(d);null!=b&&b.setEventCallback(function(a){!1!==a.redraw&&h.publish()});null!=h&&(a.redraw&&h.unsubscribe(a.redraw),h.subscribe(d));return a.redraw=d};n.route=function(a,b,h){var d=ka(a);a=function(a,n,l){var m=null,f=null;l=d.defineRoutes(l,function(d,h,k,l){if("function"!==typeof d.view){"function"!==typeof d.render&&(d.render=function(a){return a});var n=function(l){m=k;f=l;b.render(a,d.render(u(l,null,h,void 0,void 0,void 0)))};"function"!==typeof d.resolve&&
(d.resolve=function(){n(f)});k!==m?d.resolve(n,h,k,l):n(f)}else b.render(a,u(d,null,h,void 0,void 0,void 0))},function(){d.setPath(n,null,{replace:!0})});Z(a,b,h,l)};a.link=d.link;a.prefix=d.setPrefix;a.set=d.setPath;a.get=d.getPath;return a}(window,K,H);var ma={view:function(){}};n.mount=function(a,b){return function(h,d){b.unsubscribe(h.redraw);Z(h,a,b,function(){a.render(h,u(null===d?ma:d,void 0,void 0,void 0,void 0,void 0))})();null===d&&(b.unsubscribe(h.redraw),delete h.redraw)}}(K,H);n.trust=
function(a){return u("<",void 0,void 0,a,void 0,void 0)};n.withAttr=function(a,b,h){return function(d){return b.call(h||this,a in d.currentTarget?d.currentTarget[a]:d.currentTarget.getAttribute(a))}};n.prop=C.stream;n.prop.combine=C.combine;n.prop.reject=C.reject;n.prop.merge=C.merge;n.prop.HALT=C.HALT;n.render=K.render;n.redraw=H.publish;n.request=M.xhr;n.jsonp=M.jsonp;n.version="1.0.0";"undefined"!==typeof module?module.exports=n:window.m=n};

View file

@ -109,7 +109,7 @@ module.exports = function($window) {
//update
function updateNodes(parent, old, vnodes, hooks, nextSibling, ns) {
if (old == null && vnodes == null) return
if (old === vnodes || old == null && vnodes == null) return
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined)
else if (vnodes == null) removeNodes(parent, old, 0, old.length, vnodes)
else {
@ -118,7 +118,7 @@ module.exports = function($window) {
if (old.length === vnodes.length && vnodes[0] != null && vnodes[0].key == null) {
for (var i = 0; i < old.length; i++) {
if (old[i] == null && vnodes[i] == null) continue
if (old[i] === vnodes[i] || old[i] == null && vnodes[i] == null) continue
else if (old[i] == null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling))
else if (vnodes[i] == null) removeNodes(parent, old, i, i + 1, vnodes)
else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), recycling, ns)
@ -441,11 +441,11 @@ module.exports = function($window) {
//style
function updateStyle(element, old, style) {
if (old === style) element.style = "", old = null
if (style == null) element.style = ""
else if (typeof style === "string") element.style = style
if (old === style) element.cssText = "", old = null
if (style == null) element.cssText = ""
else if (typeof style === "string") element.cssText = style
else {
if (typeof old === "string") element.style = ""
if (typeof old === "string") element.cssText = ""
for (var key in style) {
element.style[key] = style[key]
}
@ -514,7 +514,12 @@ module.exports = function($window) {
function render(dom, vnodes) {
var hooks = []
var active = $doc.activeElement
if (dom.vnodes == null) dom.vnodes = []
// First time rendering into a node clears it out
if (dom.vnodes == null) {
dom.vnodes = []
dom.textContent = "";
}
if (!(vnodes instanceof Array)) vnodes = [vnodes]
updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), hooks, null, undefined)

View file

@ -38,6 +38,7 @@
<script src="test-input.js"></script>
<script src="test-textContent.js"></script>
<script src="test-component.js"></script>
<script src="test-render.js"></script>
<script>require("../../ospec/ospec").run()</script>
</body>

View file

@ -0,0 +1,24 @@
"use strict"
var o = require("../../ospec/ospec")
var domMock = require("../../test-utils/domMock")
var vdom = require("../../render/render")
o.spec("render", function() {
var $window, root, render
o.beforeEach(function() {
$window = domMock()
root = $window.document.createElement("div")
render = vdom($window).render
})
o("overwrites existing content", function() {
var vnodes = []
root.appendChild($window.document.createElement("div"));
render(root, vnodes)
o(root.childNodes.length).equals(0)
})
})

View file

@ -845,4 +845,22 @@ o.spec("updateNodes", function() {
o(root.childNodes[0].nodeName).equals("A")
o(root.childNodes[1].nodeName).equals("S")
})
o("cached, non-keyed nodes skip diff", function () {
var onupdate = o.spy();
var cached = {tag:"a", attrs:{onupdate: onupdate}}
render(root, cached)
render(root, cached)
o(onupdate.callCount).equals(0)
})
o("cached, keyed nodes skip diff", function () {
var onupdate = o.spy();
var cached = {tag:"a", key:"a", attrs:{onupdate: onupdate}}
render(root, cached)
render(root, cached)
o(onupdate.callCount).equals(0)
})
})

View file

@ -38,7 +38,7 @@ module.exports = function($window) {
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
try {
var response = args.deserialize(args.extract(xhr, args))
var response = (args.extract !== extract) ? args.extract(xhr, args) : args.deserialize(args.extract(xhr, args))
if (xhr.status >= 200 && xhr.status < 300) {
stream(cast(args.type, response))
}

View file

@ -210,7 +210,7 @@ o.spec("xhr", function() {
}
})
xhr({method: "GET", url: "/item", extract: extract}).map(function(data) {
o(data).deepEquals({test: 123})
o(data).equals("{\"test\":123}")
}).map(done)
})
o("extract parameter works in POST", function(done) {
@ -224,7 +224,24 @@ o.spec("xhr", function() {
}
})
xhr({method: "POST", url: "/item", extract: extract}).map(function(data) {
o(data).deepEquals({test: 123})
o(data).equals("{\"test\":123}")
}).map(done)
})
o("ignores deserialize if extract is defined", function(done) {
var extract = function(data) {
return data.status
}
var deserialize = o.spy()
mock.$defineRoutes({
"GET /item": function(request) {
return {status: 200, responseText: ""}
}
})
xhr({method: "GET", url: "/item", extract: extract, deserialize: deserialize}).map(function(data) {
o(data).equals(200)
}).map(function() {
o(deserialize.callCount).equals(0)
}).map(done)
})
o("config parameter works", function(done) {

View file

@ -136,7 +136,11 @@ module.exports = function() {
get style() {
return style
},
set style(value) {
set style(_){
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style#Setting_style
throw new Error("setting element.style is not portable")
},
set cssText(value) {
if (typeof value === "string") {
for (var key in style) style[key] = ""
var rules = value.split(";")

View file

@ -474,20 +474,30 @@ o.spec("domMock", function() {
o(typeof div.style).equals("object")
})
o("setting style string works", function() {
o("setting cssText string works", function() {
var div = $document.createElement("div")
div.style = "background-color: red; border-bottom: 1px solid red;"
div.cssText = "background-color: red; border-bottom: 1px solid red;"
o(div.style.backgroundColor).equals("red")
o(div.style.borderBottom).equals("1px solid red")
})
o("removing via setting style string works", function() {
o("removing via setting cssText string works", function() {
var div = $document.createElement("div")
div.style = "background: red;"
div.style = ""
div.cssText = "background: red;"
div.cssText = ""
o(div.style.background).equals("")
})
o("setting style throws", function () {
var err = false
try {
div.style = ''
} catch (e) {
err = e
}
o(err instanceof Error).equals(true)
})
})
o.spec("events", function() {
o.spec("click", function() {