From 77378af23237076d7303742703e68800eb21ec9f Mon Sep 17 00:00:00 2001 From: Gandalf-the-Bot Date: Wed, 4 Oct 2017 22:02:02 +0000 Subject: [PATCH] Bundled output for commit ae27c0ff183da5c36c9bf0052567d9c2b8ae464c [skip ci] --- README.md | 2 +- mithril.js | 54 ++++++++++++++++++++---------- mithril.min.js | 90 +++++++++++++++++++++++++------------------------- 3 files changed, 83 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 105894ed..21055536 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ mithril.js [![NPM Version](https://img.shields.io/npm/v/mithril.svg)](https://ww ## What is Mithril? -A modern client-side Javascript framework for building Single Page Applications. It's small (8.43 KB gzipped), fast and provides routing and XHR utilities out of the box. +A modern client-side Javascript framework for building Single Page Applications. It's small (8.42 KB gzipped), fast and provides routing and XHR utilities out of the box. Mithril is used by companies like Vimeo and Nike, and open source platforms like Lichess 👍. diff --git a/mithril.js b/mithril.js index a953152b..3360f865 100644 --- a/mithril.js +++ b/mithril.js @@ -1,7 +1,7 @@ ;(function() { "use strict" function Vnode(tag, key, attrs0, children, text, dom) { - return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, _state: undefined, events: undefined, instance: undefined, skip: false} + return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, events: undefined, instance: undefined, skip: false} } Vnode.normalize = function(node) { if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined) @@ -398,6 +398,22 @@ var coreRenderer = function($window) { function getNameSpace(vnode) { return vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag] } + //sanity check to discourage people from doing `vnode.state = ...` + function checkState(vnode, original) { + if (vnode.state !== original) throw new Error("`vnode.state` must not be modified") + } + //Note: the hook is passed as the `this` argument to allow proxying the + //arguments without requiring a full array allocation to do so. It also + //takes advantage of the fact the current `vnode` is the first argument in + //all lifecycle methods. + function callHook(vnode) { + var original = vnode.state + try { + return this.apply(original, arguments) + } finally { + checkState(vnode, original) + } + } //create function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) { for (var i = start; i < end; i++) { @@ -495,10 +511,9 @@ var coreRenderer = function($window) { sentinel.$$reentrantLock$$ = true vnode.state = (vnode.tag.prototype != null && typeof vnode.tag.prototype.view === "function") ? new vnode.tag(vnode) : vnode.tag(vnode) } - vnode._state = vnode.state if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks) - initLifecycle(vnode._state, vnode, hooks) - vnode.instance = Vnode.normalize(vnode._state.view.call(vnode.state, vnode)) + initLifecycle(vnode.state, vnode, hooks) + vnode.instance = Vnode.normalize(callHook.call(vnode.state.view, vnode)) if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as argument") sentinel.$$reentrantLock$$ = null } @@ -612,7 +627,6 @@ var coreRenderer = function($window) { var oldTag = old.tag, tag = vnode.tag if (oldTag === tag) { vnode.state = old.state - vnode._state = old._state vnode.events = old.events if (!recycling && shouldNotUpdate(vnode, old)) return if (typeof oldTag === "string") { @@ -692,10 +706,10 @@ var coreRenderer = function($window) { if (recycling) { initComponent(vnode, hooks) } else { - vnode.instance = Vnode.normalize(vnode._state.view.call(vnode.state, vnode)) + vnode.instance = Vnode.normalize(callHook.call(vnode.state.view, vnode)) if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as argument") if (vnode.attrs != null) updateLifecycle(vnode.attrs, vnode, hooks) - updateLifecycle(vnode._state, vnode, hooks) + updateLifecycle(vnode.state, vnode, hooks) } if (vnode.instance != null) { if (old.instance == null) createNode(parent, vnode.instance, hooks, ns, nextSibling) @@ -778,15 +792,16 @@ var coreRenderer = function($window) { } function removeNode(vnode, context) { var expected = 1, called = 0 + var original = vnode.state if (vnode.attrs && typeof vnode.attrs.onbeforeremove === "function") { - var result = vnode.attrs.onbeforeremove.call(vnode.state, vnode) + var result = callHook.call(vnode.attrs.onbeforeremove, vnode) if (result != null && typeof result.then === "function") { expected++ result.then(continuation, continuation) } } - if (typeof vnode.tag !== "string" && typeof vnode._state.onbeforeremove === "function") { - var result = vnode._state.onbeforeremove.call(vnode.state, vnode) + if (typeof vnode.tag !== "string" && typeof vnode.state.onbeforeremove === "function") { + var result = callHook.call(vnode.state.onbeforeremove, vnode) if (result != null && typeof result.then === "function") { expected++ result.then(continuation, continuation) @@ -795,6 +810,7 @@ var coreRenderer = function($window) { continuation() function continuation() { if (++called === expected) { + checkState(vnode, original) onremove(vnode) if (vnode.dom) { var count0 = vnode.domSize || 1 @@ -818,9 +834,9 @@ var coreRenderer = function($window) { if (parent != null) parent.removeChild(node) } function onremove(vnode) { - if (vnode.attrs && typeof vnode.attrs.onremove === "function") vnode.attrs.onremove.call(vnode.state, vnode) + if (vnode.attrs && typeof vnode.attrs.onremove === "function") callHook.call(vnode.attrs.onremove, vnode) if (typeof vnode.tag !== "string") { - if (typeof vnode._state.onremove === "function") vnode._state.onremove.call(vnode.state, vnode) + if (typeof vnode.state.onremove === "function") callHook.call(vnode.state.onremove, vnode) if (vnode.instance != null) onremove(vnode.instance) } else { var children = vnode.children @@ -974,16 +990,20 @@ var coreRenderer = function($window) { } //lifecycle function initLifecycle(source, vnode, hooks) { - if (typeof source.oninit === "function") source.oninit.call(vnode.state, vnode) - if (typeof source.oncreate === "function") hooks.push(source.oncreate.bind(vnode.state, vnode)) + if (typeof source.oninit === "function") callHook.call(source.oninit, vnode) + if (typeof source.oncreate === "function") hooks.push(callHook.bind(source.oncreate, vnode)) } function updateLifecycle(source, vnode, hooks) { - if (typeof source.onupdate === "function") hooks.push(source.onupdate.bind(vnode.state, vnode)) + if (typeof source.onupdate === "function") hooks.push(callHook.bind(source.onupdate, vnode)) } function shouldNotUpdate(vnode, old) { var forceVnodeUpdate, forceComponentUpdate - if (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === "function") forceVnodeUpdate = vnode.attrs.onbeforeupdate.call(vnode.state, vnode, old) - if (typeof vnode.tag !== "string" && typeof vnode._state.onbeforeupdate === "function") forceComponentUpdate = vnode._state.onbeforeupdate.call(vnode.state, vnode, old) + if (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === "function") { + forceVnodeUpdate = callHook.call(vnode.attrs.onbeforeupdate, vnode, old) + } + if (typeof vnode.tag !== "string" && typeof vnode.state.onbeforeupdate === "function") { + forceComponentUpdate = callHook.call(vnode.state.onbeforeupdate, vnode, old) + } if (!(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) { vnode.dom = old.dom vnode.domSize = old.domSize diff --git a/mithril.min.js b/mithril.min.js index 5a8f5c34..cd027993 100644 --- a/mithril.min.js +++ b/mithril.min.js @@ -1,45 +1,45 @@ -(function(){function y(b,d,h,k,q,m){return{tag:b,key:d,attrs:h,children:k,text:q,dom:m,domSize:void 0,state:void 0,_state:void 0,events:void 0,instance:void 0,skip:!1}}function O(b){for(var d in b)if(G.call(b,d))return!1;return!0}function A(b){var d=arguments[1],h=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){var k;if(!(k=P[b])){var q="div";for(var m=[],l={};k=R.exec(b);){var r= -k[1],f=k[2];""===r&&""!==f?q=f:"#"===r?l.id=f:"."===r?m.push(f):"["===k[3][0]&&((r=k[6])&&(r=r.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),"class"===k[4]?m.push(r):l[k[4]]=""===r?r:r||!0)}0a.indexOf("?")?"?":"&";a+=f+d}return a}function l(a){try{return""!==a?JSON.parse(a):null}catch(v){throw Error(a);}}function r(a){return a.responseText}function f(a,b){if("function"===typeof a)if(Array.isArray(b))for(var d=0;dn.status||304===n.status||U.test(a.url))d(f(a.type,b));else{var k=Error(n.responseText);k.code=n.status;k.response=b;h(k)}}catch(g){h(g)}};k&&null!=a.data?n.send(a.data):n.send()});return!0===a.background?v:p(v)},jsonp:function(a,l){var r=h();a=k(a,l);var p=new d(function(d,h){var k=a.callbackName||"_mithril_"+ -Math.round(1E16*Math.random())+"_"+n++,l=b.document.createElement("script");b[k]=function(h){l.parentNode.removeChild(l);d(f(a.type,h));delete b[k]};l.onerror=function(){l.parentNode.removeChild(l);h(Error("JSONP request failed"));delete b[k]};null==a.data&&(a.data={});a.url=q(a.url,a.data);a.data[a.callbackKey||"callback"]=k;l.src=m(a.url,a.data);b.document.documentElement.appendChild(l)});return!0===a.background?p:r(p)},setCompletionCallback:function(a){p=a}}}(window,w),Q=function(b){function d(g, -c,e,a,b,d,k){for(;e=x&&F>=p;){var z=c[x],t=e[p];if(z!==t||b)if(null==z)x++;else if(null==t)p++;else if(z.key===t.key){var B=null!= -C&&x>=c.length-C.length||null==C&&b;x++;p++;l(g,z,t,k,f(c,x,m),B,q);b&&z.tag===t.tag&&n(g,r(z),m)}else if(z=c[v],z!==t||b)if(null==z)v--;else if(null==t)p++;else if(z.key===t.key)B=null!=C&&v>=c.length-C.length||null==C&&b,l(g,z,t,k,f(c,v+1,m),B,q),(b||p=x&&F>=p;){z=c[v];t=e[F];if(z!==t||b)if(null==z)v--;else{if(null!=t)if(z.key===t.key)B=null!=C&&v>=c.length-C.length||null==C&&b,l(g,z,t,k,f(c,v+1,m),B,q),b&&z.tag===t.tag&& -n(g,r(z),m),null!=z.dom&&(m=z.dom),v--;else{if(!u){u=c;z=v;B={};var w;for(w=0;wb.indexOf("?")?"?":"&";b+=e+c}return b}function g(b){try{return""!==b?JSON.parse(b):null}catch(v){throw Error(b);}}function q(b){return b.responseText}function m(b,a){if("function"===typeof b)if(Array.isArray(a))for(var c=0;cl.status||304===l.status||V.test(b.url))c(m(b.type,a));else{var f=Error(l.responseText);f.code=l.status;f.response=a;e(f)}}catch(W){e(W)}};f&&null!=b.data?l.send(b.data):l.send()});return!0===b.background?v:t(v)},jsonp:function(b,g){var t=e();b=f(b,g);var q=new c(function(c,e){var f=b.callbackName||"_mithril_"+ +Math.round(1E16*Math.random())+"_"+l++,g=a.document.createElement("script");a[f]=function(e){g.parentNode.removeChild(g);c(m(b.type,e));delete a[f]};g.onerror=function(){g.parentNode.removeChild(g);e(Error("JSONP request failed"));delete a[f]};null==b.data&&(b.data={});b.url=n(b.url,b.data);b.data[b.callbackKey||"callback"]=f;g.src=k(b.url,b.data);a.document.documentElement.appendChild(g)});return!0===b.background?q:t(q)},setCompletionCallback:function(b){t=b}}}(window,r),R=function(a){function c(h, +d){if(h.state!==d)throw Error("`vnode.state` must not be modified");}function e(h){var d=h.state;try{return this.apply(d,arguments)}finally{c(h,d)}}function f(h,d,b,a,c,e,f){for(;b=u&&x>=p;){var y= +d[u],z=a[p];if(y!==z||c)if(null==y)u++;else if(null==z)p++;else if(y.key===z.key){var r=null!=q&&u>=d.length-q.length||null==q&&c;u++;p++;m(h,y,z,e,t(d,u,g),r,k);c&&y.tag===z.tag&&b(h,l(y),g)}else if(y=d[v],y!==z||c)if(null==y)v--;else if(null==z)p++;else if(y.key===z.key)r=null!=q&&v>=d.length-q.length||null==q&&c,m(h,y,z,e,t(d,v+1,g),r,k),(c||p=u&&x>=p;){y=d[v];z=a[x];if(y!==z||c)if(null==y)v--;else{if(null!=z)if(y.key=== +z.key)r=null!=q&&v>=d.length-q.length||null==q&&c,m(h,y,z,e,t(d,v+1,g),r,k),c&&y.tag===z.tag&&b(h,l(y),g),null!=y.dom&&(g=y.dom),v--;else{if(!I){I=d;y=v;r={};var w;for(w=0;w