Fix merge conflict

This commit is contained in:
Pierre-Yves Gérardy 2017-07-11 10:48:02 +02:00
commit 22bc7b2a9f
33 changed files with 2231 additions and 254 deletions

View file

@ -26,7 +26,8 @@ function throttle(callback) {
module.exports = function($window) {
var renderService = coreRenderer($window)
renderService.setEventCallback(function(e) {
if (e.redraw !== false) redraw()
if (e.redraw === false) e.redraw = undefined
else redraw()
})
var callbacks = []

View file

@ -39,7 +39,10 @@ module.exports = function($window, redrawService) {
redrawService.subscribe(root, run)
}
route.set = function(path, data, options) {
if (lastUpdate != null) options = {replace: true}
if (lastUpdate != null) {
options = options || {}
options.replace = true
}
lastUpdate = null
routeService.setPath(path, data, options)
}

View file

@ -5,7 +5,6 @@ var components = require("../../test-utils/components")
var domMock = require("../../test-utils/domMock")
var m = require("../../render/hyperscript")
var coreRenderer = require("../../render/render")
var apiRedraw = require("../../api/redraw")
var apiMounter = require("../../api/mount")
@ -20,7 +19,7 @@ o.spec("mount", function() {
redrawService = apiRedraw($window)
mount = apiMounter(redrawService)
render = coreRenderer($window).render
render = redrawService.render
})
o("throws on invalid component", function() {

View file

@ -224,9 +224,11 @@ o.spec("route", function() {
}
})
o(oninit.callCount).equals(1)
root.firstChild.dispatchEvent(e)
o(oninit.callCount).equals(1)
o(e.redraw).notEquals(false)
// Wrapped to ensure no redraw fired
callAsync(function() {
@ -665,7 +667,7 @@ o.spec("route", function() {
route(root, "/a", {
"/a" : {
onmatch: function() {
route.set("/b")
route.set("/b", {}, {state: {a: 5}})
},
render: render
},
@ -684,6 +686,7 @@ o.spec("route", function() {
o(view.callCount).equals(1)
o(root.childNodes.length).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o($window.history.state).deepEquals({a: 5})
done()
})

View file

@ -1,5 +1,6 @@
# Change log
- [v1.1.2](#v112)
- [v1.1.1](#v111)
- [v1.1.0](#v110)
- [v1.0.1](#v101)
@ -8,6 +9,33 @@
---
### v1.1.2
#### Bug fixes:
- core: Namespace fixes [#1819](https://github.com/MithrilJS/mithril.js/issues/1819), ([#1825](https://github.com/MithrilJS/mithril.js/pull/1825) [@SamuelTilly](https://github.com/SamuelTilly)), [#1820](https://github.com/MithrilJS/mithril.js/issues/1820) ([#1864](https://github.com/MithrilJS/mithril.js/pull/1864)), [#1872](https://github.com/MithrilJS/mithril.js/issues/1872) ([#1873](https://github.com/MithrilJS/mithril.js/pull/1873))
- core: Fix select option to allow empty string value [#1814](https://github.com/MithrilJS/mithril.js/issues/1814) ([#1828](https://github.com/MithrilJS/mithril.js/pull/1828) [@spacejack](https://github.com/spacejack))
- core: Reset e.redraw when it was set to `false` [#1850](https://github.com/MithrilJS/mithril.js/issues/1850) ([#1890](https://github.com/MithrilJS/mithril.js/pull/1890))
- core: differentiate between `{ value: "" }` and `{ value: 0 }` for form elements [#1595 comment](https://github.com/MithrilJS/mithril.js/pull/1595#issuecomment-304071453) ([#1862](https://github.com/MithrilJS/mithril.js/pull/1862))
- core: Don't reset the cursor of textareas in IE10 when setting an identical `value` [#1870](https://github.com/MithrilJS/mithril.js/issues/1870) (([#1871](https://github.com/MithrilJS/mithril.js/pull/1871)))
- hypertext: Correct handling of `[value=""]` ([#1843](https://github.com/MithrilJS/mithril.js/issues/1843), [@CreaturesInUnitards](https://github.com/CreaturesInUnitards))
- router: Don't overwrite the options object when redirecting from `onmatch with m.route.set()` [#1857](https://github.com/MithrilJS/mithril.js/issues/1857) ([#1889](https://github.com/MithrilJS/mithril.js/pull/1889))
- stream: Move the "use strict" directive inside the IIFE [#1831](https://github.com/MithrilJS/mithril.js/issues/1831) ([#1893](https://github.com/MithrilJS/mithril.js/pull/1893))
#### Ospec improvements:
- Shell command: Ignore hidden directories and files ([#1855](https://github.com/MithrilJS/mithril.js/pull/1855) [@pdfernhout)](https://github.com/pdfernhout))
- Library: Add the possibility to name new test suites ([#1529](https://github.com/MithrilJS/mithril.js/pull/1529))
#### Docs / Repo maintenance:
Our thanks to [@0joshuaolson1](https://github.com/0joshuaolson1), [@ACXgit](https://github.com/ACXgit), [@cavemansspa](https://github.com/cavemansspa), [@CreaturesInUnitards](https://github.com/CreaturesInUnitards), [@dlepaux](https://github.com/dlepaux), [@isaaclyman](https://github.com/isaaclyman), [@kevinkace](https://github.com/kevinkace), [@micellius](https://github.com/micellius), [@spacejack](https://github.com/spacejack) and [@yurivish](https://github.com/yurivish)
#### Other:
- Addition of a performance regression test suite (#)
### v1.1.1
#### Bug fixes
@ -155,7 +183,7 @@ m("div", {
// Called after the node is updated
onupdate : function(vnode) { /*...*/ },
// Called before the node is removed, return a Promise that resolves when
// ready for the node to be removed from the DOM
// ready for the node to be removed from the DOM
onbeforeremove : function(vnode) { /*...*/ },
// Called before the node is removed, but after onbeforeremove calls done()
onremove : function(vnode) { /*...*/ }
@ -472,9 +500,9 @@ In `v0.2.x` reading route params was entirely handled through `m.route.param()`.
```javascript
m.route(document.body, "/booga", {
"/:attr" : {
controller : function() {
m.route.param("attr") // "booga"
},
controller : function() {
m.route.param("attr") // "booga"
},
view : function() {
m.route.param("attr") // "booga"
}
@ -489,11 +517,11 @@ m.route(document.body, "/booga", {
"/:attr" : {
oninit : function(vnode) {
vnode.attrs.attr // "booga"
m.route.param("attr") // "booga"
m.route.param("attr") // "booga"
},
view : function(vnode) {
vnode.attrs.attr // "booga"
m.route.param("attr") // "booga"
m.route.param("attr") // "booga"
}
}
})
@ -531,14 +559,14 @@ It is no longer possible to prevent unmounting via `onunload`'s `e.preventDefaul
```javascript
var Component = {
controller: function() {
this.onunload = function(e) {
if (condition) e.preventDefault()
}
},
view: function() {
return m("a[href=/]", {config: m.route})
}
controller: function() {
this.onunload = function(e) {
if (condition) e.preventDefault()
}
},
view: function() {
return m("a[href=/]", {config: m.route})
}
}
```
@ -546,9 +574,9 @@ var Component = {
```javascript
var Component = {
view: function() {
return m("a", {onclick: function() {if (!condition) m.route.set("/")}})
}
view: function() {
return m("a", {onclick: function() {if (!condition) m.route.set("/")}})
}
}
```
@ -562,14 +590,14 @@ Components no longer call `this.onunload` when they are being removed. They now
```javascript
var Component = {
controller: function() {
this.onunload = function(e) {
// ...
}
},
view: function() {
// ...
}
controller: function() {
this.onunload = function(e) {
// ...
}
},
view: function() {
// ...
}
}
```
@ -577,12 +605,12 @@ var Component = {
```javascript
var Component = {
onremove : function() {
// ...
}
view: function() {
// ...
}
onremove : function() {
// ...
}
view: function() {
// ...
}
}
```
@ -598,13 +626,13 @@ In addition, requests no longer have `m.startComputation`/`m.endComputation` sem
```javascript
var data = m.request({
method: "GET",
url: "https://api.github.com/",
initialValue: [],
method: "GET",
url: "https://api.github.com/",
initialValue: [],
})
setTimeout(function() {
console.log(data())
console.log(data())
}, 1000)
```
@ -613,15 +641,15 @@ setTimeout(function() {
```javascript
var data = []
m.request({
method: "GET",
url: "https://api.github.com/",
method: "GET",
url: "https://api.github.com/",
})
.then(function (responseBody) {
data = responseBody
data = responseBody
})
setTimeout(function() {
console.log(data) // note: not a getter-setter
console.log(data) // note: not a getter-setter
}, 1000)
```
@ -653,11 +681,11 @@ greetAsync()
```javascript
var greetAsync = function() {
return new Promise(function(resolve){
setTimeout(function() {
resolve("hello")
}, 1000)
})
return new Promise(function(resolve){
setTimeout(function() {
resolve("hello")
}, 1000)
})
}
greetAsync()
@ -679,7 +707,7 @@ m.sync([
m.request({ method: 'GET', url: 'https://api.github.com/users/isiahmeadows' }),
])
.then(function (users) {
console.log("Contributors:", users[0].name, "and", users[1].name)
console.log("Contributors:", users[0].name, "and", users[1].name)
})
```
@ -691,7 +719,7 @@ Promise.all([
m.request({ method: 'GET', url: 'https://api.github.com/users/isiahmeadows' }),
])
.then(function (users) {
console.log("Contributors:", users[0].name, "and", users[1].name)
console.log("Contributors:", users[0].name, "and", users[1].name)
})
```
@ -706,7 +734,7 @@ In `v0.2.x`, the `xlink` namespace was the only supported attribute namespace, a
```javascript
m("svg",
// the `href` attribute is namespaced automatically
m("image[href='image.gif']")
m("image[href='image.gif']")
)
```
@ -715,7 +743,7 @@ m("svg",
```javascript
m("svg",
// User-specified namespace on the `href` attribute
m("image[xlink:href='image.gif']")
m("image[xlink:href='image.gif']")
)
```

View file

@ -4,7 +4,7 @@
## How do I go about contributing ideas or new features?
Create an [issue thread on Github](https://github.com/MithrilJS/mithril.js/issues/new) to suggest your idea so the community can discuss it.
Create an [issue thread on GitHub](https://github.com/MithrilJS/mithril.js/issues/new) to suggest your idea so the community can discuss it.
If the consensus is that it's a good idea, the fastest way to get it into a release is to send a pull request. Without a PR, the time to implement the feature will depend on the bandwidth of the development team and its list of priorities.
@ -20,12 +20,12 @@ Ideally, the best way to report bugs is to provide a small snippet of code where
To send a pull request:
- fork the repo (button at the top right in Github)
- clone the forked repo to your computer (green button in Github)
- fork the repo (button at the top right in GitHub)
- clone the forked repo to your computer (green button in GitHub)
- create a feature branch (run `git checkout -b the-feature-branch-name`)
- make your changes
- run the tests (run `npm t`)
- submit a pull request (go to the pull requests tab in Github, click the green button and select your feature branch)
- submit a pull request (go to the pull requests tab in GitHub, click the green button and select your feature branch)

View file

@ -70,10 +70,12 @@ Create a `.babelrc` file:
Next, create a file called `webpack.config.js`
```javascript
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: './bin',
path: path.resolve(__dirname, './bin'),
filename: 'app.js',
},
module: {

View file

@ -112,10 +112,12 @@ Create a `.babelrc` file:
Next, create a file called `webpack.config.js`
```javascript
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: './bin',
path: path.resolve(__dirname, './bin'),
filename: 'app.js',
},
module: {

View file

@ -77,7 +77,7 @@ m.request({
})
```
A call to `m.request` return a [promise](promise.md) and trigger a redraw upon completion of its promise chain.
A call to `m.request` returns a [promise](promise.md) and triggers a redraw upon completion of its promise chain.
By default, `m.request` assumes the response is in JSON format and parses it into a Javascript object (or array).

View file

@ -124,7 +124,7 @@ Argument | Type | Required | Description
##### m.route.param
Retrieves a route parameter. A route parameter is a key-value pair. Route parameters may come from a few different places:
Retrieves a route parameter from the last fully resolved route. A route parameter is a key-value pair. Route parameters may come from a few different places:
- route interpolations (e.g. if a route is `/users/:id`, and it resolves to `/users/1`, the route parameter has a key `id` and value `"1"`)
- router querystrings (e.g. if the path is `/users?page=1`, the route parameter has a key `page` and value `"1"`)
@ -137,9 +137,11 @@ Argument | Type | Required | Description
`key` | `String` | No | A route parameter name (e.g. `id` in route `/users/:id`, or `page` in path `/users/1?page=3`, or a key in `history.state`)
**returns** | `String|Object` | | Returns a value for the specified key. If a key is not specified, it returns an object that contains all the interpolation keys
Note that in the `onmatch` function of a RouteResolver, the new route hasn't yet been fully resolved, and `m.route.params()` will return the parameters of the previous route, if any. `onmatch` receives the parameters of the new route as an argument.
#### RouteResolver
A RouterResolver is an object that contains an `onmatch` method and/or a `render` method. Both methods are optional, but at least one must be present. A RouteResolver is not a component, and therefore it does NOT have lifecycle methods. As a rule of thumb, RouteResolvers should be in the same file as the `m.route` call, whereas component definitions should be in their own modules.
A RouteResolver is an object that contains an `onmatch` method and/or a `render` method. Both methods are optional, but at least one must be present. A RouteResolver is not a component, and therefore it does NOT have lifecycle methods. As a rule of thumb, RouteResolvers should be in the same file as the `m.route` call, whereas component definitions should be in their own modules.
`routeResolver = {onmatch, render}`
@ -506,7 +508,7 @@ In example 2, since `Layout` is the top-level component in both routes, the DOM
#### Authentication
The RouterResolver's `onmatch` hook can be used to run logic before the top level component in a route is initializated. The example below shows how to implement a login wall that prevents users from seeing the `/secret` page unless they login.
The RouteResolver's `onmatch` hook can be used to run logic before the top level component in a route is initializated. The example below shows how to implement a login wall that prevents users from seeing the `/secret` page unless they login.
```javascript
var isLoggedIn = false

View file

@ -392,8 +392,7 @@ var User = {
load: function(id) {
return m.request({
method: "GET",
url: "https://rem-rest-api.herokuapp.com/api/users/:id",
data: {id: id},
url: "https://rem-rest-api.herokuapp.com/api/users/" + id,
withCredentials: true,
})
.then(function(result) {
@ -508,8 +507,7 @@ var User = {
load: function(id) {
return m.request({
method: "GET",
url: "https://rem-rest-api.herokuapp.com/api/users/:id",
data: {id: id},
url: "https://rem-rest-api.herokuapp.com/api/users/" + id,
withCredentials: true,
})
.then(function(result) {
@ -520,7 +518,7 @@ var User = {
save: function() {
return m.request({
method: "PUT",
url: "https://rem-rest-api.herokuapp.com/api/users/:id",
url: "https://rem-rest-api.herokuapp.com/api/users/" + User.current.id,
data: User.current,
withCredentials: true,
})

View file

@ -28,7 +28,7 @@ function compileSelector(selector) {
var attrValue = match[6]
if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
if (match[4] === "class") classes.push(attrValue)
else attrs[match[4]] = attrValue || true
else attrs[match[4]] = attrValue === "" ? attrValue : attrValue || true
}
}
if (classes.length > 0) attrs.className = classes.join(" ")
@ -375,8 +375,15 @@ var requestService = _8(window, PromisePolyfill)
var coreRenderer = function($window) {
var $doc = $window.document
var $emptyFragment = $doc.createDocumentFragment()
var nameSpace = {
svg: "http://www.w3.org/2000/svg",
math: "http://www.w3.org/1998/Math/MathML"
}
var onevent
function setEventCallback(callback) {return onevent = callback}
function getNameSpace(vnode) {
return vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag]
}
//create
function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {
for (var i = start; i < end; i++) {
@ -433,12 +440,9 @@ var coreRenderer = function($window) {
}
function createElement(parent, vnode, hooks, ns, nextSibling) {
var tag = vnode.tag
switch (vnode.tag) {
case "svg": ns = "http://www.w3.org/2000/svg"; break
case "math": ns = "http://www.w3.org/1998/Math/MathML"; break
}
var attrs2 = vnode.attrs
var is = attrs2 && attrs2.is
ns = getNameSpace(vnode) || ns
var element = ns ?
is ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) :
is ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag)
@ -501,7 +505,7 @@ var coreRenderer = function($window) {
//update
function updateNodes(parent, old, vnodes, recycling, hooks, nextSibling, ns) {
if (old === vnodes || old == null && vnodes == null) return
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined)
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, ns)
else if (vnodes == null) removeNodes(old, 0, old.length, vnodes)
else {
if (old.length === vnodes.length) {
@ -578,7 +582,7 @@ var coreRenderer = function($window) {
if (movable.dom != null) nextSibling = movable.dom
}
else {
var dom = createNode(parent, v, hooks, undefined, nextSibling)
var dom = createNode(parent, v, hooks, ns, nextSibling)
nextSibling = dom
}
}
@ -649,10 +653,7 @@ var coreRenderer = function($window) {
}
function updateElement(old, vnode, recycling, hooks, ns) {
var element = vnode.dom = old.dom
switch (vnode.tag) {
case "svg": ns = "http://www.w3.org/2000/svg"; break
case "math": ns = "http://www.w3.org/1998/Math/MathML"; break
}
ns = getNameSpace(vnode) || ns
if (vnode.tag === "textarea") {
if (vnode.attrs == null) vnode.attrs = {}
if (vnode.text != null) {
@ -832,12 +833,21 @@ var coreRenderer = function($window) {
else if (key2[0] === "o" && key2[1] === "n" && typeof value === "function") updateEvent(vnode, key2, value)
else if (key2 === "style") updateStyle(element, old, value)
else if (key2 in element && !isAttribute(key2) && ns === undefined && !isCustomElement(vnode)) {
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
if (vnode.tag === "input" && key2 === "value" && vnode.dom.value == value && vnode.dom === $doc.activeElement) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "select" && key2 === "value" && vnode.dom.value == value && vnode.dom === $doc.activeElement) return
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "option" && key2 === "value" && vnode.dom.value == value) return
if (key2 === "value") {
var normalized0 = "" + value // eslint-disable-line no-implicit-coercion
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
if ((vnode.tag === "input" || vnode.tag === "textarea") && vnode.dom.value === normalized0 && vnode.dom === $doc.activeElement) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "select") {
if (value === null) {
if (vnode.dom.selectedIndex === -1 && vnode.dom === $doc.activeElement) return
} else {
if (old !== null && vnode.dom.value === normalized0 && vnode.dom === $doc.activeElement) return
}
}
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "option" && old != null && vnode.dom.value === normalized0) return
}
// If you assign an input type1 that is not supported by IE 11 with an assignment expression, an error0 will occur.
if (vnode.tag === "input" && key2 === "type") {
element.setAttribute(key2, value)
@ -952,10 +962,11 @@ var coreRenderer = function($window) {
if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
var hooks = []
var active = $doc.activeElement
var namespace = dom.namespaceURI
// First time0 rendering into a node clears it out
if (dom.vnodes == null) dom.textContent = ""
if (!Array.isArray(vnodes)) vnodes = [vnodes]
updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), false, hooks, null, undefined)
updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), false, hooks, null, namespace === "http://www.w3.org/1999/xhtml" ? undefined : namespace)
dom.vnodes = vnodes
for (var i = 0; i < hooks.length; i++) hooks[i]()
if ($doc.activeElement !== active) active.focus()
@ -985,7 +996,8 @@ function throttle(callback) {
var _11 = function($window) {
var renderService = coreRenderer($window)
renderService.setEventCallback(function(e) {
if (e.redraw !== false) redraw()
if (e.redraw === false) e.redraw = undefined
else redraw()
})
var callbacks = []
function subscribe(key1, callback) {
@ -1184,7 +1196,10 @@ var _20 = function($window, redrawService0) {
redrawService0.subscribe(root, run1)
}
route.set = function(path, data, options) {
if (lastUpdate != null) options = {replace: true}
if (lastUpdate != null) {
options = options || {}
options.replace = true
}
lastUpdate = null
routeService.setPath(path, data, options)
}

87
mithril.min.js vendored
View file

@ -1,43 +1,44 @@
(function(){function B(b,d,f,g,e,n){return{tag:b,key:d,attrs:f,children:g,text:e,dom:n,domSize:void 0,state:void 0,_state:void 0,events:void 0,instance:void 0,skip:!1}}function C(b){var d=arguments[1],f=2,g;if(null==b||"string"!==typeof b&&"function"!==typeof b&&"function"!==typeof b.view)throw Error("The selector must be either a string or a component.");if("string"===typeof b){var e;if(!(e=M[b])){g="div";for(var n=[],k={};e=P.exec(b);){var q=e[1],m=e[2];""===q&&""!==m?g=m:"#"===q?k.id=m:"."===q?
n.push(m):"["===e[3][0]&&((q=e[6])&&(q=q.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),"class"===e[4]?n.push(q):k[e[4]]=q||!0)}0<n.length&&(k.className=n.join(" "));e=M[b]={tag:g,attrs:k}}}if(null==d)d={};else if("object"!==typeof d||null!=d.tag||Array.isArray(d))d={},f=1;if(arguments.length===f+1)g=arguments[f],Array.isArray(g)||(g=[g]);else for(g=[];f<arguments.length;)g.push(arguments[f++]);f=B.normalizeChildren(g);if("string"===typeof b){g=!1;var l,u,n=d.className||d["class"],a;for(a in e.attrs)N.call(e.attrs,
a)&&(d[a]=e.attrs[a]);void 0!==n&&(void 0!==d["class"]&&(d["class"]=void 0,d.className=n),null!=e.attrs.className&&(d.className=e.attrs.className+" "+n));for(a in d)if(N.call(d,a)&&"key"!==a){g=!0;break}Array.isArray(f)&&1===f.length&&null!=f[0]&&"#"===f[0].tag?u=f[0].children:l=f;return B(e.tag,d.key,g?d:void 0,l,u)}return B(b,d.key,d,f)}function Q(b){var d=0,f=null,g="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(){var e=Date.now();0===d||16<=e-d?(d=e,
b()):null===f&&(f=g(function(){f=null;b();d=Date.now()},16-(e-d)))}}B.normalize=function(b){return Array.isArray(b)?B("[",void 0,void 0,B.normalizeChildren(b),void 0,void 0):null!=b&&"object"!==typeof b?B("#",void 0,void 0,!1===b?"":b,void 0,void 0):b};B.normalizeChildren=function(b){for(var d=0;d<b.length;d++)b[d]=B.normalize(b[d]);return b};var P=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,M={},N={}.hasOwnProperty;C.trust=function(b){null==b&&(b="");return B("<",
void 0,void 0,b,void 0,void 0)};C.fragment=function(b,d){return B("[",b.key,b,B.normalizeChildren(d),void 0,void 0)};var x=function(b){function d(b,a){return function r(d){var k;try{if(!a||null==d||"object"!==typeof d&&"function"!==typeof d||"function"!==typeof(k=d.then))l(function(){a||0!==b.length||console.error("Possible unhandled promise rejection:",d);for(var f=0;f<b.length;f++)b[f](d);e.length=0;n.length=0;m.state=a;m.retry=function(){r(d)}});else{if(d===g)throw new TypeError("Promise can't be resolved w/ itself");
f(k.bind(d))}}catch(R){q(R)}}}function f(b){function a(a){return function(b){0<d++||a(b)}}var d=0,e=a(q);try{b(a(k),e)}catch(A){e(A)}}if(!(this instanceof x))throw Error("Promise must be called with `new`");if("function"!==typeof b)throw new TypeError("executor must be a function");var g=this,e=[],n=[],k=d(e,!0),q=d(n,!1),m=g._instance={resolvers:e,rejectors:n},l="function"===typeof setImmediate?setImmediate:setTimeout;f(b)};x.prototype.then=function(b,d){function f(b,d,f,k){d.push(function(a){if("function"!==
typeof b)f(a);else try{e(b(a))}catch(w){n&&n(w)}});"function"===typeof g.retry&&k===g.state&&g.retry()}var g=this._instance,e,n,k=new x(function(b,d){e=b;n=d});f(b,g.resolvers,e,!0);f(d,g.rejectors,n,!1);return k};x.prototype["catch"]=function(b){return this.then(null,b)};x.resolve=function(b){return b instanceof x?b:new x(function(d){d(b)})};x.reject=function(b){return new x(function(d,f){f(b)})};x.all=function(b){return new x(function(d,f){var g=b.length,e=0,n=[];if(0===b.length)d([]);else for(var k=
0;k<b.length;k++)(function(k){function m(b){e++;n[k]=b;e===g&&d(n)}null==b[k]||"object"!==typeof b[k]&&"function"!==typeof b[k]||"function"!==typeof b[k].then?m(b[k]):b[k].then(m,f)})(k)})};x.race=function(b){return new x(function(d,f){for(var g=0;g<b.length;g++)b[g].then(d,f)})};"undefined"!==typeof window?("undefined"===typeof window.Promise&&(window.Promise=x),x=window.Promise):"undefined"!==typeof global&&("undefined"===typeof global.Promise&&(global.Promise=x),x=global.Promise);var F=function(b){function d(b,
g){if(Array.isArray(g))for(var e=0;e<g.length;e++)d(b+"["+e+"]",g[e]);else if("[object Object]"===Object.prototype.toString.call(g))for(e in g)d(b+"["+e+"]",g[e]);else f.push(encodeURIComponent(b)+(null!=g&&""!==g?"="+encodeURIComponent(g):""))}if("[object Object]"!==Object.prototype.toString.call(b))return"";var f=[],g;for(g in b)d(g,b[g]);return f.join("&")},S=/^file:\/\//i,K=function(b,d){function f(){function a(){0===--b&&"function"===typeof u&&u()}var b=0;return function A(d){var e=d.then;d.then=
function(){b++;var f=e.apply(d,arguments);f.then(a,function(d){a();if(0===b)throw d;});return A(f)};return d}}function g(a,b){if("string"===typeof a){var d=a;a=b||{};null==a.url&&(a.url=d)}return a}function e(a,b){if(null==b)return a;for(var d=a.match(/:[^\/]+/gi)||[],e=0;e<d.length;e++){var f=d[e].slice(1);null!=b[f]&&(a=a.replace(d[e],b[f]))}return a}function n(a,b){var d=F(b);if(""!==d){var e=0>a.indexOf("?")?"?":"&";a+=e+d}return a}function k(a){try{return""!==a?JSON.parse(a):null}catch(w){throw Error(a);
}}function q(a){return a.responseText}function m(a,b){if("function"===typeof a)if(Array.isArray(b))for(var d=0;d<b.length;d++)b[d]=new a(b[d]);else return new a(b);return b}var l=0,u;return{request:function(a,l){var u=f();a=g(a,l);var w=new d(function(d,f){null==a.method&&(a.method="GET");a.method=a.method.toUpperCase();var g="GET"===a.method||"TRACE"===a.method?!1:"boolean"===typeof a.useBody?a.useBody:!0;"function"!==typeof a.serialize&&(a.serialize="undefined"!==typeof FormData&&a.data instanceof
FormData?function(h){return h}:JSON.stringify);"function"!==typeof a.deserialize&&(a.deserialize=k);"function"!==typeof a.extract&&(a.extract=q);a.url=e(a.url,a.data);g?a.data=a.serialize(a.data):a.url=n(a.url,a.data);var l=new b.XMLHttpRequest,u=!1,w=l.abort;l.abort=function(){u=!0;w.call(l)};l.open(a.method,a.url,"boolean"===typeof a.async?a.async:!0,"string"===typeof a.user?a.user:void 0,"string"===typeof a.password?a.password:void 0);a.serialize===JSON.stringify&&g&&l.setRequestHeader("Content-Type",
"application/json; charset=utf-8");a.deserialize===k&&l.setRequestHeader("Accept","application/json, text/*");a.withCredentials&&(l.withCredentials=a.withCredentials);for(var r in a.headers)({}).hasOwnProperty.call(a.headers,r)&&l.setRequestHeader(r,a.headers[r]);"function"===typeof a.config&&(l=a.config(l,a)||l);l.onreadystatechange=function(){if(!u&&4===l.readyState)try{var h=a.extract!==q?a.extract(l,a):a.deserialize(a.extract(l,a));if(200<=l.status&&300>l.status||304===l.status||S.test(a.url))d(m(a.type,
h));else{var c=Error(l.responseText),p;for(p in h)c[p]=h[p];f(c)}}catch(v){f(v)}};g&&null!=a.data?l.send(a.data):l.send()});return!0===a.background?w:u(w)},jsonp:function(a,k){var u=f();a=g(a,k);var q=new d(function(d,f){var g=a.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+l++,k=b.document.createElement("script");b[g]=function(e){k.parentNode.removeChild(k);d(m(a.type,e));delete b[g]};k.onerror=function(){k.parentNode.removeChild(k);f(Error("JSONP request failed"));delete b[g]};null==
a.data&&(a.data={});a.url=e(a.url,a.data);a.data[a.callbackKey||"callback"]=g;k.src=n(a.url,a.data);b.document.documentElement.appendChild(k)});return!0===a.background?q:u(q)},setCompletionCallback:function(a){u=a}}}(window,x),O=function(b){function d(h,c,p,a,b,d,e){for(;p<a;p++){var v=c[p];null!=v&&f(h,v,b,e,d)}}function f(h,c,p,a,b){var v=c.tag;if("string"===typeof v)switch(c.state={},null!=c.attrs&&C(c.attrs,c,p),v){case "#":return c.dom=D.createTextNode(c.children),l(h,c.dom,b),c.dom;case "<":return g(h,
c,b);case "[":var k=D.createDocumentFragment();null!=c.children&&(v=c.children,d(k,v,0,v.length,p,null,a));c.dom=k.firstChild;c.domSize=k.childNodes.length;l(h,k,b);return k;default:var m=c.tag;switch(c.tag){case "svg":a="http://www.w3.org/2000/svg";break;case "math":a="http://www.w3.org/1998/Math/MathML"}var t=(v=c.attrs)&&v.is,m=a?t?D.createElementNS(a,m,{is:t}):D.createElementNS(a,m):t?D.createElement(m,{is:t}):D.createElement(m);c.dom=m;if(null!=v)for(k in t=a,v)A(c,k,null,v[k],t);l(h,m,b);null!=
c.attrs&&null!=c.attrs.contenteditable?u(c):(null!=c.text&&(""!==c.text?m.textContent=c.text:c.children=[B("#",void 0,void 0,c.text,void 0,void 0)]),null!=c.children&&(h=c.children,d(m,h,0,h.length,p,null,a),h=c.attrs,"select"===c.tag&&null!=h&&("value"in h&&A(c,"value",null,h.value,void 0),"selectedIndex"in h&&A(c,"selectedIndex",null,h.selectedIndex,void 0))));return m}else return e(c,p),null!=c.instance?(p=f(h,c.instance,p,a,b),c.dom=c.instance.dom,c.domSize=null!=c.dom?c.instance.domSize:0,l(h,
p,b),c=p):(c.domSize=0,c=J),c}function g(h,c,p){var a={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(c.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",a=D.createElement(a);a.innerHTML=c.children;c.dom=a.firstChild;c.domSize=a.childNodes.length;c=D.createDocumentFragment();for(var b;b=a.firstChild;)c.appendChild(b);l(h,c,p);return c}function e(h,c){var a;if("function"===typeof h.tag.view){h.state=Object.create(h.tag);a=h.state.view;
if(null!=a.$$reentrantLock$$)return J;a.$$reentrantLock$$=!0}else{h.state=void 0;a=h.tag;if(null!=a.$$reentrantLock$$)return J;a.$$reentrantLock$$=!0;h.state=null!=h.tag.prototype&&"function"===typeof h.tag.prototype.view?new h.tag(h):h.tag(h)}h._state=h.state;null!=h.attrs&&C(h.attrs,h,c);C(h._state,h,c);h.instance=B.normalize(h._state.view.call(h.state,h));if(h.instance===h)throw Error("A view cannot return the vnode it received as argument");a.$$reentrantLock$$=null}function n(h,c,p,b,e,g,n){if(c!==
p&&(null!=c||null!=p))if(null==c)d(h,p,0,p.length,e,g,void 0);else if(null==p)a(c,0,c.length,p);else{if(c.length===p.length){for(var v=!1,t=0;t<p.length;t++)if(null!=p[t]&&null!=c[t]){v=null==p[t].key&&null==c[t].key;break}if(v){for(t=0;t<c.length;t++)c[t]!==p[t]&&(null==c[t]&&null!=p[t]?f(h,p[t],e,n,m(c,t+1,g)):null==p[t]?a(c,t,t+1,p):k(h,c[t],p[t],e,m(c,t+1,g),b,n));return}}if(!b)a:{if(null!=c.pool&&Math.abs(c.pool.length-p.length)<=Math.abs(c.length-p.length)&&(b=p[0]&&p[0].children&&p[0].children.length||
0,Math.abs((c.pool[0]&&c.pool[0].children&&c.pool[0].children.length||0)-b)<=Math.abs((c[0]&&c[0].children&&c[0].children.length||0)-b))){b=!0;break a}b=!1}if(b){var u=c.pool;c=c.concat(c.pool)}for(var t=v=0,w=c.length-1,y=p.length-1,G;w>=v&&y>=t;){var r=c[v],z=p[t];if(r!==z||b)if(null==r)v++;else if(null==z)t++;else if(r.key===z.key){var A=null!=u&&v>=c.length-u.length||null==u&&b;v++;t++;k(h,r,z,e,m(c,v,g),A,n);b&&r.tag===z.tag&&l(h,q(r),g)}else if(r=c[w],r!==z||b)if(null==r)w--;else if(null==z)t++;
else if(r.key===z.key)A=null!=u&&w>=c.length-u.length||null==u&&b,k(h,r,z,e,m(c,w+1,g),A,n),(b||t<y)&&l(h,q(r),m(c,v,g)),w--,t++;else break;else w--,t++;else v++,t++}for(;w>=v&&y>=t;){r=c[w];z=p[y];if(r!==z||b)if(null==r)w--;else{if(null!=z)if(r.key===z.key)A=null!=u&&w>=c.length-u.length||null==u&&b,k(h,r,z,e,m(c,w+1,g),A,n),b&&r.tag===z.tag&&l(h,q(r),g),null!=r.dom&&(g=r.dom),w--;else{if(!G){G=c;var r=w,A={},E;for(E=0;E<r;E++){var x=G[E];null!=x&&(x=x.key,null!=x&&(A[x]=E))}G=A}null!=z&&(r=G[z.key],
null!=r?(A=c[r],k(h,A,z,e,m(c,w+1,g),b,n),l(h,q(A),g),c[r].skip=!0,null!=A.dom&&(g=A.dom)):g=f(h,z,e,void 0,g))}y--}else w--,y--;if(y<t)break}d(h,p,t,y+1,e,g,n);a(c,v,w+1,p)}}function k(h,c,a,b,d,m,l){var p=c.tag;if(p===a.tag){a.state=c.state;a._state=c._state;a.events=c.events;var v;if(v=!m){var r,z;null!=a.attrs&&"function"===typeof a.attrs.onbeforeupdate&&(r=a.attrs.onbeforeupdate.call(a.state,a,c));"string"!==typeof a.tag&&"function"===typeof a._state.onbeforeupdate&&(z=a._state.onbeforeupdate.call(a.state,
a,c));void 0===r&&void 0===z||r||z?v=!1:(a.dom=c.dom,a.domSize=c.domSize,a.instance=c.instance,v=!0)}if(!v)if("string"===typeof p)switch(null!=a.attrs&&(m?(a.state={},C(a.attrs,a,b)):I(a.attrs,a,b)),p){case "#":c.children.toString()!==a.children.toString()&&(c.dom.nodeValue=a.children);a.dom=c.dom;break;case "<":c.children!==a.children?(q(c),g(h,a,d)):(a.dom=c.dom,a.domSize=c.domSize);break;case "[":n(h,c.children,a.children,m,b,d,l);c=0;b=a.children;a.dom=null;if(null!=b){for(m=0;m<b.length;m++){var y=
b[m];null!=y&&null!=y.dom&&(null==a.dom&&(a.dom=y.dom),c+=y.domSize||1)}1!==c&&(a.domSize=c)}break;default:h=l;d=a.dom=c.dom;switch(a.tag){case "svg":h="http://www.w3.org/2000/svg";break;case "math":h="http://www.w3.org/1998/Math/MathML"}"textarea"===a.tag&&(null==a.attrs&&(a.attrs={}),null!=a.text&&(a.attrs.value=a.text,a.text=void 0));l=c.attrs;p=a.attrs;v=h;if(null!=p)for(y in p)A(a,y,l&&l[y],p[y],v);if(null!=l)for(y in l)null!=p&&y in p||("className"===y&&(y="class"),"o"!==y[0]||"n"!==y[1]||E(y)?
"key"!==y&&a.dom.removeAttribute(y):x(a,y,void 0));null!=a.attrs&&null!=a.attrs.contenteditable?u(a):null!=c.text&&null!=a.text&&""!==a.text?c.text.toString()!==a.text.toString()&&(c.dom.firstChild.nodeValue=a.text):(null!=c.text&&(c.children=[B("#",void 0,void 0,c.text,void 0,c.dom.firstChild)]),null!=a.text&&(a.children=[B("#",void 0,void 0,a.text,void 0,void 0)]),n(d,c.children,a.children,m,b,null,h))}else{if(m)e(a,b);else{a.instance=B.normalize(a._state.view.call(a.state,a));if(a.instance===a)throw Error("A view cannot return the vnode it received as argument");
null!=a.attrs&&I(a.attrs,a,b);I(a._state,a,b)}null!=a.instance?(null==c.instance?f(h,a.instance,b,l,d):k(h,c.instance,a.instance,b,d,m,l),a.dom=a.instance.dom,a.domSize=a.instance.domSize):null!=c.instance?(w(c.instance,null),a.dom=void 0,a.domSize=0):(a.dom=c.dom,a.domSize=c.domSize)}}else w(c,null),f(h,a,b,l,d)}function q(a){var c=a.domSize;if(null!=c||null==a.dom){var b=D.createDocumentFragment();if(0<c){for(a=a.dom;--c;)b.appendChild(a.nextSibling);b.insertBefore(a,b.firstChild)}return b}return a.dom}
function m(a,c,b){for(;c<a.length;c++)if(null!=a[c]&&null!=a[c].dom)return a[c].dom;return b}function l(a,c,b){b&&b.parentNode?a.insertBefore(c,b):a.appendChild(c)}function u(a){var c=a.children;if(null!=c&&1===c.length&&"<"===c[0].tag)c=c[0].children,a.dom.innerHTML!==c&&(a.dom.innerHTML=c);else if(null!=a.text||null!=c&&0!==c.length)throw Error("Child node of a contenteditable must be trusted");}function a(a,c,b,d){for(;c<b;c++){var h=a[c];null!=h&&(h.skip?h.skip=!1:w(h,d))}}function w(a,c){function b(){if(++d===
h&&(r(a),a.dom)){var b=a.domSize||1;if(1<b)for(var e=a.dom;--b;){var g=e.nextSibling,f=g.parentNode;null!=f&&f.removeChild(g)}b=a.dom;e=b.parentNode;null!=e&&e.removeChild(b);if(b=null!=c&&null==a.domSize)b=a.attrs,b=!(null!=b&&(b.oncreate||b.onupdate||b.onbeforeremove||b.onremove));b&&"string"===typeof a.tag&&(c.pool?c.pool.push(a):c.pool=[a])}}var h=1,d=0;if(a.attrs&&"function"===typeof a.attrs.onbeforeremove){var e=a.attrs.onbeforeremove.call(a.state,a);null!=e&&"function"===typeof e.then&&(h++,
e.then(b,b))}"string"!==typeof a.tag&&"function"===typeof a._state.onbeforeremove&&(e=a._state.onbeforeremove.call(a.state,a),null!=e&&"function"===typeof e.then&&(h++,e.then(b,b)));b()}function r(a){a.attrs&&"function"===typeof a.attrs.onremove&&a.attrs.onremove.call(a.state,a);"string"!==typeof a.tag&&"function"===typeof a._state.onremove&&a._state.onremove.call(a.state,a);if(null!=a.instance)r(a.instance);else if(a=a.children,Array.isArray(a))for(var c=0;c<a.length;c++){var b=a[c];null!=b&&r(b)}}
function A(a,c,b,d,e){var h=a.dom;if("key"!==c&&"is"!==c&&(b!==d||"value"===c||"checked"===c||"selectedIndex"===c||"selected"===c&&a.dom===D.activeElement||"object"===typeof d)&&"undefined"!==typeof d&&!E(c)){var g=c.indexOf(":");if(-1<g&&"xlink"===c.substr(0,g))h.setAttributeNS("http://www.w3.org/1999/xlink",c.slice(g+1),d);else if("o"===c[0]&&"n"===c[1]&&"function"===typeof d)x(a,c,d);else if("style"===c)if(a=b,a===d&&(h.style.cssText="",a=null),null==d)h.style.cssText="";else if("string"===typeof d)h.style.cssText=
d;else{"string"===typeof a&&(h.style.cssText="");for(var f in d)h.style[f]=d[f];if(null!=a&&"string"!==typeof a)for(f in a)f in d||(h.style[f]="")}else c in h&&"href"!==c&&"list"!==c&&"form"!==c&&"width"!==c&&"height"!==c&&void 0===e&&!(a.attrs.is||-1<a.tag.indexOf("-"))?"input"===a.tag&&"value"===c&&a.dom.value==d&&a.dom===D.activeElement||"select"===a.tag&&"value"===c&&a.dom.value==d&&a.dom===D.activeElement||"option"===a.tag&&"value"===c&&a.dom.value==d||("input"===a.tag&&"type"===c?h.setAttribute(c,
d):h[c]=d):"boolean"===typeof d?d?h.setAttribute(c,""):h.removeAttribute(c):h.setAttribute("className"===c?"class":c,d)}}function E(a){return"oninit"===a||"oncreate"===a||"onupdate"===a||"onremove"===a||"onbeforeremove"===a||"onbeforeupdate"===a}function x(a,c,b){var d=a.dom,e="function"!==typeof F?b:function(a){var c=b.call(d,a);F.call(d,a);return c};if(c in d)d[c]="function"===typeof b?e:null;else{var h=c.slice(2);void 0===a.events&&(a.events={});a.events[c]!==e&&(null!=a.events[c]&&d.removeEventListener(h,
a.events[c],!1),"function"===typeof b&&(a.events[c]=e,d.addEventListener(h,a.events[c],!1)))}}function C(a,b,d){"function"===typeof a.oninit&&a.oninit.call(b.state,b);"function"===typeof a.oncreate&&d.push(a.oncreate.bind(b.state,b))}function I(a,b,d){"function"===typeof a.onupdate&&d.push(a.onupdate.bind(b.state,b))}var D=b.document,J=D.createDocumentFragment(),F;return{render:function(a,b){if(!a)throw Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var c=
[],d=D.activeElement;null==a.vnodes&&(a.textContent="");Array.isArray(b)||(b=[b]);n(a,a.vnodes,B.normalizeChildren(b),!1,c,null,void 0);a.vnodes=b;for(var e=0;e<c.length;e++)c[e]();D.activeElement!==d&&d.focus()},setEventCallback:function(a){return F=a}}},H=function(b){function d(b){b=g.indexOf(b);-1<b&&g.splice(b,2)}function f(){for(var b=1;b<g.length;b+=2)g[b]()}b=O(b);b.setEventCallback(function(b){!1!==b.redraw&&f()});var g=[];return{subscribe:function(b,f){d(b);g.push(b,Q(f))},unsubscribe:d,
redraw:f,render:b.render}}(window);K.setCompletionCallback(H.redraw);C.mount=function(b){return function(d,f){if(null===f)b.render(d,[]),b.unsubscribe(d);else{if(null==f.view&&"function"!==typeof f)throw Error("m.mount(element, component) expects a component, not a vnode");b.subscribe(d,function(){b.render(d,B(f))});b.redraw()}}}(H);var T=x,L=function(b){if(""===b||null==b)return{};"?"===b.charAt(0)&&(b=b.slice(1));b=b.split("&");for(var d={},f={},g=0;g<b.length;g++){var e=b[g].split("="),n=decodeURIComponent(e[0]),
e=2===e.length?decodeURIComponent(e[1]):"";"true"===e?e=!0:"false"===e&&(e=!1);var k=n.split(/\]\[?|\[/),q=d;-1<n.indexOf("[")&&k.pop();for(var m=0;m<k.length;m++){var n=k[m],l=k[m+1],l=""==l||!isNaN(parseInt(l,10)),u=m===k.length-1;""===n&&(n=k.slice(0,m).join(),null==f[n]&&(f[n]=0),n=f[n]++);null==q[n]&&(q[n]=u?e:l?[]:{});q=q[n]}}return d},U=function(b){function d(d){var e=b.location[d].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===d&&"/"!==e[0]&&(e="/"+e);return e}function f(b){return function(){null==
k&&(k=n(function(){k=null;b()}))}}function g(b,d,e){var a=b.indexOf("?"),g=b.indexOf("#"),f=-1<a?a:-1<g?g:b.length;if(-1<a){var a=L(b.slice(a+1,-1<g?g:b.length)),k;for(k in a)d[k]=a[k]}if(-1<g)for(k in d=L(b.slice(g+1)),d)e[k]=d[k];return b.slice(0,f)}var e="function"===typeof b.history.pushState,n="function"===typeof setImmediate?setImmediate:setTimeout,k,q={prefix:"#!",getPath:function(){switch(q.prefix.charAt(0)){case "#":return d("hash").slice(q.prefix.length);case "?":return d("search").slice(q.prefix.length)+
d("hash");default:return d("pathname").slice(q.prefix.length)+d("search")+d("hash")}},setPath:function(d,f,k){var a={},l={};d=g(d,a,l);if(null!=f){for(var m in f)a[m]=f[m];d=d.replace(/:([^\/]+)/g,function(b,d){delete a[d];return f[d]})}(m=F(a))&&(d+="?"+m);(l=F(l))&&(d+="#"+l);e?(l=k?k.state:null,m=k?k.title:null,b.onpopstate(),k&&k.replace?b.history.replaceState(l,m,q.prefix+d):b.history.pushState(l,m,q.prefix+d)):b.location.href=q.prefix+d},defineRoutes:function(d,k,n){function a(){var a=q.getPath(),
e={},f=g(a,e,e),l=b.history.state;if(null!=l)for(var m in l)e[m]=l[m];for(var u in d)if(l=new RegExp("^"+u.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$"),l.test(f)){f.replace(l,function(){for(var b=u.match(/:[^\/]+/g)||[],g=[].slice.call(arguments,1,-2),f=0;f<b.length;f++)e[b[f].replace(/:|\./g,"")]=decodeURIComponent(g[f]);k(d[u],e,a,u)});return}n(a,e)}e?b.onpopstate=f(a):"#"===q.prefix.charAt(0)&&(b.onhashchange=a);a()}};return q};C.route=function(b,d){var f=U(b),g=function(b){return b},
e,n,k,q,m,l=function(b,a,l){if(null==b)throw Error("Ensure the DOM element that was passed to `m.route` is not undefined");var u=function(){null!=e&&d.render(b,e(B(n,k.key,k)))},w=function(b){if(b!==a)f.setPath(a,null,{replace:!0});else throw Error("Could not resolve default route "+a);};f.defineRoutes(l,function(a,b,d){var f=m=function(a,l){f===m&&(n=null==l||"function"!==typeof l.view&&"function"!==typeof l?"div":l,k=b,q=d,m=null,e=(a.render||g).bind(a),u())};a.view||"function"===typeof a?f({},
a):a.onmatch?T.resolve(a.onmatch(b,d)).then(function(b){f(a,b)},w):f(a,"div")},w);d.subscribe(b,u)};l.set=function(b,a,d){null!=m&&(d={replace:!0});m=null;f.setPath(b,a,d)};l.get=function(){return q};l.prefix=function(b){f.prefix=b};l.link=function(b){b.dom.setAttribute("href",f.prefix+b.attrs.href);b.dom.onclick=function(a){a.ctrlKey||a.metaKey||a.shiftKey||2===a.which||(a.preventDefault(),a.redraw=!1,a=this.getAttribute("href"),0===a.indexOf(f.prefix)&&(a=a.slice(f.prefix.length)),l.set(a,void 0,
void 0))}};l.param=function(b){return"undefined"!==typeof k&&"undefined"!==typeof b?k[b]:k};return l}(window,H);C.withAttr=function(b,d,f){return function(g){d.call(f||this,b in g.currentTarget?g.currentTarget[b]:g.currentTarget.getAttribute(b))}};var V=O(window);C.render=V.render;C.redraw=H.redraw;C.request=K.request;C.jsonp=K.jsonp;C.parseQueryString=L;C.buildQueryString=F;C.version="1.1.1";C.vnode=B;"undefined"!==typeof module?module.exports=C:window.m=C})();
(function(){function z(b,d,e,f,g,l){return{tag:b,key:d,attrs:e,children:f,text:g,dom:l,domSize:void 0,state:void 0,_state:void 0,events:void 0,instance:void 0,skip:!1}}function A(b){var d,e=arguments[1],f=2;if(null==b||"string"!==typeof b&&"function"!==typeof b&&"function"!==typeof b.view)throw Error("The selector must be either a string or a component.");if("string"===typeof b&&!(d=M[b])){var g="div";for(var l=[],k={};d=P.exec(b);){var r=d[1],p=d[2];""===r&&""!==p?g=p:"#"===r?k.id=p:"."===r?l.push(p):
"["===d[3][0]&&((r=d[6])&&(r=r.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),"class"===d[4]?l.push(r):k[d[4]]=""===r?r:r||!0)}0<l.length&&(k.className=l.join(" "));d=M[b]={tag:g,attrs:k}}if(null==e)e={};else if("object"!==typeof e||null!=e.tag||Array.isArray(e))e={},f=1;if(arguments.length===f+1)g=arguments[f],Array.isArray(g)||(g=[g]);else for(g=[];f<arguments.length;)g.push(arguments[f++]);f=z.normalizeChildren(g);if("string"===typeof b){g=!1;var m,n,l=e.className||e["class"],a;for(a in d.attrs)N.call(d.attrs,
a)&&(e[a]=d.attrs[a]);void 0!==l&&(void 0!==e["class"]&&(e["class"]=void 0,e.className=l),null!=d.attrs.className&&(e.className=d.attrs.className+" "+l));for(a in e)if(N.call(e,a)&&"key"!==a){g=!0;break}Array.isArray(f)&&1===f.length&&null!=f[0]&&"#"===f[0].tag?n=f[0].children:m=f;return z(d.tag,e.key,g?e:void 0,m,n)}return z(b,e.key,e,f)}function Q(b){var d=0,e=null,f="function"===typeof requestAnimationFrame?requestAnimationFrame:setTimeout;return function(){var g=Date.now();0===d||16<=g-d?(d=g,
b()):null===e&&(e=f(function(){e=null;b();d=Date.now()},16-(g-d)))}}z.normalize=function(b){return Array.isArray(b)?z("[",void 0,void 0,z.normalizeChildren(b),void 0,void 0):null!=b&&"object"!==typeof b?z("#",void 0,void 0,!1===b?"":b,void 0,void 0):b};z.normalizeChildren=function(b){for(var d=0;d<b.length;d++)b[d]=z.normalize(b[d]);return b};var P=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,M={},N={}.hasOwnProperty;A.trust=function(b){null==b&&(b="");return z("<",
void 0,void 0,b,void 0,void 0)};A.fragment=function(b,d){return z("[",b.key,b,z.normalizeChildren(d),void 0,void 0)};var y=function(b){function d(b,a){return function t(d){var k;try{if(!a||null==d||"object"!==typeof d&&"function"!==typeof d||"function"!==typeof(k=d.then))m(function(){a||0!==b.length||console.error("Possible unhandled promise rejection:",d);for(var e=0;e<b.length;e++)b[e](d);g.length=0;l.length=0;p.state=a;p.retry=function(){t(d)}});else{if(d===f)throw new TypeError("Promise can't be resolved w/ itself");
e(k.bind(d))}}catch(R){r(R)}}}function e(b){function a(a){return function(b){0<d++||a(b)}}var d=0,e=a(r);try{b(a(k),e)}catch(C){e(C)}}if(!(this instanceof y))throw Error("Promise must be called with `new`");if("function"!==typeof b)throw new TypeError("executor must be a function");var f=this,g=[],l=[],k=d(g,!0),r=d(l,!1),p=f._instance={resolvers:g,rejectors:l},m="function"===typeof setImmediate?setImmediate:setTimeout;e(b)};y.prototype.then=function(b,d){function e(b,d,e,k){d.push(function(a){if("function"!==
typeof b)e(a);else try{g(b(a))}catch(x){l&&l(x)}});"function"===typeof f.retry&&k===f.state&&f.retry()}var f=this._instance,g,l,k=new y(function(b,d){g=b;l=d});e(b,f.resolvers,g,!0);e(d,f.rejectors,l,!1);return k};y.prototype["catch"]=function(b){return this.then(null,b)};y.resolve=function(b){return b instanceof y?b:new y(function(d){d(b)})};y.reject=function(b){return new y(function(d,e){e(b)})};y.all=function(b){return new y(function(d,e){var f=b.length,g=0,l=[];if(0===b.length)d([]);else for(var k=
0;k<b.length;k++)(function(k){function p(b){g++;l[k]=b;g===f&&d(l)}null==b[k]||"object"!==typeof b[k]&&"function"!==typeof b[k]||"function"!==typeof b[k].then?p(b[k]):b[k].then(p,e)})(k)})};y.race=function(b){return new y(function(d,e){for(var f=0;f<b.length;f++)b[f].then(d,e)})};"undefined"!==typeof window?("undefined"===typeof window.Promise&&(window.Promise=y),y=window.Promise):"undefined"!==typeof global&&("undefined"===typeof global.Promise&&(global.Promise=y),y=global.Promise);var G=function(b){function d(b,
f){if(Array.isArray(f))for(var g=0;g<f.length;g++)d(b+"["+g+"]",f[g]);else if("[object Object]"===Object.prototype.toString.call(f))for(g in f)d(b+"["+g+"]",f[g]);else e.push(encodeURIComponent(b)+(null!=f&&""!==f?"="+encodeURIComponent(f):""))}if("[object Object]"!==Object.prototype.toString.call(b))return"";var e=[],f;for(f in b)d(f,b[f]);return e.join("&")},S=/^file:\/\//i,K=function(b,d){function e(){function a(){0===--b&&"function"===typeof n&&n()}var b=0;return function C(d){var e=d.then;d.then=
function(){b++;var g=e.apply(d,arguments);g.then(a,function(d){a();if(0===b)throw d;});return C(g)};return d}}function f(a,b){if("string"===typeof a){var d=a;a=b||{};null==a.url&&(a.url=d)}return a}function g(a,b){if(null==b)return a;for(var d=a.match(/:[^\/]+/gi)||[],e=0;e<d.length;e++){var g=d[e].slice(1);null!=b[g]&&(a=a.replace(d[e],b[g]))}return a}function l(a,b){var d=G(b);if(""!==d){var e=0>a.indexOf("?")?"?":"&";a+=e+d}return a}function k(a){try{return""!==a?JSON.parse(a):null}catch(x){throw Error(a);
}}function r(a){return a.responseText}function p(a,b){if("function"===typeof a)if(Array.isArray(b))for(var d=0;d<b.length;d++)b[d]=new a(b[d]);else return new a(b);return b}var m=0,n;return{request:function(a,m){var n=e();a=f(a,m);var x=new d(function(d,e){null==a.method&&(a.method="GET");a.method=a.method.toUpperCase();var f="GET"===a.method||"TRACE"===a.method?!1:"boolean"===typeof a.useBody?a.useBody:!0;"function"!==typeof a.serialize&&(a.serialize="undefined"!==typeof FormData&&a.data instanceof
FormData?function(a){return a}:JSON.stringify);"function"!==typeof a.deserialize&&(a.deserialize=k);"function"!==typeof a.extract&&(a.extract=r);a.url=g(a.url,a.data);f?a.data=a.serialize(a.data):a.url=l(a.url,a.data);var m=new b.XMLHttpRequest,n=!1,x=m.abort;m.abort=function(){n=!0;x.call(m)};m.open(a.method,a.url,"boolean"===typeof a.async?a.async:!0,"string"===typeof a.user?a.user:void 0,"string"===typeof a.password?a.password:void 0);a.serialize===JSON.stringify&&f&&m.setRequestHeader("Content-Type",
"application/json; charset=utf-8");a.deserialize===k&&m.setRequestHeader("Accept","application/json, text/*");a.withCredentials&&(m.withCredentials=a.withCredentials);for(var t in a.headers)({}).hasOwnProperty.call(a.headers,t)&&m.setRequestHeader(t,a.headers[t]);"function"===typeof a.config&&(m=a.config(m,a)||m);m.onreadystatechange=function(){if(!n&&4===m.readyState)try{var b=a.extract!==r?a.extract(m,a):a.deserialize(a.extract(m,a));if(200<=m.status&&300>m.status||304===m.status||S.test(a.url))d(p(a.type,
b));else{var h=Error(m.responseText),c;for(c in b)h[c]=b[c];e(h)}}catch(q){e(q)}};f&&null!=a.data?m.send(a.data):m.send()});return!0===a.background?x:n(x)},jsonp:function(a,k){var n=e();a=f(a,k);var r=new d(function(d,e){var f=a.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+m++,k=b.document.createElement("script");b[f]=function(e){k.parentNode.removeChild(k);d(p(a.type,e));delete b[f]};k.onerror=function(){k.parentNode.removeChild(k);e(Error("JSONP request failed"));delete b[f]};null==
a.data&&(a.data={});a.url=g(a.url,a.data);a.data[a.callbackKey||"callback"]=f;k.src=l(a.url,a.data);b.document.documentElement.appendChild(k)});return!0===a.background?r:n(r)},setCompletionCallback:function(a){n=a}}}(window,y),O=function(b){function d(h,c,q,a,b,d,g){for(;q<a;q++){var u=c[q];null!=u&&e(h,u,b,g,d)}}function e(h,c,q,a,b){var u=c.tag;if("string"===typeof u)switch(c.state={},null!=c.attrs&&A(c.attrs,c,q),u){case "#":return c.dom=w.createTextNode(c.children),m(h,c.dom,b),c.dom;case "<":return f(h,
c,b);case "[":var k=w.createDocumentFragment();null!=c.children&&(u=c.children,d(k,u,0,u.length,q,null,a));c.dom=k.firstChild;c.domSize=k.childNodes.length;m(h,k,b);return k;default:var p=c.tag,l=(u=c.attrs)&&u.is,p=(a=c.attrs&&c.attrs.xmlns||G[c.tag]||a)?l?w.createElementNS(a,p,{is:l}):w.createElementNS(a,p):l?w.createElement(p,{is:l}):w.createElement(p);c.dom=p;if(null!=u)for(k in l=a,u)C(c,k,null,u[k],l);m(h,p,b);null!=c.attrs&&null!=c.attrs.contenteditable?n(c):(null!=c.text&&(""!==c.text?p.textContent=
c.text:c.children=[z("#",void 0,void 0,c.text,void 0,void 0)]),null!=c.children&&(h=c.children,d(p,h,0,h.length,q,null,a),h=c.attrs,"select"===c.tag&&null!=h&&("value"in h&&C(c,"value",null,h.value,void 0),"selectedIndex"in h&&C(c,"selectedIndex",null,h.selectedIndex,void 0))));return p}else return g(c,q),null!=c.instance?(q=e(h,c.instance,q,a,b),c.dom=c.instance.dom,c.domSize=null!=c.dom?c.instance.domSize:0,m(h,q,b),c=q):(c.domSize=0,c=J),c}function f(h,c,q){var a={caption:"table",thead:"table",
tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(c.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",a=w.createElement(a);a.innerHTML=c.children;c.dom=a.firstChild;c.domSize=a.childNodes.length;c=w.createDocumentFragment();for(var b;b=a.firstChild;)c.appendChild(b);m(h,c,q);return c}function g(h,c){if("function"===typeof h.tag.view){h.state=Object.create(h.tag);var a=h.state.view;if(null!=a.$$reentrantLock$$)return J;a.$$reentrantLock$$=!0}else{h.state=void 0;
a=h.tag;if(null!=a.$$reentrantLock$$)return J;a.$$reentrantLock$$=!0;h.state=null!=h.tag.prototype&&"function"===typeof h.tag.prototype.view?new h.tag(h):h.tag(h)}h._state=h.state;null!=h.attrs&&A(h.attrs,h,c);A(h._state,h,c);h.instance=z.normalize(h._state.view.call(h.state,h));if(h.instance===h)throw Error("A view cannot return the vnode it received as argument");a.$$reentrantLock$$=null}function l(h,c,q,b,g,f,l){if(c!==q&&(null!=c||null!=q))if(null==c)d(h,q,0,q.length,g,f,l);else if(null==q)a(c,
0,c.length,q);else{if(c.length===q.length){var u=!1;for(var n=0;n<q.length;n++)if(null!=q[n]&&null!=c[n]){u=null==q[n].key&&null==c[n].key;break}if(u){for(n=0;n<c.length;n++)c[n]!==q[n]&&(null==c[n]&&null!=q[n]?e(h,q[n],g,l,p(c,n+1,f)):null==q[n]?a(c,n,n+1,q):k(h,c[n],q[n],g,p(c,n+1,f),b,l));return}}if(!b)a:{if(null!=c.pool&&Math.abs(c.pool.length-q.length)<=Math.abs(c.length-q.length)&&(b=q[0]&&q[0].children&&q[0].children.length||0,Math.abs((c.pool[0]&&c.pool[0].children&&c.pool[0].children.length||
0)-b)<=Math.abs((c[0]&&c[0].children&&c[0].children.length||0)-b))){b=!0;break a}b=!1}if(b){var x=c.pool;c=c.concat(c.pool)}for(var B=n=0,v=c.length-1,E=q.length-1,H;v>=n&&E>=B;){var t=c[n];u=q[B];if(t!==u||b)if(null==t)n++;else if(null==u)B++;else if(t.key===u.key){var w=null!=x&&n>=c.length-x.length||null==x&&b;n++;B++;k(h,t,u,g,p(c,n,f),w,l);b&&t.tag===u.tag&&m(h,r(t),f)}else if(t=c[v],t!==u||b)if(null==t)v--;else if(null==u)B++;else if(t.key===u.key)w=null!=x&&v>=c.length-x.length||null==x&&b,
k(h,t,u,g,p(c,v+1,f),w,l),(b||B<E)&&m(h,r(t),p(c,n,f)),v--,B++;else break;else v--,B++;else n++,B++}for(;v>=n&&E>=B;){t=c[v];u=q[E];if(t!==u||b)if(null==t)v--;else{if(null!=u)if(t.key===u.key)w=null!=x&&v>=c.length-x.length||null==x&&b,k(h,t,u,g,p(c,v+1,f),w,l),b&&t.tag===u.tag&&m(h,r(t),f),null!=t.dom&&(f=t.dom),v--;else{if(!H){H=c;w=v;t={};var C;for(C=0;C<w;C++){var D=H[C];null!=D&&(D=D.key,null!=D&&(t[D]=C))}H=t}null!=u&&(w=H[u.key],null!=w?(t=c[w],k(h,t,u,g,p(c,v+1,f),b,l),m(h,r(t),f),c[w].skip=
!0,null!=t.dom&&(f=t.dom)):f=e(h,u,g,l,f))}E--}else v--,E--;if(E<B)break}d(h,q,B,E+1,g,f,l);a(c,n,v+1,q)}}function k(h,c,a,b,d,p,m){var q=c.tag;if(q===a.tag){a.state=c.state;a._state=c._state;a.events=c.events;var u;if(u=!p){var t,B;null!=a.attrs&&"function"===typeof a.attrs.onbeforeupdate&&(t=a.attrs.onbeforeupdate.call(a.state,a,c));"string"!==typeof a.tag&&"function"===typeof a._state.onbeforeupdate&&(B=a._state.onbeforeupdate.call(a.state,a,c));void 0===t&&void 0===B||t||B?u=!1:(a.dom=c.dom,a.domSize=
c.domSize,a.instance=c.instance,u=!0)}if(!u)if("string"===typeof q)switch(null!=a.attrs&&(p?(a.state={},A(a.attrs,a,b)):I(a.attrs,a,b)),q){case "#":c.children.toString()!==a.children.toString()&&(c.dom.nodeValue=a.children);a.dom=c.dom;break;case "<":c.children!==a.children?(r(c),f(h,a,d)):(a.dom=c.dom,a.domSize=c.domSize);break;case "[":l(h,c.children,a.children,p,b,d,m);c=0;b=a.children;a.dom=null;if(null!=b){for(p=0;p<b.length;p++){var v=b[p];null!=v&&null!=v.dom&&(null==a.dom&&(a.dom=v.dom),c+=
v.domSize||1)}1!==c&&(a.domSize=c)}break;default:h=a.dom=c.dom;m=a.attrs&&a.attrs.xmlns||G[a.tag]||m;"textarea"===a.tag&&(null==a.attrs&&(a.attrs={}),null!=a.text&&(a.attrs.value=a.text,a.text=void 0));d=c.attrs;q=a.attrs;u=m;if(null!=q)for(v in q)C(a,v,d&&d[v],q[v],u);if(null!=d)for(v in d)null!=q&&v in q||("className"===v&&(v="class"),"o"!==v[0]||"n"!==v[1]||D(v)?"key"!==v&&a.dom.removeAttribute(v):y(a,v,void 0));null!=a.attrs&&null!=a.attrs.contenteditable?n(a):null!=c.text&&null!=a.text&&""!==
a.text?c.text.toString()!==a.text.toString()&&(c.dom.firstChild.nodeValue=a.text):(null!=c.text&&(c.children=[z("#",void 0,void 0,c.text,void 0,c.dom.firstChild)]),null!=a.text&&(a.children=[z("#",void 0,void 0,a.text,void 0,void 0)]),l(h,c.children,a.children,p,b,null,m))}else{if(p)g(a,b);else{a.instance=z.normalize(a._state.view.call(a.state,a));if(a.instance===a)throw Error("A view cannot return the vnode it received as argument");null!=a.attrs&&I(a.attrs,a,b);I(a._state,a,b)}null!=a.instance?
(null==c.instance?e(h,a.instance,b,m,d):k(h,c.instance,a.instance,b,d,p,m),a.dom=a.instance.dom,a.domSize=a.instance.domSize):null!=c.instance?(x(c.instance,null),a.dom=void 0,a.domSize=0):(a.dom=c.dom,a.domSize=c.domSize)}}else x(c,null),e(h,a,b,m,d)}function r(a){var c=a.domSize;if(null!=c||null==a.dom){var b=w.createDocumentFragment();if(0<c){for(a=a.dom;--c;)b.appendChild(a.nextSibling);b.insertBefore(a,b.firstChild)}return b}return a.dom}function p(a,c,b){for(;c<a.length;c++)if(null!=a[c]&&null!=
a[c].dom)return a[c].dom;return b}function m(a,c,b){b&&b.parentNode?a.insertBefore(c,b):a.appendChild(c)}function n(a){var c=a.children;if(null!=c&&1===c.length&&"<"===c[0].tag)c=c[0].children,a.dom.innerHTML!==c&&(a.dom.innerHTML=c);else if(null!=a.text||null!=c&&0!==c.length)throw Error("Child node of a contenteditable must be trusted");}function a(a,c,b,d){for(;c<b;c++){var h=a[c];null!=h&&(h.skip?h.skip=!1:x(h,d))}}function x(a,c){function b(){if(++d===h&&(t(a),a.dom)){var b=a.domSize||1;if(1<
b)for(var e=a.dom;--b;){var f=e.nextSibling,g=f.parentNode;null!=g&&g.removeChild(f)}b=a.dom;e=b.parentNode;null!=e&&e.removeChild(b);if(b=null!=c&&null==a.domSize)b=a.attrs,b=!(null!=b&&(b.oncreate||b.onupdate||b.onbeforeremove||b.onremove));b&&"string"===typeof a.tag&&(c.pool?c.pool.push(a):c.pool=[a])}}var h=1,d=0;if(a.attrs&&"function"===typeof a.attrs.onbeforeremove){var e=a.attrs.onbeforeremove.call(a.state,a);null!=e&&"function"===typeof e.then&&(h++,e.then(b,b))}"string"!==typeof a.tag&&"function"===
typeof a._state.onbeforeremove&&(e=a._state.onbeforeremove.call(a.state,a),null!=e&&"function"===typeof e.then&&(h++,e.then(b,b)));b()}function t(a){a.attrs&&"function"===typeof a.attrs.onremove&&a.attrs.onremove.call(a.state,a);"string"!==typeof a.tag&&"function"===typeof a._state.onremove&&a._state.onremove.call(a.state,a);if(null!=a.instance)t(a.instance);else if(a=a.children,Array.isArray(a))for(var c=0;c<a.length;c++){var b=a[c];null!=b&&t(b)}}function C(a,c,b,d,e){var h=a.dom;if("key"!==c&&
"is"!==c&&(b!==d||"value"===c||"checked"===c||"selectedIndex"===c||"selected"===c&&a.dom===w.activeElement||"object"===typeof d)&&"undefined"!==typeof d&&!D(c)){var f=c.indexOf(":");if(-1<f&&"xlink"===c.substr(0,f))h.setAttributeNS("http://www.w3.org/1999/xlink",c.slice(f+1),d);else if("o"===c[0]&&"n"===c[1]&&"function"===typeof d)y(a,c,d);else if("style"===c)if(a=b,a===d&&(h.style.cssText="",a=null),null==d)h.style.cssText="";else if("string"===typeof d)h.style.cssText=d;else{"string"===typeof a&&
(h.style.cssText="");for(var g in d)h.style[g]=d[g];if(null!=a&&"string"!==typeof a)for(g in a)g in d||(h.style[g]="")}else if(c in h&&"href"!==c&&"list"!==c&&"form"!==c&&"width"!==c&&"height"!==c&&void 0===e&&!(a.attrs.is||-1<a.tag.indexOf("-"))){if("value"===c){g=""+d;if(("input"===a.tag||"textarea"===a.tag)&&a.dom.value===g&&a.dom===w.activeElement)return;if("select"===a.tag)if(null===d){if(-1===a.dom.selectedIndex&&a.dom===w.activeElement)return}else if(null!==b&&a.dom.value===g&&a.dom===w.activeElement)return;
if("option"===a.tag&&null!=b&&a.dom.value===g)return}"input"===a.tag&&"type"===c?h.setAttribute(c,d):h[c]=d}else"boolean"===typeof d?d?h.setAttribute(c,""):h.removeAttribute(c):h.setAttribute("className"===c?"class":c,d)}}function D(a){return"oninit"===a||"oncreate"===a||"onupdate"===a||"onremove"===a||"onbeforeremove"===a||"onbeforeupdate"===a}function y(a,b,d){var c=a.dom,e="function"!==typeof F?d:function(a){var b=d.call(c,a);F.call(c,a);return b};if(b in c)c[b]="function"===typeof d?e:null;else{var h=
b.slice(2);void 0===a.events&&(a.events={});a.events[b]!==e&&(null!=a.events[b]&&c.removeEventListener(h,a.events[b],!1),"function"===typeof d&&(a.events[b]=e,c.addEventListener(h,a.events[b],!1)))}}function A(a,b,d){"function"===typeof a.oninit&&a.oninit.call(b.state,b);"function"===typeof a.oncreate&&d.push(a.oncreate.bind(b.state,b))}function I(a,b,d){"function"===typeof a.onupdate&&d.push(a.onupdate.bind(b.state,b))}var w=b.document,J=w.createDocumentFragment(),G={svg:"http://www.w3.org/2000/svg",
math:"http://www.w3.org/1998/Math/MathML"},F;return{render:function(a,b){if(!a)throw Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var c=[],d=w.activeElement,e=a.namespaceURI;null==a.vnodes&&(a.textContent="");Array.isArray(b)||(b=[b]);l(a,a.vnodes,z.normalizeChildren(b),!1,c,null,"http://www.w3.org/1999/xhtml"===e?void 0:e);a.vnodes=b;for(e=0;e<c.length;e++)c[e]();w.activeElement!==d&&d.focus()},setEventCallback:function(a){return F=a}}},F=function(b){function d(b){b=
f.indexOf(b);-1<b&&f.splice(b,2)}function e(){for(var b=1;b<f.length;b+=2)f[b]()}b=O(b);b.setEventCallback(function(b){!1===b.redraw?b.redraw=void 0:e()});var f=[];return{subscribe:function(b,e){d(b);f.push(b,Q(e))},unsubscribe:d,redraw:e,render:b.render}}(window);K.setCompletionCallback(F.redraw);A.mount=function(b){return function(d,e){if(null===e)b.render(d,[]),b.unsubscribe(d);else{if(null==e.view&&"function"!==typeof e)throw Error("m.mount(element, component) expects a component, not a vnode");
b.subscribe(d,function(){b.render(d,z(e))});b.redraw()}}}(F);var T=y,L=function(b){if(""===b||null==b)return{};"?"===b.charAt(0)&&(b=b.slice(1));b=b.split("&");for(var d={},e={},f=0;f<b.length;f++){var g=b[f].split("=");var l=decodeURIComponent(g[0]);g=2===g.length?decodeURIComponent(g[1]):"";"true"===g?g=!0:"false"===g&&(g=!1);var k=l.split(/\]\[?|\[/),r=d;-1<l.indexOf("[")&&k.pop();for(var p=0;p<k.length;p++){l=k[p];var m=k[p+1],m=""==m||!isNaN(parseInt(m,10)),n=p===k.length-1;""===l&&(l=k.slice(0,
p).join(),null==e[l]&&(e[l]=0),l=e[l]++);null==r[l]&&(r[l]=n?g:m?[]:{});r=r[l]}}return d},U=function(b){function d(d){var e=b.location[d].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);"pathname"===d&&"/"!==e[0]&&(e="/"+e);return e}function e(b){return function(){null==k&&(k=l(function(){k=null;b()}))}}function f(b,d,e){var a=b.indexOf("?"),f=b.indexOf("#"),g=-1<a?a:-1<f?f:b.length;if(-1<a){var a=L(b.slice(a+1,-1<f?f:b.length)),n;for(n in a)d[n]=a[n]}if(-1<f)for(n in d=L(b.slice(f+1)),d)e[n]=
d[n];return b.slice(0,g)}var g="function"===typeof b.history.pushState,l="function"===typeof setImmediate?setImmediate:setTimeout,k,r={prefix:"#!",getPath:function(){switch(r.prefix.charAt(0)){case "#":return d("hash").slice(r.prefix.length);case "?":return d("search").slice(r.prefix.length)+d("hash");default:return d("pathname").slice(r.prefix.length)+d("search")+d("hash")}},setPath:function(d,e,n){var a={},k={};d=f(d,a,k);if(null!=e){for(var l in e)a[l]=e[l];d=d.replace(/:([^\/]+)/g,function(b,
d){delete a[d];return e[d]})}(l=G(a))&&(d+="?"+l);(k=G(k))&&(d+="#"+k);g?(k=n?n.state:null,l=n?n.title:null,b.onpopstate(),n&&n.replace?b.history.replaceState(k,l,r.prefix+d):b.history.pushState(k,l,r.prefix+d)):b.location.href=r.prefix+d},defineRoutes:function(d,k,n){function a(){var a=r.getPath(),e={},g=f(a,e,e),l=b.history.state;if(null!=l)for(var m in l)e[m]=l[m];for(var p in d)if(l=new RegExp("^"+p.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$"),l.test(g)){g.replace(l,
function(){for(var b=p.match(/:[^\/]+/g)||[],f=[].slice.call(arguments,1,-2),g=0;g<b.length;g++)e[b[g].replace(/:|\./g,"")]=decodeURIComponent(f[g]);k(d[p],e,a,p)});return}n(a,e)}g?b.onpopstate=e(a):"#"===r.prefix.charAt(0)&&(b.onhashchange=a);a()}};return r};A.route=function(b,d){var e=U(b),f=function(b){return b},g,l,k,r,p,m=function(b,a,m){if(null==b)throw Error("Ensure the DOM element that was passed to `m.route` is not undefined");var n=function(){null!=g&&d.render(b,g(z(l,k.key,k)))},x=function(b){if(b!==
a)e.setPath(a,null,{replace:!0});else throw Error("Could not resolve default route "+a);};e.defineRoutes(m,function(a,b,d){var e=p=function(a,m){e===p&&(l=null==m||"function"!==typeof m.view&&"function"!==typeof m?"div":m,k=b,r=d,p=null,g=(a.render||f).bind(a),n())};a.view||"function"===typeof a?e({},a):a.onmatch?T.resolve(a.onmatch(b,d)).then(function(b){e(a,b)},x):e(a,"div")},x);d.subscribe(b,n)};m.set=function(b,a,d){null!=p&&(d=d||{},d.replace=!0);p=null;e.setPath(b,a,d)};m.get=function(){return r};
m.prefix=function(b){e.prefix=b};m.link=function(b){b.dom.setAttribute("href",e.prefix+b.attrs.href);b.dom.onclick=function(a){a.ctrlKey||a.metaKey||a.shiftKey||2===a.which||(a.preventDefault(),a.redraw=!1,a=this.getAttribute("href"),0===a.indexOf(e.prefix)&&(a=a.slice(e.prefix.length)),m.set(a,void 0,void 0))}};m.param=function(b){return"undefined"!==typeof k&&"undefined"!==typeof b?k[b]:k};return m}(window,F);A.withAttr=function(b,d,e){return function(f){d.call(e||this,b in f.currentTarget?f.currentTarget[b]:
f.currentTarget.getAttribute(b))}};var V=O(window);A.render=V.render;A.redraw=F.redraw;A.request=K.request;A.jsonp=K.jsonp;A.parseQueryString=L;A.buildQueryString=G;A.version="1.1.1";A.vnode=z;"undefined"!==typeof module?module.exports=A:window.m=A})();

View file

@ -252,7 +252,7 @@ o.run()
The `o.new()` method can be used to create new instances of ospec, which can be run in parallel. Note that each instance will report independently, and there's no aggregation of results.
```javascript
var _o = o.new()
var _o = o.new('optional name')
_o("a test", function() {
_o(1).equals(1)
})

View file

@ -17,6 +17,7 @@ function traverseDirectory(pathname, callback) {
var promises = []
for (var i = 0; i < pathnames.length; i++) {
if (pathnames[i] === "node_modules") continue
if (pathnames[i][0] === ".") continue
pathnames[i] = path.join(pathname, pathnames[i])
promises.push(traverseDirectory(pathnames[i], callback))
}

View file

@ -1,9 +1,11 @@
/* eslint-disable no-bitwise, no-process-exit */
"use strict"
module.exports = new function init() {
module.exports = new function init(name) {
var spec = {}, subjects = [], results, only = null, ctx = spec, start, stack = 0, nextTickish, hasProcess = typeof process === "object", hasOwn = ({}).hasOwnProperty
if (name != null) spec[name] = ctx = {}
function o(subject, predicate) {
if (predicate === undefined) {
if (results == null) throw new Error("Assertions should not occur outside test definitions")
@ -222,6 +224,7 @@ module.exports = new function init() {
}
}
console.log(
(name ? name + ": " : "") +
results.length + " assertions completed in " + Math.round(new Date - start) + "ms, " +
"of which " + results.filter(function(result){return result.error}).length + " failed"
)

981
package-lock.json generated Normal file
View file

@ -0,0 +1,981 @@
{
"name": "mithril",
"version": "1.1.1",
"lockfileVersion": 1,
"dependencies": {
"@alrra/travis-scripts": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@alrra/travis-scripts/-/travis-scripts-3.0.1.tgz",
"integrity": "sha1-RdW5NXMXtsxVU9/ZmTGEOuCw5To="
},
"abbrev": {
"version": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
"integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
"dev": true
},
"acorn": {
"version": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz",
"integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=",
"dev": true
},
"acorn-jsx": {
"version": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
"dev": true,
"dependencies": {
"acorn": {
"version": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
"dev": true
}
}
},
"ajv": {
"version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
"dev": true
},
"ajv-keywords": {
"version": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
"integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
"dev": true
},
"align-text": {
"version": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
"dev": true
},
"amdefine": {
"version": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
"dev": true
},
"ansi-escapes": {
"version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"dev": true
},
"ansi-regex": {
"version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"argparse": {
"version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
"integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
"dev": true
},
"array-union": {
"version": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk="
},
"array-uniq": {
"version": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
},
"arrify": {
"version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true
},
"async": {
"version": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
"babel-code-frame": {
"version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
"integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
"dev": true
},
"balanced-match": {
"version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
},
"benchmark": {
"version": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
"integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=",
"dev": true
},
"brace-expansion": {
"version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
"integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k="
},
"buffer-shims": {
"version": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
"dev": true
},
"caller-path": {
"version": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
"integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
"dev": true
},
"callsites": {
"version": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
"dev": true
},
"camelcase": {
"version": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
"integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
"dev": true,
"optional": true
},
"center-align": {
"version": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
"integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
"dev": true,
"optional": true
},
"chalk": {
"version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true
},
"circular-json": {
"version": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz",
"integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=",
"dev": true
},
"cli-cursor": {
"version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
"dev": true
},
"cli-width": {
"version": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz",
"integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=",
"dev": true
},
"cliui": {
"version": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
"integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
"dev": true,
"optional": true,
"dependencies": {
"wordwrap": {
"version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
"integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
"dev": true,
"optional": true
}
}
},
"co": {
"version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
"dev": true
},
"code-point-at": {
"version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"collections": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/collections/-/collections-0.2.2.tgz",
"integrity": "sha1-HyMCay7zb5J+7MkB6ZxfDUj6M04="
},
"commander": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q="
},
"concat-map": {
"version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"concat-stream": {
"version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
"integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
"dev": true
},
"core-util-is": {
"version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"d": {
"version": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
"integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
"dev": true
},
"debug": {
"version": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz",
"integrity": "sha1-qfpvvpykPPHnn3O3XAGJy7fW21o=",
"dev": true
},
"decamelize": {
"version": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true,
"optional": true
},
"deep-is": {
"version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"del": {
"version": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
"integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
"dev": true
},
"doctrine": {
"version": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
"integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
"dev": true
},
"es5-ext": {
"version": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.15.tgz",
"integrity": "sha1-wzClk0we4hKEp8CBqG5f2TfJHqY=",
"dev": true
},
"es6-iterator": {
"version": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
"integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
"dev": true
},
"es6-map": {
"version": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
"integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
"dev": true
},
"es6-set": {
"version": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
"integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
"dev": true
},
"es6-symbol": {
"version": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
"integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
"dev": true
},
"es6-weak-map": {
"version": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
"integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
"dev": true
},
"escape-string-regexp": {
"version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"escodegen": {
"version": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
"integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
"dev": true,
"dependencies": {
"esprima": {
"version": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
"dev": true
},
"estraverse": {
"version": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
"integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
"dev": true
}
}
},
"escope": {
"version": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
"integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
"dev": true
},
"eslint": {
"version": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz",
"integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=",
"dev": true
},
"espree": {
"version": "https://registry.npmjs.org/espree/-/espree-3.4.2.tgz",
"integrity": "sha1-ONve2+3JW4lhofvwRzSo9qnIxZI=",
"dev": true
},
"esprima": {
"version": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
"dev": true
},
"esquery": {
"version": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
"integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
"dev": true
},
"esrecurse": {
"version": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz",
"integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=",
"dev": true,
"dependencies": {
"estraverse": {
"version": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz",
"integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=",
"dev": true
}
}
},
"estraverse": {
"version": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
"dev": true
},
"esutils": {
"version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
"event-emitter": {
"version": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
"integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
"dev": true
},
"exit-hook": {
"version": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
"integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
"dev": true
},
"fast-levenshtein": {
"version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"figures": {
"version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true
},
"file-entry-cache": {
"version": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
"dev": true
},
"flat-cache": {
"version": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz",
"integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=",
"dev": true
},
"fs.realpath": {
"version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"generate-function": {
"version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
"integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
"dev": true
},
"generate-object-property": {
"version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
"dev": true
},
"gh-pages": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-0.12.0.tgz",
"integrity": "sha1-2VHj7Zi4VpnUsEGOsaFbGgSYjcE=",
"dependencies": {
"async": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/async/-/async-2.1.2.tgz",
"integrity": "sha1-YSpKtF70KnDN6Aa62G7m2wR+g4U="
},
"globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw="
},
"graceful-fs": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.10.tgz",
"integrity": "sha1-8tcgwiCS90Mih3XHXjYSYyUB8TE="
}
}
},
"glob": {
"version": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
"integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg="
},
"globals": {
"version": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz",
"integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=",
"dev": true
},
"globby": {
"version": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
"dev": true
},
"graceful-fs": {
"version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
"dev": true
},
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
},
"handlebars": {
"version": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.7.tgz",
"integrity": "sha1-6XMlrrjqC54SucTdc8TDEq0O3lk=",
"dev": true,
"dependencies": {
"source-map": {
"version": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true
}
}
},
"has-ansi": {
"version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true
},
"ignore": {
"version": "https://registry.npmjs.org/ignore/-/ignore-3.2.7.tgz",
"integrity": "sha1-SBDKXx2OylWVITo0uU8utO2Sa70=",
"dev": true
},
"imurmurhash": {
"version": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"inflight": {
"version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk="
},
"inherits": {
"version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"inquirer": {
"version": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
"integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
"dev": true
},
"interpret": {
"version": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz",
"integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=",
"dev": true
},
"is-buffer": {
"version": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true
},
"is-my-json-valid": {
"version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz",
"integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=",
"dev": true
},
"is-path-cwd": {
"version": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
"integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
"dev": true
},
"is-path-in-cwd": {
"version": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
"integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
"dev": true
},
"is-path-inside": {
"version": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
"integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
"dev": true
},
"is-property": {
"version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
"dev": true
},
"is-resolvable": {
"version": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
"integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
"dev": true
},
"isarray": {
"version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"isexe": {
"version": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"istanbul": {
"version": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
"integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
"dev": true,
"dependencies": {
"esprima": {
"version": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
"dev": true
},
"glob": {
"version": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
"integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
"dev": true
},
"resolve": {
"version": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
},
"supports-color": {
"version": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
"dev": true
}
}
},
"js-tokens": {
"version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz",
"integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=",
"dev": true
},
"js-yaml": {
"version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.3.tgz",
"integrity": "sha1-M6BexIHIUMiHWSkWb+G+thxyh2Y=",
"dev": true
},
"json-stable-stringify": {
"version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
"dev": true
},
"jsonify": {
"version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
"dev": true
},
"jsonpointer": {
"version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
"dev": true
},
"kind-of": {
"version": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz",
"integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=",
"dev": true
},
"lazy-cache": {
"version": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
"integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
"dev": true,
"optional": true
},
"levn": {
"version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"dev": true
},
"lodash": {
"version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
},
"longest": {
"version": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
"dev": true
},
"marked": {
"version": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz",
"integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=",
"dev": true
},
"mime": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz",
"integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA="
},
"mimeparse": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/mimeparse/-/mimeparse-0.1.4.tgz",
"integrity": "sha1-2vsCdSNw/SJgk64xUsJxrwGsJUo="
},
"minimatch": {
"version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q="
},
"minimist": {
"version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
"mkdirp": {
"version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true
},
"ms": {
"version": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
"integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=",
"dev": true
},
"mute-stream": {
"version": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
"integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
"dev": true
},
"natural-compare": {
"version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"nopt": {
"version": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"dev": true
},
"number-is-nan": {
"version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
"object-assign": {
"version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"once": {
"version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
},
"onetime": {
"version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
"optimist": {
"version": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
"dev": true,
"dependencies": {
"wordwrap": {
"version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
"dev": true
}
}
},
"optionator": {
"version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"dev": true
},
"os-homedir": {
"version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"dev": true
},
"path-is-absolute": {
"version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-is-inside": {
"version": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
"dev": true
},
"path-parse": {
"version": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
"dev": true
},
"pify": {
"version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
},
"pinkie": {
"version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
},
"pinkie-promise": {
"version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o="
},
"platform": {
"version": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz",
"integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=",
"dev": true
},
"pluralize": {
"version": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
"integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
"dev": true
},
"prelude-ls": {
"version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
"dev": true
},
"process-nextick-args": {
"version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
"dev": true
},
"progress": {
"version": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
"integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
"dev": true
},
"q": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
"integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4="
},
"q-io": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/q-io/-/q-io-1.13.2.tgz",
"integrity": "sha1-7qEw1IHdteGqG8WmaFX3OR0G8AM="
},
"qs": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz",
"integrity": "sha1-GbV/8k3CqZzh+L32r82ln472H4g="
},
"readable-stream": {
"version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz",
"integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=",
"dev": true
},
"readline2": {
"version": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
"integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
"dev": true
},
"rechoir": {
"version": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
"dev": true
},
"repeat-string": {
"version": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
"dev": true
},
"require-uncached": {
"version": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
"dev": true
},
"resolve": {
"version": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz",
"integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=",
"dev": true
},
"resolve-from": {
"version": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
},
"restore-cursor": {
"version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"dev": true
},
"right-align": {
"version": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
"integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
"dev": true,
"optional": true
},
"rimraf": {
"version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
"integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0="
},
"run-async": {
"version": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
"integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
"dev": true
},
"rx-lite": {
"version": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
"integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
"dev": true
},
"shelljs": {
"version": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz",
"integrity": "sha1-svXHfvlxSPS09uImguELuoZnz/E=",
"dev": true
},
"slice-ansi": {
"version": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
"integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
"dev": true
},
"source-map": {
"version": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
"integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
"dev": true,
"optional": true
},
"sprintf-js": {
"version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"string_decoder": {
"version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz",
"integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=",
"dev": true
},
"string-width": {
"version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true
},
"strip-ansi": {
"version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true
},
"strip-bom": {
"version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"dev": true
},
"strip-json-comments": {
"version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
},
"supports-color": {
"version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
"table": {
"version": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
"integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
"dev": true,
"dependencies": {
"is-fullwidth-code-point": {
"version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"string-width": {
"version": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz",
"integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=",
"dev": true
}
}
},
"text-table": {
"version": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"through": {
"version": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"tryit": {
"version": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
"integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
"dev": true
},
"type-check": {
"version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"dev": true
},
"typedarray": {
"version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
"uglify-js": {
"version": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.22.tgz",
"integrity": "sha1-1Uk0d4qNoUkD+imjJvskwKtRoaA=",
"dev": true,
"optional": true,
"dependencies": {
"source-map": {
"version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
"dev": true,
"optional": true
}
}
},
"uglify-to-browserify": {
"version": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"dev": true,
"optional": true
},
"url2": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/url2/-/url2-0.0.0.tgz",
"integrity": "sha1-Tqq9HVw6yQ1iq0SFyZhCKGWgSxo="
},
"user-home": {
"version": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
"integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
"dev": true
},
"util-deprecate": {
"version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"weak-map": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.0.tgz",
"integrity": "sha1-tm5Wqd8L0lp2u/G1FNsSkIBhSjc="
},
"which": {
"version": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
"integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
"dev": true
},
"window-size": {
"version": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
"dev": true,
"optional": true
},
"wordwrap": {
"version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
"dev": true
},
"wrappy": {
"version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"write": {
"version": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
"integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
"dev": true
},
"xtend": {
"version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
"dev": true
},
"yargs": {
"version": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
"dev": true,
"optional": true
}
}
}

View file

@ -33,5 +33,9 @@
"bin": {
"ospec": "./ospec/bin/ospec",
"bundle": "./bundler/bin/bundle"
},
"dependencies": {
"@alrra/travis-scripts": "^3.0.1",
"gh-pages": "^0.12.0"
}
}

View file

@ -17,7 +17,7 @@ function compileSelector(selector) {
var attrValue = match[6]
if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
if (match[4] === "class") classes.push(attrValue)
else attrs[match[4]] = attrValue || true
else attrs[match[4]] = attrValue === "" ? attrValue : attrValue || true
}
}
if (classes.length > 0) attrs.className = classes.join(" ")

View file

@ -6,9 +6,18 @@ module.exports = function($window) {
var $doc = $window.document
var $emptyFragment = $doc.createDocumentFragment()
var nameSpace = {
svg: "http://www.w3.org/2000/svg",
math: "http://www.w3.org/1998/Math/MathML"
}
var onevent
function setEventCallback(callback) {return onevent = callback}
function getNameSpace(vnode) {
return vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag]
}
//create
function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {
for (var i = start; i < end; i++) {
@ -66,14 +75,11 @@ module.exports = function($window) {
}
function createElement(parent, vnode, hooks, ns, nextSibling) {
var tag = vnode.tag
switch (vnode.tag) {
case "svg": ns = "http://www.w3.org/2000/svg"; break
case "math": ns = "http://www.w3.org/1998/Math/MathML"; break
}
var attrs = vnode.attrs
var is = attrs && attrs.is
ns = getNameSpace(vnode) || ns
var element = ns ?
is ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) :
is ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag)
@ -140,7 +146,7 @@ module.exports = function($window) {
//update
function updateNodes(parent, old, vnodes, recycling, hooks, nextSibling, ns) {
if (old === vnodes || old == null && vnodes == null) return
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined)
else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, ns)
else if (vnodes == null) removeNodes(old, 0, old.length, vnodes)
else {
if (old.length === vnodes.length) {
@ -218,7 +224,7 @@ module.exports = function($window) {
if (movable.dom != null) nextSibling = movable.dom
}
else {
var dom = createNode(parent, v, hooks, undefined, nextSibling)
var dom = createNode(parent, v, hooks, ns, nextSibling)
nextSibling = dom
}
}
@ -289,10 +295,8 @@ module.exports = function($window) {
}
function updateElement(old, vnode, recycling, hooks, ns) {
var element = vnode.dom = old.dom
switch (vnode.tag) {
case "svg": ns = "http://www.w3.org/2000/svg"; break
case "math": ns = "http://www.w3.org/1998/Math/MathML"; break
}
ns = getNameSpace(vnode) || ns
if (vnode.tag === "textarea") {
if (vnode.attrs == null) vnode.attrs = {}
if (vnode.text != null) {
@ -476,12 +480,21 @@ module.exports = function($window) {
else if (key[0] === "o" && key[1] === "n" && typeof value === "function") updateEvent(vnode, key, value)
else if (key === "style") updateStyle(element, old, value)
else if (key in element && !isAttribute(key) && ns === undefined && !isCustomElement(vnode)) {
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
if (vnode.tag === "input" && key === "value" && vnode.dom.value == value && vnode.dom === $doc.activeElement) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "select" && key === "value" && vnode.dom.value == value && vnode.dom === $doc.activeElement) return
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "option" && key === "value" && vnode.dom.value == value) return
if (key === "value") {
var normalized = "" + value // eslint-disable-line no-implicit-coercion
//setting input[value] to same value by typing on focused element moves cursor to end in Chrome
if ((vnode.tag === "input" || vnode.tag === "textarea") && vnode.dom.value === normalized && vnode.dom === $doc.activeElement) return
//setting select[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "select") {
if (value === null) {
if (vnode.dom.selectedIndex === -1 && vnode.dom === $doc.activeElement) return
} else {
if (old !== null && vnode.dom.value === normalized && vnode.dom === $doc.activeElement) return
}
}
//setting option[value] to same value while having select open blinks select dropdown in Chrome
if (vnode.tag === "option" && old != null && vnode.dom.value === normalized) return
}
// If you assign an input type that is not supported by IE 11 with an assignment expression, an error will occur.
if (vnode.tag === "input" && key === "type") {
element.setAttribute(key, value)
@ -600,12 +613,13 @@ module.exports = function($window) {
if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
var hooks = []
var active = $doc.activeElement
var namespace = dom.namespaceURI
// First time rendering into a node clears it out
if (dom.vnodes == null) dom.textContent = ""
if (!Array.isArray(vnodes)) vnodes = [vnodes]
updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), false, hooks, null, undefined)
updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), false, hooks, null, namespace === "http://www.w3.org/1999/xhtml" ? undefined : namespace)
dom.vnodes = vnodes
for (var i = 0; i < hooks.length; i++) hooks[i]()
if ($doc.activeElement !== active) active.focus()

View file

@ -11,6 +11,46 @@ o.spec("attributes", function() {
root = $window.document.body
render = vdom($window).render
})
o.spec("basics", function() {
o("works (create/update/remove)", function() {
var a = {tag: "div", attrs: {}}
var b = {tag: "div", attrs: {id: "test"}}
var c = {tag: "div", attrs: {}}
render(root, [a]);
o(a.dom.hasAttribute("id")).equals(false)
render(root, [b]);
o(b.dom.getAttribute("id")).equals("test")
render(root, [c]);
o(c.dom.hasAttribute("id")).equals(false)
})
o("undefined attr is equivalent to a lack of attr", function() {
var a = {tag: "div", attrs: {id: undefined}}
var b = {tag: "div", attrs: {id: "test"}}
var c = {tag: "div", attrs: {id: undefined}}
render(root, [a]);
o(a.dom.hasAttribute("id")).equals(false)
render(root, [b]);
o(b.dom.hasAttribute("id")).equals(true)
o(b.dom.getAttribute("id")).equals("test")
render(root, [c]);
// #1804
// TODO: uncomment
// o(c.dom.hasAttribute("id")).equals(false)
})
})
o.spec("customElements", function(){
o("when vnode is customElement, custom setAttribute called", function(){
@ -54,7 +94,7 @@ o.spec("attributes", function() {
render(root, [a])
o(a.dom.attributes["readonly"].nodeValue).equals("")
o(a.dom.attributes["readonly"].value).equals("")
})
o("when input readonly is false, attribute is not present", function() {
var a = {tag: "input", attrs: {readonly: false}}
@ -96,6 +136,196 @@ o.spec("attributes", function() {
o(a.dom.attributes["checked"]).equals(undefined)
})
})
o.spec("input.value", function() {
o("can be set as text", function() {
var a = {tag: "input", attrs: {value: "test"}}
render(root, [a]);
o(a.dom.value).equals("test")
})
o("a lack of attribute removes `value`", function() {
var a = {tag: "input", attrs: {}}
var b = {tag: "input", attrs: {value: "test"}}
// var c = {tag: "input", attrs: {}}
render(root, [a])
o(a.dom.value).equals("")
render(root, [b])
o(a.dom.value).equals("test")
// https://github.com/MithrilJS/mithril.js/issues/1804#issuecomment-304521235
// TODO: Uncomment
// render(root, [c])
// o(a.dom.value).equals("")
})
o("can be set as number", function() {
var a = {tag: "input", attrs: {value: 1}}
render(root, [a]);
o(a.dom.value).equals("1")
})
o("null becomes the empty string", function() {
var a = {tag: "input", attrs: {value: null}}
var b = {tag: "input", attrs: {value: "test"}}
var c = {tag: "input", attrs: {value: null}}
render(root, [a]);
o(a.dom.value).equals("")
o(a.dom.getAttribute("value")).equals(null)
render(root, [b]);
o(b.dom.value).equals("test")
o(b.dom.getAttribute("value")).equals(null)
render(root, [c]);
o(c.dom.value).equals("")
o(c.dom.getAttribute("value")).equals(null)
})
o("'' and 0 are different values", function() {
var a = {tag: "input", attrs: {value: 0}, children:[{tag:"#", children:""}]}
var b = {tag: "input", attrs: {value: ""}, children:[{tag:"#", children:""}]}
var c = {tag: "input", attrs: {value: 0}, children:[{tag:"#", children:""}]}
render(root, [a]);
o(a.dom.value).equals("0")
render(root, [b]);
o(b.dom.value).equals("")
// #1595 redux
render(root, [c]);
o(c.dom.value).equals("0")
})
o("isn't set when equivalent to the previous value and focused", function() {
var $window = domMock({spy: o.spy})
var root = $window.document.body
var render = vdom($window).render
var a = {tag: "input"}
var b = {tag: "input", attrs: {value: "1"}}
var c = {tag: "input", attrs: {value: "1"}}
var d = {tag: "input", attrs: {value: 1}}
var e = {tag: "input", attrs: {value: 2}}
render(root, [a])
var spies = $window.__getSpies(a.dom)
a.dom.focus()
o(spies.valueSetter.callCount).equals(0)
render(root, [b])
o(b.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [c])
o(c.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [d])
o(d.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [e])
o(d.dom.value).equals("2")
o(spies.valueSetter.callCount).equals(2)
})
})
o.spec("input.type", function() {
o("the input.type setter is never used", function() {
var $window = domMock({spy: o.spy})
var root = $window.document.body
var render = vdom($window).render
var a = {tag: "input", attrs: {type: "radio"}}
var b = {tag: "input", attrs: {type: "text"}}
var c = {tag: "input", attrs: {}}
render(root, [a])
var spies = $window.__getSpies(a.dom)
o(spies.typeSetter.callCount).equals(0)
o(a.dom.getAttribute("type")).equals("radio")
render(root, [b])
o(spies.typeSetter.callCount).equals(0)
o(b.dom.getAttribute("type")).equals("text")
render(root, [c])
o(spies.typeSetter.callCount).equals(0)
o(c.dom.hasAttribute("type")).equals(false)
})
})
o.spec("textarea.value", function() {
o("can be removed by not passing a value", function() {
var a = {tag: "textarea", attrs: {value:"x"}}
// var b = {tag: "textarea", attrs: {}}
render(root, [a])
o(a.dom.value).equals("x")
// https://github.com/MithrilJS/mithril.js/issues/1804#issuecomment-304521235
// TODO: Uncomment
// render(root, [b])
// o(b.dom.value).equals("")
})
o("isn't set when equivalent to the previous value and focused", function() {
var $window = domMock({spy: o.spy})
var root = $window.document.body
var render = vdom($window).render
var a = {tag: "textarea"}
var b = {tag: "textarea", attrs: {value: "1"}}
var c = {tag: "textarea", attrs: {value: "1"}}
var d = {tag: "textarea", attrs: {value: 1}}
var e = {tag: "textarea", attrs: {value: 2}}
render(root, [a])
var spies = $window.__getSpies(a.dom)
a.dom.focus()
o(spies.valueSetter.callCount).equals(0)
render(root, [b])
o(b.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [c])
o(c.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [d])
o(d.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [e])
o(d.dom.value).equals("2")
o(spies.valueSetter.callCount).equals(2)
})
})
o.spec("link href", function() {
o("when link href is true, attribute is present", function() {
var a = {tag: "a", attrs: {href: true}}
@ -118,7 +348,7 @@ o.spec("attributes", function() {
render(root, canvas)
o(canvas.dom.attributes["width"].nodeValue).equals("100%")
o(canvas.dom.attributes["width"].value).equals("100%")
o(canvas.dom.width).equals(100)
})
})
@ -128,7 +358,218 @@ o.spec("attributes", function() {
render(root, [a]);
o(a.dom.attributes["class"].nodeValue).equals("test")
o(a.dom.attributes["class"].value).equals("test")
})
})
o.spec("option.value", function() {
o("can be set as text", function() {
var a = {tag: "option", attrs: {value: "test"}}
render(root, [a]);
o(a.dom.value).equals("test")
})
o("can be set as number", function() {
var a = {tag: "option", attrs: {value: 1}}
render(root, [a]);
o(a.dom.value).equals("1")
})
o("null becomes the empty string", function() {
var a = {tag: "option", attrs: {value: null}}
var b = {tag: "option", attrs: {value: "test"}}
var c = {tag: "option", attrs: {value: null}}
render(root, [a]);
o(a.dom.value).equals("")
o(a.dom.getAttribute("value")).equals("")
render(root, [b]);
o(b.dom.value).equals("test")
o(b.dom.getAttribute("value")).equals("test")
render(root, [c]);
o(c.dom.value).equals("")
o(c.dom.getAttribute("value")).equals("")
})
o("'' and 0 are different values", function() {
var a = {tag: "option", attrs: {value: 0}, children:[{tag:"#", children:""}]}
var b = {tag: "option", attrs: {value: ""}, children:[{tag:"#", children:""}]}
var c = {tag: "option", attrs: {value: 0}, children:[{tag:"#", children:""}]}
render(root, [a]);
o(a.dom.value).equals("0")
render(root, [b]);
o(a.dom.value).equals("")
// #1595 redux
render(root, [c]);
o(c.dom.value).equals("0")
})
o("isn't set when equivalent to the previous value", function() {
var $window = domMock({spy: o.spy})
var root = $window.document.body
var render = vdom($window).render
var a = {tag: "option"}
var b = {tag: "option", attrs: {value: "1"}}
var c = {tag: "option", attrs: {value: "1"}}
var d = {tag: "option", attrs: {value: 1}}
var e = {tag: "option", attrs: {value: 2}}
render(root, [a])
var spies = $window.__getSpies(a.dom)
o(spies.valueSetter.callCount).equals(0)
render(root, [b])
o(b.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [c])
o(c.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [d])
o(d.dom.value).equals("1")
o(spies.valueSetter.callCount).equals(1)
render(root, [e])
o(d.dom.value).equals("2")
o(spies.valueSetter.callCount).equals(2)
})
})
o.spec("select.value", function() {
function makeSelect(value) {
var attrs = (arguments.length === 0) ? {} : {value: value}
return {tag: "select", attrs: attrs, children: [
{tag:"option", attrs: {value: "1"}},
{tag:"option", attrs: {value: "2"}},
{tag:"option", attrs: {value: "a"}},
{tag:"option", attrs: {value: "0"}},
{tag:"option", attrs: {value: ""}}
]}
}
o("can be set as text", function() {
var a = makeSelect()
var b = makeSelect("2")
var c = makeSelect("a")
render(root, [a])
o(a.dom.value).equals("1")
o(a.dom.selectedIndex).equals(0)
render(root, [b])
o(b.dom.value).equals("2")
o(b.dom.selectedIndex).equals(1)
render(root, [c])
o(c.dom.value).equals("a")
o(c.dom.selectedIndex).equals(2)
})
o("setting null unsets the value", function() {
var a = makeSelect(null)
render(root, [a])
o(a.dom.value).equals("")
o(a.dom.selectedIndex).equals(-1)
})
o("values are type converted", function() {
var a = makeSelect(1)
var b = makeSelect(2)
render(root, [a])
o(a.dom.value).equals("1")
o(a.dom.selectedIndex).equals(0)
render(root, [b])
o(b.dom.value).equals("2")
o(b.dom.selectedIndex).equals(1)
})
o("'' and 0 are different values when focused", function() {
var a = makeSelect("")
var b = makeSelect(0)
render(root, [a])
a.dom.focus()
o(a.dom.value).equals("")
// #1595 redux
render(root, [b])
o(b.dom.value).equals("0")
})
o("'' and null are different values when focused", function() {
var a = makeSelect("")
var b = makeSelect(null)
var c = makeSelect("")
render(root, [a])
a.dom.focus()
o(a.dom.value).equals("")
o(a.dom.selectedIndex).equals(4)
render(root, [b])
o(b.dom.value).equals("")
o(b.dom.selectedIndex).equals(-1)
render(root, [c])
o(c.dom.value).equals("")
o(c.dom.selectedIndex).equals(4)
})
o("updates with the same value do not re-set the attribute if the select has focus", function() {
var $window = domMock({spy: o.spy})
var root = $window.document.body
var render = vdom($window).render
var a = makeSelect()
var b = makeSelect("1")
var c = makeSelect(1)
var d = makeSelect("2")
render(root, [a])
var spies = $window.__getSpies(a.dom)
a.dom.focus()
o(spies.valueSetter.callCount).equals(0)
o(a.dom.value).equals("1")
render(root, [b])
o(spies.valueSetter.callCount).equals(0)
o(b.dom.value).equals("1")
render(root, [c])
o(spies.valueSetter.callCount).equals(0)
o(c.dom.value).equals("1")
render(root, [d])
o(spies.valueSetter.callCount).equals(1)
o(d.dom.value).equals("2")
})
})
o.spec("contenteditable throws on untrusted children", function() {

View file

@ -30,7 +30,7 @@ o.spec("component", function() {
render(root, [node])
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("receives arguments", function() {
@ -44,7 +44,7 @@ o.spec("component", function() {
render(root, [node])
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("updates", function() {
@ -57,7 +57,7 @@ o.spec("component", function() {
render(root, [{tag: component, attrs: {id: "c"}, text: "d"}])
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("c")
o(root.firstChild.attributes["id"].value).equals("c")
o(root.firstChild.firstChild.nodeValue).equals("d")
})
o("updates root from null", function() {
@ -400,7 +400,7 @@ o.spec("component", function() {
o(called).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("calls oninit when returning fragment", function() {
@ -423,7 +423,7 @@ o.spec("component", function() {
o(called).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("calls oninit before view", function() {
@ -479,7 +479,7 @@ o.spec("component", function() {
o(called).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("does not calls oncreate on redraw", function() {
@ -520,7 +520,7 @@ o.spec("component", function() {
o(called).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("calls onupdate", function() {
@ -546,7 +546,7 @@ o.spec("component", function() {
o(called).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("calls onupdate when returning fragment", function() {
@ -572,7 +572,7 @@ o.spec("component", function() {
o(called).equals(1)
o(root.firstChild.nodeName).equals("DIV")
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
o(root.firstChild.firstChild.nodeValue).equals("b")
})
o("calls onremove", function() {

View file

@ -24,8 +24,8 @@ o.spec("createElement", function() {
render(root, [vnode])
o(vnode.dom.nodeName).equals("DIV")
o(vnode.dom.attributes["id"].nodeValue).equals("a")
o(vnode.dom.attributes["title"].nodeValue).equals("b")
o(vnode.dom.attributes["id"].value).equals("a")
o(vnode.dom.attributes["title"].value).equals("b")
})
o("creates style", function() {
var vnode = {tag: "div", attrs: {style: {backgroundColor: "red"}}}
@ -48,28 +48,34 @@ o.spec("createElement", function() {
render(root, [vnode])
o(vnode.dom.nodeName).equals("DIV")
o(vnode.dom.attributes["id"].nodeValue).equals("a")
o(vnode.dom.attributes["title"].nodeValue).equals("b")
o(vnode.dom.attributes["id"].value).equals("a")
o(vnode.dom.attributes["title"].value).equals("b")
o(vnode.dom.childNodes.length).equals(2)
o(vnode.dom.childNodes[0].nodeName).equals("A")
o(vnode.dom.childNodes[1].nodeName).equals("B")
})
o("creates svg", function() {
var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", children: [{tag: "a", ns: "http://www.w3.org/2000/svg", attrs: {"xlink:href": "javascript:;"}}]}
var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", children: [
{tag: "a", ns: "http://www.w3.org/2000/svg", attrs: {"xlink:href": "javascript:;"}},
{tag: "foreignObject", children: [{tag: "body", attrs: {xmlns: "http://www.w3.org/1999/xhtml"}}]}
]}
render(root, [vnode])
o(vnode.dom.nodeName).equals("svg")
o(vnode.dom.namespaceURI).equals("http://www.w3.org/2000/svg")
o(vnode.dom.firstChild.nodeName).equals("a")
o(vnode.dom.firstChild.namespaceURI).equals("http://www.w3.org/2000/svg")
o(vnode.dom.firstChild.attributes["href"].nodeValue).equals("javascript:;")
o(vnode.dom.firstChild.attributes["href"].value).equals("javascript:;")
o(vnode.dom.firstChild.attributes["href"].namespaceURI).equals("http://www.w3.org/1999/xlink")
o(vnode.dom.childNodes[1].nodeName).equals("foreignObject")
o(vnode.dom.childNodes[1].firstChild.nodeName).equals("body")
o(vnode.dom.childNodes[1].firstChild.namespaceURI).equals("http://www.w3.org/1999/xhtml")
})
o("sets attributes correctly for svg", function() {
var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", attrs: {viewBox: "0 0 100 100"}}
render(root, [vnode])
o(vnode.dom.attributes["viewBox"].nodeValue).equals("0 0 100 100")
o(vnode.dom.attributes["viewBox"].value).equals("0 0 100 100")
})
o("creates mathml", function() {
var vnode = {tag: "math", ns: "http://www.w3.org/1998/Math/MathML", children: [{tag: "mrow", ns: "http://www.w3.org/1998/Math/MathML"}]}

View file

@ -69,7 +69,7 @@ o.spec("event", function() {
o(onevent.args[0].type).equals("click")
o(onevent.args[0].target).equals(div.dom)
o(div.dom).equals(updated.dom)
o(div.dom.attributes["id"].nodeValue).equals("b")
o(div.dom.attributes["id"].value).equals("b")
})
o("handles ontransitionend", function() {

View file

@ -218,6 +218,18 @@ o.spec("hyperscript", function() {
o(vnode.tag).equals("div")
o(vnode.attrs.a).equals(true)
})
o("handles explicit empty string value for input", function() {
var vnode = m('input[value=""]')
o(vnode.tag).equals("input")
o(vnode.attrs.value).equals("")
})
o("handles explicit empty string value for option", function() {
var vnode = m('option[value=""]')
o(vnode.tag).equals("option")
o(vnode.attrs.value).equals("")
})
})
o.spec("attrs", function() {
o("handles string attr", function() {

View file

@ -80,6 +80,57 @@ o.spec("form inputs", function() {
o(select.dom.selectedIndex).equals(0)
})
o("select option can have empty string value", function() {
var select = {tag: "select", children :[
{tag: "option", attrs: {value: ""}, text: "aaa"}
]}
render(root, [select])
o(select.dom.firstChild.value).equals("")
})
o("option value defaults to textContent unless explicitly set", function() {
var select = {tag: "select", children :[
{tag: "option", text: "aaa"}
]}
render(root, [select])
o(select.dom.firstChild.value).equals("aaa")
o(select.dom.value).equals("aaa")
//test that value changes when content changes
select = {tag: "select", children :[
{tag: "option", text: "bbb"}
]}
render(root, [select])
o(select.dom.firstChild.value).equals("bbb")
o(select.dom.value).equals("bbb")
//test that value can be set to "" in subsequent render
select = {tag: "select", children :[
{tag: "option", attrs: {value: ""}, text: "aaa"}
]}
render(root, [select])
o(select.dom.firstChild.value).equals("")
o(select.dom.value).equals("")
//test that value reverts to textContent when value omitted
select = {tag: "select", children :[
{tag: "option", text: "aaa"}
]}
render(root, [select])
o(select.dom.firstChild.value).equals("aaa")
o(select.dom.value).equals("aaa")
})
o("select yields invalid value without children", function() {
var select = {tag: "select", attrs: {value: "a"}}

View file

@ -21,7 +21,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
})
o("prevents update in text", function() {
@ -65,7 +65,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("accepts arguments for comparison", function() {
@ -86,7 +86,7 @@ o.spec("onbeforeupdate", function() {
}
o(count).equals(1)
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("is not called on creation", function() {
@ -167,7 +167,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("a")
o(root.firstChild.attributes["id"].value).equals("a")
})
o("does not prevent update if returning true in component and true in vnode", function() {
@ -183,7 +183,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("does not prevent update if returning false in component but true in vnode", function() {
@ -199,7 +199,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("does not prevent update if returning true in component but false in vnode", function() {
@ -215,7 +215,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("does not prevent update if returning true from component", function() {
@ -231,7 +231,7 @@ o.spec("onbeforeupdate", function() {
render(root, [vnode])
render(root, [updated])
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("accepts arguments for comparison in component", function() {
@ -258,7 +258,7 @@ o.spec("onbeforeupdate", function() {
}
o(count).equals(1)
o(root.firstChild.attributes["id"].nodeValue).equals("b")
o(root.firstChild.attributes["id"].value).equals("b")
})
o("is not called on component creation", function() {

View file

@ -170,9 +170,9 @@ o.spec("onupdate", function() {
function update(vnode) {
called = true
o(vnode.dom.parentNode.attributes["id"].nodeValue).equals("11")
o(vnode.dom.attributes["id"].nodeValue).equals("22")
o(vnode.dom.childNodes[0].attributes["id"].nodeValue).equals("33")
o(vnode.dom.parentNode.attributes["id"].value).equals("11")
o(vnode.dom.attributes["id"].value).equals("22")
o(vnode.dom.childNodes[0].attributes["id"].value).equals("33")
}
o(called).equals(true)
})

View file

@ -271,4 +271,32 @@ o.spec("render", function() {
o(updateA.callCount).equals(2)
o(removeA.callCount).equals(1)
})
o("svg namespace is preserved in keyed diff (#1820)", function(){
// note that this only exerciese one branch of the keyed diff algo
var svg = {tag:"svg", children: [
{tag:"g", key: 0},
{tag:"g", key: 1}
]}
render(root, [svg])
o(svg.dom.namespaceURI).equals("http://www.w3.org/2000/svg")
o(svg.dom.childNodes[0].namespaceURI).equals("http://www.w3.org/2000/svg")
o(svg.dom.childNodes[1].namespaceURI).equals("http://www.w3.org/2000/svg")
svg = {tag:"svg", children: [
{tag:"g", key: 1, attrs: {x: 1}},
{tag:"g", key: 2, attrs: {x: 2}}
]}
render(root, [svg])
o(svg.dom.namespaceURI).equals("http://www.w3.org/2000/svg")
o(svg.dom.childNodes[0].namespaceURI).equals("http://www.w3.org/2000/svg")
o(svg.dom.childNodes[1].namespaceURI).equals("http://www.w3.org/2000/svg")
})
o("the namespace of the root is passed to children", function() {
render(root, [{tag: "svg"}])
o(root.childNodes[0].namespaceURI).equals("http://www.w3.org/2000/svg")
render(root.childNodes[0], [{tag: "g"}])
o(root.childNodes[0].childNodes[0].namespaceURI).equals("http://www.w3.org/2000/svg")
})
})

View file

@ -21,7 +21,7 @@ o.spec("updateElement", function() {
o(updated.dom).equals(vnode.dom)
o(updated.dom).equals(root.firstChild)
o(updated.dom.attributes["id"].nodeValue).equals("c")
o(updated.dom.attributes["id"].value).equals("c")
})
o("adds attr", function() {
var vnode = {tag: "a", attrs: {id: "b"}}
@ -32,7 +32,7 @@ o.spec("updateElement", function() {
o(updated.dom).equals(vnode.dom)
o(updated.dom).equals(root.firstChild)
o(updated.dom.attributes["title"].nodeValue).equals("d")
o(updated.dom.attributes["title"].value).equals("d")
})
o("adds attr from empty attrs", function() {
var vnode = {tag: "a"}
@ -43,7 +43,7 @@ o.spec("updateElement", function() {
o(updated.dom).equals(vnode.dom)
o(updated.dom).equals(root.firstChild)
o(updated.dom.attributes["title"].nodeValue).equals("d")
o(updated.dom.attributes["title"].value).equals("d")
})
o("removes attr", function() {
var vnode = {tag: "a", attrs: {id: "b", title: "d"}}
@ -209,7 +209,7 @@ o.spec("updateElement", function() {
render(root, [vnode])
render(root, [updated])
o(updated.dom.attributes["class"].nodeValue).equals("b")
o(updated.dom.attributes["class"].value).equals("b")
})
o("updates svg child", function() {
var vnode = {tag: "svg", children: [{

View file

@ -1,6 +1,7 @@
"use strict"
/* eslint-disable */
;(function() {
"use strict"
/* eslint-enable */
var guid = 0, HALT = {}
function createStream() {

View file

@ -1,6 +1,39 @@
"use strict"
module.exports = function() {
/*
Known limitations:
- `option.selected` can't be set/read when the option doesn't have a `select` parent
- `element.attributes` is just a map of attribute names => Attr objects stubs
- ...
*/
/*
options:
- spy:(f: Function) => Function
*/
module.exports = function(options) {
options = options || {}
var spy = options.spy || function(f){return f}
var spymap = []
function registerSpies(element, spies) {
if(options.spy) {
var i = spymap.indexOf(element)
if (i === -1) {
spymap.push(element, spies)
} else {
var existing = spymap[i + 1]
for (var k in spies) existing[k] = spies[k]
}
}
}
function getSpies(element) {
if (element == null || typeof element !== "object") throw new Error("Element expected")
if(options.spy) return spymap[spymap.indexOf(element) + 1]
}
function isModernEvent(type) {
return type === "transitionstart" || type === "transitionend" || type === "animationstart" || type === "animationend"
}
@ -62,14 +95,26 @@ module.exports = function() {
}
function getAttribute(name) {
if (this.attributes[name] == null) return null
return this.attributes[name].nodeValue
return this.attributes[name].value
}
function setAttribute(name, value) {
var nodeValue = String(value)
/*eslint-disable no-implicit-coercion*/
// this is the correct kind of conversion, passing a Symbol throws in browsers too.
var nodeValue = "" + value
/*eslint-enable no-implicit-coercion*/
this.attributes[name] = {
namespaceURI: null,
get value() {return nodeValue},
set value(value) {
/*eslint-disable no-implicit-coercion*/
nodeValue = "" + value
/*eslint-enable no-implicit-coercion*/
},
get nodeValue() {return nodeValue},
set nodeValue(value) {nodeValue = String(value)},
set nodeValue(value) {
this.value = value
}
}
}
function setAttributeNS(ns, name, value) {
@ -79,6 +124,9 @@ module.exports = function() {
function removeAttribute(name) {
delete this.attributes[name]
}
function hasAttribute(name) {
return name in this.attributes
}
var declListTokenizer = /;|"(?:\\.|[^"\n])*"|'(?:\\.|[^'\n])*'/g
/**
* This will split a semicolon-separated CSS declaration list into an array of
@ -150,6 +198,7 @@ module.exports = function() {
appendChild: appendChild,
removeChild: removeChild,
insertBefore: insertBefore,
hasAttribute: hasAttribute,
getAttribute: getAttribute,
setAttribute: setAttribute,
setAttributeNS: setAttributeNS,
@ -204,7 +253,7 @@ module.exports = function() {
throw new Error("setting element.style is not portable")
},
get className() {
return this.attributes["class"] ? this.attributes["class"].nodeValue : ""
return this.attributes["class"] ? this.attributes["class"].value : ""
},
set className(value) {
if (this.namespaceURI === "http://www.w3.org/2000/svg") throw new Error("Cannot set property className of SVGElement")
@ -222,7 +271,7 @@ module.exports = function() {
}
},
dispatchEvent: function(e) {
if (this.nodeName === "INPUT" && this.attributes["type"] != null && this.attributes["type"].nodeValue === "checkbox" && e.type === "click") {
if (this.nodeName === "INPUT" && this.attributes["type"] != null && this.attributes["type"].value === "checkbox" && e.type === "click") {
this.checked = !this.checked
}
@ -256,30 +305,73 @@ module.exports = function() {
enumerable: true,
})
element.value = ""
}
if (element.nodeName === "TEXTAREA") {
var value
var value = ""
var valueSetter = spy(function(v) {
/*eslint-disable no-implicit-coercion*/
value = v === null ? "" : "" + v
/*eslint-enable no-implicit-coercion*/
})
Object.defineProperty(element, "value", {
get: function() {
return value != null ? value :
this.firstChild ? this.firstChild.nodeValue : ""
return value
},
set: function(v) {value = v},
set: valueSetter,
enumerable: true,
})
// we currently emulate the non-ie behavior, but emulating ie may be more useful (throw when an invalid type is set)
var typeSetter = spy(function(v) {
this.setAttribute("type", v)
})
Object.defineProperty(element, "type", {
get: function() {
if (!this.hasAttribute("type")) return "text"
var type = this.getAttribute("type")
return (/^(?:radio|button|checkbox|color|date|datetime|datetime-local|email|file|hidden|month|number|password|range|research|search|submit|tel|text|url|week|image)$/)
.test(type)
? type
: "text"
},
set: typeSetter,
enumerable: true,
})
registerSpies(element, {
valueSetter: valueSetter,
typeSetter: typeSetter
})
}
if (element.nodeName === "TEXTAREA") {
var wasNeverSet = true
var value = ""
var valueSetter = spy(function(v) {
wasNeverSet = false
/*eslint-disable no-implicit-coercion*/
value = v === null ? "" : "" + v
/*eslint-enable no-implicit-coercion*/
})
Object.defineProperty(element, "value", {
get: function() {
return wasNeverSet && this.firstChild ? this.firstChild.nodeValue : value
},
set: valueSetter,
enumerable: true,
})
registerSpies(element, {
valueSetter: valueSetter
})
}
/* eslint-disable radix */
if (element.nodeName === "CANVAS") {
Object.defineProperty(element, "width", {
get: function() {return this.attributes["width"] ? Math.floor(parseInt(this.attributes["width"].nodeValue) || 0) : 300},
get: function() {return this.attributes["width"] ? Math.floor(parseInt(this.attributes["width"].value) || 0) : 300},
set: function(value) {this.setAttribute("width", Math.floor(Number(value) || 0).toString())},
})
Object.defineProperty(element, "height", {
get: function() {return this.attributes["height"] ? Math.floor(parseInt(this.attributes["height"].nodeValue) || 0) : 300},
get: function() {return this.attributes["height"] ? Math.floor(parseInt(this.attributes["height"].value) || 0) : 300},
set: function(value) {this.setAttribute("height", Math.floor(Number(value) || 0).toString())},
})
}
@ -296,7 +388,7 @@ module.exports = function() {
}
function getOptionValue(element) {
return element.attributes["value"] != null ?
element.attributes["value"].nodeValue :
element.attributes["value"].value :
element.firstChild != null ? element.firstChild.nodeValue : ""
}
if (element.nodeName === "SELECT") {
@ -317,14 +409,14 @@ module.exports = function() {
},
enumerable: true,
})
Object.defineProperty(element, "value", {
get: function() {
if (this.selectedIndex > -1) return getOptionValue(getOptions(this)[this.selectedIndex])
return ""
},
set: function(value) {
var valueSetter = spy(function(value) {
if (value === null) {
selectedIndex = -1
} else {
var options = getOptions(this)
var stringValue = String(value)
/*eslint-disable no-implicit-coercion*/
var stringValue = "" + value
/*eslint-enable no-implicit-coercion*/
for (var i = 0; i < options.length; i++) {
if (getOptionValue(options[i]) === stringValue) {
// selectedValue = stringValue
@ -334,19 +426,37 @@ module.exports = function() {
}
// selectedValue = stringValue
selectedIndex = -1
}
})
Object.defineProperty(element, "value", {
get: function() {
if (this.selectedIndex > -1) return getOptionValue(getOptions(this)[this.selectedIndex])
return ""
},
set: valueSetter,
enumerable: true,
})
registerSpies(element, {
valueSetter: valueSetter
})
}
if (element.nodeName === "OPTION") {
var valueSetter = spy(function(value) {
/*eslint-disable no-implicit-coercion*/
this.setAttribute("value", value === null ? "" : "" + value)
/*eslint-enable no-implicit-coercion*/
})
Object.defineProperty(element, "value", {
get: function() {return getOptionValue(this)},
set: function(value) {
this.setAttribute("value", value)
},
set: valueSetter,
enumerable: true,
})
registerSpies(element, {
valueSetter: valueSetter
})
Object.defineProperty(element, "selected", {
// TODO? handle `selected` without a parent (works in browsers)
get: function() {
var options = getOptions(this.parentNode)
var index = options.indexOf(this)
@ -372,13 +482,19 @@ module.exports = function() {
return element
},
createTextNode: function(text) {
var nodeValue = String(text)
/*eslint-disable no-implicit-coercion*/
var nodeValue = "" + text
/*eslint-enable no-implicit-coercion*/
return {
nodeType: 3,
nodeName: "#text",
parentNode: null,
get nodeValue() {return nodeValue},
set nodeValue(value) {nodeValue = String(value)},
set nodeValue(value) {
/*eslint-disable no-implicit-coercion*/
nodeValue = "" + value
/*eslint-enable no-implicit-coercion*/
},
}
},
createDocumentFragment: function() {
@ -409,5 +525,7 @@ module.exports = function() {
$window.document.documentElement.appendChild($window.document.body)
activeElement = $window.document.body
if (options.spy) $window.__getSpies = getSpies
return $window
}

View file

@ -77,6 +77,27 @@ o.spec("domMock", function() {
o(node.nodeValue).equals("true")
})
if (typeof Symbol === "function") {
o("doesn't work with symbols", function(){
var threw = false
try {
$document.createTextNode(Symbol("nono"))
} catch(e) {
threw = true
}
o(threw).equals(true)
})
o("symbols can't be used as nodeValue", function(){
var threw = false
try {
var node = $document.createTextNode("a")
node.nodeValue = Symbol("nono")
} catch(e) {
threw = true
}
o(threw).equals(true)
})
}
})
o.spec("createDocumentFragment", function() {
@ -327,6 +348,7 @@ o.spec("domMock", function() {
var div = $document.createElement("div")
div.setAttribute("id", "aaa")
o(div.attributes["id"].value).equals("aaa")
o(div.attributes["id"].nodeValue).equals("aaa")
o(div.attributes["id"].namespaceURI).equals(null)
})
@ -334,32 +356,51 @@ o.spec("domMock", function() {
var div = $document.createElement("div")
div.setAttribute("id", 123)
o(div.attributes["id"].nodeValue).equals("123")
o(div.attributes["id"].value).equals("123")
})
o("works w/ null", function() {
var div = $document.createElement("div")
div.setAttribute("id", null)
o(div.attributes["id"].nodeValue).equals("null")
o(div.attributes["id"].value).equals("null")
})
o("works w/ undefined", function() {
var div = $document.createElement("div")
div.setAttribute("id", undefined)
o(div.attributes["id"].nodeValue).equals("undefined")
o(div.attributes["id"].value).equals("undefined")
})
o("works w/ object", function() {
var div = $document.createElement("div")
div.setAttribute("id", {})
o(div.attributes["id"].nodeValue).equals("[object Object]")
o(div.attributes["id"].value).equals("[object Object]")
})
o("setting via attributes map stringifies", function() {
var div = $document.createElement("div")
div.setAttribute("id", "a")
div.attributes["id"].nodeValue = 123
div.attributes["id"].value = 123
o(div.attributes["id"].nodeValue).equals("123")
o(div.attributes["id"].value).equals("123")
div.attributes["id"].nodeValue = 456
o(div.attributes["id"].value).equals("456")
})
})
o.spec("hasAttribute", function() {
o("works", function() {
var div = $document.createElement("div")
o(div.hasAttribute("id")).equals(false)
div.setAttribute("id", "aaa")
o(div.hasAttribute("id")).equals(true)
div.removeAttribute("id")
o(div.hasAttribute("id")).equals(false)
})
})
@ -368,14 +409,14 @@ o.spec("domMock", function() {
var div = $document.createElement("div")
div.setAttributeNS("http://www.w3.org/1999/xlink", "href", "aaa")
o(div.attributes["href"].nodeValue).equals("aaa")
o(div.attributes["href"].value).equals("aaa")
o(div.attributes["href"].namespaceURI).equals("http://www.w3.org/1999/xlink")
})
o("works w/ number", function() {
var div = $document.createElement("div")
div.setAttributeNS("http://www.w3.org/1999/xlink", "href", 123)
o(div.attributes["href"].nodeValue).equals("123")
o(div.attributes["href"].value).equals("123")
o(div.attributes["href"].namespaceURI).equals("http://www.w3.org/1999/xlink")
})
})
@ -416,18 +457,18 @@ o.spec("domMock", function() {
o(div.childNodes[0].nodeName).equals("BR")
o(div.childNodes[1].nodeType).equals(1)
o(div.childNodes[1].nodeName).equals("A")
o(div.childNodes[1].attributes["class"].nodeValue).equals("aaa")
o(div.childNodes[1].attributes["id"].nodeValue).equals("xyz")
o(div.childNodes[1].attributes["class"].value).equals("aaa")
o(div.childNodes[1].attributes["id"].value).equals("xyz")
o(div.childNodes[1].childNodes[0].nodeType).equals(3)
o(div.childNodes[1].childNodes[0].nodeValue).equals("123")
o(div.childNodes[1].childNodes[1].nodeType).equals(1)
o(div.childNodes[1].childNodes[1].nodeName).equals("B")
o(div.childNodes[1].childNodes[1].attributes["class"].nodeValue).equals("bbb")
o(div.childNodes[1].childNodes[1].attributes["class"].value).equals("bbb")
o(div.childNodes[1].childNodes[2].nodeType).equals(3)
o(div.childNodes[1].childNodes[2].nodeValue).equals("234")
o(div.childNodes[1].childNodes[3].nodeType).equals(1)
o(div.childNodes[1].childNodes[3].nodeName).equals("BR")
o(div.childNodes[1].childNodes[3].attributes["class"].nodeValue).equals("ccc")
o(div.childNodes[1].childNodes[3].attributes["class"].value).equals("ccc")
o(div.childNodes[1].childNodes[4].nodeType).equals(3)
o(div.childNodes[1].childNodes[4].nodeValue).equals("345")
})
@ -628,14 +669,14 @@ o.spec("domMock", function() {
a.setAttribute("href", "")
o(a.href).notEquals("")
o(a.attributes["href"].nodeValue).equals("")
o(a.attributes["href"].value).equals("")
})
o("is path if property is set", function() {
var a = $document.createElement("a")
a.href = ""
o(a.href).notEquals("")
o(a.attributes["href"].nodeValue).equals("")
o(a.attributes["href"].value).equals("")
})
})
o.spec("input[checked]", function() {
@ -656,7 +697,7 @@ o.spec("domMock", function() {
input.setAttribute("checked", "")
o(input.checked).equals(true)
o(input.attributes["checked"].nodeValue).equals("")
o(input.attributes["checked"].value).equals("")
input.removeAttribute("checked")
@ -699,20 +740,95 @@ o.spec("domMock", function() {
o("value" in input).equals(true)
o("value" in a).equals(false)
})
o("converts null to ''", function() {
var input = $document.createElement("input")
input.value = "x"
o(input.value).equals("x")
input.value = null
o(input.value).equals("")
})
o("converts values to strings", function() {
var input = $document.createElement("input")
input.value = 5
o(input.value).equals("5")
input.value = 0
o(input.value).equals("0")
input.value = undefined
o(input.value).equals("undefined")
})
if (typeof Symbol === "function") o("throws when set to a symbol", function() {
var threw = false
var input = $document.createElement("input")
try {
input.value = Symbol("")
} catch (e) {
o(e instanceof TypeError).equals(true)
threw = true
}
o(input.value).equals("")
o(threw).equals(true)
})
})
o.spec("input[type]", function(){
o("only exists in input elements", function() {
var input = $document.createElement("input")
var a = $document.createElement("a")
o("type" in input).equals(true)
o("type" in a).equals(false)
})
o("is 'text' by default", function() {
var input = $document.createElement("input")
o(input.type).equals("text")
})
"radio|button|checkbox|color|date|datetime|datetime-local|email|file|hidden|month|number|password|range|research|search|submit|tel|text|url|week|image"
.split("|").forEach(function(type) {
o("can be set to " + type, function(){
var input = $document.createElement("input")
input.type = type
o(input.getAttribute("type")).equals(type)
o(input.type).equals(type)
})
o("bad values set the attribute, but the getter corrects to 'text', " + type, function(){
var input = $document.createElement("input")
input.type = "badbad" + type
o(input.getAttribute("type")).equals("badbad" + type)
o(input.type).equals("text")
})
})
})
o.spec("textarea[value]", function() {
o("reads from child if no value", function() {
var input = $document.createElement("textarea")
input.appendChild($document.createTextNode("aaa"))
o("reads from child if no value was ever set", function() {
var textarea = $document.createElement("textarea")
textarea.appendChild($document.createTextNode("aaa"))
o(input.value).equals("aaa")
o(textarea.value).equals("aaa")
})
o("ignores child if value set", function() {
var input = $document.createElement("textarea")
input.value = "aaa"
input.setAttribute("value", "bbb")
var textarea = $document.createElement("textarea")
textarea.value = null
textarea.appendChild($document.createTextNode("aaa"))
o(input.value).equals("aaa")
o(textarea.value).equals("")
})
o("textarea[value] doesn't reflect `attributes.value`", function() {
var textarea = $document.createElement("textarea")
textarea.value = "aaa"
textarea.setAttribute("value", "bbb")
o(textarea.value).equals("aaa")
})
})
o.spec("select[value] and select[selectedIndex]", function() {
@ -773,10 +889,76 @@ o.spec("domMock", function() {
option2.setAttribute("value", "b")
select.appendChild(option2)
var option3 = $document.createElement("option")
option3.setAttribute("value", "")
select.appendChild(option3)
var option4 = $document.createElement("option")
option4.setAttribute("value", "null")
select.appendChild(option4)
select.value = "b"
o(select.value).equals("b")
o(select.selectedIndex).equals(1)
select.value = ""
o(select.value).equals("")
o(select.selectedIndex).equals(2)
select.value = "null"
o(select.value).equals("null")
o(select.selectedIndex).equals(3)
select.value = null
o(select.value).equals("")
o(select.selectedIndex).equals(-1)
})
o("setting valid value works with type conversion", function() {
var select = $document.createElement("select")
var option1 = $document.createElement("option")
option1.setAttribute("value", "0")
select.appendChild(option1)
var option2 = $document.createElement("option")
option2.setAttribute("value", "undefined")
select.appendChild(option2)
var option3 = $document.createElement("option")
option3.setAttribute("value", "")
select.appendChild(option3)
select.value = 0
o(select.value).equals("0")
o(select.selectedIndex).equals(0)
select.value = undefined
o(select.value).equals("undefined")
o(select.selectedIndex).equals(1)
if (typeof Symbol === "function") {
var threw = false
try {
select.value = Symbol("x")
} catch (e) {
threw = true
}
o(threw).equals(true)
o(select.value).equals("undefined")
o(select.selectedIndex).equals(1)
}
})
o("option.value = null is converted to the empty string", function() {
var option = $document.createElement("option")
option.value = null
o(option.value).equals("")
})
o("setting valid value works with optgroup", function() {
var select = $document.createElement("select")
@ -920,55 +1102,55 @@ o.spec("domMock", function() {
var canvas = $document.createElement("canvas")
canvas.width = 100
o(canvas.attributes["width"].nodeValue).equals("100")
o(canvas.attributes["width"].value).equals("100")
o(canvas.width).equals(100)
canvas.height = 100
o(canvas.attributes["height"].nodeValue).equals("100")
o(canvas.attributes["height"].value).equals("100")
o(canvas.height).equals(100)
})
o("setting string casts to number", function() {
var canvas = $document.createElement("canvas")
canvas.width = "100"
o(canvas.attributes["width"].nodeValue).equals("100")
o(canvas.attributes["width"].value).equals("100")
o(canvas.width).equals(100)
canvas.height = "100"
o(canvas.attributes["height"].nodeValue).equals("100")
o(canvas.attributes["height"].value).equals("100")
o(canvas.height).equals(100)
})
o("setting float casts to int", function() {
var canvas = $document.createElement("canvas")
canvas.width = 1.2
o(canvas.attributes["width"].nodeValue).equals("1")
o(canvas.attributes["width"].value).equals("1")
o(canvas.width).equals(1)
canvas.height = 1.2
o(canvas.attributes["height"].nodeValue).equals("1")
o(canvas.attributes["height"].value).equals("1")
o(canvas.height).equals(1)
})
o("setting percentage fails", function() {
var canvas = $document.createElement("canvas")
canvas.width = "100%"
o(canvas.attributes["width"].nodeValue).equals("0")
o(canvas.attributes["width"].value).equals("0")
o(canvas.width).equals(0)
canvas.height = "100%"
o(canvas.attributes["height"].nodeValue).equals("0")
o(canvas.attributes["height"].value).equals("0")
o(canvas.height).equals(0)
})
o("setting attribute works", function() {
var canvas = $document.createElement("canvas")
canvas.setAttribute("width", "100%")
o(canvas.attributes["width"].nodeValue).equals("100%")
o(canvas.attributes["width"].value).equals("100%")
o(canvas.width).equals(100)
canvas.setAttribute("height", "100%")
o(canvas.attributes["height"].nodeValue).equals("100%")
o(canvas.attributes["height"].value).equals("100%")
o(canvas.height).equals(100)
})
})
@ -979,7 +1161,7 @@ o.spec("domMock", function() {
el.className = "a"
o(el.className).equals("a")
o(el.attributes["class"].nodeValue).equals("a")
o(el.attributes["class"].value).equals("a")
})
o("setter throws in svg", function(done) {
var el = $document.createElementNS("http://www.w3.org/2000/svg", "svg")
@ -991,4 +1173,85 @@ o.spec("domMock", function() {
}
})
})
o.spec("spies", function() {
var $window
o.beforeEach(function() {
$window = domMock({spy: o.spy})
})
o("basics", function() {
o(typeof $window.__getSpies).equals("function")
o("__getSpies" in domMock()).equals(false)
})
o("input elements have spies on value and type setters", function() {
var input = $window.document.createElement("input")
var spies = $window.__getSpies(input)
o(typeof spies).equals("object")
o(spies).notEquals(null)
o(typeof spies.valueSetter).equals("function")
o(typeof spies.typeSetter).equals("function")
o(spies.valueSetter.callCount).equals(0)
o(spies.typeSetter.callCount).equals(0)
input.value = "aaa"
input.type = "radio"
o(spies.valueSetter.callCount).equals(1)
o(spies.valueSetter.this).equals(input)
o(spies.valueSetter.args[0]).equals("aaa")
o(spies.typeSetter.callCount).equals(1)
o(spies.typeSetter.this).equals(input)
o(spies.typeSetter.args[0]).equals("radio")
})
o("select elements have spies on value setters", function() {
var select = $window.document.createElement("select")
var spies = $window.__getSpies(select)
o(typeof spies).equals("object")
o(spies).notEquals(null)
o(typeof spies.valueSetter).equals("function")
o(spies.valueSetter.callCount).equals(0)
select.value = "aaa"
o(spies.valueSetter.callCount).equals(1)
o(spies.valueSetter.this).equals(select)
o(spies.valueSetter.args[0]).equals("aaa")
})
o("option elements have spies on value setters", function() {
var option = $window.document.createElement("option")
var spies = $window.__getSpies(option)
o(typeof spies).equals("object")
o(spies).notEquals(null)
o(typeof spies.valueSetter).equals("function")
o(spies.valueSetter.callCount).equals(0)
option.value = "aaa"
o(spies.valueSetter.callCount).equals(1)
o(spies.valueSetter.this).equals(option)
o(spies.valueSetter.args[0]).equals("aaa")
})
o("textarea elements have spies on value setters", function() {
var textarea = $window.document.createElement("textarea")
var spies = $window.__getSpies(textarea)
o(typeof spies).equals("object")
o(spies).notEquals(null)
o(typeof spies.valueSetter).equals("function")
o(spies.valueSetter.callCount).equals(0)
textarea.value = "aaa"
o(spies.valueSetter.callCount).equals(1)
o(spies.valueSetter.this).equals(textarea)
o(spies.valueSetter.args[0]).equals("aaa")
})
})
})