From 579bf3695724f733e5798489b53024542f64bf84 Mon Sep 17 00:00:00 2001 From: Danny Stey | coma AG Date: Wed, 19 Dec 2018 09:56:42 +0100 Subject: [PATCH] improved some tests --- lib/loadmanager.js | 23 ++++++++++++++++------- lib/loadmanager.js.map | 2 +- src/index.js | 19 ++++++++++++++----- test/loadTests.js | 18 ++++++++++++++++++ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/lib/loadmanager.js b/lib/loadmanager.js index 4b7704d..092ed9c 100644 --- a/lib/loadmanager.js +++ b/lib/loadmanager.js @@ -217,7 +217,8 @@ function () { }); var counter = 0; - var checkComplete = function checkComplete() { + var checkComplete = function checkComplete(script) { + if (script.onRequest) return; counter++; if (counter >= scripts.length) { @@ -225,11 +226,11 @@ function () { } }; - this.on('loaded', function () { - return checkComplete(); + this.on('loaded', function (script) { + return checkComplete(script); }); - this.on('error', function () { - return checkComplete(); + this.on('error', function (script) { + return checkComplete(script); }); } }, { @@ -291,7 +292,7 @@ function () { if (script.loaded) { resolve(); - } else { + } else if (script.onRequest) { // onRequest // check if the script is allowed to be loaded if (script.onRequest) { @@ -300,8 +301,14 @@ function () { if (level >= script.level) { _this5.addToDom(script); } - } + _this5.on('loaded', function (script) { + if (script.key == key) { + resolve(); + } + }); + } + } else { _this5.scriptListener[key] = _this5.scriptListener[key] || []; _this5.scriptListener[key].push(resolve); @@ -329,6 +336,8 @@ function () { return callback(); }); } + + this.scriptListener = {}; } // EVENT HANDLING }, { diff --git a/lib/loadmanager.js.map b/lib/loadmanager.js.map index ba5533b..46b0794 100644 --- a/lib/loadmanager.js.map +++ b/lib/loadmanager.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://loadmanager/webpack/universalModuleDefinition","webpack://loadmanager/webpack/bootstrap","webpack://loadmanager/./src/index.js"],"names":["loadManager","options","level","scripts","listener","scriptListener","explicit","no_cookie","on","ready","Array","isArray","forEach","script","addScript","filter","onRequest","key","path","position","push","loaded","d","Date","days","setTime","getTime","document","cookie","toGMTString","value","match","parseInt","setLevel","getScripts","addToDom","counter","checkComplete","length","emit","data","createElement","src","setAttribute","onload","event","map","s","onerror","body","appendChild","head","Promise","resolve","reject","getLevel","callback","name"],"mappings":"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","file":"loadmanager.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"loadmanager\"] = factory();\n\telse\n\t\troot[\"loadmanager\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/index.js\");\n","\r\nclass loadManager {\r\n constructor(options) {\r\n this.level = 0;\r\n\r\n this.scripts = [];\r\n\r\n this.listener = {};\r\n\r\n this.scriptListener = {};\r\n\r\n this.options = {\r\n ...{\r\n explicit: false,\r\n no_cookie: false\r\n }, \r\n ...options\r\n };\r\n\r\n this.on('complete', () => this.ready())\r\n }\r\n\r\n setScripts(scripts = null) {\r\n if(scripts && Array.isArray(scripts)) {\r\n scripts.forEach((script) => this.addScript(script))\r\n }\r\n }\r\n\r\n getScripts(level = -1) {\r\n if(level === -1) return this.scripts;\r\n if(level === 0) return [];\r\n return this.scripts.filter((script) => (script.level <= level && !script.onRequest));\r\n }\r\n\r\n addScript({key, path, level = 1, position = 'body', onRequest = false}) {\r\n this.scripts.push({\r\n key: key,\r\n path: path,\r\n level: level,\r\n position: position,\r\n onRequest: onRequest,\r\n loaded: false\r\n });\r\n }\r\n\r\n clearScripts() {\r\n this.scripts = [];\r\n }\r\n\r\n setLevel(level) {\r\n this.level = level;\r\n\r\n // set cookie\r\n let d = new Date;\r\n let days = 100;\r\n d.setTime(d.getTime() + 24*60*60*1000*days);\r\n document.cookie = \"_lm_level=\" + level + \";path=/;expires=\" + d.toGMTString();\r\n }\r\n\r\n getLevel() {\r\n // get from cookie\r\n let value = document.cookie.match('(^|;) ?_lm_level=([^;]*)(;|$)');\r\n let level = value ? value[2] : null;\r\n\r\n return parseInt(level || this.level);\r\n }\r\n \r\n // Load\r\n load(level = -1) {\r\n this.setLevel(level);\r\n\r\n if(level == 0) return;\r\n\r\n let scripts = this.getScripts(level);\r\n\r\n scripts.forEach((script) => this.addToDom(script));\r\n\r\n let counter = 0;\r\n let checkComplete = () => {\r\n counter++;\r\n \r\n if(counter >= scripts.length) {\r\n this.emit('complete');\r\n }\r\n }\r\n this.on('loaded', () => checkComplete())\r\n this.on('error', () => checkComplete())\r\n }\r\n\r\n addToDom(data) {\r\n if(data.loaded) return;\r\n\r\n let script = document.createElement('script');\r\n script.src = data.path;\r\n script.setAttribute('id', data.key);\r\n if(script.onRequest) {\r\n script.setAttribute('data-onrequest', true);\r\n }\r\n script.onload = (event) => {\r\n data.loaded = true;\r\n this.scripts = this.scripts.map((s) => {\r\n if(s.key == data.key ) {\r\n s.loaded = true;\r\n }\r\n return s;\r\n });\r\n this.emit('loaded', data);\r\n \r\n };\r\n script.onerror = (event) => {\r\n data.loaded = false;\r\n this.scripts = this.scripts.map((s) => {\r\n if(s.key == data.key ) {\r\n s.loaded = false;\r\n }\r\n return s;\r\n });\r\n this.emit('error', data);\r\n };\r\n \r\n if(data.position == 'body') {\r\n document.body.appendChild(script); \r\n }\r\n else {\r\n document.head.appendChild(script);\r\n } \r\n }\r\n\r\n // SCRIPT LISTENERS\r\n whenever(key) {\r\n return new Promise((resolve, reject) => {\r\n let script = this.scripts.filter((script) => script.key == key)[0];\r\n if(script.loaded) {\r\n resolve()\r\n }\r\n else {\r\n // onRequest\r\n // check if the script is allowed to be loaded\r\n if(script.onRequest) {\r\n let level = this.getLevel();\r\n if(level >= script.level) {\r\n this.addToDom(script);\r\n }\r\n }\r\n \r\n this.scriptListener[key] = this.scriptListener[key] || [];\r\n this.scriptListener[key].push(resolve);\r\n }\r\n });\r\n }\r\n\r\n has(key) {\r\n return new Promise(function(resolve, reject) {\r\n if(this.scripts.filter((script) => script.key === key && script.loaded === true).length >= 1) {\r\n resolve();\r\n }\r\n else {\r\n reject();\r\n }\r\n });\r\n }\r\n\r\n ready() {\r\n for(let key in this.scriptListener) {\r\n this.scriptListener[key].forEach((callback) => callback());\r\n }\r\n }\r\n\r\n // EVENT HANDLING\r\n on(name, callback) {\r\n if(!this.listener[name]) {\r\n this.listener[name] = [];\r\n }\r\n this.listener[name].push(callback);\r\n }\r\n\r\n emit(name, data) {\r\n if(!this.listener[name]) return;\r\n this.listener[name].forEach((listener) => listener(data));\r\n }\r\n\r\n\r\n\r\n}\r\n\r\nexport default loadManager;"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://loadmanager/webpack/universalModuleDefinition","webpack://loadmanager/webpack/bootstrap","webpack://loadmanager/./src/index.js"],"names":["loadManager","options","level","scripts","listener","scriptListener","explicit","no_cookie","on","ready","Array","isArray","forEach","script","addScript","filter","onRequest","key","path","position","push","loaded","d","Date","days","setTime","getTime","document","cookie","toGMTString","value","match","parseInt","setLevel","getScripts","addToDom","counter","checkComplete","length","emit","data","createElement","src","setAttribute","onload","event","map","s","onerror","body","appendChild","head","Promise","resolve","reject","getLevel","callback","name"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ICjFMA,W;;;AACF,uBAAYC,OAAZ,EAAqB;AAAA;;AAAA;;AACjB,SAAKC,KAAL,GAAa,CAAb;AAEA,SAAKC,OAAL,GAAe,EAAf;AAEA,SAAKC,QAAL,GAAgB,EAAhB;AAEA,SAAKC,cAAL,GAAsB,EAAtB;AAEA,SAAKJ,OAAL,qBACO;AACCK,cAAQ,EAAE,KADX;AAECC,eAAS,EAAE;AAFZ,KADP,EAKON,OALP;AAQA,SAAKO,EAAL,CAAQ,UAAR,EAAoB;AAAA,aAAM,KAAI,CAACC,KAAL,EAAN;AAAA,KAApB;AACH;;;;iCAE0B;AAAA;;AAAA,UAAhBN,OAAgB,uEAAN,IAAM;;AACvB,UAAGA,OAAO,IAAIO,KAAK,CAACC,OAAN,CAAcR,OAAd,CAAd,EAAsC;AAClCA,eAAO,CAACS,OAAR,CAAgB,UAACC,MAAD;AAAA,iBAAY,MAAI,CAACC,SAAL,CAAeD,MAAf,CAAZ;AAAA,SAAhB;AACH;AACJ;;;iCAEsB;AAAA,UAAZX,KAAY,uEAAJ,CAAC,CAAG;AACnB,UAAGA,KAAK,KAAK,CAAC,CAAd,EAAiB,OAAO,KAAKC,OAAZ;AACjB,UAAGD,KAAK,KAAK,CAAb,EAAgB,OAAO,EAAP;AAChB,aAAO,KAAKC,OAAL,CAAaY,MAAb,CAAoB,UAACF,MAAD;AAAA,eAAaA,MAAM,CAACX,KAAP,IAAgBA,KAAhB,IAAyB,CAACW,MAAM,CAACG,SAA9C;AAAA,OAApB,CAAP;AACH;;;oCAEuE;AAAA,UAA7DC,GAA6D,QAA7DA,GAA6D;AAAA,UAAxDC,IAAwD,QAAxDA,IAAwD;AAAA,4BAAlDhB,KAAkD;AAAA,UAAlDA,KAAkD,2BAA1C,CAA0C;AAAA,+BAAvCiB,QAAuC;AAAA,UAAvCA,QAAuC,8BAA5B,MAA4B;AAAA,gCAApBH,SAAoB;AAAA,UAApBA,SAAoB,+BAAR,KAAQ;AACpE,WAAKb,OAAL,CAAaiB,IAAb,CAAkB;AACdH,WAAG,EAAEA,GADS;AAEdC,YAAI,EAAEA,IAFQ;AAGdhB,aAAK,EAAEA,KAHO;AAIdiB,gBAAQ,EAAEA,QAJI;AAKdH,iBAAS,EAAEA,SALG;AAMdK,cAAM,EAAE;AANM,OAAlB;AAQH;;;mCAEc;AACX,WAAKlB,OAAL,GAAe,EAAf;AACH;;;6BAEQD,K,EAAO;AACZ,WAAKA,KAAL,GAAaA,KAAb,CADY,CAGZ;;AACA,UAAIoB,CAAC,GAAG,IAAIC,IAAJ,EAAR;AACA,UAAIC,IAAI,GAAG,GAAX;AACAF,OAAC,CAACG,OAAF,CAAUH,CAAC,CAACI,OAAF,KAAc,KAAG,EAAH,GAAM,EAAN,GAAS,IAAT,GAAcF,IAAtC;AACAG,cAAQ,CAACC,MAAT,GAAkB,eAAe1B,KAAf,GAAuB,kBAAvB,GAA4CoB,CAAC,CAACO,WAAF,EAA9D;AACH;;;+BAEU;AACP;AACA,UAAIC,KAAK,GAAGH,QAAQ,CAACC,MAAT,CAAgBG,KAAhB,CAAsB,+BAAtB,CAAZ;AACA,UAAI7B,KAAK,GAAG4B,KAAK,GAAGA,KAAK,CAAC,CAAD,CAAR,GAAc,IAA/B;AAEA,aAAOE,QAAQ,CAAC9B,KAAK,IAAI,KAAKA,KAAf,CAAf;AACH,K,CAED;;;;2BACiB;AAAA;;AAAA,UAAZA,KAAY,uEAAJ,CAAC,CAAG;AACb,WAAK+B,QAAL,CAAc/B,KAAd;AAEA,UAAGA,KAAK,IAAI,CAAZ,EAAe;AAEf,UAAIC,OAAO,GAAG,KAAK+B,UAAL,CAAgBhC,KAAhB,CAAd;AAEAC,aAAO,CAACS,OAAR,CAAgB,UAACC,MAAD;AAAA,eAAY,MAAI,CAACsB,QAAL,CAActB,MAAd,CAAZ;AAAA,OAAhB;AAEA,UAAIuB,OAAO,GAAG,CAAd;;AACA,UAAIC,aAAa,GAAG,SAAhBA,aAAgB,CAACxB,MAAD,EAAY;AAC5B,YAAGA,MAAM,CAACG,SAAV,EAAqB;AAErBoB,eAAO;;AAEP,YAAGA,OAAO,IAAIjC,OAAO,CAACmC,MAAtB,EAA8B;AAC1B,gBAAI,CAACC,IAAL,CAAU,UAAV;AACH;AACJ,OARD;;AASA,WAAK/B,EAAL,CAAQ,QAAR,EAAkB,UAACK,MAAD;AAAA,eAAYwB,aAAa,CAACxB,MAAD,CAAzB;AAAA,OAAlB;AACA,WAAKL,EAAL,CAAQ,OAAR,EAAiB,UAACK,MAAD;AAAA,eAAYwB,aAAa,CAACxB,MAAD,CAAzB;AAAA,OAAjB;AACH;;;6BAEQ2B,I,EAAM;AAAA;;AACX,UAAGA,IAAI,CAACnB,MAAR,EAAgB;AAEhB,UAAIR,MAAM,GAAGc,QAAQ,CAACc,aAAT,CAAuB,QAAvB,CAAb;AACA5B,YAAM,CAAC6B,GAAP,GAAaF,IAAI,CAACtB,IAAlB;AACAL,YAAM,CAAC8B,YAAP,CAAoB,IAApB,EAA0BH,IAAI,CAACvB,GAA/B;;AACA,UAAGJ,MAAM,CAACG,SAAV,EAAqB;AACjBH,cAAM,CAAC8B,YAAP,CAAoB,gBAApB,EAAsC,IAAtC;AACH;;AACD9B,YAAM,CAAC+B,MAAP,GAAgB,UAACC,KAAD,EAAW;AACvBL,YAAI,CAACnB,MAAL,GAAc,IAAd;AACA,cAAI,CAAClB,OAAL,GAAe,MAAI,CAACA,OAAL,CAAa2C,GAAb,CAAiB,UAACC,CAAD,EAAO;AACnC,cAAGA,CAAC,CAAC9B,GAAF,IAASuB,IAAI,CAACvB,GAAjB,EAAuB;AACnB8B,aAAC,CAAC1B,MAAF,GAAW,IAAX;AACH;;AACD,iBAAO0B,CAAP;AACH,SALc,CAAf;;AAMA,cAAI,CAACR,IAAL,CAAU,QAAV,EAAoBC,IAApB;AAEH,OAVD;;AAWA3B,YAAM,CAACmC,OAAP,GAAiB,UAACH,KAAD,EAAW;AACxBL,YAAI,CAACnB,MAAL,GAAc,KAAd;AACA,cAAI,CAAClB,OAAL,GAAe,MAAI,CAACA,OAAL,CAAa2C,GAAb,CAAiB,UAACC,CAAD,EAAO;AACnC,cAAGA,CAAC,CAAC9B,GAAF,IAASuB,IAAI,CAACvB,GAAjB,EAAuB;AACnB8B,aAAC,CAAC1B,MAAF,GAAW,KAAX;AACH;;AACD,iBAAO0B,CAAP;AACH,SALc,CAAf;;AAMA,cAAI,CAACR,IAAL,CAAU,OAAV,EAAmBC,IAAnB;AACH,OATD;;AAWA,UAAGA,IAAI,CAACrB,QAAL,IAAiB,MAApB,EAA4B;AACxBQ,gBAAQ,CAACsB,IAAT,CAAcC,WAAd,CAA0BrC,MAA1B;AACH,OAFD,MAGK;AACDc,gBAAQ,CAACwB,IAAT,CAAcD,WAAd,CAA0BrC,MAA1B;AACH;AACJ,K,CAED;;;;6BACSI,G,EAAK;AAAA;;AACV,aAAO,IAAImC,OAAJ,CAAY,UAACC,OAAD,EAAUC,MAAV,EAAqB;AACpC,YAAIzC,MAAM,GAAG,MAAI,CAACV,OAAL,CAAaY,MAAb,CAAoB,UAACF,MAAD;AAAA,iBAAYA,MAAM,CAACI,GAAP,IAAcA,GAA1B;AAAA,SAApB,EAAmD,CAAnD,CAAb;;AACA,YAAGJ,MAAM,CAACQ,MAAV,EAAkB;AACdgC,iBAAO;AACV,SAFD,MAGK,IAAGxC,MAAM,CAACG,SAAV,EAAqB;AACtB;AACA;AACA,cAAGH,MAAM,CAACG,SAAV,EAAqB;AACjB,gBAAId,KAAK,GAAG,MAAI,CAACqD,QAAL,EAAZ;;AACA,gBAAGrD,KAAK,IAAIW,MAAM,CAACX,KAAnB,EAA0B;AACtB,oBAAI,CAACiC,QAAL,CAActB,MAAd;AACH;;AACD,kBAAI,CAACL,EAAL,CAAQ,QAAR,EAAkB,UAACK,MAAD,EAAY;AAC1B,kBAAGA,MAAM,CAACI,GAAP,IAAcA,GAAjB,EAAsB;AAClBoC,uBAAO;AACV;AACJ,aAJD;AAKH;AACJ,SAdI,MAeA;AACD,gBAAI,CAAChD,cAAL,CAAoBY,GAApB,IAA2B,MAAI,CAACZ,cAAL,CAAoBY,GAApB,KAA4B,EAAvD;;AACA,gBAAI,CAACZ,cAAL,CAAoBY,GAApB,EAAyBG,IAAzB,CAA8BiC,OAA9B;AACH;AACJ,OAxBM,CAAP;AAyBH;;;wBAEGpC,G,EAAK;AACL,aAAO,IAAImC,OAAJ,CAAY,UAASC,OAAT,EAAkBC,MAAlB,EAA0B;AACzC,YAAG,KAAKnD,OAAL,CAAaY,MAAb,CAAoB,UAACF,MAAD;AAAA,iBAAYA,MAAM,CAACI,GAAP,KAAeA,GAAf,IAAsBJ,MAAM,CAACQ,MAAP,KAAkB,IAApD;AAAA,SAApB,EAA8EiB,MAA9E,IAAwF,CAA3F,EAA8F;AAC1Fe,iBAAO;AACV,SAFD,MAGK;AACDC,gBAAM;AACT;AACJ,OAPM,CAAP;AAQH;;;4BAEO;AACJ,WAAI,IAAIrC,GAAR,IAAe,KAAKZ,cAApB,EAAoC;AAChC,aAAKA,cAAL,CAAoBY,GAApB,EAAyBL,OAAzB,CAAiC,UAAC4C,QAAD;AAAA,iBAAcA,QAAQ,EAAtB;AAAA,SAAjC;AACH;;AACD,WAAKnD,cAAL,GAAsB,EAAtB;AACH,K,CAED;;;;uBACGoD,I,EAAMD,Q,EAAU;AACf,UAAG,CAAC,KAAKpD,QAAL,CAAcqD,IAAd,CAAJ,EAAyB;AACrB,aAAKrD,QAAL,CAAcqD,IAAd,IAAsB,EAAtB;AACH;;AACD,WAAKrD,QAAL,CAAcqD,IAAd,EAAoBrC,IAApB,CAAyBoC,QAAzB;AACH;;;yBAEIC,I,EAAMjB,I,EAAM;AACb,UAAG,CAAC,KAAKpC,QAAL,CAAcqD,IAAd,CAAJ,EAAyB;AACzB,WAAKrD,QAAL,CAAcqD,IAAd,EAAoB7C,OAApB,CAA4B,UAACR,QAAD;AAAA,eAAcA,QAAQ,CAACoC,IAAD,CAAtB;AAAA,OAA5B;AACH;;;;;;AAMUxC,0EAAf,E","file":"loadmanager.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"loadmanager\"] = factory();\n\telse\n\t\troot[\"loadmanager\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/index.js\");\n","\r\nclass loadManager {\r\n constructor(options) {\r\n this.level = 0;\r\n\r\n this.scripts = [];\r\n\r\n this.listener = {};\r\n\r\n this.scriptListener = {};\r\n\r\n this.options = {\r\n ...{\r\n explicit: false,\r\n no_cookie: false\r\n }, \r\n ...options\r\n };\r\n\r\n this.on('complete', () => this.ready())\r\n }\r\n\r\n setScripts(scripts = null) {\r\n if(scripts && Array.isArray(scripts)) {\r\n scripts.forEach((script) => this.addScript(script))\r\n }\r\n }\r\n\r\n getScripts(level = -1) {\r\n if(level === -1) return this.scripts;\r\n if(level === 0) return [];\r\n return this.scripts.filter((script) => (script.level <= level && !script.onRequest));\r\n }\r\n\r\n addScript({key, path, level = 1, position = 'body', onRequest = false}) {\r\n this.scripts.push({\r\n key: key,\r\n path: path,\r\n level: level,\r\n position: position,\r\n onRequest: onRequest,\r\n loaded: false\r\n });\r\n }\r\n\r\n clearScripts() {\r\n this.scripts = [];\r\n }\r\n\r\n setLevel(level) {\r\n this.level = level;\r\n\r\n // set cookie\r\n let d = new Date;\r\n let days = 100;\r\n d.setTime(d.getTime() + 24*60*60*1000*days);\r\n document.cookie = \"_lm_level=\" + level + \";path=/;expires=\" + d.toGMTString();\r\n }\r\n\r\n getLevel() {\r\n // get from cookie\r\n let value = document.cookie.match('(^|;) ?_lm_level=([^;]*)(;|$)');\r\n let level = value ? value[2] : null;\r\n\r\n return parseInt(level || this.level);\r\n }\r\n \r\n // Load\r\n load(level = -1) {\r\n this.setLevel(level);\r\n\r\n if(level == 0) return;\r\n\r\n let scripts = this.getScripts(level);\r\n\r\n scripts.forEach((script) => this.addToDom(script));\r\n\r\n let counter = 0;\r\n let checkComplete = (script) => {\r\n if(script.onRequest) return;\r\n\r\n counter++;\r\n \r\n if(counter >= scripts.length) {\r\n this.emit('complete');\r\n }\r\n }\r\n this.on('loaded', (script) => checkComplete(script))\r\n this.on('error', (script) => checkComplete(script))\r\n }\r\n\r\n addToDom(data) {\r\n if(data.loaded) return;\r\n\r\n let script = document.createElement('script');\r\n script.src = data.path;\r\n script.setAttribute('id', data.key);\r\n if(script.onRequest) {\r\n script.setAttribute('data-onrequest', true);\r\n }\r\n script.onload = (event) => {\r\n data.loaded = true;\r\n this.scripts = this.scripts.map((s) => {\r\n if(s.key == data.key ) {\r\n s.loaded = true;\r\n }\r\n return s;\r\n });\r\n this.emit('loaded', data);\r\n \r\n };\r\n script.onerror = (event) => {\r\n data.loaded = false;\r\n this.scripts = this.scripts.map((s) => {\r\n if(s.key == data.key ) {\r\n s.loaded = false;\r\n }\r\n return s;\r\n });\r\n this.emit('error', data);\r\n };\r\n \r\n if(data.position == 'body') {\r\n document.body.appendChild(script); \r\n }\r\n else {\r\n document.head.appendChild(script);\r\n } \r\n }\r\n\r\n // SCRIPT LISTENERS\r\n whenever(key) {\r\n return new Promise((resolve, reject) => {\r\n let script = this.scripts.filter((script) => script.key == key)[0];\r\n if(script.loaded) {\r\n resolve()\r\n }\r\n else if(script.onRequest) {\r\n // onRequest\r\n // check if the script is allowed to be loaded\r\n if(script.onRequest) {\r\n let level = this.getLevel();\r\n if(level >= script.level) {\r\n this.addToDom(script);\r\n }\r\n this.on('loaded', (script) => {\r\n if(script.key == key) {\r\n resolve();\r\n }\r\n })\r\n }\r\n }\r\n else {\r\n this.scriptListener[key] = this.scriptListener[key] || [];\r\n this.scriptListener[key].push(resolve);\r\n }\r\n });\r\n }\r\n\r\n has(key) {\r\n return new Promise(function(resolve, reject) {\r\n if(this.scripts.filter((script) => script.key === key && script.loaded === true).length >= 1) {\r\n resolve();\r\n }\r\n else {\r\n reject();\r\n }\r\n });\r\n }\r\n\r\n ready() {\r\n for(let key in this.scriptListener) {\r\n this.scriptListener[key].forEach((callback) => callback());\r\n }\r\n this.scriptListener = {};\r\n }\r\n\r\n // EVENT HANDLING\r\n on(name, callback) {\r\n if(!this.listener[name]) {\r\n this.listener[name] = [];\r\n }\r\n this.listener[name].push(callback);\r\n }\r\n\r\n emit(name, data) {\r\n if(!this.listener[name]) return;\r\n this.listener[name].forEach((listener) => listener(data));\r\n }\r\n\r\n\r\n\r\n}\r\n\r\nexport default loadManager;"],"sourceRoot":""} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 1915486..a38f264 100644 --- a/src/index.js +++ b/src/index.js @@ -76,15 +76,17 @@ class loadManager { scripts.forEach((script) => this.addToDom(script)); let counter = 0; - let checkComplete = () => { + let checkComplete = (script) => { + if(script.onRequest) return; + counter++; if(counter >= scripts.length) { this.emit('complete'); } } - this.on('loaded', () => checkComplete()) - this.on('error', () => checkComplete()) + this.on('loaded', (script) => checkComplete(script)) + this.on('error', (script) => checkComplete(script)) } addToDom(data) { @@ -133,7 +135,7 @@ class loadManager { if(script.loaded) { resolve() } - else { + else if(script.onRequest) { // onRequest // check if the script is allowed to be loaded if(script.onRequest) { @@ -141,8 +143,14 @@ class loadManager { if(level >= script.level) { this.addToDom(script); } + this.on('loaded', (script) => { + if(script.key == key) { + resolve(); + } + }) } - + } + else { this.scriptListener[key] = this.scriptListener[key] || []; this.scriptListener[key].push(resolve); } @@ -164,6 +172,7 @@ class loadManager { for(let key in this.scriptListener) { this.scriptListener[key].forEach((callback) => callback()); } + this.scriptListener = {}; } // EVENT HANDLING diff --git a/test/loadTests.js b/test/loadTests.js index aa41893..8db6745 100644 --- a/test/loadTests.js +++ b/test/loadTests.js @@ -103,5 +103,23 @@ export default function (scripts) { manager.load(1); }); }); + + describe('#whenever (on request)', function() { + it('should load the script and execute afterwards without error', function(done) { + var manager = new loadManager; + + + scripts[0].onRequest = true; + + // set scripts + manager.setScripts(scripts); + + manager.whenever('cdn-jquery-1').then(() => { + done(); + }); + + manager.load(1); + }); + }); }); } \ No newline at end of file