diff --git a/assets/core/core.js b/assets/core/core.js index 5044f7d..4a85680 100644 --- a/assets/core/core.js +++ b/assets/core/core.js @@ -9,7 +9,7 @@ kit.config = kit.config || {}; * @class kitConfig */ var defaultConfig = { - version: '2.0', + version: '2.1', assetsPath: '', requiredDependencies: [], autoloadPluginList: [], @@ -793,7 +793,7 @@ kit.config = kit.config || {}; * @param callback * @param argArr * @param context - * @returns {undefined} + * @return {Promise} */ PluginManager.prototype.exec = function (deps, callback, argArr = [], context = undefined) { var self = this; @@ -813,7 +813,7 @@ kit.config = kit.config || {}; argArr = []; } if(typeof callback !== 'function') { - return undefined; + callback = function(){}; } if(global.config && global.config.requiredDependencies) { @@ -823,11 +823,17 @@ kit.config = kit.config || {}; var depsPromiseCallback = self.__getDepsPromiseCallback(deps); if(depsPromiseCallback) { - depsPromiseCallback().then(function(){ - callback.apply(context, argArr); + return depsPromiseCallback().then(function(){ + return new Promise(function(resolve, reject){ + callback.apply(context, argArr) + resolve(); + }); }); } else { - callback.apply(context, argArr) + return new Promise(function(resolve, reject){ + callback.apply(context, argArr) + resolve(); + }); } }; @@ -836,11 +842,20 @@ kit.config = kit.config || {}; * @see https://requirejs.org/ * @param deps * @param callback + * @return {Promise} */ __proto.define = function (deps, callback) { var self = this; var context = this; + if(typeof deps === 'string'){ + deps = [deps]; + } + + if(typeof callback !== 'function') { + callback = function (){}; + } + var depsPromiseCallback = self.__getDepsPromiseCallback(deps); var getArgArr = function () { @@ -857,11 +872,17 @@ kit.config = kit.config || {}; }.bind(self); if(depsPromiseCallback) { - depsPromiseCallback().then(function(){ - callback.apply(context, getArgArr()); + return depsPromiseCallback().then(function(){ + return new Promise(function(resolve, reject){ + callback.apply(context, getArgArr()); + resolve(); + }); }); } else { - callback.apply(context, getArgArr()) + return new Promise(function(resolve, reject){ + callback.apply(context, getArgArr()) + resolve(); + }); } }; @@ -870,8 +891,9 @@ kit.config = kit.config || {}; * * @param {(string|string[])} deps * @param {function} callback + * @return {Promise} */ - __proto.ready = function(deps, callback = undefined) { + __proto.ready = function(deps = [], callback = undefined) { var self = this; if(typeof deps === 'function') { callback = deps; @@ -880,19 +902,28 @@ kit.config = kit.config || {}; if(typeof callback !== 'function') { callback = function (){}; } - self.__ready(self.exec, [deps, callback], self); + return self.__ready(self.exec, [deps, callback], self); }; __proto.__ready = function(fn, args = [], context = window) { + var promise; var self = this; context = context || this; if (/complete|interactive|loaded/.test(document.readyState)) { - fn.apply(context, args); - } else { - document.addEventListener("DOMContentLoaded", function () { + promise = new Promise(function(resolve, reject){ fn.apply(context, args); - }.bind(this)); + resolve(); + }); + } else { + promise = new Promise(function(resolve, reject){ + document.addEventListener("DOMContentLoaded", function () { + resolve(); + }.bind(this)); + }).then(function(){ + return fn.apply(context, args); + }); } + return promise; }; /** @@ -901,7 +932,7 @@ kit.config = kit.config || {}; * @param {(string|string[])} deps * @param {function} callback */ - __proto.loaded = function(deps, callback = undefined) { + __proto.loaded = function(deps = [], callback = undefined) { var self = this; if(typeof deps === 'function') { callback = deps; @@ -910,19 +941,28 @@ kit.config = kit.config || {}; if(typeof callback !== 'function') { callback = function (){}; } - self.__loaded(self.exec, [deps, callback], self); + return self.__loaded(self.exec, [deps, callback], self); }; __proto.__loaded = function(fn, args = [], context = window) { + var promise; var self = this; context = context || this; if (/complete|interactive|loaded/.test(document.readyState)) { - fn.apply(context, args); - } else { - window.addEventListener("load", function () { + promise = new Promise(function(resolve, reject){ fn.apply(context, args); - }.bind(this)); + resolve(); + }); + } else { + promise = new Promise(function(resolve, reject){ + window.addEventListener("load", function () { + resolve(); + }.bind(this)); + }).then(function(){ + return fn.apply(context, args); + }); } + return promise; }; /** diff --git a/assets/core/core.min.js b/assets/core/core.min.js index 0c0fc3f..38f45fe 100644 --- a/assets/core/core.min.js +++ b/assets/core/core.min.js @@ -1 +1 @@ -var kit,kit=window.kit=window.kit||{};kit.service=kit.service||{},kit.config=kit.config||{},!function(global){var defaultConfig={version:"2.0",assetsPath:"",requiredDependencies:[],autoloadPluginList:[],debug:!0},stateList={undefined:0,registered:1,loading:3,loaded:4,installing:5,installed:6},MD_TYPE={ES:"ES",UMD:"UMD",HMD:"HMD",default:"default"};function Plugin(e,t={}){this.id=e,this.state=stateList.undefined,this.state2=stateList.undefined,this.module={code:"",exports:{}},this.config={autoRequire:!1,loadJsAfterModule:!1,isSetTimestamp:!0,path:"",module:"",type:"default",handler:void 0,onRegister:function(e){},onLoad:function(e){},onInstall:function(e){},js:[],css:[],alias:[],deps:[],debug:!1},this.pluginManager=void 0,this.promise=new Promise(function(e,t){e()}),this.errors=[],this.register(t)}function isAssetLoaded(e){return e=e.match(/^[^#?]*/)[0],document.querySelector('script[src^="'+e+'"]')||document.querySelector('link[href^="'+e+'"]')||document.querySelector('meta[property="kit:file-load"][content="'+e+'"]')}function getUrlWithTimestamp(t){var i=3600*((new Date).getTime()/1e3/3600>>0);try{var e=new URL(t);e.searchParams.append("__pm",String(i)),t=e.toString()}catch(e){t=(t=String(t).split("?")[0])+"?__pm"+i}return t}Plugin.prototype.setPluginManager=function(e){this.pluginManager=e},Plugin.prototype.queuePush=function(i,n=[]){"function"==typeof i&&(this.promise=this.promise.then(function(e){var t=i.apply(this,n);if(t)return t}))},Plugin.prototype.__queue=function(e,i,n=[],o=void 0){var t=this;void 0===o&&(o=t),t.__checkState(e)?i.apply(o,n):t.promise=t.promise.then(function(){return new Promise(function(e,t){i.apply(o,n),e()})}.bind(t))},Plugin.prototype.__exec=function(e,t,i=[],n=void 0){var o=this;void 0===n&&(n=o),o.__checkState(e)?t.apply(n,i):o.promise=o.promise.then(function(){t.apply(n,i)}.bind(o))},Plugin.prototype.__checkState=function(e,t=void 0){return void 0===t?this.state>=e:this.state>=e&&this.state<=t},Plugin.prototype.__check2State=function(e,t=void 0){return void 0===t?this.state2>=e:this.state2>=e&&this.state2<=t},Plugin.prototype.__getValidConfig=function(e={}){e=Object.assign({},e);return"function"!=typeof e.onLoad&&(e.onLoad=function(e){}),"function"!=typeof e.onInstall&&(e.onInstall=function(e){}),"function"!=typeof e.onRegister&&(e.onRegister=function(e){}),"string"!=typeof e.path&&(e.path=""),"string"==typeof e.js?e.js=[e.js]:Array.isArray(e.js)||(e.js=[]),"string"==typeof e.css?e.css=[e.css]:Array.isArray(e.css)||(e.css=[]),"string"==typeof e.alias?e.alias=[e.alias]:Array.isArray(e.alias)||(e.alias=[]),e.autoRequire=!!e.hasOwnProperty("autoRequire")&&!!e.autoRequire,e.loadJsAfterModule=!!e.hasOwnProperty("loadJsAfterModule")&&!!e.loadJsAfterModule,e.isSetTimestamp=!e.hasOwnProperty("isSetTimestamp")||!!e.isSetTimestamp,e.type=e.type||"default","string"==typeof e.deps?e.deps=[e.deps]:Array.isArray(e.deps)||(e.deps=[]),e},Plugin.prototype.__setState=function(e,t=!1){var i=this;(t||i.__checkState(e))&&(i.state=e)},Plugin.prototype.register=function(e={}){var t,i=this,n=i.id;if(this.__checkState(stateList.installed))throw new Error("Plugin "+n+" уже невозможно конфигурировать ("+i.state+"/"+i.state2+")");if("function"==typeof e)t=e,(e=this.config).handler=t,e.type=MD_TYPE.HMD;else{if(this.__checkState(stateList.loaded)||this.__check2State(stateList.loading))throw new Error("Plugin "+n+" уже невозможно конфигурировать ("+i.state+")");if("object"!=typeof e)throw new Error("Plugin.register: plugin "+n+" is not a valid format");e=this.__getValidConfig(e),Object.assign(this.config,e)}this.__checkState(stateList.registered)||(i.config.debug&&console.log(`Plugin ${i.id}: onRegister + event.`),this.state=stateList.registered,this.config.onRegister(this),t=new CustomEvent("onRegister"+this.id+"Plugin",{detail:{plugin:this}}),document.dispatchEvent(t)),e.autoRequire},Plugin.prototype.load=function(e){var n,t,i,o,s,r=this,l=("function"!=typeof e&&(e=function(){}),r.id);return r.__checkState(stateList.registered)?r.__checkState(stateList.loaded)?e():r.__check2State(stateList.loading)?r.__exec(stateList.loaded,e):(r.state2=stateList.loading,(n=r.config).css.forEach(function(e,t,i){r.getStylePromise(n.path+e)}),r.pluginManager&&(t=r.pluginManager.__getDepsPromiseCallback(r.config.deps),r.queuePush(t)),o=n.path+n.module,i="string"==typeof n.module&&""!==n.module&&"ES"===n.type?function(){return r.getESModulePromise(o).then(function(e){e.__esModule=!0,r.module.exports=e}.bind(r))}:"string"==typeof n.module&&""!==n.module&&"UMD"===n.type?isAssetLoaded(o)?void(r.config.debug&&console.warn(`Plugin ${r.id}: Скрипт ${o} уже загружен!`)):function(){return r.httpGet(o).then(function(e){r.module.code=e}.bind(r))}:"HMD"!==n.type||n.hasOwnProperty("handler")&&"function"==typeof n.handler?"string"==typeof n.module&&""!==n.module&&"default"===n.type?isAssetLoaded(o)?void(r.config.debug&&console.warn(`Plugin ${r.id}: Скрипт ${o} уже загружен!`)):function(){return r.getScriptPromise(o)}:void 0:function(){return r.getScriptPromise(o)},s=r.getJsAssetsPromiseCallback(n.js),n.loadJsAfterModule?(r.queuePush(i),r.queuePush(s)):(r.queuePush(s),r.queuePush(i)),t||i||s||(r.state=stateList.loaded),r.__queue(stateList.loaded,function(){r.config.debug&&console.log(`Plugin ${r.id}: onLoad + event.`),r.isLoaded()||(r.state=stateList.loaded),n.onLoad.call(r,r);var e=new CustomEvent("onLoad"+r.id+"Plugin",{detail:{plugin:r}});document.dispatchEvent(e)}),r.__exec(stateList.loaded,function(){e()}.bind(r))):console.warn(`Plugin.load(${l}): is not register!.`),r},Plugin.prototype.install=function(callback){var self=this,global=self.pluginManager.global,require=self.pluginManager.require.bind(self.pluginManager),pluginId=("function"!=typeof callback&&(callback=function(){}),self.id),setGlobals,module,installer;return self.__checkState(stateList.registered)?self.__checkState(stateList.installed)?callback():self.__check2State(stateList.installing)?self.__exec(stateList.installed,callback):(self.__checkState(stateList.loaded)||this.load(),self.state2=stateList.installing,setGlobals=function(t,i){var e,n;void 0!==i&&(e=self.id,n=self.config.alias,t.hasOwnProperty(e)||(t[e]=i),Array.isArray(n))&&n.length&&n.forEach(function(e){t.hasOwnProperty(e)||(t[e]=i)})},module=self.module,installer=function(){var __exports=self.module.exports,event=("ES"===self.config.type&&"string"==typeof self.config.module&&""!==self.config.module?__exports="object"==typeof self.module.exports&&void 0!==self.module.exports.default?self.module.exports.default:self.module.exports:"UMD"===self.config.type&&"string"==typeof self.config.module&&""!==self.config.module?(function(require,exports,module,global){var self=global;eval(module.code)}.bind(global).call(global,require,self.module.exports,module,global),__exports="object"==typeof self.module.exports&&void 0!==self.module.exports.default?self.module.exports.default:self.module.exports):"HMD"===self.config.type&&"function"==typeof self.config.handler&&(__exports=self.config.handler.bind(global).call(global,require,self.module.exports,module,global),void 0===__exports)&&self.module.exports&&(__exports=self.module.exports),"object"==typeof global&&setGlobals(global,__exports),self.state=stateList.installed,console.log(`%cPlugin ${pluginId}: installed.`,"color: green;"),self.config.onInstall.call(self,self),new CustomEvent("onInstall"+self.id+"Plugin",{detail:{plugin:self}}));return document.dispatchEvent(event),!0}.bind(this),this.__queue(stateList.loaded,installer),this.__exec(stateList.loaded,function(){callback()})):console.warn(`Plugin ${pluginId}: is not register!`),self},Plugin.prototype.exec=function(e,t=[],i=void 0){var n=this;void 0===i&&(i=n),n.__checkState(stateList.installed)||(n.load(),n.install()),n.__exec(stateList.installed,e,t,i)},Plugin.prototype.getESModulePromise=function(e){var n=this;return new Promise(function(t,i){import(e).then(function(e){t(e)},function(e){n.errors.push(e),console.log(`%cPlugin ${n.id}: error import module!`,"color: red;"),i(e)})})},Plugin.prototype.httpGet=function(n){var o=this;return new Promise(function(t,i){o.config.debug&&console.log(`Plugin ${o.id}: httpGet `+n);var e=n;o.config.isSetTimestamp&&(e=getUrlWithTimestamp(n)),p=fetch(e,{method:"GET",redirect:"follow"}).then(function(e){if(e.ok)return e.text();throw console.log(`%cPlugin.load(${o.id}): bad status ${e.status}!`,"color: red;"),["bad status",e.status,e.statusText].filter().join(" ")},function(e){i("Network Error")}).then(function(e){t(e)},function(e){i(e)})})},Plugin.prototype.getScriptPromise=function(n){var o=this;if(!isAssetLoaded(n))return new Promise(function(e,t){o.config.debug&&console.log(`Plugin ${o.id}: load script `+n);var i=document.createElement("script");i.async=!0,i.onload=function(){e(i)},i.onerror=function(){var e=new Error("Ошибка загрузки скрипта "+n);o.errors.push(e),console.log(`%cPlugin.load(${o.id}): error load script ${n}!`,"color: red;"),t(e)},i.src=n,o.config.isSetTimestamp&&(i.src=getUrlWithTimestamp(n)),document.head.append(i)});o.config.debug&&console.warn(`Plugin ${o.id}: Скрипт ${n} уже загружен!`)},Plugin.prototype.getStylePromise=function(n){var o=this;return new Promise(function(e,t){var i;isAssetLoaded(n)?(o.config.debug&&console.warn(`Plugin ${o.id}: Стиль ${n} уже загружен`),e()):((i=document.createElement("link")).rel="stylesheet",i.type="text/css",i.media="all",i.href=n,o.config.isSetTimestamp&&(i.href=getUrlWithTimestamp(n)),document.head.append(i),e(i))})},Plugin.prototype.getAsyncScriptListPromise=function(e){e=e.map(this.getScriptPromise.bind(this)).filter(e=>void 0!==e);if(e.length)return Promise.all(e)},Plugin.prototype.getJsAssetsPromiseCallback=function(e=[]){var o=this;if(e.length)return function(){var n=new Promise(function(e,t){e()});return e.forEach(function(e,t,i){n=Array.isArray(e)?n.then(function(){return o.getAsyncScriptListPromise(e.map(e=>o.config.path+e))}):n.then(function(){return o.getScriptPromise(o.config.path+e)})}),n}},Plugin.prototype.__getRealId=function(e){var t,i=e.toLowerCase();if(this.id.toLowerCase()===i)return this.id;for(t of this.config.alias)if(i===t.toLowerCase())return this.id},Plugin.prototype.__is=function(e){return this.id===this.__getRealId(e)},Plugin.prototype.isLoaded=function(){return this.__checkState(stateList.loaded)},Plugin.prototype.isInstalled=function(){return this.__checkState(stateList.installed)},Plugin.prototype.require=function(){return this.isInstalled()||this.config.debug&&console.warn(`Plugin ${this.id}: not instaled!`),this.module.exports};var PluginManager=function(e){this.plugins={},this.global=e},__proto=PluginManager.prototype;function init(e){var o=new PluginManager(e);e.ready=o.ready.bind(o),e.loaded=o.loaded.bind(o),e.exec=o.exec.bind(o),e.require=o.require.bind(o),e.define=o.define.bind(o),e.PluginManager=PluginManager,o.register("pluginManager",{alias:["pm"],type:MD_TYPE.HMD,handler:function(e,t,i,n){return"object"==typeof window&&(window.__PluginManager__=o,window.__pmGlobal__=n),i.exports=o},onInstall:function(e){}}),o.install("pluginManager"),o.register("config",{type:MD_TYPE.HMD,handler:function(e,t,i,n){var o=document.currentScript;if(o)try{var s=new URL(o.src);defaultConfig.assetsPath=s.pathname.split("/").slice(0,-2).join("/")}catch(e){s=o.src.split("?")[0];defaultConfig.assetsPath=s.split("/").slice(0,-2).join("/")}o=n.config||{};n.config=Object.assign({},defaultConfig,o),"object"==typeof window&&(window.__pmConfig__=n.config),document.addEventListener("DOMContentLoaded",function(){console.log("%cDOMContentLoaded","color:#2053ff")}),window.addEventListener("load",e=>{console.log("%cWindowLoaded","color:#2053ff")})},onInstall:function(e){"object"==typeof window&&window.hasOwnProperty("__PluginManagerConfigHandler__")&&"function"==typeof __PluginManagerConfigHandler__&&o.registerPlugins(__PluginManagerConfigHandler__())}}),o.install("config")}PluginManager.prototype.registerPlugins=function(e){for(var t in e)e.hasOwnProperty(t)&&this.register(t,e[t]);return this},PluginManager.prototype.register=function(e,t={}){var i;"string"!=typeof e||""===e?console.warn("Invalid pluginId!",e):(i=this.__getPlugin(e))?i.register(t):((i=new Plugin(e,t)).setPluginManager(this),this.plugins[e]=i)},PluginManager.prototype.__getPlugin=function(e){var t,i;for(t in this.plugins)if(this.plugins.hasOwnProperty(t)&&(i=this.plugins[t]).__is(e))return i},PluginManager.prototype.__getDepsPromiseCallback=function(e=[]){var i=this,t=e.map(function(e){var t=i.__getPlugin(e);if(t)return t.install(),t.isInstalled()?void 0:t.promise;console.log(`%cPluginManager: plugin ${e} not found!`,"color: red;")}).filter(e=>void 0!==e);if(t.length)return function(){return Promise.all(t)}},PluginManager.prototype.__getRealIdList=function(e=[]){var t=this;return e.map(function(e){e=t.__getPlugin(e);if(e)return e.id})},PluginManager.prototype.exec=function(e,t,i=[],n=void 0){"function"==typeof e&&(n=i,i=t,t=e,e=[]),"string"==typeof e&&(e=[e]),void 0===n&&(n=this),void 0===i&&(i=[]),"function"==typeof t&&(global.config&&global.config.requiredDependencies&&(e=Array.from(new Set(e.concat(global.config.requiredDependencies)))),(e=this.__getDepsPromiseCallback(e))?e().then(function(){t.apply(n,i)}):t.apply(n,i))},__proto.define=function(e,t){var i=this,n=this,o=i.__getDepsPromiseCallback(e),s=function(){var t=[];return e.forEach(function(e){i.__getPlugin(e)?t.push(i.require(e)):t.push(void 0)}.bind(i)),t}.bind(i);o?o().then(function(){t.apply(n,s())}):t.apply(n,s())},__proto.ready=function(e,t=void 0){"function"==typeof e&&(t=e,e=[]),this.__ready(this.exec,[e,t="function"!=typeof t?function(){}:t],this)},__proto.__ready=function(e,t=[],i=window){i=i||this,/complete|interactive|loaded/.test(document.readyState)?e.apply(i,t):document.addEventListener("DOMContentLoaded",function(){e.apply(i,t)}.bind(this))},__proto.loaded=function(e,t=void 0){"function"==typeof e&&(t=e,e=[]),this.__loaded(this.exec,[e,t="function"!=typeof t?function(){}:t],this)},__proto.__loaded=function(e,t=[],i=window){i=i||this,/complete|interactive|loaded/.test(document.readyState)?e.apply(i,t):window.addEventListener("load",function(){e.apply(i,t)}.bind(this))},__proto.require=function(e,t){var i,n=this.__getPlugin(e);if(n)return e=n.id,i=n.module,n.install(t="function"!=typeof t?function(){}:t),i.exports;console.warn("PluginManager.require: plugin "+e+" not found!")},__proto.install=function(e,t){var i=this.__getPlugin(e);i?(e=i.id,i.module,i.install(t)):console.warn("PluginManager.install: plugin "+e+" not found!")},init(global)}(kit); \ No newline at end of file +var kit;kit=window.kit=window.kit||{};kit.service=kit.service||{};kit.config=kit.config||{};(function(global){var defaultConfig={version:"2.1",assetsPath:"",requiredDependencies:[],autoloadPluginList:[],debug:true};var stateList={undefined:0,registered:1,loading:3,loaded:4,installing:5,installed:6};var MD_TYPE={ES:"ES",UMD:"UMD",HMD:"HMD",default:"default"};function Plugin(pluginId,config={}){this.id=pluginId;this.state=stateList.undefined;this.state2=stateList.undefined;this.module={code:"",exports:{}};this.config={autoRequire:false,loadJsAfterModule:false,isSetTimestamp:true,path:"",module:"",type:"default",handler:undefined,onRegister:function(plugin){},onLoad:function(plugin){},onInstall:function(plugin){},js:[],css:[],alias:[],deps:[],debug:false};this.pluginManager=undefined,this.promise=new Promise(function(resolve,reject){resolve()});this.errors=[];this.register(config)}Plugin.prototype.setPluginManager=function(pluginManager){this.pluginManager=pluginManager};function isAssetLoaded(src){src=src.match(/^[^#?]*/)[0];return document.querySelector('script[src^="'+src+'"]')||document.querySelector('link[href^="'+src+'"]')||document.querySelector('meta[property="kit:file-load"][content="'+src+'"]')}function getUrlWithTimestamp(url){var t=((new Date).getTime()/1e3/3600>>0)*3600;try{var uri=new URL(url);uri.searchParams.append("__pm",String(t));url=uri.toString()}catch(e){url=String(url).split("?")[0];url=""+url+"?__pm"+t}return url}Plugin.prototype.queuePush=function(callbackPromise,argArr=[]){var self=this;if(typeof callbackPromise!=="function"){return}this.promise=this.promise.then(function(m){var p=callbackPromise.apply(this,argArr);if(p){return p}})};Plugin.prototype.__queue=function(admission,callback,argArr=[],context=undefined){var self=this;if(context===undefined){context=self}if(self.__checkState(admission)){callback.apply(context,argArr)}else{self.promise=self.promise.then(function(){return new Promise(function(resolve,reject){callback.apply(context,argArr);resolve()})}.bind(self))}};Plugin.prototype.__exec=function(admission,callback,argArr=[],context=undefined){var self=this;if(context===undefined){context=self}if(self.__checkState(admission)){callback.apply(context,argArr)}else{self.promise=self.promise.then(function(){callback.apply(context,argArr)}.bind(self))}};Plugin.prototype.__checkState=function(state,stateTo=undefined){if(stateTo===undefined){return this.state>=state}return this.state>=state&&this.state<=stateTo};Plugin.prototype.__check2State=function(state,stateTo=undefined){if(stateTo===undefined){return this.state2>=state}return this.state2>=state&&this.state2<=stateTo};Plugin.prototype.__getValidConfig=function(c={}){var config=Object.assign({},c);if(typeof config.onLoad!=="function"){config.onLoad=function(plugin){}}if(typeof config.onInstall!=="function"){config.onInstall=function(plugin){}}if(typeof config.onRegister!=="function"){config.onRegister=function(plugin){}}if(typeof config.path!=="string"){config.path=""}if(typeof config.js==="string"){config.js=[config.js]}else if(!Array.isArray(config.js)){config.js=[]}if(typeof config.css==="string"){config.css=[config.css]}else if(!Array.isArray(config.css)){config.css=[]}if(typeof config.alias==="string"){config.alias=[config.alias]}else if(!Array.isArray(config.alias)){config.alias=[]}config.autoRequire=config.hasOwnProperty("autoRequire")?!!config.autoRequire:false;config.loadJsAfterModule=config.hasOwnProperty("loadJsAfterModule")?!!config.loadJsAfterModule:false;config.isSetTimestamp=config.hasOwnProperty("isSetTimestamp")?!!config.isSetTimestamp:true;config.type=config.type||"default";if(typeof config.deps==="string"){config.deps=[config.deps]}else if(!Array.isArray(config.deps)){config.deps=[]}return config};Plugin.prototype.__setState=function(state,force=false){var self=this;if(force){self.state=state;return}if(self.__checkState(state)){self.state=state}};Plugin.prototype.register=function(config={}){var self=this;var pluginId=self.id;if(this.__checkState(stateList.installed)){throw new Error("Plugin "+pluginId+" уже невозможно конфигурировать ("+self.state+"/"+self.state2+")")}var handler;if(typeof config==="function"){handler=config;config=this.config;config.handler=handler;config.type=MD_TYPE.HMD}else{if(this.__checkState(stateList.loaded)||this.__check2State(stateList.loading)){throw new Error("Plugin "+pluginId+" уже невозможно конфигурировать ("+self.state+")")}if(typeof config==="object"){config=this.__getValidConfig(config)}else{throw new Error("Plugin.register: plugin "+pluginId+" is not a valid format")}Object.assign(this.config,config)}if(!this.__checkState(stateList.registered)){self.config.debug&&console.log(`Plugin ${self.id}: onRegister + event.`);this.state=stateList.registered;this.config.onRegister(this);var event=new CustomEvent("onRegister"+this.id+"Plugin",{detail:{plugin:this}});document.dispatchEvent(event)}if(config.autoRequire){}};Plugin.prototype.load=function(callback){var self=this;if(typeof callback!=="function"){callback=function(){}}var pluginId=self.id;if(!self.__checkState(stateList.registered)){console.warn(`Plugin.load(${pluginId}): is not register!.`);return self}if(self.__checkState(stateList.loaded)){callback();return self}if(self.__check2State(stateList.loading)){self.__exec(stateList.loaded,callback);return self}self.state2=stateList.loading;var config=self.config;var getModulePromiseCallback=function(){var src=config.path+config.module;if(typeof config.module==="string"&&config.module!==""&&config.type==="ES"){return function(){return self.getESModulePromise(src).then(function(m){m.__esModule=true;self.module.exports=m}.bind(self))}}else if(typeof config.module==="string"&&config.module!==""&&config.type==="UMD"){if(isAssetLoaded(src)){self.config.debug&&console.warn(`Plugin ${self.id}: Скрипт ${src} уже загружен!`);return}else{return function(){return self.httpGet(src).then(function(m){self.module.code=m}.bind(self))}}}else if(config.type==="HMD"&&!(config.hasOwnProperty("handler")&&typeof config.handler==="function")){return function(){return self.getScriptPromise(src)}}else if(typeof config.module==="string"&&config.module!==""&&config.type==="default"){if(isAssetLoaded(src)){self.config.debug&&console.warn(`Plugin ${self.id}: Скрипт ${src} уже загружен!`);return}else{return function(){return self.getScriptPromise(src)}}}return};config.css.forEach(function(item,i,array){self.getStylePromise(config.path+item)});var f0;if(self.pluginManager){f0=self.pluginManager.__getDepsPromiseCallback(self.config.deps);self.queuePush(f0)}var f1=getModulePromiseCallback();var f2=self.getJsAssetsPromiseCallback(config.js);if(config.loadJsAfterModule){self.queuePush(f1);self.queuePush(f2)}else{self.queuePush(f2);self.queuePush(f1)}if(!f0&&!f1&&!f2){self.state=stateList.loaded}self.__queue(stateList.loaded,function(){self.config.debug&&console.log(`Plugin ${self.id}: onLoad + event.`);if(!self.isLoaded()){self.state=stateList.loaded}config.onLoad.call(self,self);var event=new CustomEvent("onLoad"+self.id+"Plugin",{detail:{plugin:self}});document.dispatchEvent(event)});self.__exec(stateList.loaded,function(){callback()}.bind(self));return self};Plugin.prototype.install=function(callback){var self=this,global=self.pluginManager.global,require=self.pluginManager.require.bind(self.pluginManager);if(typeof callback!=="function"){callback=function(){}}var pluginId=self.id;if(!self.__checkState(stateList.registered)){console.warn(`Plugin ${pluginId}: is not register!`);return self}if(self.__checkState(stateList.installed)){callback();return self}if(self.__check2State(stateList.installing)){self.__exec(stateList.installed,callback);return self}if(!self.__checkState(stateList.loaded)){this.load()}self.state2=stateList.installing;var setGlobals=function(global,data){if(data===undefined){return}var pluginId=self.id;var aliasList=self.config.alias;if(!global.hasOwnProperty(pluginId)){global[pluginId]=data}if(Array.isArray(aliasList)&&aliasList.length){aliasList.forEach(function(alias){if(!global.hasOwnProperty(alias)){global[alias]=data}})}};var module=self.module;var installer=function(){var __exports=self.module.exports;if(self.config.type==="ES"&&typeof self.config.module==="string"&&self.config.module!==""){__exports=typeof self.module.exports==="object"&&self.module.exports.default!==undefined?self.module.exports.default:self.module.exports}else if(self.config.type==="UMD"&&typeof self.config.module==="string"&&self.config.module!==""){(function(require,exports,module,global){var self=global;eval(module.code)}).bind(global).call(global,require,self.module.exports,module,global);__exports=typeof self.module.exports==="object"&&self.module.exports.default!==undefined?self.module.exports.default:self.module.exports}else if(self.config.type==="HMD"&&typeof self.config.handler==="function"){__exports=self.config.handler.bind(global).call(global,require,self.module.exports,module,global);if(__exports===undefined&&self.module.exports){__exports=self.module.exports}}if(typeof global==="object"){setGlobals(global,__exports)}self.state=stateList.installed;console.log(`%cPlugin ${pluginId}: installed.`,"color: green;");self.config.onInstall.call(self,self);var event=new CustomEvent("onInstall"+self.id+"Plugin",{detail:{plugin:self}});document.dispatchEvent(event);return true}.bind(this);this.__queue(stateList.loaded,installer);this.__exec(stateList.loaded,function(){callback()});return self};Plugin.prototype.exec=function(callback,argArr=[],context=undefined){var self=this;if(context===undefined){context=self}if(!self.__checkState(stateList.installed)){self.load();self.install()}self.__exec(stateList.installed,callback,argArr,context)};Plugin.prototype.getESModulePromise=function(src){var self=this;return new Promise(function(resolve,reject){import(src).then(function(m){resolve(m)},function(error){self.errors.push(error);console.log(`%cPlugin ${self.id}: error import module!`,"color: red;");reject(error)})})};Plugin.prototype.httpGet=function(url){var self=this;return new Promise(function(resolve,reject){self.config.debug&&console.log(`Plugin ${self.id}: httpGet ${url}`);var url2=url;if(self.config.isSetTimestamp){url2=getUrlWithTimestamp(url)}p=fetch(url2,{method:"GET",redirect:"follow"}).then(function(response){if(response.ok){return response.text()}console.log(`%cPlugin.load(${self.id}): bad status ${response.status}!`,"color: red;");throw["bad status",response.status,response.statusText].filter().join(" ")},function(reason){reject("Network Error")}).then(function(data){resolve(data)},function(reason){reject(reason)})})};Plugin.prototype.getScriptPromise=function(src){var self=this;if(isAssetLoaded(src)){self.config.debug&&console.warn(`Plugin ${self.id}: Скрипт ${src} уже загружен!`);return undefined}return new Promise(function(resolve,reject){self.config.debug&&console.log(`Plugin ${self.id}: load script ${src}`);var script=document.createElement("script");script.async=true;script.onload=function(){resolve(script)};script.onerror=function(){var error=new Error(`Ошибка загрузки скрипта ${src}`);self.errors.push(error);console.log(`%cPlugin.load(${self.id}): error load script ${src}!`,"color: red;");reject(error)};script.src=src;if(self.config.isSetTimestamp){script.src=getUrlWithTimestamp(src)}document.head.append(script)})};Plugin.prototype.getStylePromise=function(src){var self=this;return new Promise(function(resolve,reject){if(isAssetLoaded(src)){self.config.debug&&console.warn(`Plugin ${self.id}: Стиль ${src} уже загружен`);resolve()}else{var link=document.createElement("link");link.rel="stylesheet";link.type="text/css";link.media="all";link.href=src;if(self.config.isSetTimestamp){link.href=getUrlWithTimestamp(src)}document.head.append(link);resolve(link)}})};Plugin.prototype.getAsyncScriptListPromise=function(list){var self=this;var pList=list.map(self.getScriptPromise.bind(self)).filter(p=>p!==undefined);if(pList.length){return Promise.all(pList)}return undefined};Plugin.prototype.getJsAssetsPromiseCallback=function(list=[]){var self=this;if(!list.length){return}return function(){var p=new Promise(function(resolve,reject){resolve()});list.forEach(function(item,i,array){if(Array.isArray(item)){p=p.then(function(){return self.getAsyncScriptListPromise(item.map(src=>self.config.path+src))})}else{p=p.then(function(){return self.getScriptPromise(self.config.path+item)})}});return p}};Plugin.prototype.__getRealId=function(pluginId){var self=this;var pluginIdLowerCase=pluginId.toLowerCase();if(self.id.toLowerCase()===pluginIdLowerCase){return self.id}var alias;for(alias of self.config.alias){if(pluginIdLowerCase===alias.toLowerCase()){return self.id}}return undefined};Plugin.prototype.__is=function(pluginId){var self=this;return self.id===self.__getRealId(pluginId)};Plugin.prototype.isLoaded=function(){var self=this;return self.__checkState(stateList.loaded)};Plugin.prototype.isInstalled=function(){var self=this;return self.__checkState(stateList.installed)};Plugin.prototype.require=function(){var self=this;if(!self.isInstalled()){self.config.debug&&console.warn(`Plugin ${self.id}: not instaled!`)}return self.module.exports};var PluginManager=function(global){this.plugins={};this.global=global};var __proto=PluginManager.prototype;PluginManager.prototype.registerPlugins=function(plugins){for(var pluginId in plugins){if(plugins.hasOwnProperty(pluginId)){this.register(pluginId,plugins[pluginId])}}return this};PluginManager.prototype.register=function(pluginId,config={}){if(typeof pluginId!=="string"||pluginId===""){console.warn(`Invalid pluginId!`,pluginId);return}var plugin=this.__getPlugin(pluginId);if(plugin){plugin.register(config)}else{plugin=new Plugin(pluginId,config);plugin.setPluginManager(this);this.plugins[pluginId]=plugin}};PluginManager.prototype.__getPlugin=function(pluginId){var self=this;var pid,plugin;for(pid in self.plugins){if(self.plugins.hasOwnProperty(pid)){plugin=self.plugins[pid];if(plugin.__is(pluginId)){return plugin}}}return undefined};PluginManager.prototype.__getDepsPromiseCallback=function(pluginIdList=[]){var self=this;var pList=pluginIdList.map(function(pluginId){var plugin=self.__getPlugin(pluginId);if(plugin){plugin.install();if(plugin.isInstalled()){return undefined}return plugin.promise}console.log(`%cPluginManager: plugin ${pluginId} not found!`,"color: red;");return undefined}).filter(p=>p!==undefined);if(!pList.length){return undefined}return function(){return Promise.all(pList)}};PluginManager.prototype.__getRealIdList=function(pluginIdList=[]){var self=this;var pList=pluginIdList.map(function(pluginId){var plugin=self.__getPlugin(pluginId);if(plugin){return plugin.id}return undefined});return pList};PluginManager.prototype.exec=function(deps,callback,argArr=[],context=undefined){var self=this;if(typeof deps==="function"){context=argArr;argArr=callback;callback=deps;deps=[]}if(typeof deps==="string"){deps=[deps]}if(context===undefined){context=self}if(typeof argArr==="undefined"){argArr=[]}if(typeof callback!=="function"){callback=function(){}}if(global.config&&global.config.requiredDependencies){deps=Array.from(new Set(deps.concat(global.config.requiredDependencies)))}var depsPromiseCallback=self.__getDepsPromiseCallback(deps);if(depsPromiseCallback){return depsPromiseCallback().then(function(){return new Promise(function(resolve,reject){callback.apply(context,argArr);resolve()})})}else{return new Promise(function(resolve,reject){callback.apply(context,argArr);resolve()})}};__proto.define=function(deps,callback){var self=this;var context=this;if(typeof deps==="string"){deps=[deps]}if(typeof callback!=="function"){callback=function(){}}var depsPromiseCallback=self.__getDepsPromiseCallback(deps);var getArgArr=function(){var argArr=[];deps.forEach(function(pluginId){var plugin=self.__getPlugin(pluginId);if(plugin){argArr.push(self.require(pluginId));return}argArr.push(undefined)}.bind(self));return argArr}.bind(self);if(depsPromiseCallback){return depsPromiseCallback().then(function(){return new Promise(function(resolve,reject){callback.apply(context,getArgArr());resolve()})})}else{return new Promise(function(resolve,reject){callback.apply(context,getArgArr());resolve()})}};__proto.ready=function(deps=[],callback=undefined){var self=this;if(typeof deps==="function"){callback=deps;deps=[]}if(typeof callback!=="function"){callback=function(){}}return self.__ready(self.exec,[deps,callback],self)};__proto.__ready=function(fn,args=[],context=window){var promise;var self=this;context=context||this;if(/complete|interactive|loaded/.test(document.readyState)){promise=new Promise(function(resolve,reject){fn.apply(context,args);resolve()})}else{promise=new Promise(function(resolve,reject){document.addEventListener("DOMContentLoaded",function(){resolve()}.bind(this))}).then(function(){return fn.apply(context,args)})}return promise};__proto.loaded=function(deps=[],callback=undefined){var self=this;if(typeof deps==="function"){callback=deps;deps=[]}if(typeof callback!=="function"){callback=function(){}}return self.__loaded(self.exec,[deps,callback],self)};__proto.__loaded=function(fn,args=[],context=window){var promise;var self=this;context=context||this;if(/complete|interactive|loaded/.test(document.readyState)){promise=new Promise(function(resolve,reject){fn.apply(context,args);resolve()})}else{promise=new Promise(function(resolve,reject){window.addEventListener("load",function(){resolve()}.bind(this))}).then(function(){return fn.apply(context,args)})}return promise};__proto.require=function(pluginId,callback){var plugin=this.__getPlugin(pluginId);if(!plugin){console.warn("PluginManager.require: plugin "+pluginId+" not found!");return undefined}pluginId=plugin.id;var module=plugin.module;if(typeof callback!=="function"){callback=function(){}}plugin.install(callback);return module.exports};__proto.install=function(pluginId,callback){var plugin=this.__getPlugin(pluginId);if(!plugin){console.warn("PluginManager.install: plugin "+pluginId+" not found!");return undefined}pluginId=plugin.id;var module=plugin.module;plugin.install(callback)};function init(global){var manager=new PluginManager(global);global.ready=manager.ready.bind(manager);global.loaded=manager.loaded.bind(manager);global.exec=manager.exec.bind(manager);global.require=manager.require.bind(manager);var pm;global.define=manager.define.bind(manager);global.PluginManager=PluginManager;manager.register("pluginManager",{alias:["pm"],type:MD_TYPE.HMD,handler:function(require,exports,module,global){if(typeof window==="object"){window.__PluginManager__=manager;window.__pmGlobal__=global}return module.exports=manager},onInstall:function(plugin){}});manager.install("pluginManager");manager.register("config",{type:MD_TYPE.HMD,handler:function(require,exports,module,global){var script=document.currentScript;if(script){try{var uri=new URL(script.src);defaultConfig.assetsPath=uri.pathname.split("/").slice(0,-2).join("/")}catch(e){var path=script.src.split("?")[0];defaultConfig.assetsPath=path.split("/").slice(0,-2).join("/")}}var config=global.config||{};global.config=Object.assign({},defaultConfig,config);if(typeof window==="object"){window.__pmConfig__=global.config}document.addEventListener("DOMContentLoaded",function(){console.log("%cDOMContentLoaded","color:#2053ff")});window.addEventListener("load",event=>{console.log("%cWindowLoaded","color:#2053ff")})},onInstall:function(plugin){if(typeof window==="object"){if(window.hasOwnProperty("__PluginManagerConfigHandler__")&&typeof __PluginManagerConfigHandler__==="function"){manager.registerPlugins(__PluginManagerConfigHandler__())}}}});manager.install("config")}init(global)})(kit); \ No newline at end of file diff --git a/images/colors/black.png b/images/colors/black.png new file mode 100644 index 0000000..9b06e43 Binary files /dev/null and b/images/colors/black.png differ diff --git a/images/colors/brown.png b/images/colors/brown.png new file mode 100644 index 0000000..07e6016 Binary files /dev/null and b/images/colors/brown.png differ diff --git a/images/colors/colors.psd b/images/colors/colors.psd index c11e3f3..9a81764 100644 Binary files a/images/colors/colors.psd and b/images/colors/colors.psd differ diff --git a/images/colors/gray.png b/images/colors/gray.png new file mode 100644 index 0000000..76a6fa9 Binary files /dev/null and b/images/colors/gray.png differ diff --git a/images/colors/green.png b/images/colors/green.png new file mode 100644 index 0000000..634c906 Binary files /dev/null and b/images/colors/green.png differ diff --git a/images/colors/mix.jpg b/images/colors/mix.jpg new file mode 100644 index 0000000..81e9ec8 Binary files /dev/null and b/images/colors/mix.jpg differ diff --git a/images/colors/orange.png b/images/colors/orange.png new file mode 100644 index 0000000..bb37a9b Binary files /dev/null and b/images/colors/orange.png differ diff --git a/images/colors/red.png b/images/colors/red.png new file mode 100644 index 0000000..b9cc676 Binary files /dev/null and b/images/colors/red.png differ diff --git a/images/colors/violet.png b/images/colors/violet.png new file mode 100644 index 0000000..af9e744 Binary files /dev/null and b/images/colors/violet.png differ diff --git a/images/colors/white.png b/images/colors/white.png new file mode 100644 index 0000000..05e7620 Binary files /dev/null and b/images/colors/white.png differ diff --git a/images/colors/yellow.png b/images/colors/yellow.png new file mode 100644 index 0000000..07b0f84 Binary files /dev/null and b/images/colors/yellow.png differ diff --git a/tests/pluginManagerTest.php b/tests/pluginManagerTest.php new file mode 100644 index 0000000..2759d9d --- /dev/null +++ b/tests/pluginManagerTest.php @@ -0,0 +1,58 @@ + + + + +
+
+
+', 100000); diff --git a/tests/templaterTest.php b/tests/templaterTest.php index 03f8abb..9789cf3 100644 --- a/tests/templaterTest.php +++ b/tests/templaterTest.php @@ -1,6 +1,10 @@ - - +service()->assets()->setPlugins([ 'kit:config', 'kit:flex-kit', @@ -12,11 +16,14 @@ if(\Bitrix\Main\Loader::includeModule('wt.core')) { 'kit:theme', ])->render(); } +/** + * @global CMain $APPLICATION + */ $APPLICATION->ShowHead(); ?>
-
templater()->render('kit:input', [ 'TYPE' => 'text', 'HINT' => '', @@ -25,7 +32,7 @@ $APPLICATION->ShowHead(); 'LABEL' => 'value = дв ковычки', ]); ?>
-
templater()->render('kit:input', [ 'TYPE' => 'text', 'HINT' => '', @@ -34,7 +41,7 @@ $APPLICATION->ShowHead(); 'LABEL' => 'value = одинарные ковычки', ]); ?>
-
templater()->render('kit:input', [ 'TYPE' => 'text', 'HINT' => '', @@ -43,7 +50,7 @@ $APPLICATION->ShowHead(); 'LABEL' => 'value = спецсимволы', ]); ?>
-
templater()->render('kit:input', [ 'TYPE' => 'text', 'HINT' => '', @@ -52,7 +59,7 @@ $APPLICATION->ShowHead(); 'LABEL' => 'value = лев пр слеши, лев пр стрелки, дв од кав', ]); ?>
-
templater()->render('kit:input', [ 'TYPE' => 'text', 'HINT' => '',