diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/mithril.js | 674 | ||||
-rw-r--r-- | js/mithril.min.js | 8 |
2 files changed, 674 insertions, 8 deletions
diff --git a/js/mithril.js b/js/mithril.js new file mode 100644 index 0000000..128d1d4 --- /dev/null +++ b/js/mithril.js @@ -0,0 +1,674 @@ +Mithril = m = new function app(window) { + var type = {}.toString + var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/ + + function m() { + var args = arguments + var hasAttrs = type.call(args[1]) == "[object Object]" && !("tag" in args[1]) && !("subtree" in args[1]) + var attrs = hasAttrs ? args[1] : {} + var classAttrName = "class" in attrs ? "class" : "className" + var cell = {tag: "div", attrs: {}} + var match, classes = [] + while (match = parser.exec(args[0])) { + if (match[1] == "") cell.tag = match[2] + else if (match[1] == "#") cell.attrs.id = match[2] + else if (match[1] == ".") classes.push(match[2]) + else if (match[3][0] == "[") { + var pair = attrParser.exec(match[3]) + cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" :true) + } + } + if (classes.length > 0) cell.attrs[classAttrName] = classes.join(" ") + + cell.children = hasAttrs ? args[2] : args[1] + + for (var attrName in attrs) { + if (attrName == classAttrName) cell.attrs[attrName] = (cell.attrs[attrName] || "") + " " + attrs[attrName] + else cell.attrs[attrName] = attrs[attrName] + } + return cell + } + function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace, configs) { + if (data === null || data === undefined) data = "" + if (data.subtree === "retain") return cached + + var cachedType = type.call(cached), dataType = type.call(data) + if (cachedType != dataType) { + if (cached !== null && cached !== undefined) { + if (parentCache && parentCache.nodes) { + var offset = index - parentIndex + var end = offset + (dataType == "[object Array]" ? data : cached.nodes).length + clear(parentCache.nodes.slice(offset, end), parentCache.slice(offset, end)) + } + else clear(cached.nodes, cached) + } + cached = new data.constructor + cached.nodes = [] + } + + if (dataType == "[object Array]") { + data = flatten(data) + var nodes = [], intact = cached.length === data.length, subArrayCount = 0 + + var DELETION = 1, INSERTION = 2 , MOVE = 3 + var existing = {}, unkeyed = [], shouldMaintainIdentities = false + for (var i = 0; i < cached.length; i++) { + if (cached[i] && cached[i].attrs && cached[i].attrs.key !== undefined) { + shouldMaintainIdentities = true + existing[cached[i].attrs.key] = {action: DELETION, index: i} + } + } + if (shouldMaintainIdentities) { + for (var i = 0; i < data.length; i++) { + if (data[i] && data[i].attrs) { + if (data[i].attrs.key !== undefined) { + var key = data[i].attrs.key + if (!existing[key]) existing[key] = {action: INSERTION, index: i} + else existing[key] = {action: MOVE, index: i, from: existing[key].index, element: parentElement.childNodes[existing[key].index]} + } + else unkeyed.push({index: i, element: parentElement.childNodes[i]}) + } + } + var actions = Object.keys(existing).map(function(key) {return existing[key]}) + var changes = actions.sort(function(a, b) {return a.action - b.action || a.index - b.index}) + var newCached = cached.slice() + + for (var i = 0, change; change = changes[i]; i++) { + if (change.action == DELETION) { + clear(cached[change.index].nodes, cached[change.index]) + newCached.splice(change.index, 1) + } + if (change.action == INSERTION) { + var dummy = window.document.createElement("div") + dummy.key = data[change.index].attrs.key + parentElement.insertBefore(dummy, parentElement.childNodes[change.index]) + newCached.splice(change.index, 0, {attrs: {key: data[change.index].attrs.key}, nodes: [dummy]}) + } + + if (change.action == MOVE) { + if (parentElement.childNodes[change.index] !== change.element) { + parentElement.insertBefore(change.element, parentElement.childNodes[change.index]) + } + newCached[change.index] = cached[change.from] + } + } + for (var i = 0; i < unkeyed.length; i++) { + var change = unkeyed[i] + parentElement.insertBefore(change.element, parentElement.childNodes[change.index]) + newCached[change.index] = cached[change.index] + } + cached = newCached + cached.nodes = [] + for (var i = 0, child; child = parentElement.childNodes[i]; i++) cached.nodes.push(child) + } + + for (var i = 0, cacheCount = 0; i < data.length; i++) { + var item = build(parentElement, parentTag, cached, index, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace, configs) + if (item === undefined) continue + if (!item.nodes.intact) intact = false + var isArray = item instanceof Array + subArrayCount += isArray ? item.length : 1 + cached[cacheCount++] = item + } + if (!intact) { + for (var i = 0; i < data.length; i++) { + if (cached[i] !== undefined) nodes = nodes.concat(cached[i].nodes) + } + for (var i = 0, node; node = cached.nodes[i]; i++) { + if (node.parentNode !== null && nodes.indexOf(node) < 0) node.parentNode.removeChild(node) + } + for (var i = cached.nodes.length, node; node = nodes[i]; i++) { + if (node.parentNode === null) parentElement.appendChild(node) + } + if (data.length < cached.length) cached.length = data.length + cached.nodes = nodes + } + + } + else if (dataType == "[object Object]") { + if (data.tag != cached.tag || Object.keys(data.attrs).join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) { + clear(cached.nodes) + if (cached.configContext && typeof cached.configContext.onunload == "function") cached.configContext.onunload() + } + if (typeof data.tag != "string") return + + var node, isNew = cached.nodes.length === 0 + if (data.attrs.xmlns) namespace = data.attrs.xmlns + else if (data.tag === "svg") namespace = "http://www.w3.org/2000/svg" + if (isNew) { + node = namespace === undefined ? window.document.createElement(data.tag) : window.document.createElementNS(namespace, data.tag) + cached = { + tag: data.tag, + //process children before attrs so that select.value works correctly + children: data.children !== undefined ? build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace, configs) : undefined, + attrs: setAttributes(node, data.tag, data.attrs, {}, namespace), + nodes: [node] + } + parentElement.insertBefore(node, parentElement.childNodes[index] || null) + } + else { + node = cached.nodes[0] + setAttributes(node, data.tag, data.attrs, cached.attrs, namespace) + cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs) + cached.nodes.intact = true + if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null) + } + if (type.call(data.attrs["config"]) == "[object Function]") { + configs.push(data.attrs["config"].bind(window, node, !isNew, cached.configContext = cached.configContext || {}, cached)) + } + } + else { + var nodes + if (cached.nodes.length === 0) { + if (data.$trusted) { + nodes = injectHTML(parentElement, index, data) + } + else { + nodes = [window.document.createTextNode(data)] + parentElement.insertBefore(nodes[0], parentElement.childNodes[index] || null) + } + cached = "string number boolean".indexOf(typeof data) > -1 ? new data.constructor(data) : data + cached.nodes = nodes + } + else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) { + nodes = cached.nodes + if (!editable || editable !== window.document.activeElement) { + if (data.$trusted) { + clear(nodes, cached) + nodes = injectHTML(parentElement, index, data) + } + else { + if (parentTag === "textarea") parentElement.value = data + else if (editable) editable.innerHTML = data + else { + if (nodes[0].nodeType == 1 || nodes.length > 1) { //was a trusted string + clear(cached.nodes, cached) + nodes = [window.document.createTextNode(data)] + } + parentElement.insertBefore(nodes[0], parentElement.childNodes[index] || null) + nodes[0].nodeValue = data + } + } + } + cached = new data.constructor(data) + cached.nodes = nodes + } + else cached.nodes.intact = true + } + + return cached + } + function setAttributes(node, tag, dataAttrs, cachedAttrs, namespace) { + var groups = {} + for (var attrName in dataAttrs) { + var dataAttr = dataAttrs[attrName] + var cachedAttr = cachedAttrs[attrName] + if (!(attrName in cachedAttrs) || (cachedAttr !== dataAttr) || node === window.document.activeElement) { + cachedAttrs[attrName] = dataAttr + if (attrName === "config") continue + else if (typeof dataAttr == "function" && attrName.indexOf("on") == 0) { + node[attrName] = autoredraw(dataAttr, node) + } + else if (attrName === "style" && typeof dataAttr == "object") { + for (var rule in dataAttr) { + if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule] + } + for (var rule in cachedAttr) { + if (!(rule in dataAttr)) node.style[rule] = "" + } + } + else if (namespace !== undefined) { + if (attrName === "href") node.setAttributeNS("http://www.w3.org/1999/xlink", "href", dataAttr) + else if (attrName === "className") node.setAttribute("class", dataAttr) + else node.setAttribute(attrName, dataAttr) + } + else if (attrName === "value" && tag === "input") { + if (node.value !== dataAttr) node.value = dataAttr + } + else if (attrName in node && !(attrName == "list" || attrName == "style")) { + node[attrName] = dataAttr + } + else node.setAttribute(attrName, dataAttr) + } + } + return cachedAttrs + } + function clear(nodes, cached) { + for (var i = nodes.length - 1; i > -1; i--) { + if (nodes[i] && nodes[i].parentNode) { + nodes[i].parentNode.removeChild(nodes[i]) + cached = [].concat(cached) + if (cached[i]) unload(cached[i]) + } + } + if (nodes.length != 0) nodes.length = 0 + } + function unload(cached) { + if (cached.configContext && typeof cached.configContext.onunload == "function") cached.configContext.onunload() + if (cached.children) { + if (cached.children instanceof Array) for (var i = 0; i < cached.children.length; i++) unload(cached.children[i]) + else if (cached.children.tag) unload(cached.children) + } + } + function injectHTML(parentElement, index, data) { + var nextSibling = parentElement.childNodes[index] + if (nextSibling) { + var isElement = nextSibling.nodeType != 1 + var placeholder = window.document.createElement("span") + if (isElement) { + parentElement.insertBefore(placeholder, nextSibling) + placeholder.insertAdjacentHTML("beforebegin", data) + parentElement.removeChild(placeholder) + } + else nextSibling.insertAdjacentHTML("beforebegin", data) + } + else parentElement.insertAdjacentHTML("beforeend", data) + var nodes = [] + while (parentElement.childNodes[index] !== nextSibling) { + nodes.push(parentElement.childNodes[index]) + index++ + } + return nodes + } + function flatten(data) { + var flattened = [] + for (var i = 0; i < data.length; i++) { + var item = data[i] + if (item instanceof Array) flattened.push.apply(flattened, flatten(item)) + else flattened.push(item) + } + return flattened + } + function autoredraw(callback, object, group) { + return function(e) { + e = e || event + m.startComputation() + try {return callback.call(object, e)} + finally { + if (!lastRedrawId) lastRedrawId = -1; + m.endComputation() + } + } + } + + var html + var documentNode = { + insertAdjacentHTML: function(_, data) { + window.document.write(data) + window.document.close() + }, + appendChild: function(node) { + if (html === undefined) html = window.document.createElement("html") + if (node.nodeName == "HTML") html = node + else html.appendChild(node) + if (window.document.documentElement && window.document.documentElement !== html) { + window.document.replaceChild(html, window.document.documentElement) + } + else window.document.appendChild(html) + }, + insertBefore: function(node) { + this.appendChild(node) + }, + childNodes: [] + } + var nodeCache = [], cellCache = {} + m.render = function(root, cell) { + var configs = [] + if (!root) throw new Error("Please ensure the DOM element exists before rendering a template into it.") + var id = getCellCacheKey(root) + var node = root == window.document || root == window.document.documentElement ? documentNode : root + if (cellCache[id] === undefined) clear(node.childNodes) + cellCache[id] = build(node, null, undefined, undefined, cell, cellCache[id], false, 0, null, undefined, configs) + for (var i = 0; i < configs.length; i++) configs[i]() + } + function getCellCacheKey(element) { + var index = nodeCache.indexOf(element) + return index < 0 ? nodeCache.push(element) - 1 : index + } + + m.trust = function(value) { + value = new String(value) + value.$trusted = true + return value + } + + var roots = [], modules = [], controllers = [], lastRedrawId = 0, computePostRedrawHook = null + m.module = function(root, module) { + var index = roots.indexOf(root) + if (index < 0) index = roots.length + var isPrevented = false + if (controllers[index] && typeof controllers[index].onunload == "function") { + var event = { + preventDefault: function() {isPrevented = true} + } + controllers[index].onunload(event) + } + if (!isPrevented) { + m.startComputation() + roots[index] = root + modules[index] = module + controllers[index] = new module.controller + m.endComputation() + } + } + m.redraw = function() { + var cancel = window.cancelAnimationFrame || window.clearTimeout + var defer = window.requestAnimationFrame || window.setTimeout + if (lastRedrawId) { + cancel(lastRedrawId) + lastRedrawId = defer(redraw, 0) + } + else { + redraw() + lastRedrawId = defer(function() {lastRedrawId = null}, 0) + } + } + function redraw() { + for (var i = 0; i < roots.length; i++) { + if (controllers[i]) m.render(roots[i], modules[i].view(controllers[i])) + } + if (computePostRedrawHook) { + computePostRedrawHook() + computePostRedrawHook = null + } + lastRedrawId = null + } + + var pendingRequests = 0 + m.startComputation = function() {pendingRequests++} + m.endComputation = function() { + pendingRequests = Math.max(pendingRequests - 1, 0) + if (pendingRequests == 0) m.redraw() + } + + m.withAttr = function(prop, withAttrCallback) { + return function(e) { + e = e || event + withAttrCallback(prop in e.currentTarget ? e.currentTarget[prop] : e.currentTarget.getAttribute(prop)) + } + } + + //routing + var modes = {pathname: "", hash: "#", search: "?"} + var redirect = function() {}, routeParams = {}, currentRoute + m.route = function() { + if (arguments.length === 0) return currentRoute + else if (arguments.length === 3 && typeof arguments[1] == "string") { + var root = arguments[0], defaultRoute = arguments[1], router = arguments[2] + redirect = function(source) { + var path = currentRoute = normalizeRoute(source) + if (!routeByValue(root, router, path)) { + m.route(defaultRoute, true) + } + } + var listener = m.route.mode == "hash" ? "onhashchange" : "onpopstate" + window[listener] = function() { + if (currentRoute != normalizeRoute(window.location[m.route.mode])) { + redirect(window.location[m.route.mode]) + } + } + computePostRedrawHook = setScroll + window[listener]() + } + else if (arguments[0].addEventListener) { + var element = arguments[0] + var isInitialized = arguments[1] + if (element.href.indexOf(modes[m.route.mode]) < 0) { + element.href = window.location.pathname + modes[m.route.mode] + element.pathname + } + if (!isInitialized) { + element.removeEventListener("click", routeUnobtrusive) + element.addEventListener("click", routeUnobtrusive) + } + } + else if (typeof arguments[0] == "string") { + currentRoute = arguments[0] + var querystring = typeof arguments[1] == "object" ? buildQueryString(arguments[1]) : null + if (querystring) currentRoute += (currentRoute.indexOf("?") === -1 ? "?" : "&") + querystring + + var shouldReplaceHistoryEntry = (arguments.length == 3 ? arguments[2] : arguments[1]) === true + + if (window.history.pushState) { + computePostRedrawHook = function() { + window.history[shouldReplaceHistoryEntry ? "replaceState" : "pushState"](null, window.document.title, modes[m.route.mode] + currentRoute) + setScroll() + } + redirect(modes[m.route.mode] + currentRoute) + } + else window.location[m.route.mode] = currentRoute + } + } + m.route.param = function(key) {return routeParams[key]} + m.route.mode = "search" + function normalizeRoute(route) {return route.slice(modes[m.route.mode].length)} + function routeByValue(root, router, path) { + routeParams = {} + + var queryStart = path.indexOf("?") + if (queryStart !== -1) { + routeParams = parseQueryString(path.substr(queryStart + 1, path.length)) + path = path.substr(0, queryStart) + } + + for (var route in router) { + if (route == path) { + reset(root) + m.module(root, router[route]) + return true + } + + var matcher = new RegExp("^" + route.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$") + + if (matcher.test(path)) { + reset(root) + path.replace(matcher, function() { + var keys = route.match(/:[^\/]+/g) || [] + var values = [].slice.call(arguments, 1, -2) + for (var i = 0; i < keys.length; i++) routeParams[keys[i].replace(/:|\./g, "")] = decodeSpace(values[i]) + m.module(root, router[route]) + }) + return true + } + } + } + function reset(root) { + var cacheKey = getCellCacheKey(root) + clear(root.childNodes, cellCache[cacheKey]) + cellCache[cacheKey] = undefined + } + function routeUnobtrusive(e) { + e = e || event + if (e.ctrlKey || e.metaKey || e.which == 2) return + e.preventDefault() + m.route(e.currentTarget[m.route.mode].slice(modes[m.route.mode].length)) + } + function setScroll() { + if (m.route.mode != "hash" && window.location.hash) window.location.hash = window.location.hash + else window.scrollTo(0, 0) + } + function buildQueryString(object, prefix) { + var str = [] + for(var prop in object) { + var key = prefix ? prefix + "[" + prop + "]" : prop, value = object[prop] + str.push(typeof value == "object" ? buildQueryString(value, key) : encodeURIComponent(key) + "=" + encodeURIComponent(value)) + } + return str.join("&") + } + function parseQueryString(str) { + var pairs = str.split("&"), params = {} + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i].split("=") + params[decodeSpace(pair[0])] = pair[1] ? decodeSpace(pair[1]) : (pair.length === 1 ? true : "") + } + return params + } + function decodeSpace(string) { + return decodeURIComponent(string.replace(/\+/g, " ")) + } + + //model + m.prop = function(store) { + var prop = function() { + if (arguments.length) store = arguments[0] + return store + } + prop.toJSON = function() { + return store + } + return prop + } + + var none = {} + m.deferred = function() { + var resolvers = [], rejecters = [], resolved = none, rejected = none, promise = m.prop() + var object = { + resolve: function(value) { + if (resolved === none) promise(resolved = value) + for (var i = 0; i < resolvers.length; i++) resolvers[i](value) + resolvers.length = rejecters.length = 0 + }, + reject: function(value) { + if (rejected === none) rejected = value + for (var i = 0; i < rejecters.length; i++) rejecters[i](value) + resolvers.length = rejecters.length = 0 + }, + promise: promise + } + object.promise.resolvers = resolvers + object.promise.then = function(success, error) { + var next = m.deferred() + if (!success) success = identity + if (!error) error = identity + function callback(method, callback) { + return function(value) { + try { + var result = callback(value) + if (result && typeof result.then == "function") result.then(next[method], error) + else next[method](result !== undefined ? result : value) + } + catch (e) { + if (e instanceof Error && e.constructor !== Error) throw e + else next.reject(e) + } + } + } + if (resolved !== none) callback("resolve", success)(resolved) + else if (rejected !== none) callback("reject", error)(rejected) + else { + resolvers.push(callback("resolve", success)) + rejecters.push(callback("reject", error)) + } + return next.promise + } + return object + } + m.sync = function(args) { + var method = "resolve" + function synchronizer(pos, resolved) { + return function(value) { + results[pos] = value + if (!resolved) method = "reject" + if (--outstanding == 0) { + deferred.promise(results) + deferred[method](results) + } + return value + } + } + + var deferred = m.deferred() + var outstanding = args.length + var results = new Array(outstanding) + for (var i = 0; i < args.length; i++) { + args[i].then(synchronizer(i, true), synchronizer(i, false)) + } + return deferred.promise + } + function identity(value) {return value} + + function ajax(options) { + var xhr = new window.XMLHttpRequest + xhr.open(options.method, options.url, true, options.user, options.password) + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + if (xhr.status >= 200 && xhr.status < 300) options.onload({type: "load", target: xhr}) + else options.onerror({type: "error", target: xhr}) + } + } + if (options.serialize == JSON.stringify && options.method != "GET") { + xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); + } + if (typeof options.config == "function") { + var maybeXhr = options.config(xhr, options) + if (maybeXhr !== undefined) xhr = maybeXhr + } + xhr.send(options.method == "GET" ? "" : options.data) + return xhr + } + function bindData(xhrOptions, data, serialize) { + if (data && Object.keys(data).length > 0) { + if (xhrOptions.method == "GET") { + xhrOptions.url = xhrOptions.url + (xhrOptions.url.indexOf("?") < 0 ? "?" : "&") + buildQueryString(data) + } + else xhrOptions.data = serialize(data) + } + return xhrOptions + } + function parameterizeUrl(url, data) { + var tokens = url.match(/:[a-z]\w+/gi) + if (tokens && data) { + for (var i = 0; i < tokens.length; i++) { + var key = tokens[i].slice(1) + url = url.replace(tokens[i], data[key]) + delete data[key] + } + } + return url + } + + m.request = function(xhrOptions) { + if (xhrOptions.background !== true) m.startComputation() + var deferred = m.deferred() + var serialize = xhrOptions.serialize = xhrOptions.serialize || JSON.stringify + var deserialize = xhrOptions.deserialize = xhrOptions.deserialize || JSON.parse + var extract = xhrOptions.extract || function(xhr) { + return xhr.responseText.length === 0 && deserialize === JSON.parse ? null : xhr.responseText + } + xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data) + xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize) + xhrOptions.onload = xhrOptions.onerror = function(e) { + try { + e = e || event + var unwrap = (e.type == "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity + var response = unwrap(deserialize(extract(e.target, xhrOptions))) + if (e.type == "load") { + if (response instanceof Array && xhrOptions.type) { + for (var i = 0; i < response.length; i++) response[i] = new xhrOptions.type(response[i]) + } + else if (xhrOptions.type) response = new xhrOptions.type(response) + } + deferred[e.type == "load" ? "resolve" : "reject"](response) + } + catch (e) { + if (e instanceof SyntaxError) throw new SyntaxError("Could not parse HTTP response. See http://lhorie.github.io/mithril/mithril.request.html#using-variable-data-formats") + else if (e instanceof Error && e.constructor !== Error) throw e + else deferred.reject(e) + } + if (xhrOptions.background !== true) m.endComputation() + } + ajax(xhrOptions) + return deferred.promise + } + + //testing API + m.deps = function(mock) {return window = mock} + //for internal testing only, do not use `m.deps.factory` + m.deps.factory = app + + return m +}(typeof window != "undefined" ? window : {}) + +if (typeof module != "undefined" && module !== null) module.exports = m +if (typeof define == "function" && define.amd) define(function() {return m}) + +;;; diff --git a/js/mithril.min.js b/js/mithril.min.js deleted file mode 100644 index 29134a3..0000000 --- a/js/mithril.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -Mithril v0.1.19 -http://github.com/lhorie/mithril.js -(c) Leo Horie -License: MIT -*/ -Mithril=m=new function a(b){function c(){for(var a,b=arguments,c=(!("[object Object]"!=z.call(b[1])||"tag"in b[1]||"subtree"in b[1])),d=c?b[1]:{},e=("class"in d?"class":"className"),f={tag:"div",attrs:{}},g=[];a=A.exec(b[0]);)if(""==a[1])f.tag=a[2];else if("#"==a[1])f.attrs.id=a[2];else if("."==a[1])g.push(a[2]);else if("["==a[3][0]){var h=B.exec(a[3]);f.attrs[h[1]]=h[3]||(h[2]?"":!0)}g.length>0&&(f.attrs[e]=g.join(" ")),f.children=c?b[2]:b[1];for(var i in d)f.attrs[i]=i==e?(f.attrs[i]||"")+" "+d[i]:d[i];return f}function d(a,c,g,j,k,l,m,n,o,p,q){if((null===k||void 0===k)&&(k=""),"retain"===k.subtree)return l;var r=z.call(l),s=z.call(k);if(r!=s){if(null!==l&&void 0!==l)if(g&&g.nodes){var t=n-j,u=t+("[object Array]"==s?k:l.nodes).length;f(g.nodes.slice(t,u),g.slice(t,u))}else f(l.nodes,l);l=new k.constructor,l.nodes=[]}if("[object Array]"==s){k=i(k);for(var v=[],w=l.length===k.length,x=0,y=1,A=2,B=3,C={},D=[],E=!1,F=0;F<l.length;F++)l[F]&&l[F].attrs&&void 0!==l[F].attrs.key&&(E=!0,C[l[F].attrs.key]={action:y,index:F});if(E){for(var F=0;F<k.length;F++)if(k[F]&&k[F].attrs)if(void 0!==k[F].attrs.key){var G=k[F].attrs.key;C[G]=C[G]?{action:B,index:F,from:C[G].index,element:a.childNodes[C[G].index]}:{action:A,index:F}}else D.push({index:F,element:a.childNodes[F]});for(var H,I=Object.keys(C).map(function(a){return C[a]}),J=I.sort(function(a,b){return a.action-b.action||a.index-b.index}),K=l.slice(),F=0;H=J[F];F++){if(H.action==y&&(f(l[H.index].nodes,l[H.index]),K.splice(H.index,1)),H.action==A){var L=b.document.createElement("div");L.key=k[H.index].attrs.key,a.insertBefore(L,a.childNodes[H.index]),K.splice(H.index,0,{attrs:{key:k[H.index].attrs.key},nodes:[L]})}H.action==B&&(a.childNodes[H.index]!==H.element&&a.insertBefore(H.element,a.childNodes[H.index]),K[H.index]=l[H.from])}for(var F=0;F<D.length;F++){var H=D[F];a.insertBefore(H.element,a.childNodes[H.index]),K[H.index]=l[H.index]}l=K,l.nodes=[];for(var M,F=0;M=a.childNodes[F];F++)l.nodes.push(M)}for(var F=0,N=0;F<k.length;F++){var O=d(a,c,l,n,k[F],l[N],m,n+x||x,o,p,q);if(void 0!==O){O.nodes.intact||(w=!1);var P=O instanceof Array;x+=P?O.length:1,l[N++]=O}}if(!w){for(var F=0;F<k.length;F++)void 0!==l[F]&&(v=v.concat(l[F].nodes));for(var Q,F=0;Q=l.nodes[F];F++)null!==Q.parentNode&&v.indexOf(Q)<0&&Q.parentNode.removeChild(Q);for(var Q,F=l.nodes.length;Q=v[F];F++)null===Q.parentNode&&a.appendChild(Q);k.length<l.length&&(l.length=k.length),l.nodes=v}}else if("[object Object]"==s){if((k.tag!=l.tag||Object.keys(k.attrs).join()!=Object.keys(l.attrs).join()||k.attrs.id!=l.attrs.id)&&(f(l.nodes),l.configContext&&"function"==typeof l.configContext.onunload&&l.configContext.onunload()),"string"!=typeof k.tag)return;var Q,R=0===l.nodes.length;k.attrs.xmlns?p=k.attrs.xmlns:"svg"===k.tag&&(p="http://www.w3.org/2000/svg"),R?(Q=void 0===p?b.document.createElement(k.tag):b.document.createElementNS(p,k.tag),l={tag:k.tag,children:void 0!==k.children?d(Q,k.tag,void 0,void 0,k.children,l.children,!0,0,k.attrs.contenteditable?Q:o,p,q):void 0,attrs:e(Q,k.tag,k.attrs,{},p),nodes:[Q]},a.insertBefore(Q,a.childNodes[n]||null)):(Q=l.nodes[0],e(Q,k.tag,k.attrs,l.attrs,p),l.children=d(Q,k.tag,void 0,void 0,k.children,l.children,!1,0,k.attrs.contenteditable?Q:o,p,q),l.nodes.intact=!0,m===!0&&a.insertBefore(Q,a.childNodes[n]||null)),"[object Function]"==z.call(k.attrs.config)&&q.push(k.attrs.config.bind(b,Q,!R,l.configContext=l.configContext||{},l))}else{var v;0===l.nodes.length?(k.$trusted?v=h(a,n,k):(v=[b.document.createTextNode(k)],a.insertBefore(v[0],a.childNodes[n]||null)),l="string number boolean".indexOf(typeof k)>-1?new k.constructor(k):k,l.nodes=v):l.valueOf()!==k.valueOf()||m===!0?(v=l.nodes,o&&o===b.document.activeElement||(k.$trusted?(f(v,l),v=h(a,n,k)):"textarea"===c?a.value=k:o?o.innerHTML=k:((1==v[0].nodeType||v.length>1)&&(f(l.nodes,l),v=[b.document.createTextNode(k)]),a.insertBefore(v[0],a.childNodes[n]||null),v[0].nodeValue=k)),l=new k.constructor(k),l.nodes=v):l.nodes.intact=!0}return l}function e(a,c,d,e,f){for(var g in d){var h=d[g],i=e[g];if(!(g in e)||i!==h||a===b.document.activeElement){if(e[g]=h,"config"===g)continue;if("function"==typeof h&&0==g.indexOf("on"))a[g]=j(h,a);else if("style"===g&&"object"==typeof h){for(var k in h)(void 0===i||i[k]!==h[k])&&(a.style[k]=h[k]);for(var k in i)k in h||(a.style[k]="")}else void 0!==f?"href"===g?a.setAttributeNS("http://www.w3.org/1999/xlink","href",h):"className"===g?a.setAttribute("class",h):a.setAttribute(g,h):"value"===g&&"input"===c?a.value!==h&&(a.value=h):g in a&&"list"!=g&&"style"!=g?a[g]=h:a.setAttribute(g,h)}}return e}function f(a,b){for(var c=a.length-1;c>-1;c--)a[c]&&a[c].parentNode&&(a[c].parentNode.removeChild(a[c]),b=[].concat(b),b[c]&&g(b[c]));0!=a.length&&(a.length=0)}function g(a){if(a.configContext&&"function"==typeof a.configContext.onunload&&a.configContext.onunload(),a.children)if(a.children instanceof Array)for(var b=0;b<a.children.length;b++)g(a.children[b]);else a.children.tag&&g(a.children)}function h(a,c,d){var e=a.childNodes[c];if(e){var f=1!=e.nodeType,g=b.document.createElement("span");f?(a.insertBefore(g,e),g.insertAdjacentHTML("beforebegin",d),a.removeChild(g)):e.insertAdjacentHTML("beforebegin",d)}else a.insertAdjacentHTML("beforeend",d);for(var h=[];a.childNodes[c]!==e;)h.push(a.childNodes[c]),c++;return h}function i(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d instanceof Array?b.push.apply(b,i(d)):b.push(d)}return b}function j(a,b){return function(d){d=d||event,c.startComputation();try{return a.call(b,d)}finally{I||(I=-1),c.endComputation()}}}function k(a){var b=D.indexOf(a);return 0>b?D.push(a)-1:b}function l(){for(var a=0;a<F.length;a++)H[a]&&c.render(F[a],G[a].view(H[a]));J&&(J(),J=null),I=null}function m(a){return a.slice(M[c.route.mode].length)}function n(a,b,d){O={};var e=d.indexOf("?");-1!==e&&(O=s(d.substr(e+1,d.length)),d=d.substr(0,e));for(var f in b){if(f==d)return o(a),c.module(a,b[f]),!0;var g=new RegExp("^"+f.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(g.test(d))return o(a),d.replace(g,function(){for(var d=f.match(/:[^\/]+/g)||[],e=[].slice.call(arguments,1,-2),g=0;g<d.length;g++)O[d[g].replace(/:|\./g,"")]=t(e[g]);c.module(a,b[f])}),!0}}function o(a){var b=k(a);f(a.childNodes,E[b]),E[b]=void 0}function p(a){a=a||event,a.ctrlKey||a.metaKey||2==a.which||(a.preventDefault(),c.route(a.currentTarget[c.route.mode].slice(M[c.route.mode].length)))}function q(){"hash"!=c.route.mode&&b.location.hash?b.location.hash=b.location.hash:b.scrollTo(0,0)}function r(a,b){var c=[];for(var d in a){var e=b?b+"["+d+"]":d,f=a[d];c.push("object"==typeof f?r(f,e):encodeURIComponent(e)+"="+encodeURIComponent(f))}return c.join("&")}function s(a){for(var b=a.split("&"),c={},d=0;d<b.length;d++){var e=b[d].split("=");c[t(e[0])]=e[1]?t(e[1]):1===e.length?!0:""}return c}function t(a){return decodeURIComponent(a.replace(/\+/g," "))}function u(a){return a}function v(a){var c=new b.XMLHttpRequest;if(c.open(a.method,a.url,!0,a.user,a.password),c.onreadystatechange=function(){4===c.readyState&&(c.status>=200&&c.status<300?a.onload({type:"load",target:c}):a.onerror({type:"error",target:c}))},a.serialize==JSON.stringify&&"GET"!=a.method&&c.setRequestHeader("Content-Type","application/json; charset=utf-8"),"function"==typeof a.config){var d=a.config(c,a);void 0!==d&&(c=d)}return c.send("GET"==a.method?"":a.data),c}function w(a,b,c){return b&&Object.keys(b).length>0&&("GET"==a.method?a.url=a.url+(a.url.indexOf("?")<0?"?":"&")+r(b):a.data=c(b)),a}function x(a,b){var c=a.match(/:[a-z]\w+/gi);if(c&&b)for(var d=0;d<c.length;d++){var e=c[d].slice(1);a=a.replace(c[d],b[e]),delete b[e]}return a}var y,z={}.toString,A=/(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g,B=/\[(.+?)(?:=("|'|)(.*?)\2)?\]/,C={insertAdjacentHTML:function(a,c){b.document.write(c),b.document.close()},appendChild:function(a){void 0===y&&(y=b.document.createElement("html")),"HTML"==a.nodeName?y=a:y.appendChild(a),b.document.documentElement&&b.document.documentElement!==y?b.document.replaceChild(y,b.document.documentElement):b.document.appendChild(y)},insertBefore:function(a){this.appendChild(a)},childNodes:[]},D=[],E={};c.render=function(a,c){var e=[];if(!a)throw new Error("Please ensure the DOM element exists before rendering a template into it.");var g=k(a),h=a==b.document||a==b.document.documentElement?C:a;void 0===E[g]&&f(h.childNodes),E[g]=d(h,null,void 0,void 0,c,E[g],!1,0,null,void 0,e);for(var i=0;i<e.length;i++)e[i]()},c.trust=function(a){return a=new String(a),a.$trusted=!0,a};var F=[],G=[],H=[],I=0,J=null;c.module=function(a,b){var d=F.indexOf(a);0>d&&(d=F.length);var e=!1;if(H[d]&&"function"==typeof H[d].onunload){var f={preventDefault:function(){e=!0}};H[d].onunload(f)}e||(c.startComputation(),F[d]=a,G[d]=b,H[d]=new b.controller,c.endComputation())},c.redraw=function(){var a=b.cancelAnimationFrame||b.clearTimeout,c=b.requestAnimationFrame||b.setTimeout;I?(a(I),I=c(l,0)):(l(),I=c(function(){I=null},0))};var K=0;c.startComputation=function(){K++},c.endComputation=function(){K=Math.max(K-1,0),0==K&&c.redraw()},c.withAttr=function(a,b){return function(c){c=c||event,b(a in c.currentTarget?c.currentTarget[a]:c.currentTarget.getAttribute(a))}};var L,M={pathname:"",hash:"#",search:"?"},N=function(){},O={};c.route=function(){if(0===arguments.length)return L;if(3===arguments.length&&"string"==typeof arguments[1]){var a=arguments[0],d=arguments[1],e=arguments[2];N=function(b){var f=L=m(b);n(a,e,f)||c.route(d,!0)};var f="hash"==c.route.mode?"onhashchange":"onpopstate";b[f]=function(){L!=m(b.location[c.route.mode])&&N(b.location[c.route.mode])},J=q,b[f]()}else if(arguments[0].addEventListener){var g=arguments[0],h=arguments[1];g.href.indexOf(M[c.route.mode])<0&&(g.href=b.location.pathname+M[c.route.mode]+g.pathname),h||(g.removeEventListener("click",p),g.addEventListener("click",p))}else if("string"==typeof arguments[0]){L=arguments[0];var i="object"==typeof arguments[1]?r(arguments[1]):null;i&&(L+=(-1===L.indexOf("?")?"?":"&")+i);var j=(3==arguments.length?arguments[2]:arguments[1])===!0;b.history.pushState?(J=function(){b.history[j?"replaceState":"pushState"](null,b.document.title,M[c.route.mode]+L),q()},N(M[c.route.mode]+L)):b.location[c.route.mode]=L}},c.route.param=function(a){return O[a]},c.route.mode="search",c.prop=function(a){var b=function(){return arguments.length&&(a=arguments[0]),a};return b.toJSON=function(){return a},b};var P={};return c.deferred=function(){var a=[],b=[],d=P,e=P,f=c.prop(),g={resolve:function(c){d===P&&f(d=c);for(var e=0;e<a.length;e++)a[e](c);a.length=b.length=0},reject:function(c){e===P&&(e=c);for(var d=0;d<b.length;d++)b[d](c);a.length=b.length=0},promise:f};return g.promise.resolvers=a,g.promise.then=function(f,g){function h(a,b){return function(c){try{var d=b(c);d&&"function"==typeof d.then?d.then(i[a],g):i[a](void 0!==d?d:c)}catch(e){if(e instanceof Error&&e.constructor!==Error)throw e;i.reject(e)}}}var i=c.deferred();return f||(f=u),g||(g=u),d!==P?h("resolve",f)(d):e!==P?h("reject",g)(e):(a.push(h("resolve",f)),b.push(h("reject",g))),i.promise},g},c.sync=function(a){function b(a,b){return function(c){return g[a]=c,b||(d="reject"),0==--f&&(e.promise(g),e[d](g)),c}}for(var d="resolve",e=c.deferred(),f=a.length,g=new Array(f),h=0;h<a.length;h++)a[h].then(b(h,!0),b(h,!1));return e.promise},c.request=function(a){a.background!==!0&&c.startComputation();var b=c.deferred(),d=a.serialize=a.serialize||JSON.stringify,e=a.deserialize=a.deserialize||JSON.parse,f=a.extract||function(a){return 0===a.responseText.length&&e===JSON.parse?null:a.responseText};return a.url=x(a.url,a.data),a=w(a,a.data,d),a.onload=a.onerror=function(d){try{d=d||event;var g=("load"==d.type?a.unwrapSuccess:a.unwrapError)||u,h=g(e(f(d.target,a)));if("load"==d.type)if(h instanceof Array&&a.type)for(var i=0;i<h.length;i++)h[i]=new a.type(h[i]);else a.type&&(h=new a.type(h));b["load"==d.type?"resolve":"reject"](h)}catch(d){if(d instanceof SyntaxError)throw new SyntaxError("Could not parse HTTP response. See http://lhorie.github.io/mithril/mithril.request.html#using-variable-data-formats");if(d instanceof Error&&d.constructor!==Error)throw d;b.reject(d)}a.background!==!0&&c.endComputation()},v(a),b.promise},c.deps=function(a){return b=a},c.deps.factory=a,c}("undefined"!=typeof window?window:{}),"undefined"!=typeof module&&null!==module&&(module.exports=m),"function"==typeof define&&define.amd&&define(function(){return m}); -//# sourceMappingURL=mithril.min.map |