diff --git a/README.md b/README.md
index df5e0db..6bf4f7b 100644
--- a/README.md
+++ b/README.md
@@ -21,9 +21,6 @@ Load modules on demand (lazy load) in AngularJS
With $ocLazyLoad you can load angular modules, but if you want to load controllers / services / filters / ... without defining a new module it's entirely possible, just use the name an existing module (your app name for example).
There are multiple ways to use `$ocLazyLoad` to load your files, just choose the one that fits you the best.
-###### Using requireJS:
-If you decide to use ocLazyLoad with requireJS, you must declare the bootstraped module in the configuration of the provider. More info [here](#loaded-modules)
-
###### More examples / tutorials / articles
You can find three basic examples in the example folder. If you need more, check out these links:
- Lazy loading with requirejs, ocLazyLoad and ui-router: [using the templateProvider](http://plnkr.co/edit/OGvi01?p=preview) / [using the uiRouterDecorator](http://plnkr.co/edit/6CLDsz?p=preview) - by @gilbox
@@ -288,16 +285,6 @@ The options are:
});
```
-- `loadedModules`: If you use angular.bootstrap(...) to launch your application, you need to define the main app module as a loaded module.
- ```js
- angular.bootstrap(document.body, ['test']);
- ```
- ```js
- $ocLazyLoadProvider.config({
- loadedModules: ['test']
- });
- ```
-
- `modules`: predefine the configuration of your modules for a later use
```js
$ocLazyLoadProvider.config({
diff --git a/dist/ocLazyLoad.js b/dist/ocLazyLoad.js
index cd67bae..b68a9fd 100644
--- a/dist/ocLazyLoad.js
+++ b/dist/ocLazyLoad.js
@@ -8,6 +8,7 @@
(function() {
'use strict';
var regModules = ['ng'],
+ initModules = [],
regInvokes = {},
regConfigs = [],
justLoaded = [],
@@ -625,17 +626,6 @@
templatesLoader = config.templatesLoader;
}
- // for bootstrap apps, we need to define the main module name
- if(angular.isDefined(config.loadedModules)) {
- var addRegModule = function(loadedModule) {
- if(regModules.indexOf(loadedModule) < 0) {
- regModules.push(loadedModule);
- angular.forEach(angular.module(loadedModule).requires, addRegModule);
- }
- };
- angular.forEach(config.loadedModules, addRegModule);
- }
-
// If we want to define modules configs
if(angular.isDefined(config.modules)) {
if(angular.isArray(config.modules)) {
@@ -870,63 +860,70 @@
* @param element
*/
function init(element) {
- var elements = [element],
- appElement,
- moduleName,
- names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
- NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
-
- function append(elm) {
- return (elm && elements.push(elm));
- }
+ if(initModules.length === 0) {
+ var elements = [element],
+ names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
+ NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/,
+ append = function append(elm) {
+ return (elm && elements.push(elm));
+ };
- angular.forEach(names, function(name) {
- names[name] = true;
- append(document.getElementById(name));
- name = name.replace(':', '\\:');
- if(element[0].querySelectorAll) {
- angular.forEach(element[0].querySelectorAll('.' + name), append);
- angular.forEach(element[0].querySelectorAll('.' + name + '\\:'), append);
- angular.forEach(element[0].querySelectorAll('[' + name + ']'), append);
- }
- });
+ angular.forEach(names, function(name) {
+ names[name] = true;
+ append(document.getElementById(name));
+ name = name.replace(':', '\\:');
+ if(element[0].querySelectorAll) {
+ angular.forEach(element[0].querySelectorAll('.' + name), append);
+ angular.forEach(element[0].querySelectorAll('.' + name + '\\:'), append);
+ angular.forEach(element[0].querySelectorAll('[' + name + ']'), append);
+ }
+ });
- //TODO: search the script tags for angular.bootstrap
- angular.forEach(elements, function(elm) {
- if(!appElement) {
- var className = ' ' + element.className + ' ';
- var match = NG_APP_CLASS_REGEXP.exec(className);
- if(match) {
- appElement = elm;
- moduleName = (match[2] || '').replace(/\s+/g, ',');
- } else {
- angular.forEach(elm.attributes, function(attr) {
- if(!appElement && names[attr.name]) {
- appElement = elm;
- moduleName = attr.value;
- }
- });
+ angular.forEach(elements, function(elm) {
+ if(initModules.length === 0) {
+ var className = ' ' + element.className + ' ';
+ var match = NG_APP_CLASS_REGEXP.exec(className);
+ if(match) {
+ initModules.push((match[2] || '').replace(/\s+/g, ','));
+ } else {
+ angular.forEach(elm.attributes, function(attr) {
+ if(initModules.length === 0 && names[attr.name]) {
+ initModules.push(attr.value);
+ }
+ });
+ }
}
- }
- });
+ });
+ }
+ if(initModules.length === 0) {
+ throw 'No module found during bootstrap, unable to init ocLazyLoad';
+ }
- if(appElement) {
- (function addReg(moduleName) {
- if(regModules.indexOf(moduleName) === -1) {
- // register existing modules
- regModules.push(moduleName);
- var mainModule = angular.module(moduleName);
+ var addReg = function addReg(moduleName) {
+ if(regModules.indexOf(moduleName) === -1) {
+ // register existing modules
+ regModules.push(moduleName);
+ var mainModule = angular.module(moduleName);
- // register existing components (directives, services, ...)
- invokeQueue(null, mainModule._invokeQueue, moduleName);
- invokeQueue(null, mainModule._configBlocks, moduleName); // angular 1.3+
+ // register existing components (directives, services, ...)
+ invokeQueue(null, mainModule._invokeQueue, moduleName);
+ invokeQueue(null, mainModule._configBlocks, moduleName); // angular 1.3+
- angular.forEach(mainModule.requires, addReg);
- }
- })(moduleName);
- }
+ angular.forEach(mainModule.requires, addReg);
+ }
+ };
+
+ angular.forEach(initModules, function(moduleName) {
+ addReg(moduleName);
+ });
}
+ var bootstrap = angular.bootstrap;
+ angular.bootstrap = function(element, modules, config) {
+ initModules = modules.slice(); // make a clean copy
+ return bootstrap(element, modules, config);
+ };
+
// Array.indexOf polyfill for IE8
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
diff --git a/dist/ocLazyLoad.min.js b/dist/ocLazyLoad.min.js
index e612ddd..1fc197c 100644
--- a/dist/ocLazyLoad.min.js
+++ b/dist/ocLazyLoad.min.js
@@ -5,4 +5,4 @@
* @license MIT
* @author Olivier Combe
*/
-!function(){"use strict";function e(e){var n=[];return angular.forEach(e.requires,function(e){-1===l.indexOf(e)&&n.push(e)}),n}function n(e){try{return angular.module(e)}catch(n){if(/No module/.test(n)||n.message.indexOf("$injector:nomod")>-1)return!1}}function r(e){try{return angular.module(e)}catch(n){throw(/No module/.test(n)||n.message.indexOf("$injector:nomod")>-1)&&(n.message='The module "'+e+'" that you are trying to load does not exist. '+n.message),n}}function a(e,n,r,a){if(n){var o,i,u,l;for(o=0,i=n.length;i>o;o++)if(u=n[o],angular.isArray(u)){if(null!==e){if(!e.hasOwnProperty(u[0]))throw new Error("unsupported provider "+u[0]);l=e[u[0]]}var s=t(u,r);if("invoke"!==u[1])s&&angular.isDefined(l)&&l[u[1]].apply(l,u[2]);else{var c=function(e){var n=f.indexOf(r+"-"+e);(-1===n||a)&&(-1===n&&f.push(r+"-"+e),angular.isDefined(l)&&l[u[1]].apply(l,u[2]))};if(angular.isFunction(u[2][0]))c(u[2][0]);else if(angular.isArray(u[2][0]))for(var d=0,g=u[2][0].length;g>d;d++)angular.isFunction(u[2][0][d])&&c(u[2][0][d])}}}}function o(e,n,r){if(n){var t,u,s,f=[];for(t=n.length-1;t>=0;t--)if(u=n[t],"string"!=typeof u&&(u=i(u)),u&&-1===c.indexOf(u)){var g=-1===l.indexOf(u);if(s=angular.module(u),g&&(l.push(u),o(e,s.requires,r)),s._runBlocks.length>0)for(d[u]=[];s._runBlocks.length>0;)d[u].push(s._runBlocks.shift());angular.isDefined(d[u])&&(g||r.rerun)&&(f=f.concat(d[u])),a(e,s._invokeQueue,u,r.reconfig),a(e,s._configBlocks,u,r.reconfig),h(g?"ocLazyLoad.moduleLoaded":"ocLazyLoad.moduleReloaded",u),n.pop(),c.push(u)}var p=e.getInstanceInjector();angular.forEach(f,function(e){p.invoke(e)})}}function t(e,n){var r=e[2][0],a=e[1],o=!1;angular.isUndefined(s[n])&&(s[n]={}),angular.isUndefined(s[n][a])&&(s[n][a]=[]);var t=function(e){o=!0,s[n][a].push(e),h("ocLazyLoad.componentLoaded",[n,a,e])};if(angular.isString(r)&&-1===s[n][a].indexOf(r))t(r);else{if(!angular.isObject(r))return!1;angular.forEach(r,function(e){angular.isString(e)&&-1===s[n][a].indexOf(e)&&t(e)})}return o}function i(e){var n=null;return angular.isString(e)?n=e:angular.isObject(e)&&e.hasOwnProperty("name")&&angular.isString(e.name)&&(n=e.name),n}function u(e){function n(e){return e&&t.push(e)}var r,o,t=[e],i=["ng:app","ng-app","x-ng-app","data-ng-app"],u=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;angular.forEach(i,function(r){i[r]=!0,n(document.getElementById(r)),r=r.replace(":","\\:"),e[0].querySelectorAll&&(angular.forEach(e[0].querySelectorAll("."+r),n),angular.forEach(e[0].querySelectorAll("."+r+"\\:"),n),angular.forEach(e[0].querySelectorAll("["+r+"]"),n))}),angular.forEach(t,function(n){if(!r){var a=" "+e.className+" ",t=u.exec(a);t?(r=n,o=(t[2]||"").replace(/\s+/g,",")):angular.forEach(n.attributes,function(e){!r&&i[e.name]&&(r=n,o=e.value)})}}),r&&!function s(e){if(-1===l.indexOf(e)){l.push(e);var n=angular.module(e);a(null,n._invokeQueue,e),a(null,n._configBlocks,e),angular.forEach(n.requires,s)}}(o)}var l=["ng"],s={},f=[],c=[],d={},g=angular.module("oc.lazyLoad",["ng"]),h=angular.noop;g.provider("$ocLazyLoad",["$controllerProvider","$provide","$compileProvider","$filterProvider","$injector","$animateProvider",function(a,t,s,f,d,g){var p,m,v,y={},L={$controllerProvider:a,$compileProvider:s,$filterProvider:f,$provide:t,$injector:d,$animateProvider:g},w=document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0],O=!1,E=!1;u(angular.element(window.document)),this.$get=["$log","$q","$templateCache","$http","$rootElement","$rootScope","$cacheFactory","$interval",function(a,t,u,s,f,d,g,j){var $,x=g("ocLazyLoad"),b=!1,D=!1;O||(a={},a.error=angular.noop,a.warn=angular.noop,a.info=angular.noop),L.getInstanceInjector=function(){return $?$:$=f.data("$injector")||angular.injector()},h=function(e,n){E&&d.$broadcast(e,n),O&&a.info(e,n)};var P=function(e,n,r){var a,o,i=t.defer(),u=function(e){var n=(new Date).getTime();return e.indexOf("?")>=0?"&"===e.substring(0,e.length-1)?e+"_dc="+n:e+"&_dc="+n:e+"?_dc="+n};switch(angular.isUndefined(x.get(n))&&x.put(n,i.promise),e){case"css":a=document.createElement("link"),a.type="text/css",a.rel="stylesheet",a.href=r.cache===!1?u(n):n;break;case"js":a=document.createElement("script"),a.src=r.cache===!1?u(n):n;break;default:i.reject(new Error('Requested type "'+e+'" is not known. Could not inject "'+n+'"'))}a.onload=a.onreadystatechange=function(){a.readyState&&!/^c|loade/.test(a.readyState)||o||(a.onload=a.onreadystatechange=null,o=1,h("ocLazyLoad.fileLoaded",n),i.resolve())},a.onerror=function(){i.reject(new Error("Unable to load "+n))},a.async=r.serie?0:1;var l=w.lastChild;if(r.insertBefore){var s=angular.element(r.insertBefore);s&&s.length>0&&(l=s[0])}if(w.insertBefore(a,l),"css"==e){if(!b){var f=navigator.userAgent.toLowerCase();if(/iP(hone|od|ad)/.test(navigator.platform)){var c=navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),d=parseFloat([parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3]||0,10)].join("."));D=6>d}else if(f.indexOf("android")>-1){var g=parseFloat(f.slice(f.indexOf("android")+8));D=4.4>g}else if(f.indexOf("safari")>-1&&-1==f.indexOf("chrome")){var p=parseFloat(f.match(/version\/([\.\d]+)/i)[1]);D=6>p}}if(D)var m=1e3,v=j(function(){try{a.sheet.cssRules,j.cancel(v),a.onload()}catch(e){--m<=0&&a.onerror()}},20)}return i.promise};angular.isUndefined(p)&&(p=function(e,n,r){var a=[];angular.forEach(e,function(e){a.push(P("js",e,r))}),t.all(a).then(function(){n()},function(e){n(e)})},p.ocLazyLoadLoader=!0),angular.isUndefined(m)&&(m=function(e,n,r){var a=[];angular.forEach(e,function(e){a.push(P("css",e,r))}),t.all(a).then(function(){n()},function(e){n(e)})},m.ocLazyLoadLoader=!0),angular.isUndefined(v)&&(v=function(e,n,r){var a=[];return angular.forEach(e,function(e){var n=t.defer();a.push(n.promise),s.get(e,r).success(function(r){angular.isString(r)&&r.length>0&&angular.forEach(angular.element(r),function(e){"SCRIPT"===e.nodeName&&"text/ng-template"===e.type&&u.put(e.id,e.innerHTML)}),angular.isUndefined(x.get(e))&&x.put(e,!0),n.resolve()}).error(function(r){n.reject(new Error('Unable to load template file "'+e+'": '+r))})}),t.all(a).then(function(){n()},function(e){n(e)})},v.ocLazyLoadLoader=!0);var z=function(e,n){var r=[],o=[],i=[],u=[],l=null;angular.extend(n||{},e);var s=function(e){l=x.get(e),angular.isUndefined(l)||n.cache===!1?/\.(css|less)[^\.]*$/.test(e)&&-1===r.indexOf(e)?r.push(e):/\.(htm|html)[^\.]*$/.test(e)&&-1===o.indexOf(e)?o.push(e):-1===i.indexOf(e)&&i.push(e):l&&u.push(l)};if(n.serie?s(n.files.shift()):angular.forEach(n.files,function(e){s(e)}),r.length>0){var f=t.defer();m(r,function(e){angular.isDefined(e)&&m.hasOwnProperty("ocLazyLoadLoader")?(a.error(e),f.reject(e)):f.resolve()},n),u.push(f.promise)}if(o.length>0){var c=t.defer();v(o,function(e){angular.isDefined(e)&&v.hasOwnProperty("ocLazyLoadLoader")?(a.error(e),c.reject(e)):c.resolve()},n),u.push(c.promise)}if(i.length>0){var d=t.defer();p(i,function(e){angular.isDefined(e)&&p.hasOwnProperty("ocLazyLoadLoader")?(a.error(e),d.reject(e)):d.resolve()},n),u.push(d.promise)}return n.serie&&n.files.length>0?t.all(u).then(function(){return z(e,n)}):t.all(u)};return{getModuleConfig:function(e){if(!angular.isString(e))throw new Error("You need to give the name of the module to get");return y[e]?y[e]:null},setModuleConfig:function(e){if(!angular.isObject(e))throw new Error("You need to give the module config object to set");return y[e.name]=e,e},getModules:function(){return l},isLoaded:function(e){var r=function(e){var r=l.indexOf(e)>-1;return r||(r=!!n(e)),r};if(angular.isString(e)&&(e=[e]),angular.isArray(e)){var a,o;for(a=0,o=e.length;o>a;a++)if(!r(e[a]))return!1;return!0}throw new Error("You need to define the module(s) name(s)")},load:function(u,s){var f,d,g=this,h=null,p=[],m=[],v=t.defer();if(angular.isUndefined(s)&&(s={}),angular.isArray(u))return angular.forEach(u,function(e){e&&m.push(g.load(e,s))}),t.all(m).then(function(){v.resolve(u)},function(e){v.reject(e)}),v.promise;if(f=i(u),"string"==typeof u?(h=g.getModuleConfig(u),h||(h={files:[u]},f=null)):"object"==typeof u&&(h=g.setModuleConfig(u)),null===h?(d='Module "'+f+'" is not configured, cannot load.',a.error(d),v.reject(new Error(d))):angular.isDefined(h.template)&&(angular.isUndefined(h.files)&&(h.files=[]),angular.isString(h.template)?h.files.push(h.template):angular.isArray(h.template)&&h.files.concat(h.template)),p.push=function(e){-1===this.indexOf(e)&&Array.prototype.push.apply(this,arguments)},angular.isDefined(f)&&n(f)&&-1!==l.indexOf(f)&&(p.push(f),angular.isUndefined(h.files)))return v.resolve(),v.promise;var y={};angular.extend(y,s,h);var w=function O(o){var u,l,s,f,c=[];if(u=i(o),null===u)return t.when();try{l=r(u)}catch(d){var h=t.defer();return a.error(d.message),h.reject(d),h.promise}return s=e(l),angular.forEach(s,function(e){if("string"==typeof e){var r=g.getModuleConfig(e);if(null===r)return void p.push(e);e=r}return n(e.name)?void("string"!=typeof o&&(f=e.files.filter(function(n){return g.getModuleConfig(e.name).files.indexOf(n)<0}),0!==f.length&&a.warn('Module "',u,'" attempted to redefine configuration for dependency. "',e.name,'"\n Additional Files Loaded:',f),c.push(z(e.files,y).then(function(){return O(e)})))):("object"==typeof e&&(e.hasOwnProperty("name")&&e.name&&(g.setModuleConfig(e),p.push(e.name)),e.hasOwnProperty("css")&&0!==e.css.length&&angular.forEach(e.css,function(e){P("css",e,y)})),void(e.hasOwnProperty("files")&&0!==e.files.length&&e.files&&c.push(z(e,y).then(function(){return O(e)}))))}),t.all(c)};return z(h,y).then(function(){null===f?v.resolve(u):(p.push(f),w(f).then(function(){try{c=[],o(L,p,y)}catch(e){return a.error(e.message),void v.reject(e)}v.resolve(u)},function(e){v.reject(e)}))},function(e){v.reject(e)}),v.promise}}}],this.config=function(e){if(angular.isDefined(e.jsLoader)||angular.isDefined(e.asyncLoader)){if(!angular.isFunction(e.jsLoader||e.asyncLoader))throw"The js loader needs to be a function";p=e.jsLoader||e.asyncLoader}if(angular.isDefined(e.cssLoader)){if(!angular.isFunction(e.cssLoader))throw"The css loader needs to be a function";m=e.cssLoader}if(angular.isDefined(e.templatesLoader)){if(!angular.isFunction(e.templatesLoader))throw"The template loader needs to be a function";v=e.templatesLoader}if(angular.isDefined(e.loadedModules)){var n=function(e){l.indexOf(e)<0&&(l.push(e),angular.forEach(angular.module(e).requires,n))};angular.forEach(e.loadedModules,n)}angular.isDefined(e.modules)&&(angular.isArray(e.modules)?angular.forEach(e.modules,function(e){y[e.name]=e}):y[e.modules.name]=e.modules),angular.isDefined(e.debug)&&(O=e.debug),angular.isDefined(e.events)&&(E=e.events)}}]),g.directive("ocLazyLoad",["$ocLazyLoad","$compile","$animate","$parse",function(e,n,r,a){return{restrict:"A",terminal:!0,priority:1e3,compile:function(o){var t=o[0].innerHTML;return o.html(""),function(o,i,u){var l=a(u.ocLazyLoad);o.$watch(function(){return l(o)||u.ocLazyLoad},function(a){angular.isDefined(a)&&e.load(a).then(function(){r.enter(n(t)(o),null,i)})},!0)}}}}]),Array.prototype.indexOf||(Array.prototype.indexOf=function(e,n){var r;if(null==this)throw new TypeError('"this" is null or not defined');var a=Object(this),o=a.length>>>0;if(0===o)return-1;var t=+n||0;if(1/0===Math.abs(t)&&(t=0),t>=o)return-1;for(r=Math.max(t>=0?t:o-Math.abs(t),0);o>r;){if(r in a&&a[r]===e)return r;r++}return-1})}();
\ No newline at end of file
+!function(){"use strict";function e(e){var n=[];return angular.forEach(e.requires,function(e){-1===l.indexOf(e)&&n.push(e)}),n}function n(e){try{return angular.module(e)}catch(n){if(/No module/.test(n)||n.message.indexOf("$injector:nomod")>-1)return!1}}function r(e){try{return angular.module(e)}catch(n){throw(/No module/.test(n)||n.message.indexOf("$injector:nomod")>-1)&&(n.message='The module "'+e+'" that you are trying to load does not exist. '+n.message),n}}function a(e,n,r,a){if(n){var t,i,u,l;for(t=0,i=n.length;i>t;t++)if(u=n[t],angular.isArray(u)){if(null!==e){if(!e.hasOwnProperty(u[0]))throw new Error("unsupported provider "+u[0]);l=e[u[0]]}var s=o(u,r);if("invoke"!==u[1])s&&angular.isDefined(l)&&l[u[1]].apply(l,u[2]);else{var f=function(e){var n=c.indexOf(r+"-"+e);(-1===n||a)&&(-1===n&&c.push(r+"-"+e),angular.isDefined(l)&&l[u[1]].apply(l,u[2]))};if(angular.isFunction(u[2][0]))f(u[2][0]);else if(angular.isArray(u[2][0]))for(var d=0,g=u[2][0].length;g>d;d++)angular.isFunction(u[2][0][d])&&f(u[2][0][d])}}}}function t(e,n,r){if(n){var o,u,s,f=[];for(o=n.length-1;o>=0;o--)if(u=n[o],"string"!=typeof u&&(u=i(u)),u&&-1===d.indexOf(u)){var c=-1===l.indexOf(u);if(s=angular.module(u),c&&(l.push(u),t(e,s.requires,r)),s._runBlocks.length>0)for(g[u]=[];s._runBlocks.length>0;)g[u].push(s._runBlocks.shift());angular.isDefined(g[u])&&(c||r.rerun)&&(f=f.concat(g[u])),a(e,s._invokeQueue,u,r.reconfig),a(e,s._configBlocks,u,r.reconfig),p(c?"ocLazyLoad.moduleLoaded":"ocLazyLoad.moduleReloaded",u),n.pop(),d.push(u)}var h=e.getInstanceInjector();angular.forEach(f,function(e){h.invoke(e)})}}function o(e,n){var r=e[2][0],a=e[1],t=!1;angular.isUndefined(f[n])&&(f[n]={}),angular.isUndefined(f[n][a])&&(f[n][a]=[]);var o=function(e){t=!0,f[n][a].push(e),p("ocLazyLoad.componentLoaded",[n,a,e])};if(angular.isString(r)&&-1===f[n][a].indexOf(r))o(r);else{if(!angular.isObject(r))return!1;angular.forEach(r,function(e){angular.isString(e)&&-1===f[n][a].indexOf(e)&&o(e)})}return t}function i(e){var n=null;return angular.isString(e)?n=e:angular.isObject(e)&&e.hasOwnProperty("name")&&angular.isString(e.name)&&(n=e.name),n}function u(e){if(0===s.length){var n=[e],r=["ng:app","ng-app","x-ng-app","data-ng-app"],t=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/,o=function(e){return e&&n.push(e)};angular.forEach(r,function(n){r[n]=!0,o(document.getElementById(n)),n=n.replace(":","\\:"),e[0].querySelectorAll&&(angular.forEach(e[0].querySelectorAll("."+n),o),angular.forEach(e[0].querySelectorAll("."+n+"\\:"),o),angular.forEach(e[0].querySelectorAll("["+n+"]"),o))}),angular.forEach(n,function(n){if(0===s.length){var a=" "+e.className+" ",o=t.exec(a);o?s.push((o[2]||"").replace(/\s+/g,",")):angular.forEach(n.attributes,function(e){0===s.length&&r[e.name]&&s.push(e.value)})}})}if(0===s.length)throw"No module found during bootstrap, unable to init ocLazyLoad";var i=function u(e){if(-1===l.indexOf(e)){l.push(e);var n=angular.module(e);a(null,n._invokeQueue,e),a(null,n._configBlocks,e),angular.forEach(n.requires,u)}};angular.forEach(s,function(e){i(e)})}var l=["ng"],s=[],f={},c=[],d=[],g={},h=angular.module("oc.lazyLoad",["ng"]),p=angular.noop;h.provider("$ocLazyLoad",["$controllerProvider","$provide","$compileProvider","$filterProvider","$injector","$animateProvider",function(a,o,s,f,c,g){var h,m,v,y={},L={$controllerProvider:a,$compileProvider:s,$filterProvider:f,$provide:o,$injector:c,$animateProvider:g},w=document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0],O=!1,j=!1;u(angular.element(window.document)),this.$get=["$log","$q","$templateCache","$http","$rootElement","$rootScope","$cacheFactory","$interval",function(a,o,u,s,f,c,g,E){var $,x=g("ocLazyLoad"),b=!1,z=!1;O||(a={},a.error=angular.noop,a.warn=angular.noop,a.info=angular.noop),L.getInstanceInjector=function(){return $?$:$=f.data("$injector")||angular.injector()},p=function(e,n){j&&c.$broadcast(e,n),O&&a.info(e,n)};var P=function(e,n,r){var a,t,i=o.defer(),u=function(e){var n=(new Date).getTime();return e.indexOf("?")>=0?"&"===e.substring(0,e.length-1)?e+"_dc="+n:e+"&_dc="+n:e+"?_dc="+n};switch(angular.isUndefined(x.get(n))&&x.put(n,i.promise),e){case"css":a=document.createElement("link"),a.type="text/css",a.rel="stylesheet",a.href=r.cache===!1?u(n):n;break;case"js":a=document.createElement("script"),a.src=r.cache===!1?u(n):n;break;default:i.reject(new Error('Requested type "'+e+'" is not known. Could not inject "'+n+'"'))}a.onload=a.onreadystatechange=function(){a.readyState&&!/^c|loade/.test(a.readyState)||t||(a.onload=a.onreadystatechange=null,t=1,p("ocLazyLoad.fileLoaded",n),i.resolve())},a.onerror=function(){i.reject(new Error("Unable to load "+n))},a.async=r.serie?0:1;var l=w.lastChild;if(r.insertBefore){var s=angular.element(r.insertBefore);s&&s.length>0&&(l=s[0])}if(w.insertBefore(a,l),"css"==e){if(!b){var f=navigator.userAgent.toLowerCase();if(/iP(hone|od|ad)/.test(navigator.platform)){var c=navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),d=parseFloat([parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3]||0,10)].join("."));z=6>d}else if(f.indexOf("android")>-1){var g=parseFloat(f.slice(f.indexOf("android")+8));z=4.4>g}else if(f.indexOf("safari")>-1&&-1==f.indexOf("chrome")){var h=parseFloat(f.match(/version\/([\.\d]+)/i)[1]);z=6>h}}if(z)var m=1e3,v=E(function(){try{a.sheet.cssRules,E.cancel(v),a.onload()}catch(e){--m<=0&&a.onerror()}},20)}return i.promise};angular.isUndefined(h)&&(h=function(e,n,r){var a=[];angular.forEach(e,function(e){a.push(P("js",e,r))}),o.all(a).then(function(){n()},function(e){n(e)})},h.ocLazyLoadLoader=!0),angular.isUndefined(m)&&(m=function(e,n,r){var a=[];angular.forEach(e,function(e){a.push(P("css",e,r))}),o.all(a).then(function(){n()},function(e){n(e)})},m.ocLazyLoadLoader=!0),angular.isUndefined(v)&&(v=function(e,n,r){var a=[];return angular.forEach(e,function(e){var n=o.defer();a.push(n.promise),s.get(e,r).success(function(r){angular.isString(r)&&r.length>0&&angular.forEach(angular.element(r),function(e){"SCRIPT"===e.nodeName&&"text/ng-template"===e.type&&u.put(e.id,e.innerHTML)}),angular.isUndefined(x.get(e))&&x.put(e,!0),n.resolve()}).error(function(r){n.reject(new Error('Unable to load template file "'+e+'": '+r))})}),o.all(a).then(function(){n()},function(e){n(e)})},v.ocLazyLoadLoader=!0);var D=function(e,n){var r=[],t=[],i=[],u=[],l=null;angular.extend(n||{},e);var s=function(e){l=x.get(e),angular.isUndefined(l)||n.cache===!1?/\.(css|less)[^\.]*$/.test(e)&&-1===r.indexOf(e)?r.push(e):/\.(htm|html)[^\.]*$/.test(e)&&-1===t.indexOf(e)?t.push(e):-1===i.indexOf(e)&&i.push(e):l&&u.push(l)};if(n.serie?s(n.files.shift()):angular.forEach(n.files,function(e){s(e)}),r.length>0){var f=o.defer();m(r,function(e){angular.isDefined(e)&&m.hasOwnProperty("ocLazyLoadLoader")?(a.error(e),f.reject(e)):f.resolve()},n),u.push(f.promise)}if(t.length>0){var c=o.defer();v(t,function(e){angular.isDefined(e)&&v.hasOwnProperty("ocLazyLoadLoader")?(a.error(e),c.reject(e)):c.resolve()},n),u.push(c.promise)}if(i.length>0){var d=o.defer();h(i,function(e){angular.isDefined(e)&&h.hasOwnProperty("ocLazyLoadLoader")?(a.error(e),d.reject(e)):d.resolve()},n),u.push(d.promise)}return n.serie&&n.files.length>0?o.all(u).then(function(){return D(e,n)}):o.all(u)};return{getModuleConfig:function(e){if(!angular.isString(e))throw new Error("You need to give the name of the module to get");return y[e]?y[e]:null},setModuleConfig:function(e){if(!angular.isObject(e))throw new Error("You need to give the module config object to set");return y[e.name]=e,e},getModules:function(){return l},isLoaded:function(e){var r=function(e){var r=l.indexOf(e)>-1;return r||(r=!!n(e)),r};if(angular.isString(e)&&(e=[e]),angular.isArray(e)){var a,t;for(a=0,t=e.length;t>a;a++)if(!r(e[a]))return!1;return!0}throw new Error("You need to define the module(s) name(s)")},load:function(u,s){var f,c,g=this,h=null,p=[],m=[],v=o.defer();if(angular.isUndefined(s)&&(s={}),angular.isArray(u))return angular.forEach(u,function(e){e&&m.push(g.load(e,s))}),o.all(m).then(function(){v.resolve(u)},function(e){v.reject(e)}),v.promise;if(f=i(u),"string"==typeof u?(h=g.getModuleConfig(u),h||(h={files:[u]},f=null)):"object"==typeof u&&(h=g.setModuleConfig(u)),null===h?(c='Module "'+f+'" is not configured, cannot load.',a.error(c),v.reject(new Error(c))):angular.isDefined(h.template)&&(angular.isUndefined(h.files)&&(h.files=[]),angular.isString(h.template)?h.files.push(h.template):angular.isArray(h.template)&&h.files.concat(h.template)),p.push=function(e){-1===this.indexOf(e)&&Array.prototype.push.apply(this,arguments)},angular.isDefined(f)&&n(f)&&-1!==l.indexOf(f)&&(p.push(f),angular.isUndefined(h.files)))return v.resolve(),v.promise;var y={};angular.extend(y,s,h);var w=function O(t){var u,l,s,f,c=[];if(u=i(t),null===u)return o.when();try{l=r(u)}catch(d){var h=o.defer();return a.error(d.message),h.reject(d),h.promise}return s=e(l),angular.forEach(s,function(e){if("string"==typeof e){var r=g.getModuleConfig(e);if(null===r)return void p.push(e);e=r}return n(e.name)?void("string"!=typeof t&&(f=e.files.filter(function(n){return g.getModuleConfig(e.name).files.indexOf(n)<0}),0!==f.length&&a.warn('Module "',u,'" attempted to redefine configuration for dependency. "',e.name,'"\n Additional Files Loaded:',f),c.push(D(e.files,y).then(function(){return O(e)})))):("object"==typeof e&&(e.hasOwnProperty("name")&&e.name&&(g.setModuleConfig(e),p.push(e.name)),e.hasOwnProperty("css")&&0!==e.css.length&&angular.forEach(e.css,function(e){P("css",e,y)})),void(e.hasOwnProperty("files")&&0!==e.files.length&&e.files&&c.push(D(e,y).then(function(){return O(e)}))))}),o.all(c)};return D(h,y).then(function(){null===f?v.resolve(u):(p.push(f),w(f).then(function(){try{d=[],t(L,p,y)}catch(e){return a.error(e.message),void v.reject(e)}v.resolve(u)},function(e){v.reject(e)}))},function(e){v.reject(e)}),v.promise}}}],this.config=function(e){if(angular.isDefined(e.jsLoader)||angular.isDefined(e.asyncLoader)){if(!angular.isFunction(e.jsLoader||e.asyncLoader))throw"The js loader needs to be a function";h=e.jsLoader||e.asyncLoader}if(angular.isDefined(e.cssLoader)){if(!angular.isFunction(e.cssLoader))throw"The css loader needs to be a function";m=e.cssLoader}if(angular.isDefined(e.templatesLoader)){if(!angular.isFunction(e.templatesLoader))throw"The template loader needs to be a function";v=e.templatesLoader}angular.isDefined(e.modules)&&(angular.isArray(e.modules)?angular.forEach(e.modules,function(e){y[e.name]=e}):y[e.modules.name]=e.modules),angular.isDefined(e.debug)&&(O=e.debug),angular.isDefined(e.events)&&(j=e.events)}}]),h.directive("ocLazyLoad",["$ocLazyLoad","$compile","$animate","$parse",function(e,n,r,a){return{restrict:"A",terminal:!0,priority:1e3,compile:function(t){var o=t[0].innerHTML;return t.html(""),function(t,i,u){var l=a(u.ocLazyLoad);t.$watch(function(){return l(t)||u.ocLazyLoad},function(a){angular.isDefined(a)&&e.load(a).then(function(){r.enter(n(o)(t),null,i)})},!0)}}}}]);var m=angular.bootstrap;angular.bootstrap=function(e,n,r){return s=n.slice(),m(e,n,r)},Array.prototype.indexOf||(Array.prototype.indexOf=function(e,n){var r;if(null==this)throw new TypeError('"this" is null or not defined');var a=Object(this),t=a.length>>>0;if(0===t)return-1;var o=+n||0;if(1/0===Math.abs(o)&&(o=0),o>=t)return-1;for(r=Math.max(o>=0?o:t-Math.abs(o),0);t>r;){if(r in a&&a[r]===e)return r;r++}return-1})}();
\ No newline at end of file
diff --git a/examples/requireJSExample/js/testmodule.js b/examples/requireJSExample/js/testmodule.js
index 77f328d..c5b1a94 100644
--- a/examples/requireJSExample/js/testmodule.js
+++ b/examples/requireJSExample/js/testmodule.js
@@ -1,7 +1,6 @@
angular.module('test', ['oc.lazyLoad'])
.config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
- loadedModules: ['test'],
jsLoader: requirejs,
debug: true
});
diff --git a/src/ocLazyLoad.js b/src/ocLazyLoad.js
index 4277f7d..33279e4 100644
--- a/src/ocLazyLoad.js
+++ b/src/ocLazyLoad.js
@@ -1,6 +1,7 @@
(function() {
'use strict';
var regModules = ['ng'],
+ initModules = [],
regInvokes = {},
regConfigs = [],
justLoaded = [],
@@ -618,17 +619,6 @@
templatesLoader = config.templatesLoader;
}
- // for bootstrap apps, we need to define the main module name
- if(angular.isDefined(config.loadedModules)) {
- var addRegModule = function(loadedModule) {
- if(regModules.indexOf(loadedModule) < 0) {
- regModules.push(loadedModule);
- angular.forEach(angular.module(loadedModule).requires, addRegModule);
- }
- };
- angular.forEach(config.loadedModules, addRegModule);
- }
-
// If we want to define modules configs
if(angular.isDefined(config.modules)) {
if(angular.isArray(config.modules)) {
@@ -863,63 +853,70 @@
* @param element
*/
function init(element) {
- var elements = [element],
- appElement,
- moduleName,
- names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
- NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
-
- function append(elm) {
- return (elm && elements.push(elm));
- }
+ if(initModules.length === 0) {
+ var elements = [element],
+ names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
+ NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/,
+ append = function append(elm) {
+ return (elm && elements.push(elm));
+ };
- angular.forEach(names, function(name) {
- names[name] = true;
- append(document.getElementById(name));
- name = name.replace(':', '\\:');
- if(element[0].querySelectorAll) {
- angular.forEach(element[0].querySelectorAll('.' + name), append);
- angular.forEach(element[0].querySelectorAll('.' + name + '\\:'), append);
- angular.forEach(element[0].querySelectorAll('[' + name + ']'), append);
- }
- });
+ angular.forEach(names, function(name) {
+ names[name] = true;
+ append(document.getElementById(name));
+ name = name.replace(':', '\\:');
+ if(element[0].querySelectorAll) {
+ angular.forEach(element[0].querySelectorAll('.' + name), append);
+ angular.forEach(element[0].querySelectorAll('.' + name + '\\:'), append);
+ angular.forEach(element[0].querySelectorAll('[' + name + ']'), append);
+ }
+ });
- //TODO: search the script tags for angular.bootstrap
- angular.forEach(elements, function(elm) {
- if(!appElement) {
- var className = ' ' + element.className + ' ';
- var match = NG_APP_CLASS_REGEXP.exec(className);
- if(match) {
- appElement = elm;
- moduleName = (match[2] || '').replace(/\s+/g, ',');
- } else {
- angular.forEach(elm.attributes, function(attr) {
- if(!appElement && names[attr.name]) {
- appElement = elm;
- moduleName = attr.value;
- }
- });
+ angular.forEach(elements, function(elm) {
+ if(initModules.length === 0) {
+ var className = ' ' + element.className + ' ';
+ var match = NG_APP_CLASS_REGEXP.exec(className);
+ if(match) {
+ initModules.push((match[2] || '').replace(/\s+/g, ','));
+ } else {
+ angular.forEach(elm.attributes, function(attr) {
+ if(initModules.length === 0 && names[attr.name]) {
+ initModules.push(attr.value);
+ }
+ });
+ }
}
- }
- });
+ });
+ }
+ if(initModules.length === 0) {
+ throw 'No module found during bootstrap, unable to init ocLazyLoad';
+ }
- if(appElement) {
- (function addReg(moduleName) {
- if(regModules.indexOf(moduleName) === -1) {
- // register existing modules
- regModules.push(moduleName);
- var mainModule = angular.module(moduleName);
+ var addReg = function addReg(moduleName) {
+ if(regModules.indexOf(moduleName) === -1) {
+ // register existing modules
+ regModules.push(moduleName);
+ var mainModule = angular.module(moduleName);
- // register existing components (directives, services, ...)
- invokeQueue(null, mainModule._invokeQueue, moduleName);
- invokeQueue(null, mainModule._configBlocks, moduleName); // angular 1.3+
+ // register existing components (directives, services, ...)
+ invokeQueue(null, mainModule._invokeQueue, moduleName);
+ invokeQueue(null, mainModule._configBlocks, moduleName); // angular 1.3+
- angular.forEach(mainModule.requires, addReg);
- }
- })(moduleName);
- }
+ angular.forEach(mainModule.requires, addReg);
+ }
+ };
+
+ angular.forEach(initModules, function(moduleName) {
+ addReg(moduleName);
+ });
}
+ var bootstrap = angular.bootstrap;
+ angular.bootstrap = function(element, modules, config) {
+ initModules = modules.slice(); // make a clean copy
+ return bootstrap(element, modules, config);
+ };
+
// Array.indexOf polyfill for IE8
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {