-
Notifications
You must be signed in to change notification settings - Fork 0
/
ccm.js
28 lines (28 loc) · 17.4 KB
/
ccm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* @overview runtime environment for <i>ccm</i> components
* @author André Kless <andre.kless@web.de> 2014-2016
* @copyright Copyright (c) 2014-2016 André Kless
* @license
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, publish, distribute, sublicense, and/or sell
* (<b>NOT MODIFY OR MERGE</b>) copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* All rights that the author André Kless do not expressly grant in these Terms are reserved by the author André Kless.
* @version latest (6.0.0)
* @changes
* version 6.0.0 (09.05.2016):
* - placeholder with %% instead of % (incompatible change)
* (for older version changes see ccm-5.8.3.js)
*/
window.jQuery||(document.body?(window.jQuery=document.createElement("script"),window.jQuery.setAttribute("src","https://code.jquery.com/jquery-2.2.2.min.js"),document.head.appendChild(window.jQuery)):document.write('<script src="https://code.jquery.com/jquery-2.2.2.min.js"></script>')),document.body?(window.ccm=document.createElement("style"),window.ccm.appendChild(document.createTextNode("@keyframes ccm_loading { to { transform: rotate(360deg); } }")),document.head.appendChild(window.ccm)):document.write("<style>@keyframes ccm_loading { to { transform: rotate(360deg); } }</style>"),ccm=function(){function e(e){if(-1===e.indexOf(".js"))return e;var n=e.split("/").pop();return n.substr(0,n.lastIndexOf("."))}function n(e){var n=JSON.stringify(e);return"{}"===n&&(n=Object.keys(o).length),n}var t,c={},r={},o={},i={},a=function(){function e(e,t){function c(){function n(){o--,0===o&&t&&t(c)}var c=[],o=1;for(var i in p.local)if(ccm.helper.isSubset(e,p.local[i])){var a=ccm.helper.clone(p.local[i]);c.push(a),o++,r(a,n)}return n(),c}function r(e,t){function c(e,t){return null===o[n(e[t][1])]?a.push([c,e,t]):(i++,void ccm.helper.solveDependency(e,t,r))}function r(){return i--,0===i?a.length>0?ccm.helper.action(a.pop()):void(t&&t(e)):void 0}var i=1,a=[];for(var s in e){var u=e[s];if(ccm.helper.isDependency(u))c(e,s);else if(jQuery.isArray(u))for(var l=0;l<u.length;l++)ccm.helper.isDependency(u[l])&&c(u,l)}r()}if(void 0===e||jQuery.isPlainObject(e))return c();var i=p.local[e]?ccm.helper.clone(p.local[e]):null;return r(i,t),i}function c(n,t){return p.local[n.key]?ccm.helper.integrate(n,p.local[n.key]):p.local[n.key]=n,e(n.key,t)}function r(e,n){var t;return void 0===e?(t=p.local,p.local={}):(t=p.local[e],delete p.local[e]),n&&n(t),t}function i(){var e=t.transaction([p.store],"readwrite");return e.objectStore(p.store)}function a(e,n,t){return n=n||p.user,ccm.helper.integrate(e,{db:p.db,store:p.store,username:"object"==typeof n?n.key:n,password:t||p.password})}function s(e,n){f.push(n),e.callback=f.length,p.socket.send(JSON.stringify(e))}function u(e,n){ccm.load([p.url,e],n)}function l(e,n){return"string"==typeof e&&0===e.indexOf("[ccm]")?(ccm.helper.isInstance(n)&&n.logout(),!1):!0}var f=[],p=this;this.init=function(){p.socket&&(p.socket.onmessage=function(e){if(e=JSON.parse(e.data),e.callback)f[e.callback-1](e.data);else{var n=jQuery.isPlainObject(e)?c(e):r(e);p.onChange&&p.onChange(n,e)}})},this.get=function(n,t,c,r){function o(){return e(n,t)}function f(){var e=m();if(e)return e;var c=i(),r=c.get(n);r.onsuccess=function(e){var c=e.target.result;return c?(void 0!==c.key&&(p.local[n]=c),void(t&&t(c))):t(null)}}function d(){function e(e){if(l(e,c)){if(!e)return t(null);if(ccm.helper.isDataset(e))p.local[e.key]=e;else for(var n=0;n<e.length;n++)void 0!==e[n].key&&(p.local[e[n].key]=e[n]);t(e)}}if(!jQuery.isPlainObject(n)){var o=m();if(o)return o}var i=a({key:n},c,r);p.socket?s(i,e):u(i,e)}function m(){var c=e(n);return c&&t&&t(c),c}return"function"==typeof n&&(r=c,c=t,t=n,n={}),void 0===n&&(n={}),p.url?d():p.store?f():p.local?o():void 0},this.set=function(e,n,t,r){function o(){return c(e,n)}function f(){var n=i(),t=n.put(e);t.onsuccess=o}function d(){function n(n){l(n,t)&&(e=n,o())}var c=a({dataset:e},t,r);p.socket?s(c,n):u(c,n)}return e.key||(e.key=ccm.helper.generateKey()),p.url?d():p.store?f():p.local?o():void 0},this.del=function(e,n,t,c){function o(){return r(e,n)}function f(){var n=i(),t=n["delete"](e);t.onsuccess=o}function d(){function r(e){l(e,t)&&(n&&n(e),n=void 0,o())}var i=a({del:e},t,c);p.socket?s(i,r):u(i,r)}return p.url?d():p.store?f():p.local?o():void 0},this.count=function(e,n,t){function c(){var n=Object.keys(p.local).length;return e&&e(n),n}function r(){if(!e)return-1;var n=i(),t=n.count();return t.onsuccess=function(){e(t.result)},-1}function o(){function c(t){l(t,n)&&e&&e(t)}if(!e)return-1;var r=a({count:!0},n,t);return p.socket?s(r,c):u(r,c),-1}return p.url?o():p.store?r():p.local?c():void 0},this.clear=function(){p.local={}}};return{callback:{},loading_icon:"./img/ccm-load-icon.gif",version:[6,0,0],load:function(){function n(n,s){function l(e){if(null!==e&&a[s].push(e),n.length>0){var c=n.shift();!Array.isArray(c)||c.length>1&&ccm.helper.isObject(c[1])?ccm.load(c,l):(c.push(l),ccm.load.apply(null,c))}else t()}function p(){if(!g()){if(0!==n.indexOf("http"))return jQuery.ajax({url:n,cache:!1,dataType:"html",crossDomain:!0,success:b});var e=n.split("/").pop();ccm.callback[e]=b,jQuery("head").append('<script src="'+n+'"></script>')}}function d(){Q||jQuery("head").append('<link rel="stylesheet" type="text/css" href="'+n+'">'),k()}function m(){Q||jQuery('<img src="'+n+'">'),k()}function h(){g()||jQuery.getScript(n,j).fail(x)}function y(){if(!g()){if(0!==n.indexOf("http"))return jQuery.getJSON(n,b).fail(x);var e=n.split("/").pop();ccm.callback[e]=b,jQuery("head").append('<script src="'+n+'"></script>')}}function v(){f||(0===n.indexOf("http")?jQuery.ajax({url:n,data:w,dataType:"jsonp",username:w&&w.username?w.username:void 0,password:w&&w.password?w.password:void 0,success:b}):jQuery.ajax({url:n,data:w,username:w&&w.username?w.username:void 0,password:w&&w.password?w.password:void 0,success:b}).fail(x))}function g(){return null===Q?f?!0:(f=!0,i[n]||(i[n]=[]),i[n].push(u),!0):Q?(a[s]=r[n]=Q,k(),!0):!1}function j(){var t=e(n),o=c[t];if(!o)return k();for(a[s]=r[n]=o;i[o.index]&&i[o.index].length>0;)ccm.helper.action(i[o.index].pop());k()}function b(e){a[s]=r[n]=e,k()}function k(){for(r[n]||(r[n]=n);i[n]&&i[n].length>0;)ccm.helper.action(i[n].pop());t()}function x(e,n,t){console.log(e,this.url),jQuery("body").html(e.responseText+"<p>Request Failed: "+n+", "+t+"</p>")}var w;if(jQuery.isArray(n)){if(!(n.length>1&&ccm.helper.isObject(n[1])))return o++,a[s]=[],l(null);w=n[1],n=n[0]}var Q=r[n];if(r[n]=null,o++,w)return v();var O=n.split(".").pop();switch(O){case"html":return p();case"css":return d();case"jpg":case"gif":case"png":case"svg":return m();case"js":return h();case"json":return y();default:v()}}function t(){return o--,0===o?(a.length<=1&&(a=a[0]),l&&l(a),a):void 0}var o=1,a=[],s=Array.prototype.slice.call(arguments),u=s.slice(0);u.unshift(ccm.load);var l,f=!1;"function"!=typeof s[s.length-1]&&void 0!==s[s.length-1]||(l=s.pop());for(var p=0;p<s.length;p++)n(s[p],p);return t()},component:function(e,n,t){function r(){t&&t(e)}function o(){if(e.index){var n=e.index.split("-");e.name=n[0],n.length>1&&(e.version=n[1].split("."));for(var t=0;3>t;t++)e.version[t]=parseInt(e.version[t])}e.index=e.name,e.version&&(e.index+="-"+e.version.join("."))}function i(){e.instances=0,e.instance=function(n,t){return ccm.instance(e.index,n,t)},e.render=function(n,t){return ccm.render(e.index,n,t)},ccm.helper.integrate(n,e.config),e.config||(e.config={}),e.config.element||(e.config.element=jQuery("body"))}return"function"==typeof n&&(t=n,n=void 0),"string"==typeof e?ccm.load(e,function(e){ccm.helper.integrate(n,e.config),t&&t(e)}):(o(),c[e.index]?c[e.index]:(i(),c[e.index]=e,void(e.init?(e.init(r),delete e.init):r())))},instance:function(n,t,r){function o(n,t,s,u,l){function f(){function e(e){function n(e){function c(e,n){function c(c){e[n]=c,t()}function r(e,n,t,c,r){function o(n){t[c]={component:e,parent:r,render:function(r){delete this.component,delete this.render,n||(n={}),ccm.helper.integrate(this,n),ccm.render(e,n,function(e){t[c]=e,r&&r()})}}}ccm.helper.isDependency(n)?ccm.dataset(n[1],n[2],o):o(n)}var i=e[n];switch(i[0]){case ccm.load:case"ccm.load":a++,ccm.load(i[1],c);break;case ccm.component:case"ccm.component":a++,ccm.component(i[1],i[2],c);break;case ccm.instance:case"ccm.instance":o(i[1],i[2],e,n,d);break;case ccm.proxy:case"ccm.proxy":r(i[1],i[2],e,n,d);break;case ccm.store:case"ccm.store":a++,ccm.store(i[1],c);break;case ccm.dataset:case"ccm.dataset":a++,ccm.dataset(i[1],i[2],c)}}for(var r in e){var i=e[r];if(ccm.helper.isDependency(i))c(e,r);else if("object"==typeof i&&null!==i){if(ccm.helper.isElement(i)||ccm.helper.isInstance(i)||ccm.helper.isComponent(i))continue;n(i)}}}function t(){return a--,0===a&&f(i,function(){r&&r(i)}),0===a?i:null}function f(e,n){function t(e){ccm.helper.isInstance(e)&&o.push(e);for(var n in e){var c=e[n];if(ccm.helper.isInstance(c)&&"parent"!==n&&!ccm.helper.isProxy(c))t(c);else if("object"==typeof c&&null!==c){if(ccm.helper.isElement(c)||ccm.helper.isInstance(c)||ccm.helper.isComponent(c))continue;t(c)}}}function c(){if(i===o.length)return r();var e=o[i];i++,e.init?(e.init(c),delete e.init):c()}function r(){if(0===o.length)return n();var e=o.pop();e.ready?(e.ready(r),delete e.ready):r()}var o=[];t(e);var i=0;c()}var d=new c[p].Instance;switch(c[p].instances++,s&&(s[u]=d),l&&(d.parent=l),i||(i=d),d.id=c[p].instances,d.index=p+"-"+d.id,d.component=c[p],ccm.helper.integrate(c[p].config,d),e&&ccm.helper.integrate(e,d),d.element){case"name":d.element=ccm.helper.find(l,"."+d.component.name);break;case"parent":d.element=l.element}return n(d),t()}return ccm.helper.isDependency(t)?ccm.dataset(t[1],t[2],e):e(t)}var p=e(n);return a++,c[p]?f():ccm.load(n,f)}"function"==typeof t&&(r=t,t=void 0);var i,a=0;return o(n,t)},render:function(e,n,t){ccm.instance(e,n,function(e){e.render(function(){t&&t(e)})})},store:function(e,c){function r(n){function r(n){function c(e){var n=indexedDB.open("ccm");n.onsuccess=function(){t=this.result,e()}}function r(){function c(n){var c=parseInt(localStorage.getItem("ccm"));c||(c=1),t.close();var r=indexedDB.open("ccm",c+1);r.onupgradeneeded=function(){t=this.result,localStorage.setItem("ccm",t.version),t.createObjectStore(e.store,{keyPath:"key"})},r.onsuccess=n}t.objectStoreNames.contains(e.store)?n():c(n)}t?r():c(r)}function s(){function n(){return t.init(),o[i]=t,c&&c(t),t}var t=new a;return ccm.helper.integrate(e,t),t.url&&0===t.url.indexOf("ws")?(t.socket=new WebSocket(t.url,"ccm"),void(t.socket.onopen=function(){this.send([t.db,t.store]),n()})):n()}return e.local=n,e.store&&!e.url?r(s):s()}"function"==typeof e&&(c=e,e=void 0),e||(e={}),("string"==typeof e||ccm.helper.isObject(e)&&!e.local&&!e.store)&&(e={local:e}),e=ccm.helper.clone(e);var i=n(e);return o[i]?(c&&c(o[i]),o[i]):(e.local||(e.local={}),"string"==typeof e.local?ccm.load(e.local,r):r(e.local))},dataset:function(e,n,t,c,r){ccm.store(e,function(e){e.get(n,t,c,r)})},context:{find:function(e,n){for(var t=e;e=e.parent;)if(e[n]&&e[n]!==t)return e[n]},root:function(e){for(;e.parent;)e=e.parent;return e}},helper:{action:function(e,n){return"function"==typeof e?e():("object"!=typeof e&&(e=e.split(" ")),"function"==typeof e[0]?e[0].apply(window,e.slice(1)):0===e[0].indexOf("this.")?this.executeByName(e[0].substr(5),e.slice(1),n):this.executeByName(e[0],e.slice(1)))},clone:function(e,n){return"object"==typeof e?jQuery.extend(!n,{},e):void 0},dataset:function(e,n){e.store.get(e.key,function(t){function c(t){e.key=t.key,n&&n(t)}null===t?e.store.set({key:e.key},c):c(t)})},element:function(e){ccm.helper.reselect(e);var n=e.component.name;jQuery.isArray(e.classes)&&(e.classes=e.classes.join(" ")),e.element.html('<div id="ccm-'+e.index+'" class="ccm '+(e.classes?e.classes:"ccm-"+n)+'"></div>');var t=e.element.find('div[id="ccm-'+e.index+'"]');return ccm.helper.loading(t),t},executeByName:function(e,n,t){t||(t=window);var c=e.split(".");e=c.pop();for(var r=0;r<c.length;r++)t=t[c[r]];return t[e].apply(t,n)},filter:function(e,n){e=ccm.helper.clone(e);for(var t in e)e[t]===n[t]&&delete e[t]},find:function(e,n,t){return"string"==typeof n&&(t=n,n=void 0),n||(n=e.element),n.find(t+":not(.ccm, #ccm-"+e.index+" .ccm *)")},focusInput:function(e,n){e=e.get(0),void 0===n&&(n=e.value.length),e.selectionStart=e.selectionEnd=n,e.focus()},format:function(e,n){function t(e){return e.replace(/"/g,"'").replace(/\\/g,"\\\\").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\f/g,"\\f")}var c=[[],[]];e=JSON.stringify(e,function(e,n){return"function"==typeof n?(c[0].push(n),"%f0%"):n});for(var r=1;r<arguments.length;r++)if("function"==typeof arguments[r]&&(c[1].push(arguments[r]),arguments[r]="%f1%"),"object"==typeof arguments[r])for(var o in arguments[r])"function"==typeof arguments[r][o]&&(c[1].push(arguments[r][o]),arguments[r][o]="%f1%"),"string"==typeof arguments[r][o]&&(arguments[r][o]=t(arguments[r][o])),e=e.replace(new RegExp("%"+o+"%","g"),arguments[r][o]);else"string"==typeof arguments[r]&&(arguments[r]=t(arguments[r])),e=e.replace(/%%/,arguments[r]);return JSON.parse(e,function(e,n){return"%f0%"===n?c[0].shift():"%f1%"===n?c[1].shift():n})},formData:function(e){e.find("input[type=checkbox]").each(function(){var e=jQuery(this);e.is(":checked")||(e.attr("data-input",e.attr("value")),e.attr("value","")),e.prop("checked",!0)});var n=e.serializeArray();e.find('input[type=checkbox][value=""]').each(function(){var e=jQuery(this);e.prop("checked",!1),e.attr("value",e.attr("data-input")),e.removeAttr("data-input")});for(var t={},c=0;c<n.length;c++)t[n[c].name]=n[c].value;return t},generateKey:function(){return Date.now()+"X"+Math.random().toString().substr(2)},getCursor:function(e){return e.get(0).selectionStart},getElementID:function(e){return"ccm-"+e.index},html:function(e,n){if(arguments.length>1&&(e=ccm.helper.format.apply(this,arguments)),jQuery.isArray(e)){for(var t=[],c=0;c<e.length;c++)t.push(ccm.helper.html(e[c]));return t}if("string"==typeof e&&(e=ccm.helper.val(e)),"object"!=typeof e)return e;var r=jQuery("<"+ccm.helper.val(e.tag||"div","tag")+">");delete e.tag;for(var o in e){var i=e[o];switch(o){case"checked":case"disabled":case"readonly":case"required":case"selected":i&&"undefined"!==i&&"false"!==i&&r.prop(o,!0);break;case"inner":r.html(this.html(i));break;case"onblur":r.blur(i);break;case"onchange":r.change(i);break;case"onclick":r.click(i);break;case"ondblclick":r.dblclick(i);break;case"oninput":r.on("input",i);break;case"onmouseenter":r.mouseenter(i);break;case"onsubmit":r.submit(i);break;default:r.attr(o,ccm.helper.val(i))}}return r},htmlEncode:function(e,n,t){return"string"!=typeof e&&(e=e.toString()),e=n||void 0===n?e.trim():e,e=jQuery("<div>").text(e).html(),e=t||void 0===t?e.replace(/"/g,"""):e},htmlDecode:function(e){return jQuery("<div>").html(e).text()},integrate:function(e,n){if(!e)return n;if(!n)return e;for(var t in e)void 0!==e[t]?n[t]=e[t]:delete n[t];return n},isComponent:function(e){return"object"==typeof e&&null!==e&&e.Instance&&!0},isDataset:function(e){return"object"==typeof e&&!jQuery.isArray(e)&&null!==e},isDependency:function(e){if(jQuery.isArray(e)&&e.length>0)switch(e[0]){case ccm.load:case"ccm.load":case ccm.component:case"ccm.component":case ccm.instance:case"ccm.instance":case ccm.proxy:case"ccm.proxy":case ccm.render:case"ccm.render":case ccm.store:case"ccm.store":case ccm.dataset:case"ccm.dataset":return!0}return!1},isElement:function(e){return e instanceof jQuery},isInDOM:function(e){return ccm.helper.tagExists(jQuery("#ccm-"+e.index))},isInstance:function(e){return"object"==typeof e&&null!==e&&e.component&&!0},isObject:function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)},isProxy:function(e){return ccm.helper.isInstance(e)&&"string"==typeof e.component},isSubset:function(e,n){for(var t in e)if("object"==typeof e[t]&&"object"==typeof n[t]){if(JSON.stringify(e[t])!==JSON.stringify(n[t]))return!1}else if(e[t]!==n[t])return!1;return!0},loading:function(e){(e?e:jQuery("body")).html(jQuery("<div>").css({display:"inline-block",width:"0.5em",height:"0.5em",border:"0.15em solid #009ee0","border-right-color":"transparent","border-radius":"50%",animation:"ccm_loading 1s linear infinite"}))},noScript:function(e){var n=jQuery("<div>").html(e);return n.find("script").remove(),n.html()},regex:function(e){switch(e){case"key":return/^[a-z_0-9][a-zA-Z_0-9]*$/;case"tag":return/^[a-z][a-zA-Z]*$/;case"url":return/^(((http|ftp|https):\/\/)?[\w-]+(\.[\w-]*)+)?([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?$/}},reselect:function(e){e.element&&(e.element=jQuery(e.element.selector))},solveDependency:function(e,n,t){return e[n].push(function(c){e[n]=c,t(c)}),ccm.helper.action(e[n])},tagExists:function(e){return e.closest("html").length>0},val:function(e,n){return n?n===!0?ccm.helper.htmlEncode(e):("string"==typeof n?ccm.helper.regex(n):n).test(e)?e:null:ccm.helper.noScript(e)},wait:function(e,n){window.setTimeout(n,e)}}}}();