Advertisement
Guest User

ocLazyLoad.compoxure.js

a guest
Jun 28th, 2015
375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * oclazyload - Load modules on demand (lazy load) with angularJS
  3.  * @version v1.0.1
  4.  * @link https://github.com/ocombe/ocLazyLoad
  5.  * @license MIT
  6.  * @author Olivier Combe <olivier.combe@gmail.com>
  7.  */
  8. (function (angular, window) {
  9.     "use strict";
  10.  
  11.     var regModules = ["ng", "oc.lazyLoad"],
  12.         regInvokes = {},
  13.         regConfigs = [],
  14.         modulesToLoad = [],
  15.         recordDeclarations = [],
  16.         broadcast = angular.noop,
  17.         runBlocks = {},
  18.         justLoaded = [];
  19.  
  20.     var ocLazyLoad = angular.module("oc.lazyLoad", ["ng"]);
  21.  
  22.     ocLazyLoad.provider("$ocLazyLoad", ["$controllerProvider", "$provide", "$compileProvider", "$filterProvider", "$injector", "$animateProvider", function ($controllerProvider, $provide, $compileProvider, $filterProvider, $injector, $animateProvider) {
  23.         var modules = {},
  24.             providers = {
  25.             $controllerProvider: $controllerProvider,
  26.             $compileProvider: $compileProvider,
  27.             $filterProvider: $filterProvider,
  28.             $provide: $provide, // other things (constant, decorator, provider, factory, service)
  29.             $injector: $injector,
  30.             $animateProvider: $animateProvider
  31.         },
  32.             debug = false,
  33.             events = false,
  34.             moduleCache = [];
  35.  
  36.         moduleCache.push = function (value) {
  37.             if (this.indexOf(value) === -1) {
  38.                 Array.prototype.push.apply(this, arguments);
  39.             }
  40.         };
  41.  
  42.         this.config = function (config) {
  43.             // If we want to define modules configs
  44.             if (angular.isDefined(config.modules)) {
  45.                 if (angular.isArray(config.modules)) {
  46.                     angular.forEach(config.modules, function (moduleConfig) {
  47.                         modules[moduleConfig.name] = moduleConfig;
  48.                     });
  49.                 } else {
  50.                     modules[config.modules.name] = config.modules;
  51.                 }
  52.             }
  53.  
  54.             if (angular.isDefined(config.debug)) {
  55.                 debug = config.debug;
  56.             }
  57.  
  58.             if (angular.isDefined(config.events)) {
  59.                 events = config.events;
  60.             }
  61.         };
  62.  
  63.         /**
  64.          * Get the list of existing registered modules
  65.          * @param element
  66.          */
  67.         this._init = function _init(element) {
  68.             // this is probably useless now because we override angular.bootstrap
  69.             if (modulesToLoad.length === 0) {
  70.                 var elements = [element],
  71.                     names = ["ng:app", "ng-app", "x-ng-app", "data-ng-app"],
  72.                     NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/,
  73.                     append = function append(elm) {
  74.                     return elm && elements.push(elm);
  75.                 };
  76.  
  77.                 angular.forEach(names, function (name) {
  78.                     names[name] = true;
  79.                     append(document.getElementById(name));
  80.                     name = name.replace(":", "\\:");
  81.                     if (element[0].querySelectorAll) {
  82.                         angular.forEach(element[0].querySelectorAll("." + name), append);
  83.                         angular.forEach(element[0].querySelectorAll("." + name + "\\:"), append);
  84.                         angular.forEach(element[0].querySelectorAll("[" + name + "]"), append);
  85.                     }
  86.                 });
  87.  
  88.                 angular.forEach(elements, function (elm) {
  89.                     if (modulesToLoad.length === 0) {
  90.                         var className = " " + element.className + " ";
  91.                         var match = NG_APP_CLASS_REGEXP.exec(className);
  92.                         if (match) {
  93.                             modulesToLoad.push((match[2] || "").replace(/\s+/g, ","));
  94.                         } else {
  95.                             angular.forEach(elm.attributes, function (attr) {
  96.                                 if (modulesToLoad.length === 0 && names[attr.name]) {
  97.                                     modulesToLoad.push(attr.value);
  98.                                 }
  99.                             });
  100.                         }
  101.                     }
  102.                 });
  103.             }
  104.  
  105.             if (modulesToLoad.length === 0 && !((window.jasmine || window.mocha) && angular.isDefined(angular.mock))) {
  106.                 console.error("No module found during bootstrap, unable to init ocLazyLoad. You should always use the ng-app directive or angular.boostrap when you use ocLazyLoad.");
  107.             }
  108.  
  109.             var addReg = function addReg(moduleName) {
  110.                 if (regModules.indexOf(moduleName) === -1) {
  111.                     // register existing modules
  112.                     regModules.push(moduleName);
  113.                     var mainModule = angular.module(moduleName);
  114.  
  115.                     // register existing components (directives, services, ...)
  116.                     _invokeQueue(null, mainModule._invokeQueue, moduleName);
  117.                     _invokeQueue(null, mainModule._configBlocks, moduleName); // angular 1.3+
  118.  
  119.                     angular.forEach(mainModule.requires, addReg);
  120.                 }
  121.             };
  122.  
  123.             angular.forEach(modulesToLoad, function (moduleName) {
  124.                 addReg(moduleName);
  125.             });
  126.  
  127.             modulesToLoad = []; // reset for next bootstrap
  128.             recordDeclarations.pop(); // wait for the next lazy load
  129.         };
  130.  
  131.         /**
  132.          * Like JSON.stringify but that doesn't throw on circular references
  133.          * @param obj
  134.          */
  135.         var stringify = function stringify(obj) {
  136.             var cache = [];
  137.             return JSON.stringify(obj, function (key, value) {
  138.                 if (angular.isObject(value) && value !== null) {
  139.                     if (cache.indexOf(value) !== -1) {
  140.                         // Circular reference found, discard key
  141.                         return;
  142.                     }
  143.                     // Store value in our collection
  144.                     cache.push(value);
  145.                 }
  146.                 return value;
  147.             });
  148.         };
  149.  
  150.         var hashCode = function hashCode(str) {
  151.             var hash = 0,
  152.                 i,
  153.                 chr,
  154.                 len;
  155.             if (str.length == 0) {
  156.                 return hash;
  157.             }
  158.             for (i = 0, len = str.length; i < len; i++) {
  159.                 chr = str.charCodeAt(i);
  160.                 hash = (hash << 5) - hash + chr;
  161.                 hash |= 0; // Convert to 32bit integer
  162.             }
  163.             return hash;
  164.         };
  165.  
  166.         function _register(providers, registerModules, params) {
  167.             if (registerModules) {
  168.                 var k,
  169.                     moduleName,
  170.                     moduleFn,
  171.                     tempRunBlocks = [];
  172.                 for (k = registerModules.length - 1; k >= 0; k--) {
  173.                     moduleName = registerModules[k];
  174.                     if (!angular.isString(moduleName)) {
  175.                         moduleName = getModuleName(moduleName);
  176.                     }
  177.                     if (!moduleName || justLoaded.indexOf(moduleName) !== -1) {
  178.                         continue;
  179.                     }
  180.                     var newModule = regModules.indexOf(moduleName) === -1;
  181.                     moduleFn = ngModuleFct(moduleName);
  182.                     if (newModule) {
  183.                         // new module
  184.                         regModules.push(moduleName);
  185.                         _register(providers, moduleFn.requires, params);
  186.                     }
  187.                     if (moduleFn._runBlocks.length > 0) {
  188.                         // new run blocks detected! Replace the old ones (if existing)
  189.                         runBlocks[moduleName] = [];
  190.                         while (moduleFn._runBlocks.length > 0) {
  191.                             runBlocks[moduleName].push(moduleFn._runBlocks.shift());
  192.                         }
  193.                     }
  194.                     if (angular.isDefined(runBlocks[moduleName]) && (newModule || params.rerun)) {
  195.                         tempRunBlocks = tempRunBlocks.concat(runBlocks[moduleName]);
  196.                     }
  197.                     _invokeQueue(providers, moduleFn._invokeQueue, moduleName, params.reconfig);
  198.                     _invokeQueue(providers, moduleFn._configBlocks, moduleName, params.reconfig); // angular 1.3+
  199.                     broadcast(newModule ? "ocLazyLoad.moduleLoaded" : "ocLazyLoad.moduleReloaded", moduleName);
  200.                     registerModules.pop();
  201.                     justLoaded.push(moduleName);
  202.                 }
  203.                 // execute the run blocks at the end
  204.                 var instanceInjector = providers.getInstanceInjector();
  205.                 angular.forEach(tempRunBlocks, function (fn) {
  206.                     instanceInjector.invoke(fn);
  207.                 });
  208.             }
  209.         }
  210.  
  211.         function _registerInvokeList(args, moduleName) {
  212.             var invokeList = args[2][0],
  213.                 type = args[1],
  214.                 newInvoke = false;
  215.             if (angular.isUndefined(regInvokes[moduleName])) {
  216.                 regInvokes[moduleName] = {};
  217.             }
  218.             if (angular.isUndefined(regInvokes[moduleName][type])) {
  219.                 regInvokes[moduleName][type] = {};
  220.             }
  221.             var onInvoke = function onInvoke(invokeName, signature) {
  222.                 if (!regInvokes[moduleName][type].hasOwnProperty(invokeName)) {
  223.                     regInvokes[moduleName][type][invokeName] = [];
  224.                 }
  225.                 if (regInvokes[moduleName][type][invokeName].indexOf(signature) === -1) {
  226.                     newInvoke = true;
  227.                     regInvokes[moduleName][type][invokeName].push(signature);
  228.                     broadcast("ocLazyLoad.componentLoaded", [moduleName, type, invokeName]);
  229.                 }
  230.             };
  231.  
  232.             function signature(data) {
  233.                 if (angular.isArray(data)) {
  234.                     // arrays are objects, we need to test for it first
  235.                     return hashCode(data.toString());
  236.                 } else if (angular.isObject(data)) {
  237.                     // constants & values for example
  238.                     return hashCode(stringify(data));
  239.                 } else {
  240.                     if (angular.isDefined(data) && data !== null) {
  241.                         return hashCode(data.toString());
  242.                     } else {
  243.                         // null & undefined constants
  244.                         return data;
  245.                     }
  246.                 }
  247.             }
  248.  
  249.             if (angular.isString(invokeList)) {
  250.                 onInvoke(invokeList, signature(args[2][1]));
  251.             } else if (angular.isObject(invokeList)) {
  252.                 angular.forEach(invokeList, function (invoke, key) {
  253.                     if (angular.isString(invoke)) {
  254.                         // decorators for example
  255.                         onInvoke(invoke, signature(invokeList[1]));
  256.                     } else {
  257.                         // components registered as object lists {"componentName": function() {}}
  258.                         onInvoke(key, signature(invoke));
  259.                     }
  260.                 });
  261.             } else {
  262.                 return false;
  263.             }
  264.             return newInvoke;
  265.         }
  266.  
  267.         function _invokeQueue(providers, queue, moduleName, reconfig) {
  268.             if (!queue) {
  269.                 return;
  270.             }
  271.  
  272.             var i, len, args, provider;
  273.             for (i = 0, len = queue.length; i < len; i++) {
  274.                 args = queue[i];
  275.                 if (angular.isArray(args)) {
  276.                     if (providers !== null) {
  277.                         if (providers.hasOwnProperty(args[0])) {
  278.                             provider = providers[args[0]];
  279.                         } else {
  280.                             throw new Error("unsupported provider " + args[0]);
  281.                         }
  282.                     }
  283.                     var isNew = _registerInvokeList(args, moduleName);
  284.                     if (args[1] !== "invoke") {
  285.                         if (isNew && angular.isDefined(provider)) {
  286.                             provider[args[1]].apply(provider, args[2]);
  287.                         }
  288.                     } else {
  289.                         // config block
  290.                         var callInvoke = function callInvoke(fct) {
  291.                             var invoked = regConfigs.indexOf("" + moduleName + "-" + fct);
  292.                             if (invoked === -1 || reconfig) {
  293.                                 if (invoked === -1) {
  294.                                     regConfigs.push("" + moduleName + "-" + fct);
  295.                                 }
  296.                                 if (angular.isDefined(provider)) {
  297.                                     provider[args[1]].apply(provider, args[2]);
  298.                                 }
  299.                             }
  300.                         };
  301.                         if (angular.isFunction(args[2][0])) {
  302.                             callInvoke(args[2][0]);
  303.                         } else if (angular.isArray(args[2][0])) {
  304.                             for (var j = 0, jlen = args[2][0].length; j < jlen; j++) {
  305.                                 if (angular.isFunction(args[2][0][j])) {
  306.                                     callInvoke(args[2][0][j]);
  307.                                 }
  308.                             }
  309.                         }
  310.                     }
  311.                 }
  312.             }
  313.         }
  314.  
  315.         function getModuleName(module) {
  316.             var moduleName = null;
  317.             if (angular.isString(module)) {
  318.                 moduleName = module;
  319.             } else if (angular.isObject(module) && module.hasOwnProperty("name") && angular.isString(module.name)) {
  320.                 moduleName = module.name;
  321.             }
  322.             return moduleName;
  323.         }
  324.  
  325.         function moduleExists(moduleName) {
  326.             if (!angular.isString(moduleName)) {
  327.                 return false;
  328.             }
  329.             try {
  330.                 return ngModuleFct(moduleName);
  331.             } catch (e) {
  332.                 if (/No module/.test(e) || e.message.indexOf("$injector:nomod") > -1) {
  333.                     return false;
  334.                 }
  335.             }
  336.         }
  337.  
  338.         this.$get = ["$log", "$rootElement", "$rootScope", "$cacheFactory", "$q", function ($log, $rootElement, $rootScope, $cacheFactory, $q) {
  339.             var instanceInjector,
  340.                 filesCache = $cacheFactory("ocLazyLoad");
  341.  
  342.             if (!debug) {
  343.                 $log = {};
  344.                 $log.error = angular.noop;
  345.                 $log.warn = angular.noop;
  346.                 $log.info = angular.noop;
  347.             }
  348.  
  349.             // Make this lazy because when $get() is called the instance injector hasn't been assigned to the rootElement yet
  350.             providers.getInstanceInjector = function () {
  351.                 return instanceInjector ? instanceInjector : instanceInjector = $rootElement.data("$injector") || angular.injector();
  352.             };
  353.  
  354.             broadcast = function broadcast(eventName, params) {
  355.                 if (events) {
  356.                     $rootScope.$broadcast(eventName, params);
  357.                 }
  358.                 if (debug) {
  359.                     $log.info(eventName, params);
  360.                 }
  361.             };
  362.  
  363.             function reject(e) {
  364.                 var deferred = $q.defer();
  365.                 $log.error(e.message);
  366.                 deferred.reject(e);
  367.                 return deferred.promise;
  368.             }
  369.  
  370.             return {
  371.                 _broadcast: broadcast,
  372.  
  373.                 _$log: $log,
  374.  
  375.                 /**
  376.                  * Returns the files cache used by the loaders to store the files currently loading
  377.                  * @returns {*}
  378.                  */
  379.                 _getFilesCache: function getFilesCache() {
  380.                     return filesCache;
  381.                 },
  382.  
  383.                 /**
  384.                  * Let the service know that it should monitor angular.module because files are loading
  385.                  * @param watch boolean
  386.                  */
  387.                 toggleWatch: function toggleWatch(watch) {
  388.                     if (watch) {
  389.                         recordDeclarations.push(true);
  390.                     } else {
  391.                         recordDeclarations.pop();
  392.                     }
  393.                 },
  394.  
  395.                 /**
  396.                  * Let you get a module config object
  397.                  * @param moduleName String the name of the module
  398.                  * @returns {*}
  399.                  */
  400.                 getModuleConfig: function getModuleConfig(moduleName) {
  401.                     if (!angular.isString(moduleName)) {
  402.                         throw new Error("You need to give the name of the module to get");
  403.                     }
  404.                     if (!modules[moduleName]) {
  405.                         return null;
  406.                     }
  407.                     return angular.copy(modules[moduleName]);
  408.                 },
  409.  
  410.                 /**
  411.                  * Let you define a module config object
  412.                  * @param moduleConfig Object the module config object
  413.                  * @returns {*}
  414.                  */
  415.                 setModuleConfig: function setModuleConfig(moduleConfig) {
  416.                     if (!angular.isObject(moduleConfig)) {
  417.                         throw new Error("You need to give the module config object to set");
  418.                     }
  419.                     modules[moduleConfig.name] = moduleConfig;
  420.                     return moduleConfig;
  421.                 },
  422.  
  423.                 /**
  424.                  * Returns the list of loaded modules
  425.                  * @returns {string[]}
  426.                  */
  427.                 getModules: function () {
  428.                     return regModules;
  429.                 },
  430.  
  431.                 /**
  432.                  * Let you check if a module has been loaded into Angular or not
  433.                  * @param modulesNames String/Object a module name, or a list of module names
  434.                  * @returns {boolean}
  435.                  */
  436.                 isLoaded: function isLoaded(modulesNames) {
  437.                     var moduleLoaded = function moduleLoaded(module) {
  438.                         var isLoaded = regModules.indexOf(module) > -1;
  439.                         if (!isLoaded) {
  440.                             isLoaded = !!moduleExists(module);
  441.                         }
  442.                         return isLoaded;
  443.                     };
  444.                     if (angular.isString(modulesNames)) {
  445.                         modulesNames = [modulesNames];
  446.                     }
  447.                     if (angular.isArray(modulesNames)) {
  448.                         var i, len;
  449.                         for (i = 0, len = modulesNames.length; i < len; i++) {
  450.                             if (!moduleLoaded(modulesNames[i])) {
  451.                                 return false;
  452.                             }
  453.                         }
  454.                         return true;
  455.                     } else {
  456.                         throw new Error("You need to define the module(s) name(s)");
  457.                     }
  458.                 },
  459.  
  460.                 /**
  461.                  * Given a module, return its name
  462.                  * @param module
  463.                  * @returns {String}
  464.                  */
  465.                 _getModuleName: getModuleName,
  466.  
  467.                 /**
  468.                  * Returns a module if it exists
  469.                  * @param moduleName
  470.                  * @returns {module}
  471.                  */
  472.                 _getModule: function getModule(moduleName) {
  473.                     try {
  474.                         return ngModuleFct(moduleName);
  475.                     } catch (e) {
  476.                         // this error message really suxx
  477.                         if (/No module/.test(e) || e.message.indexOf("$injector:nomod") > -1) {
  478.                             e.message = "The module \"" + stringify(moduleName) + "\" that you are trying to load does not exist. " + e.message;
  479.                         }
  480.                         throw e;
  481.                     }
  482.                 },
  483.  
  484.                 /**
  485.                  * Check if a module exists and returns it if it does
  486.                  * @param moduleName
  487.                  * @returns {boolean}
  488.                  */
  489.                 moduleExists: moduleExists,
  490.  
  491.                 /**
  492.                  * Load the dependencies, and might try to load new files depending on the config
  493.                  * @param moduleName (String or Array of Strings)
  494.                  * @param localParams
  495.                  * @returns {*}
  496.                  * @private
  497.                  */
  498.                 _loadDependencies: function _loadDependencies(moduleName, localParams) {
  499.                     var loadedModule,
  500.                         requires,
  501.                         diff,
  502.                         promisesList = [],
  503.                         self = this;
  504.  
  505.                     moduleName = self._getModuleName(moduleName);
  506.  
  507.                     if (moduleName === null) {
  508.                         return $q.when();
  509.                     } else {
  510.                         try {
  511.                             loadedModule = self._getModule(moduleName);
  512.                         } catch (e) {
  513.                             return reject(e);
  514.                         }
  515.                         // get unloaded requires
  516.                         requires = self.getRequires(loadedModule);
  517.                     }
  518.  
  519.                     angular.forEach(requires, function (requireEntry) {
  520.                         // If no configuration is provided, try and find one from a previous load.
  521.                         // If there isn't one, bail and let the normal flow run
  522.                         if (angular.isString(requireEntry)) {
  523.                             var config = self.getModuleConfig(requireEntry);
  524.                             if (config === null) {
  525.                                 moduleCache.push(requireEntry); // We don't know about this module, but something else might, so push it anyway.
  526.                                 return;
  527.                             }
  528.                             requireEntry = config;
  529.                         }
  530.  
  531.                         // Check if this dependency has been loaded previously
  532.                         if (self.moduleExists(requireEntry.name)) {
  533.                             // compare against the already loaded module to see if the new definition adds any new files
  534.                             diff = requireEntry.files.filter(function (n) {
  535.                                 return self.getModuleConfig(requireEntry.name).files.indexOf(n) < 0;
  536.                             });
  537.  
  538.                             // If the module was redefined, advise via the console
  539.                             if (diff.length !== 0) {
  540.                                 self._$log.warn("Module \"", moduleName, "\" attempted to redefine configuration for dependency. \"", requireEntry.name, "\"\n Additional Files Loaded:", diff);
  541.                             }
  542.  
  543.                             // Push everything to the file loader, it will weed out the duplicates.
  544.                             if (angular.isDefined(self.filesLoader)) {
  545.                                 // if a files loader is defined
  546.                                 promisesList.push(self.filesLoader(requireEntry, localParams).then(function () {
  547.                                     return self._loadDependencies(requireEntry);
  548.                                 }));
  549.                             } else {
  550.                                 return reject(new Error("Error: New dependencies need to be loaded from external files (" + requireEntry.files + "), but no loader has been defined."));
  551.                             }
  552.                             return;
  553.                         } else if (angular.isArray(requireEntry)) {
  554.                             requireEntry = {
  555.                                 files: requireEntry
  556.                             };
  557.                         } else if (angular.isObject(requireEntry)) {
  558.                             if (requireEntry.hasOwnProperty("name") && requireEntry.name) {
  559.                                 // The dependency doesn't exist in the module cache and is a new configuration, so store and push it.
  560.                                 self.setModuleConfig(requireEntry);
  561.                                 moduleCache.push(requireEntry.name);
  562.                             }
  563.                         }
  564.  
  565.                         // Check if the dependency has any files that need to be loaded. If there are, push a new promise to the promise list.
  566.                         if (angular.isDefined(requireEntry.files) && requireEntry.files.length !== 0) {
  567.                             if (angular.isDefined(self.filesLoader)) {
  568.                                 // if a files loader is defined
  569.                                 promisesList.push(self.filesLoader(requireEntry, localParams).then(function () {
  570.                                     return self._loadDependencies(requireEntry);
  571.                                 }));
  572.                             } else {
  573.                                 return reject(new Error("Error: the module \"" + requireEntry.name + "\" is defined in external files (" + requireEntry.files + "), but no loader has been defined."));
  574.                             }
  575.                         }
  576.                     });
  577.  
  578.                     // Create a wrapper promise to watch the promise list and resolve it once everything is done.
  579.                     return $q.all(promisesList);
  580.                 },
  581.  
  582.                 /**
  583.                  * Inject new modules into Angular
  584.                  * @param moduleName
  585.                  * @param localParams
  586.                  */
  587.                 inject: function inject(moduleName) {
  588.                     var localParams = arguments[1] === undefined ? {} : arguments[1];
  589.  
  590.                     var self = this,
  591.                         deferred = $q.defer();
  592.                     if (angular.isDefined(moduleName) && moduleName !== null) {
  593.                         if (angular.isArray(moduleName)) {
  594.                             var promisesList = [];
  595.                             angular.forEach(moduleName, function (module) {
  596.                                 promisesList.push(self.inject(module));
  597.                             });
  598.                             return $q.all(promisesList);
  599.                         } else {
  600.                             self._addToLoadList(self._getModuleName(moduleName), true);
  601.                         }
  602.                     }
  603.                     if (modulesToLoad.length > 0) {
  604.                         var res = modulesToLoad.slice(); // clean copy
  605.                         var loadNext = function loadNext(moduleName) {
  606.                             moduleCache.push(moduleName);
  607.                             self._loadDependencies(moduleName, localParams).then(function success() {
  608.                                 try {
  609.                                     justLoaded = [];
  610.                                     _register(providers, moduleCache, localParams);
  611.                                 } catch (e) {
  612.                                     self._$log.error(e.message);
  613.                                     deferred.reject(e);
  614.                                     return;
  615.                                 }
  616.  
  617.                                 if (modulesToLoad.length > 0) {
  618.                                     loadNext(modulesToLoad.shift()); // load the next in list
  619.                                 } else {
  620.                                     deferred.resolve(res); // everything has been loaded, resolve
  621.                                 }
  622.                             }, function error(err) {
  623.                                 deferred.reject(err);
  624.                             });
  625.                         };
  626.  
  627.                         // load the first in list
  628.                         loadNext(modulesToLoad.shift());
  629.                     } else {
  630.                         deferred.resolve();
  631.                     }
  632.                     return deferred.promise;
  633.                 },
  634.  
  635.                 /**
  636.                  * Get the list of required modules/services/... for this module
  637.                  * @param module
  638.                  * @returns {Array}
  639.                  */
  640.                 getRequires: function getRequires(module) {
  641.                     var requires = [];
  642.                     angular.forEach(module.requires, function (requireModule) {
  643.                         if (regModules.indexOf(requireModule) === -1) {
  644.                             requires.push(requireModule);
  645.                         }
  646.                     });
  647.                     return requires;
  648.                 },
  649.  
  650.                 /**
  651.                  * Invoke the new modules & component by their providers
  652.                  * @param providers
  653.                  * @param queue
  654.                  * @param moduleName
  655.                  * @param reconfig
  656.                  * @private
  657.                  */
  658.                 _invokeQueue: _invokeQueue,
  659.  
  660.                 /**
  661.                  * Check if a module has been invoked and registers it if not
  662.                  * @param args
  663.                  * @param moduleName
  664.                  * @returns {boolean} is new
  665.                  */
  666.                 _registerInvokeList: _registerInvokeList,
  667.  
  668.                 /**
  669.                  * Register a new module and loads it, executing the run/config blocks if needed
  670.                  * @param providers
  671.                  * @param registerModules
  672.                  * @param params
  673.                  * @private
  674.                  */
  675.                 _register: _register,
  676.  
  677.                 /**
  678.                  * Add a module name to the list of modules that will be loaded in the next inject
  679.                  * @param name
  680.                  * @param force
  681.                  * @private
  682.                  */
  683.                 _addToLoadList: _addToLoadList
  684.             };
  685.         }];
  686.  
  687.         // Let's get the list of loaded modules & components
  688.         this._init(angular.element(window.document));
  689.     }]);
  690.  
  691.     var bootstrapFct = angular.bootstrap;
  692.     angular.bootstrap = function (element, modules, config) {
  693.         // we use slice to make a clean copy
  694.         angular.forEach(modules.slice(), function (module) {
  695.             _addToLoadList(module, true);
  696.         });
  697.         return bootstrapFct(element, modules, config);
  698.     };
  699.  
  700.     var _addToLoadList = function _addToLoadList(name, force) {
  701.         if ((recordDeclarations.length > 0 || force) && angular.isString(name) && modulesToLoad.indexOf(name) === -1) {
  702.             modulesToLoad.push(name);
  703.         }
  704.     };
  705.  
  706.     var ngModuleFct = angular.module;
  707.     angular.module = function (name, requires, configFn) {
  708.         _addToLoadList(name);
  709.         return ngModuleFct(name, requires, configFn);
  710.     };
  711. })(angular, window);
  712. (function (angular) {
  713.     "use strict";
  714.  
  715.     angular.module("oc.lazyLoad").directive("ocLazyLoad", ["$ocLazyLoad", "$compile", "$animate", "$parse", function ($ocLazyLoad, $compile, $animate, $parse) {
  716.         return {
  717.             restrict: "A",
  718.             terminal: true,
  719.             priority: 1000,
  720.             compile: function compile(element, attrs) {
  721.                 // we store the content and remove it before compilation
  722.                 var content = element[0].innerHTML;
  723.                 element.html("");
  724.  
  725.                 return function ($scope, $element, $attr) {
  726.                     var model = $parse($attr.ocLazyLoad);
  727.                     $scope.$watch(function () {
  728.                         return model($scope) || $attr.ocLazyLoad; // it can be a module name (string), an object, an array, or a scope reference to any of this
  729.                     }, function (moduleName) {
  730.                         if (angular.isDefined(moduleName)) {
  731.                             $ocLazyLoad.load(moduleName).then(function () {
  732.                                 $animate.enter(content, $element);
  733.                                 var contents = element.contents();
  734.                                 angular.forEach(contents, function (content) {
  735.                                     if (content.nodeType !== 3) {
  736.                                         // 3 is a text node
  737.                                         $compile(content)($scope);
  738.                                     }
  739.                                 });
  740.                             });
  741.                         }
  742.                     }, true);
  743.                 };
  744.             }
  745.         };
  746.     }]);
  747. })(angular);
  748. (function (angular) {
  749.     "use strict";
  750.  
  751.     angular.module("oc.lazyLoad").config(["$provide", function ($provide) {
  752.         $provide.decorator("$ocLazyLoad", ["$delegate", "$q", "$window", "$interval", function ($delegate, $q, $window, $interval) {
  753.             var uaCssChecked = false,
  754.                 useCssLoadPatch = false,
  755.                 anchor = $window.document.getElementsByTagName("head")[0] || $window.document.getElementsByTagName("body")[0];
  756.  
  757.             /**
  758.              * Load a js/css file
  759.              * @param type
  760.              * @param path
  761.              * @param params
  762.              * @returns promise
  763.              */
  764.             $delegate.buildElement = function buildElement(type, path, params) {
  765.                 var deferred = $q.defer(),
  766.                     el,
  767.                     loaded,
  768.                     filesCache = $delegate._getFilesCache(),
  769.                     cacheBuster = function cacheBuster(url) {
  770.                     var dc = new Date().getTime();
  771.                     if (url.indexOf("?") >= 0) {
  772.                         if (url.substring(0, url.length - 1) === "&") {
  773.                             return "" + url + "_dc=" + dc;
  774.                         }
  775.                         return "" + url + "&_dc=" + dc;
  776.                     } else {
  777.                         return "" + url + "?_dc=" + dc;
  778.                     }
  779.                 };
  780.  
  781.                 // Store the promise early so the file load can be detected by other parallel lazy loads
  782.                 // (ie: multiple routes on one page) a 'true' value isn't sufficient
  783.                 // as it causes false positive load results.
  784.                 if (angular.isUndefined(filesCache.get(path))) {
  785.                     filesCache.put(path, deferred.promise);
  786.                 }
  787.  
  788.                 // Switch in case more content types are added later
  789.                 switch (type) {
  790.                     case "css":
  791.                         el = $window.document.createElement("link");
  792.                         el.type = "text/css";
  793.                         el.rel = "stylesheet";
  794.                         el.href = params.cache === false ? cacheBuster(path) : path;
  795.                         break;
  796.                     case "js":
  797.                         el = $window.document.createElement("script");
  798.                         el.src = params.cache === false ? cacheBuster(path) : path;
  799.                         break;
  800.                     default:
  801.                         filesCache.remove(path);
  802.                         deferred.reject(new Error("Requested type \"" + type + "\" is not known. Could not inject \"" + path + "\""));
  803.                         break;
  804.                 }
  805.                 el.onload = el.onreadystatechange = function (e) {
  806.                     if (el.readyState && !/^c|loade/.test(el.readyState) || loaded) return;
  807.                     el.onload = el.onreadystatechange = null;
  808.                     loaded = 1;
  809.                     $delegate._broadcast("ocLazyLoad.fileLoaded", path);
  810.                     deferred.resolve();
  811.                 };
  812.                 el.onerror = function () {
  813.                     filesCache.remove(path);
  814.                     deferred.reject(new Error("Unable to load " + path));
  815.                 };
  816.                 el.async = params.serie ? 0 : 1;
  817.  
  818.                 var insertBeforeElem = anchor.lastChild;
  819.                 if (params.insertBefore) {
  820.                     var element = angular.element(angular.isDefined(window.jQuery) ? params.insertBefore : document.querySelector(params.insertBefore));
  821.                     if (element && element.length > 0) {
  822.                         insertBeforeElem = element[0];
  823.                     }
  824.                 }
  825.                 insertBeforeElem.parentNode.insertBefore(el, insertBeforeElem);
  826.  
  827.                 /*
  828.                  The event load or readystatechange doesn't fire in:
  829.                  - iOS < 6       (default mobile browser)
  830.                  - Android < 4.4 (default mobile browser)
  831.                  - Safari < 6    (desktop browser)
  832.                  */
  833.                 if (type == "css") {
  834.                     if (!uaCssChecked) {
  835.                         var ua = $window.navigator.userAgent.toLowerCase();
  836.  
  837.                         // iOS < 6
  838.                         if (/iP(hone|od|ad)/.test($window.navigator.platform)) {
  839.                             var v = $window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/);
  840.                             var iOSVersion = parseFloat([parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)].join("."));
  841.                             useCssLoadPatch = iOSVersion < 6;
  842.                         } else if (ua.indexOf("android") > -1) {
  843.                             // Android < 4.4
  844.                             var androidVersion = parseFloat(ua.slice(ua.indexOf("android") + 8));
  845.                             useCssLoadPatch = androidVersion < 4.4;
  846.                         } else if (ua.indexOf("safari") > -1) {
  847.                             var versionMatch = ua.match(/version\/([\.\d]+)/i);
  848.                             useCssLoadPatch = versionMatch && versionMatch[1] && parseFloat(versionMatch[1]) < 6;
  849.                         }
  850.                     }
  851.  
  852.                     if (useCssLoadPatch) {
  853.                         var tries = 1000; // * 20 = 20000 miliseconds
  854.                         var interval = $interval(function () {
  855.                             try {
  856.                                 el.sheet.cssRules;
  857.                                 $interval.cancel(interval);
  858.                                 el.onload();
  859.                             } catch (e) {
  860.                                 if (--tries <= 0)="" {="" el.onerror();="" }="" },="" 20);="" return="" deferred.promise;="" };="" $delegate;="" }]);="" })(angular);="" (function="" (angular)="" "use="" strict";="" angular.module("oc.lazyload").config(["$provide",="" function="" ($provide)="" $provide.decorator("$oclazyload",="" ["$delegate",="" "$q",="" ($delegate,="" $q)="" **="" *="" the="" that="" loads="" new="" files="" @param="" config="" params="" @returns="" {*}="" $delegate.filesloader="function" filesloader(config)="" var="" =="=" undefined="" ?="" {}="" :="" arguments[1];="" cssfiles="[]," templatesfiles="[]," jsfiles="[]," promises="[]," cachepromise="null," filescache="$delegate._getFilesCache();" $delegate.togglewatch(true);="" start="" watching="" angular.module="" calls="" angular.extend(params,="" config);="" pushfile="function" pushfile(path)="" file_type="null," m;="" if="" (angular.isobject(path))="" path="path.path;" (angular.isundefined(cachepromise)="" ||="" params.cache="==" false)="" always="" check="" for="" requirejs="" syntax="" just="" in="" case="" ((m="/^(css|less|html|htm|js)?(?=!)/.exec(path))" !="=" null)="" detect="" file="" type="" using="" preceding="" declaration="" (ala="" requirejs)="" +="" 1,="" path.length);="" strip="" from="" (!file_type)="" via="" extension="" else="" (!$delegate.jsloader.hasownproperty("oclazyloadloader")="" &&="" $delegate.jsloader.hasownproperty("load"))="" ;="" $delegate._$log.error("file="" could="" not="" be="" determined.="" "="" path);="" return;="" ((file_type="==" "css"="" "less")="" cssfiles.indexof(path)="==" -1)="" cssfiles.push(path);="" "html"="" "htm")="" templatesfiles.indexof(path)="==" templatesfiles.push(path);="" (file_type="==" "js"="" jsfiles.indexof(path)="==" jsfiles.push(path);="" is="" valid.="" (cachepromise)="" promises.push(cachepromise);="" (params.serie)="" pushfile(params.files.shift());="" angular.foreach(params.files,="" (path)="" pushfile(path);="" });="" (cssfiles.length=""> 0) {
  861.                     var cssDeferred = $q.defer();
  862.                     $delegate.cssLoader(cssFiles, function (err) {
  863.                         if (angular.isDefined(err) && $delegate.cssLoader.hasOwnProperty("ocLazyLoadLoader")) {
  864.                             $delegate._$log.error(err);
  865.                             cssDeferred.reject(err);
  866.                         } else {
  867.                             cssDeferred.resolve();
  868.                         }
  869.                     }, params);
  870.                     promises.push(cssDeferred.promise);
  871.                 }
  872.  
  873.                 if (templatesFiles.length > 0) {
  874.                     var templatesDeferred = $q.defer();
  875.                     $delegate.templatesLoader(templatesFiles, function (err) {
  876.                         if (angular.isDefined(err) && $delegate.templatesLoader.hasOwnProperty("ocLazyLoadLoader")) {
  877.                             $delegate._$log.error(err);
  878.                             templatesDeferred.reject(err);
  879.                         } else {
  880.                             templatesDeferred.resolve();
  881.                         }
  882.                     }, params);
  883.                     promises.push(templatesDeferred.promise);
  884.                 }
  885.  
  886.                 if (jsFiles.length > 0) {
  887.                     var jsDeferred = $q.defer();
  888.                     $delegate.jsLoader(jsFiles, function (err) {
  889.                         if (angular.isDefined(err) && $delegate.jsLoader.hasOwnProperty("ocLazyLoadLoader")) {
  890.                             $delegate._$log.error(err);
  891.                             jsDeferred.reject(err);
  892.                         } else {
  893.                             jsDeferred.resolve();
  894.                         }
  895.                     }, params);
  896.                     promises.push(jsDeferred.promise);
  897.                 }
  898.  
  899.                 if (promises.length === 0) {
  900.                     var deferred = $q.defer(),
  901.                         err = "Error: no file to load has been found, if you're trying to load an existing module you should use the 'inject' method instead of 'load'.";
  902.                     $delegate._$log.error(err);
  903.                     deferred.reject(err);
  904.                     return deferred.promise;
  905.                 } else if (params.serie && params.files.length > 0) {
  906.                     return $q.all(promises).then(function () {
  907.                         return $delegate.filesLoader(config, params);
  908.                     });
  909.                 } else {
  910.                     return $q.all(promises)["finally"](function (res) {
  911.                         $delegate.toggleWatch(false); // stop watching angular.module calls
  912.                         return res;
  913.                     });
  914.                 }
  915.             };
  916.  
  917.             /**
  918.              * Load a module or a list of modules into Angular
  919.              * @param module Mixed the name of a predefined module config object, or a module config object, or an array of either
  920.              * @param params Object optional parameters
  921.              * @returns promise
  922.              */
  923.             $delegate.load = function (originalModule) {
  924.                 var originalParams = arguments[1] === undefined ? {} : arguments[1];
  925.  
  926.                 var self = this,
  927.                     config = null,
  928.                     deferredList = [],
  929.                     deferred = $q.defer(),
  930.                     errText;
  931.  
  932.                 // clean copy
  933.                 var module = angular.copy(originalModule);
  934.                 var params = angular.copy(originalParams);
  935.  
  936.                 // If module is an array, break it down
  937.                 if (angular.isArray(module)) {
  938.                     // Resubmit each entry as a single module
  939.                     angular.forEach(module, function (m) {
  940.                         deferredList.push(self.load(m, params));
  941.                     });
  942.  
  943.                     // Resolve the promise once everything has loaded
  944.                     $q.all(deferredList).then(function (res) {
  945.                         deferred.resolve(res);
  946.                     }, function (err) {
  947.                         deferred.reject(err);
  948.                     });
  949.  
  950.                     return deferred.promise;
  951.                 }
  952.  
  953.                 // Get or Set a configuration depending on what was passed in
  954.                 if (angular.isString(module)) {
  955.                     config = self.getModuleConfig(module);
  956.                     if (!config) {
  957.                         config = {
  958.                             files: [module]
  959.                         };
  960.                     }
  961.                 } else if (angular.isObject(module)) {
  962.                     // case {type: 'js', path: lazyLoadUrl + 'testModule.fakejs'}
  963.                     if (angular.isDefined(module.path) && angular.isDefined(module.type)) {
  964.                         config = {
  965.                             files: [module]
  966.                         };
  967.                     } else {
  968.                         config = self.setModuleConfig(module);
  969.                     }
  970.                 }
  971.  
  972.                 if (config === null) {
  973.                     var moduleName = self._getModuleName(module);
  974.                     errText = "Module \"" + (moduleName || "unknown") + "\" is not configured, cannot load.";
  975.                     $delegate._$log.error(errText);
  976.                     deferred.reject(new Error(errText));
  977.                     return deferred.promise;
  978.                 } else {
  979.                     // deprecated
  980.                     if (angular.isDefined(config.template)) {
  981.                         if (angular.isUndefined(config.files)) {
  982.                             config.files = [];
  983.                         }
  984.                         if (angular.isString(config.template)) {
  985.                             config.files.push(config.template);
  986.                         } else if (angular.isArray(config.template)) {
  987.                             config.files.concat(config.template);
  988.                         }
  989.                     }
  990.                 }
  991.  
  992.                 var localParams = angular.extend({}, params, config);
  993.  
  994.                 // if someone used an external loader and called the load function with just the module name
  995.                 if (angular.isUndefined(config.files) && angular.isDefined(config.name) && $delegate.moduleExists(config.name)) {
  996.                     return $delegate.inject(config.name, localParams);
  997.                 }
  998.  
  999.                 $delegate.filesLoader(config, localParams).then(function () {
  1000.                     $delegate.inject(null, localParams).then(function (res) {
  1001.                         deferred.resolve(res);
  1002.                     }, function (err) {
  1003.                         deferred.reject(err);
  1004.                     });
  1005.                 }, function (err) {
  1006.                     deferred.reject(err);
  1007.                 });
  1008.  
  1009.                 return deferred.promise;
  1010.             };
  1011.  
  1012.             // return the patched service
  1013.             return $delegate;
  1014.         }]);
  1015.     }]);
  1016. })(angular);
  1017. (function (angular) {
  1018.     "use strict";
  1019.  
  1020.     angular.module("oc.lazyLoad").config(["$provide", function ($provide) {
  1021.         $provide.decorator("$ocLazyLoad", ["$delegate", "$q", function ($delegate, $q) {
  1022.             /**
  1023.              * cssLoader function
  1024.              * @type Function
  1025.              * @param paths array list of css files to load
  1026.              * @param callback to call when everything is loaded. We use a callback and not a promise
  1027.              * @param params object config parameters
  1028.              * because the user can overwrite cssLoader and it will probably not use promises :(
  1029.              */
  1030.             $delegate.cssLoader = function (paths, callback, params) {
  1031.                 var promises = [];
  1032.                 angular.forEach(paths, function (path) {
  1033.                     promises.push($delegate.buildElement("css", path, params));
  1034.                 });
  1035.                 $q.all(promises).then(function () {
  1036.                     callback();
  1037.                 }, function (err) {
  1038.                     callback(err);
  1039.                 });
  1040.             };
  1041.             $delegate.cssLoader.ocLazyLoadLoader = true;
  1042.  
  1043.             return $delegate;
  1044.         }]);
  1045.     }]);
  1046. })(angular);
  1047. (function (angular) {
  1048.     "use strict";
  1049.  
  1050.     angular.module("oc.lazyLoad").config(["$provide", function ($provide) {
  1051.         $provide.decorator("$ocLazyLoad", ["$delegate", "$q", function ($delegate, $q) {
  1052.             /**
  1053.              * jsLoader function
  1054.              * @type Function
  1055.              * @param paths array list of js files to load
  1056.              * @param callback to call when everything is loaded. We use a callback and not a promise
  1057.              * @param params object config parameters
  1058.              * because the user can overwrite jsLoader and it will probably not use promises :(
  1059.              */
  1060.             $delegate.jsLoader = function (paths, callback, params) {
  1061.                 var promises = [];
  1062.                 angular.forEach(paths, function (path) {
  1063.                     promises.push($delegate.buildElement("js", path, params));
  1064.                 });
  1065.                 $q.all(promises).then(function () {
  1066.                     callback();
  1067.                 }, function (err) {
  1068.                     callback(err);
  1069.                 });
  1070.             };
  1071.             $delegate.jsLoader.ocLazyLoadLoader = true;
  1072.  
  1073.             return $delegate;
  1074.         }]);
  1075.     }]);
  1076. })(angular);
  1077. (function (angular) {
  1078.     "use strict";
  1079.  
  1080.     angular.module("oc.lazyLoad").config(["$provide", function ($provide) {
  1081.         $provide.decorator("$ocLazyLoad", ["$delegate", "$templateCache", "$q", "$http", function ($delegate, $templateCache, $q, $http) {
  1082.             /**
  1083.              * templatesLoader function
  1084.              * @type Function
  1085.              * @param paths array list of css files to load
  1086.              * @param callback to call when everything is loaded. We use a callback and not a promise
  1087.              * @param params object config parameters for $http
  1088.              * because the user can overwrite templatesLoader and it will probably not use promises :(
  1089.              */
  1090.             $delegate.templatesLoader = function (paths, callback, params) {
  1091.                 var promises = [],
  1092.                     filesCache = $delegate._getFilesCache();
  1093.  
  1094.                 angular.forEach(paths, function (url) {
  1095.                     var deferred = $q.defer();
  1096.                     promises.push(deferred.promise);
  1097.                     $http.get(url, params).success(function (data) {
  1098.                         if (angular.isString(data) && data.length > 0) {
  1099.                             angular.forEach(angular.element(data), function (node) {
  1100.                                 if (node.nodeName === "SCRIPT" && node.type === "text/ng-template") {
  1101.                                     $templateCache.put(node.id, node.innerHTML);
  1102.                                 }
  1103.                             });
  1104.                         }
  1105.                         if (angular.isUndefined(filesCache.get(url))) {
  1106.                             filesCache.put(url, true);
  1107.                         }
  1108.                         deferred.resolve();
  1109.                     }).error(function (err) {
  1110.                         deferred.reject(new Error("Unable to load template file \"" + url + "\": " + err));
  1111.                     });
  1112.                 });
  1113.                 return $q.all(promises).then(function () {
  1114.                     callback();
  1115.                 }, function (err) {
  1116.                     callback(err);
  1117.                 });
  1118.             };
  1119.             $delegate.templatesLoader.ocLazyLoadLoader = true;
  1120.  
  1121.             return $delegate;
  1122.         }]);
  1123.     }]);
  1124. })(angular);
  1125. // Array.indexOf polyfill for IE8
  1126. if (!Array.prototype.indexOf) {
  1127.         Array.prototype.indexOf = function (searchElement, fromIndex) {
  1128.                 var k;
  1129.  
  1130.                 // 1. Let O be the result of calling ToObject passing
  1131.                 //    the this value as the argument.
  1132.                 if (this == null) {
  1133.                         throw new TypeError("\"this\" is null or not defined");
  1134.                 }
  1135.  
  1136.                 var O = Object(this);
  1137.  
  1138.                 // 2. Let lenValue be the result of calling the Get
  1139.                 //    internal method of O with the argument "length".
  1140.                 // 3. Let len be ToUint32(lenValue).
  1141.                 var len = O.length >>> 0;
  1142.  
  1143.                 // 4. If len is 0, return -1.
  1144.                 if (len === 0) {
  1145.                         return -1;
  1146.                 }
  1147.  
  1148.                 // 5. If argument fromIndex was passed let n be
  1149.                 //    ToInteger(fromIndex); else let n be 0.
  1150.                 var n = +fromIndex || 0;
  1151.  
  1152.                 if (Math.abs(n) === Infinity) {
  1153.                         n = 0;
  1154.                 }
  1155.  
  1156.                 // 6. If n >= len, return -1.
  1157.                 if (n >= len) {
  1158.                         return -1;
  1159.                 }
  1160.  
  1161.                 // 7. If n >= 0, then Let k be n.
  1162.                 // 8. Else, n<0, let="" k="" be="" len="" -="" abs(n).="" if="" is="" less="" than="" 0,="" then="" 0.="">= 0 ? n : len - Math.abs(n), 0);
  1163.  
  1164.                 // 9. Repeat, while k < len
  1165.                 while (k < len) {
  1166.                         // a. Let Pk be ToString(k).
  1167.                         //   This is implicit for LHS operands of the in operator
  1168.                         // b. Let kPresent be the result of calling the
  1169.                         //    HasProperty internal method of O with argument Pk.
  1170.                         //   This step can be combined with c
  1171.                         // c. If kPresent is true, then
  1172.                         //    i.  Let elementK be the result of calling the Get
  1173.                         //        internal method of O with the argument ToString(k).
  1174.                         //   ii.  Let same be the result of applying the
  1175.                         //        Strict Equality Comparison Algorithm to
  1176.                         //        searchElement and elementK.
  1177.                         //  iii.  If same is true, return k.
  1178.                         if (k in O && O[k] === searchElement) {
  1179.                                 return k;
  1180.                         }
  1181.                         k++;
  1182.                 }
  1183.                 return -1;
  1184.         };
  1185. }
  1186. //# sourceMappingURL=ocLazyLoad.js.map</0,></=></olivier.combe@gmail.com>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement