UNPKG

choo

Version:

A 4kb framework for creating sturdy frontend applications

1 lines 16.6 kB
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Choo=e()}}(function(){var e=function(e,t){if(e)try{var n=document.querySelector(e);n&&n.scrollIntoView(t)}catch(i){}},t=function(e){if("undefined"==typeof document)throw new Error("document-ready only runs in the browser");var t=document.readyState;if("complete"===t||"interactive"===t)return setTimeout(e,0);document.addEventListener("DOMContentLoaded",function(){e()})},n="undefined"!=typeof window;function i(e){this.hasWindow=e,this.hasIdle=this.hasWindow&&window.requestIdleCallback,this.method=this.hasIdle?window.requestIdleCallback.bind(window):this.setTimeout,this.scheduled=!1,this.queue=[]}i.prototype.push=function(e){this.queue.push(e),this.schedule()},i.prototype.schedule=function(){if(!this.scheduled){this.scheduled=!0;var e=this;this.method(function(t){for(;e.queue.length&&t.timeRemaining()>0;)e.queue.shift()(t);e.scheduled=!1,e.queue.length&&e.schedule()})}},i.prototype.setTimeout=function(e){setTimeout(e,0,{timeRemaining:function(){return 1}})};var r,o=function(){var e;return n?(window._nanoScheduler||(window._nanoScheduler=new i(!0)),e=window._nanoScheduler):e=new i,e}();s.disabled=!0;try{r=window.performance,s.disabled="true"===window.localStorage.DISABLE_NANOTIMING||!r.mark}catch(K){}function s(e){if(s.disabled)return a;var t=(1e4*r.now()).toFixed()%Number.MAX_SAFE_INTEGER,n="start-"+t+"-"+e;function i(i){var s="end-"+t+"-"+e;r.mark(s),o.push(function(){var o=null;try{var a=e+" ["+t+"]";r.measure(a,n,s),r.clearMarks(n),r.clearMarks(s)}catch(K){o=K}i&&i(o,e)})}return r.mark(n),i.uuid=t,i}function a(e){e&&o.push(function(){e(new Error("nanotiming: performance API unavailable"))})}var h=s,u={};function c(){if(!(this instanceof c))return new c;this.trie={nodes:{}}}u=c,c.prototype.create=function(e){var t=e.replace(/^\//,"").split("/");return function e(n,i){var r=t.hasOwnProperty(n)&&t[n];if(!1===r)return i;var o=null;return/^:|^\*/.test(r)?(i.nodes.hasOwnProperty("$$")?o=i.nodes.$$:(o={nodes:{}},i.nodes.$$=o),"*"===r[0]&&(i.wildcard=!0),i.name=r.replace(/^:|^\*/,"")):i.nodes.hasOwnProperty(r)?o=i.nodes[r]:(o={nodes:{}},i.nodes[r]=o),e(n+1,o)}(0,this.trie)},c.prototype.match=function(e){var t=e.replace(/^\//,"").split("/"),n={},i=function e(i,r){if(void 0!==r){var o=t[i];if(void 0===o)return r;if(r.nodes.hasOwnProperty(o))return e(i+1,r.nodes[o]);if(r.name){try{n[r.name]=decodeURIComponent(o)}catch(K){return e(i,void 0)}return e(i+1,r.nodes.$$)}if(r.wildcard){try{n.wildcard=decodeURIComponent(t.slice(i).join("/"))}catch(K){return e(i,void 0)}return r.nodes.$$}return e(i+1)}}(0,this.trie);if(i)return(i=Object.assign({},i)).params=n,i},c.prototype.mount=function(e,t){var n=e.replace(/^\//,"").split("/"),i=null,r=null;if(1===n.length)r=n[0],i=this.create(r);else{var o=n.join("/");r=n[0],i=this.create(o)}Object.assign(i.nodes,t.nodes),t.name&&(i.name=t.name),i.nodes[""]&&(Object.keys(i.nodes[""]).forEach(function(e){"nodes"!==e&&(i[e]=i.nodes[""][e])}),Object.assign(i.nodes,i.nodes[""].nodes),delete i.nodes[""].nodes)};var l=function e(t){if(!(this instanceof e))return new e(t);var n=(t||"").replace(/^\//,""),i=u();return r._trie=i,r.on=function(e,t){if(e=e||"/",t._wayfarer&&t._trie)i.mount(e,t._trie.trie);else{var n=i.create(e);n.cb=t,n.route=e}return r},r.emit=r,r.match=o,r._wayfarer=!0,r;function r(e){var t=o(e),n=new Array(arguments.length);n[0]=t.params;for(var i=1;i<n.length;i++)n[i]=arguments[i];return t.cb.apply(t.cb,n)}function o(e){var t=i.match(e);if(t&&t.cb)return new s(t);var r=i.match(n);if(r&&r.cb)return new s(r);throw new Error("route '"+e+"' did not match")}function s(e){this.cb=e.cb,this.route=e.route,this.params=e.params}},d={},f=/file:\/\//.test("object"==typeof window&&window.location&&window.location.origin),p=new RegExp("^(file://|/)(.*.html?/?)?"),m=new RegExp("^(http(s)?(://))?(www.)?[a-zA-Z0-9-_.]+(:[0-9]{1,5})?(/{1})?"),v=new RegExp("#"),w=new RegExp("[?].*$");function y(e){if(!(this instanceof y))return new y(e);e=e||{},this.router=l(e.default||"/404")}function _(e,t){return e=t?e.replace(p,""):e.replace(m,""),decodeURI(e.replace(w,"").replace(v,"/"))}d=y,y.prototype.on=function(e,t){e=e.replace(/^[#/]/,""),this.router.on(e,t)},y.prototype.emit=function(e){return e=_(e,f),this.router.emit(e)},y.prototype.match=function(e){return e=_(e,f),this.router.match(e)};function g(e,t){if(!e)throw new Error(t||"AssertionError")}g.notEqual=function(e,t,n){},g.notOk=function(e,t){},g.equal=function(e,t,n){},g.ok=g;var b=["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onmouseenter","onmouseleave","ontouchcancel","ontouchend","ontouchmove","ontouchstart","ondragstart","ondrag","ondragenter","ondragleave","ondragover","ondrop","ondragend","onkeydown","onkeypress","onkeyup","onunload","onabort","onerror","onresize","onscroll","onselect","onchange","onsubmit","onreset","onfocus","onblur","oninput","oncontextmenu","onfocusin","onfocusout"],A=b.length;function E(e,t,n){e[n]!==t[n]&&(t[n]=e[n],e[n]?t.setAttribute(n,""):t.removeAttribute(n))}var N=function(e,t){var n=e.nodeType,i=e.nodeName;1===n&&function(e,t){for(var n=t.attributes,i=e.attributes,r=null,o=null,s=null,a=null,h=i.length-1;h>=0;--h)s=(a=i[h]).name,r=a.namespaceURI,o=a.value,r?(s=a.localName||s,t.getAttributeNS(r,s)!==o&&t.setAttributeNS(r,s,o)):t.hasAttribute(s)?t.getAttribute(s)!==o&&("null"===o||"undefined"===o?t.removeAttribute(s):t.setAttribute(s,o)):t.setAttribute(s,o);for(var u=n.length-1;u>=0;--u)!1!==(a=n[u]).specified&&(s=a.name,(r=a.namespaceURI)?(s=a.localName||s,e.hasAttributeNS(r,s)||t.removeAttributeNS(r,s)):e.hasAttributeNS(null,s)||t.removeAttribute(s))}(e,t),3!==n&&8!==n||t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue),"INPUT"===i?function(e,t){var n=e.value,i=t.value;E(e,t,"checked"),E(e,t,"disabled"),n!==i&&(t.setAttribute("value",n),t.value=n),"null"===n&&(t.value="",t.removeAttribute("value")),e.hasAttributeNS(null,"value")?"range"===t.type&&(t.value=n):t.removeAttribute("value")}(e,t):"OPTION"===i?function(e,t){E(e,t,"selected")}(e,t):"TEXTAREA"===i&&function(e,t){var n=e.value;if(n!==t.value&&(t.value=n),t.firstChild&&t.firstChild.nodeValue!==n){if(""===n&&t.firstChild.nodeValue===t.placeholder)return;t.firstChild.nodeValue=n}}(e,t),function(e,t){for(var n=0;n<A;n++){var i=b[n];e[i]?t[i]=e[i]:t[i]&&(t[i]=void 0)}}(e,t)},T=3;function S(e,t){return t?e?e.isSameNode&&e.isSameNode(t)?t:e.tagName!==t.tagName||L(e)!==L(t)?e:(N(e,t),O(e,t),t):null:e}function L(e){return e.dataset?e.dataset.nanomorphComponentId:void 0}function O(e,t){for(var n,i,r,o,s=0,a=0;n=t.childNodes[a],i=e.childNodes[a-s],n||i;a++)if(i)if(n)if(x(i,n))(r=S(i,n))!==n&&(t.replaceChild(r,n),s++);else{o=null;for(var h=a;h<t.childNodes.length;h++)if(x(t.childNodes[h],i)){o=t.childNodes[h];break}o?((r=S(i,o))!==o&&s++,t.insertBefore(r,n)):i.id||n.id?(t.insertBefore(i,n),s++):(r=S(i,n))!==n&&(t.replaceChild(r,n),s++)}else t.appendChild(i),s++;else t.removeChild(n),a--}function x(e,t){return e.id?e.id===t.id:e.isSameNode?e.isSameNode(t):e.tagName===t.tagName&&e.type===T&&e.nodeValue===t.nodeValue}var k=function(e,t,n){return n&&n.childrenOnly?(O(t,e),e):S(t,e)},C=/([^?=&]+)(=([^&]*))?/g,I=/(noopener|noreferrer) (noopener|noreferrer)/,R=/^[\w-_]+:/,P=function(e,t,n){var i,r=e.length;if(!(t>=r||0===n)){var o=r-(n=t+n>r?r-t:n);for(i=t;i<o;++i)e[i]=e[i+n];e.length=o}},D={};function V(e){if(!(this instanceof V))return new V(e);this._name=e||"nanobus",this._starListeners=[],this._listeners={}}D=V,V.prototype.emit=function(e){for(var t=[],n=1,i=arguments.length;n<i;n++)t.push(arguments[n]);var r=h(this._name+"('"+e.toString()+"')"),o=this._listeners[e];return o&&o.length>0&&this._emit(this._listeners[e],t),this._starListeners.length>0&&this._emit(this._starListeners,e,t,r.uuid),r(),this},V.prototype.on=V.prototype.addListener=function(e,t){return"*"===e?this._starListeners.push(t):(this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t)),this},V.prototype.prependListener=function(e,t){return"*"===e?this._starListeners.unshift(t):(this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].unshift(t)),this},V.prototype.once=function(e,t){var n=this;return this.on(e,function i(){t.apply(n,arguments),n.removeListener(e,i)}),this},V.prototype.prependOnceListener=function(e,t){var n=this;return this.prependListener(e,function i(){t.apply(n,arguments),n.removeListener(e,i)}),this},V.prototype.removeListener=function(e,t){return"*"===e?(this._starListeners=this._starListeners.slice(),n(this._starListeners,t)):(void 0!==this._listeners[e]&&(this._listeners[e]=this._listeners[e].slice()),n(this._listeners[e],t));function n(e,t){if(e){var n=e.indexOf(t);return-1!==n?(P(e,n,1),!0):void 0}}},V.prototype.removeAllListeners=function(e){return e?"*"===e?this._starListeners=[]:this._listeners[e]=[]:(this._starListeners=[],this._listeners={}),this},V.prototype.listeners=function(e){var t="*"!==e?this._listeners[e]:this._starListeners,n=[];if(t)for(var i=t.length,r=0;r<i;r++)n.push(t[r]);return n},V.prototype._emit=function(e,t,n,i){if(void 0!==e&&0!==e.length){void 0===n&&(n=t,t=null),t&&(n=void 0!==i?[t].concat(n,i):[t].concat(n));for(var r=e.length,o=0;o<r;o++){var s=e[o];s.apply(s,n)}}};var $={};function j(e){if(!(this instanceof j))return new j(e);"number"==typeof e&&(e={max:e}),e||(e={}),this.cache={},this.head=this.tail=null,this.length=0,this.max=e.max||1e3,this.maxAge=e.maxAge||0}$=j,Object.defineProperty(j.prototype,"keys",{get:function(){return Object.keys(this.cache)}}),j.prototype.clear=function(){this.cache={},this.head=this.tail=null,this.length=0},j.prototype.remove=function(e){if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){var t=this.cache[e];return delete this.cache[e],this._unlink(e,t.prev,t.next),t.value}},j.prototype._unlink=function(e,t,n){this.length--,0===this.length?this.head=this.tail=null:this.head===e?(this.head=t,this.cache[this.head].next=null):this.tail===e?(this.tail=n,this.cache[this.tail].prev=null):(this.cache[t].next=n,this.cache[n].prev=t)},j.prototype.peek=function(e){if(this.cache.hasOwnProperty(e)){var t=this.cache[e];if(this._checkAge(e,t))return t.value}},j.prototype.set=function(e,t){var n;if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){if((n=this.cache[e]).value=t,this.maxAge&&(n.modified=Date.now()),e===this.head)return t;this._unlink(e,n.prev,n.next)}else n={value:t,modified:0,next:null,prev:null},this.maxAge&&(n.modified=Date.now()),this.cache[e]=n,this.length===this.max&&this.evict();return this.length++,n.next=null,n.prev=this.head,this.head&&(this.cache[this.head].next=e),this.head=e,this.tail||(this.tail=e),t},j.prototype._checkAge=function(e,t){return!(this.maxAge&&Date.now()-t.modified>this.maxAge&&(this.remove(e),1))},j.prototype.get=function(e){if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){var t=this.cache[e];if(this._checkAge(e,t))return this.head!==e&&(e===this.tail?(this.tail=t.next,this.cache[this.tail].prev=null):this.cache[t.prev].next=t.next,this.cache[t.next].prev=t.prev,this.cache[this.head].next=e,t.prev=this.head,t.next=null,this.head=e),t.value}},j.prototype.evict=function(){this.tail&&this.remove(this.tail)};var q={};function M(e,t,n){this.cache="number"==typeof n?new $(n):n||new $(100),this.state=e,this.emit=t}function U(e){return new(e.bind.apply(e,arguments))}q=M,M.prototype.render=function(e,t){var n=this.cache.get(t);if(!n){for(var i=[],r=2,o=arguments.length;r<o;r++)i.push(arguments[r]);i.unshift(e,t,this.state,this.emit),n=U.apply(U,i),this.cache.set(t,n)}return n};var G=W,H={};function W(e){var t=h("choo.constructor");if(!(this instanceof W))return new W(e);e=e||{};var n=this;this._events={DOMCONTENTLOADED:"DOMContentLoaded",DOMTITLECHANGE:"DOMTitleChange",REPLACESTATE:"replaceState",PUSHSTATE:"pushState",NAVIGATE:"navigate",POPSTATE:"popState",RENDER:"render"},this._historyEnabled=void 0===e.history||e.history,this._hrefEnabled=void 0===e.href||e.href,this._hashEnabled=void 0!==e.hash&&e.hash,this._hasWindow="undefined"!=typeof window,this._cache=e.cache,this._loaded=!1,this._stores=[function(e){n.emitter.prependListener(n._events.DOMTITLECHANGE,function(t){e.title=t,n._hasWindow&&(document.title=t)})}],this._tree=null;var i={events:this._events,components:{}};this._hasWindow?(this.state=window.initialState?Object.assign({},window.initialState,i):i,delete window.initialState):this.state=i,this.router=d({curry:!0}),this.emitter=D("choo.emit"),this.emit=this.emitter.emit.bind(this.emitter),this._hasWindow&&(this.state.title=document.title),t()}return W.prototype.route=function(e,t){var n=h("choo.route('"+e+"')");this.router.on(e,t),n()},W.prototype.use=function(e){var t=this;this._stores.push(function(n){var i="choo.use";i=e.storeName?i+"("+e.storeName+")":i;var r=h(i);e(n,t.emitter,t),r()})},W.prototype.start=function(){var n,i,r=h("choo.start"),o=this;return this._historyEnabled&&(this.emitter.prependListener(this._events.NAVIGATE,function(){o._matchRoute(o.state),o._loaded&&(o.emitter.emit(o._events.RENDER),setTimeout(e.bind(null,window.location.hash),0))}),this.emitter.prependListener(this._events.POPSTATE,function(){o.emitter.emit(o._events.NAVIGATE)}),this.emitter.prependListener(this._events.PUSHSTATE,function(e){window.history.pushState(H,null,e),o.emitter.emit(o._events.NAVIGATE)}),this.emitter.prependListener(this._events.REPLACESTATE,function(e){window.history.replaceState(H,null,e),o.emitter.emit(o._events.NAVIGATE)}),window.onpopstate=function(){o.emitter.emit(o._events.POPSTATE)},o._hrefEnabled&&(n=function(t){var n=t.href,i=t.hash;n!==window.location.href?o.emitter.emit(o._events.PUSHSTATE,n):!o._hashEnabled&&i&&e(i)},i=i||window.document,window.addEventListener("click",function(e){if(!(e.button&&0!==e.button||e.ctrlKey||e.metaKey||e.altKey||e.shiftKey||e.defaultPrevented)){var t=function e(t){if(t&&t!==i)return"a"!==t.localName||void 0===t.href?e(t.parentNode):t}(e.target);t&&(window.location.protocol!==t.protocol||window.location.hostname!==t.hostname||window.location.port!==t.port||t.hasAttribute("data-nanohref-ignore")||t.hasAttribute("download")||"_blank"===t.getAttribute("target")&&I.test(t.getAttribute("rel"))||R.test(t.getAttribute("href"))||(e.preventDefault(),n(t)))}}))),this._setCache(this.state),this._matchRoute(this.state),this._stores.forEach(function(e){e(o.state)}),this._tree=this._prerender(this.state),this.emitter.prependListener(o._events.RENDER,function(e,t){t||(t=window.requestAnimationFrame);var n=!1,i=null;return function(){null!==i||n||(n=!0,t(function(){n=!1;for(var t=i.length,r=new Array(t),o=0;o<t;o++)r[o]=i[o];e.apply(e,r),i=null})),i=arguments}}(function(){var e=h("choo.render"),t=o._prerender(o.state),n=h("choo.morph");k(o._tree,t),n(),e()})),t(function(){o.emitter.emit(o._events.DOMCONTENTLOADED),o._loaded=!0}),r(),this._tree},W.prototype.mount=function(e){var n=h("choo.mount('"+e+"')");if("object"!=typeof window)return this.selector=e,n(),this;var i=this;t(function(){var t=h("choo.render"),n=i.start();i._tree="string"==typeof e?document.querySelector(e):e;var r=h("choo.morph");k(i._tree,n),r(),t()}),n()},W.prototype.toString=function(e,t){(t=t||{}).components=t.components||{},t.events=Object.assign({},t.events,this._events),this._setCache(t),this._matchRoute(t,e),this.emitter.removeAllListeners(),this._stores.forEach(function(e){e(t)});var n=this._prerender(t);return"string"==typeof n.outerHTML?n.outerHTML:n.toString()},W.prototype._matchRoute=function(e,t){var n,i;t?(n=t.replace(/\?.+$/,"").replace(/\/$/,""),this._hashEnabled||(n=n.replace(/#.+$/,"")),i=t):(n=window.location.pathname.replace(/\/$/,""),this._hashEnabled&&(n+=window.location.hash.replace(/^#/,"/")),i=window.location.search);var r,o=this.router.match(n);this._handler=o.cb,e.href=n,e.query=(r={},i.replace(/^.*\?/,"").replace(C,function(e,t,n,i){var o=decodeURIComponent(i),s=decodeURIComponent(t);r.hasOwnProperty(s)?Array.isArray(r[s])?r[s].push(o):r[s]=[r[s],o]:r[s]=o}),r),e.route=o.route,e.params=o.params},W.prototype._prerender=function(e){var t=h("choo.prerender('"+e.route+"')"),n=this._handler(e,this.emit);return t(),n},W.prototype._setCache=function(e){var t=new q(e,this.emitter.emit.bind(this.emitter),this._cache);function n(e,n){for(var i=[],r=0,o=arguments.length;r<o;r++)i.push(arguments[r]);return t.render.apply(t,i)}e.cache=n,n.toJSON=function(){return null}},G});