diff --git a/src/Umbraco.Web.UI.Client/lib/lazyload/lazyload.min.js b/src/Umbraco.Web.UI.Client/lib/lazyload/lazyload.min.js new file mode 100644 index 0000000000..bc49920cfe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/lib/lazyload/lazyload.min.js @@ -0,0 +1,4 @@ +LazyLoad=function(x,h){function r(b,a){var c=h.createElement(b),d;for(d in a)a.hasOwnProperty(d)&&c.setAttribute(d,a[d]);return c}function k(b){var a=i[b],c,d;if(a){c=a.callback;d=a.urls;d.shift();l=0;if(!d.length){c&&c.call(a.context,a.obj);i[b]=null;j[b].length&&m(b)}}}function w(){if(!e){var b=navigator.userAgent;e={async:h.createElement("script").async===true};(e.webkit=/AppleWebKit\//.test(b))||(e.ie=/MSIE/.test(b))||(e.opera=/Opera/.test(b))||(e.gecko=/Gecko\//.test(b))||(e.unknown=true)}}function m(b, +a,c,d,s){var n=function(){k(b)},o=b==="css",f,g,p;w();if(a){a=typeof a==="string"?[a]:a.concat();if(o||e.async||e.gecko||e.opera)j[b].push({urls:a,callback:c,obj:d,context:s});else{f=0;for(g=a.length;f0) ? "&" : "?"; url = url + _op + "umb__rnd=" + rnd; return url; }; - return { + var service = { + loadedAssets:{}, + _getAssetPromise : function(path){ + if(this.loadedAssets[path]){ + return this.loadedAssets[path]; + }else{ + var deferred = $q.defer(); + this.loadedAssets[path] = {deferred: deferred, state: "new", path: path}; + return this.loadedAssets[path]; + } + }, /** Internal method. This is called when the application is loading and the user is already authenticated, or once the user is authenticated. There's a few assets the need to be loaded for the application to function but these assets require authentication to load. @@ -97,21 +107,27 @@ angular.module('umbraco.services') * @returns {Promise} Promise object which resolves when the file has loaded */ loadCss : function(path, scope, attributes, timeout){ - var deferred = $q.defer(); + var asset = this._getAssetPromise(path); // $q.defer(); var t = timeout || 5000; var a = attributes || undefined; - - yepnope.injectCss(appendRnd(path), function () { - if (!scope) { - deferred.resolve(true); - }else{ - angularHelper.safeApply(scope, function () { - deferred.resolve(true); - }); - } - },a,t); - - return deferred.promise; + + if(asset.state === "new"){ + asset.state = "loading"; + LazyLoad.css(appendRnd(path), function () { + if (!scope) { + asset.state = "loaded"; + asset.deferred.resolve(true); + }else{ + asset.state = "loaded"; + angularHelper.safeApply(scope, function () { + asset.deferred.resolve(true); + }); + } + }); + }else if(asset.state === "loaded"){ + asset.deferred.resolve(true); + } + return asset.deferred.promise; }, /** @@ -129,22 +145,31 @@ angular.module('umbraco.services') * @returns {Promise} Promise object which resolves when the file has loaded */ loadJs : function(path, scope, attributes, timeout){ - var deferred = $q.defer(); + + var asset = this._getAssetPromise(path); // $q.defer(); var t = timeout || 5000; var a = attributes || undefined; - yepnope.injectJs(appendRnd(path), function () { - if (!scope) { - deferred.resolve(true); - }else{ - angularHelper.safeApply(scope, function () { - deferred.resolve(true); - }); - } - },a,t); + if(asset.state === "new"){ + asset.state = "loading"; + LazyLoad.js(appendRnd(path), function () { + if (!scope) { + asset.state = "loaded"; + asset.deferred.resolve(true); + }else{ + asset.state = "loaded"; + angularHelper.safeApply(scope, function () { + asset.deferred.resolve(true); + }); + } + }); - return deferred.promise; + }else if(asset.state === "loaded"){ + asset.deferred.resolve(true); + } + + return asset.deferred.promise; }, /** @@ -162,8 +187,7 @@ angular.module('umbraco.services') * @returns {Promise} Promise object which resolves when all the files has loaded */ load: function (pathArray, scope) { - var deferred = $q.defer(); - + var promise; var nonEmpty = _.reject(pathArray, function(item) { return item === undefined || item === ""; }); @@ -171,36 +195,55 @@ angular.module('umbraco.services') //don't load anything if there's nothing to load if (nonEmpty.length > 0) { - yepnope({ - load: pathArray, - complete: function() { + var promises = []; + var assets = []; - //if a scope is supplied then we need to make a digest here because - // deferred only executes in a digest. This might be required if we - // are doing a load script after an http request or some other async call. - if (!scope) { - deferred.resolve(true); - } - else { - angularHelper.safeApply(scope, function () { - deferred.resolve(true); - }); + //compile a list of promises + //blocking + _.each(nonEmpty, function(path){ + var asset = service._getAssetPromise(path); + //if not previously loaded, add to list of promises + if(asset.state !== "loaded") + { + if(asset.state === "new"){ + asset.state = "loading"; + assets.push(asset); } + + //we need to always push to the promises collection to monitor correct + //execution + promises.push(asset.deferred.promise); } }); - } - else { - if (!scope) { - deferred.resolve(true); - } - else { - angularHelper.safeApply(scope, function () { - deferred.resolve(true); - }); - } + + + //gives a central monitoring of all assets to load + promise = $q.all(promises); + + _.each(assets, function(asset){ + LazyLoad.js(appendRnd(asset.path), function () { + if (!scope) { + asset.state = "loaded"; + asset.deferred.resolve(true); + }else{ + asset.state = "loaded"; + angularHelper.safeApply(scope, function () { + asset.deferred.resolve(true); + }); + } + }); + }); + }else{ + //return and resolve + var deferred = $q.defer(); + promise = deferred.promise; + deferred.resolve(true); } - return deferred.promise; + + return promise; } }; + + return service; }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/index.html b/src/Umbraco.Web.UI.Client/src/index.html index 16bf7b4721..6a1b32b03f 100644 --- a/src/Umbraco.Web.UI.Client/src/index.html +++ b/src/Umbraco.Web.UI.Client/src/index.html @@ -22,7 +22,7 @@ - + diff --git a/src/Umbraco.Web.UI.Client/src/loader.js b/src/Umbraco.Web.UI.Client/src/loader.js index 9695ae0b59..23d2079edd 100644 --- a/src/Umbraco.Web.UI.Client/src/loader.js +++ b/src/Umbraco.Web.UI.Client/src/loader.js @@ -1,61 +1,47 @@ -//global no-cache filter, this is enabled when we're in debug mode -//in live mode we use client dependency and don't turn this thing on -yepnope.addFilter(function (resourceObj) { - var url = resourceObj.url; - if(url.indexOf("lib/") === 0 || url.indexOf("js/umbraco.") === 0){ - return resourceObj; - } +LazyLoad.js( + [ + 'lib/jquery/jquery-2.0.3.min.js', - resourceObj.url = resourceObj.url + "?umb__rnd=" + (new Date).getTime(); - return resourceObj; -}); + /* the jquery ui elements we need */ + 'lib/jquery/jquery-ui-1.10.3.custom.min.js', + + /* 1.1.5 */ + 'lib/angular/1.1.5/angular.min.js', + 'lib/angular/1.1.5/angular-cookies.min.js', + 'lib/angular/1.1.5/angular-mobile.min.js', + 'lib/angular/1.1.5/angular-mocks.js', + 'lib/angular/1.1.5/angular-sanitize.min.js', + 'lib/angular/angular-ui-sortable.js', -yepnope({ + /* App-wide file-upload helper */ + 'lib/jquery/jquery.upload/js/jquery.fileupload.js', + 'lib/jquery/jquery.upload/js/jquery.fileupload-process.js', + 'lib/jquery/jquery.upload/js/jquery.fileupload-angular.js', + + 'lib/bootstrap/js/bootstrap.2.3.2.min.js', + 'lib/underscore/underscore.js', + 'lib/umbraco/Extensions.js', + 'lib/umbraco/NamespaceManager.js', - load: [ - 'lib/jquery/jquery-2.0.3.min.js', + 'js/umbraco.servervariables.js', + 'js/app.dev.js', + 'js/umbraco.httpbackend.js', + 'js/umbraco.testing.js', - /* the jquery ui elements we need */ - 'lib/jquery/jquery-ui-1.10.3.custom.min.js', - - /* 1.1.5 */ - 'lib/angular/1.1.5/angular.min.js', - 'lib/angular/1.1.5/angular-cookies.min.js', - 'lib/angular/1.1.5/angular-mobile.min.js', - 'lib/angular/1.1.5/angular-mocks.js', - 'lib/angular/1.1.5/angular-sanitize.min.js', - - 'lib/angular/angular-ui-sortable.js', - - /* App-wide file-upload helper */ - 'lib/jquery/jquery.upload/js/jquery.fileupload.js', - 'lib/jquery/jquery.upload/js/jquery.fileupload-process.js', - 'lib/jquery/jquery.upload/js/jquery.fileupload-angular.js', - - 'lib/bootstrap/js/bootstrap.2.3.2.min.js', - 'lib/underscore/underscore.js', - 'lib/umbraco/Extensions.js', - 'lib/umbraco/NamespaceManager.js', - - 'js/umbraco.servervariables.js', - 'js/app.dev.js', - 'js/umbraco.httpbackend.js', - 'js/umbraco.testing.js', - - 'js/umbraco.directives.js', - 'js/umbraco.filters.js', - 'js/umbraco.resources.js', - 'js/umbraco.services.js', - 'js/umbraco.security.js', - 'js/umbraco.controllers.js', - 'js/routes.js', - 'js/init.js' + 'js/umbraco.directives.js', + 'js/umbraco.filters.js', + 'js/umbraco.resources.js', + 'js/umbraco.services.js', + 'js/umbraco.security.js', + 'js/umbraco.controllers.js', + 'js/routes.js', + 'js/init.js' ], - complete: function () { + function () { jQuery(document).ready(function () { angular.bootstrap(document, ['umbraco']); - }); + }); } -}); \ No newline at end of file +); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml index a93c49933a..78bfbd6330 100644 --- a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml @@ -59,7 +59,7 @@ @*And finally we can load in our angular app*@ - + diff --git a/src/Umbraco.Web/UI/JavaScript/CssInitialization.cs b/src/Umbraco.Web/UI/JavaScript/CssInitialization.cs index c2b200604e..c7772944c2 100644 --- a/src/Umbraco.Web/UI/JavaScript/CssInitialization.cs +++ b/src/Umbraco.Web/UI/JavaScript/CssInitialization.cs @@ -14,7 +14,6 @@ namespace Umbraco.Web.UI.JavaScript internal class CssInitialization : AssetInitialization { private readonly ManifestParser _parser; - public CssInitialization(ManifestParser parser) { _parser = parser; @@ -57,7 +56,7 @@ namespace Umbraco.Web.UI.JavaScript { var sb = new StringBuilder(); foreach (var file in files) - sb.AppendFormat("{0}yepnope.injectCss('{1}');", Environment.NewLine, file); + sb.AppendFormat("{0}LazyLoad.css('{1}');", Environment.NewLine, file); return sb.ToString(); } diff --git a/src/Umbraco.Web/UI/JavaScript/JsInitialization.cs b/src/Umbraco.Web/UI/JavaScript/JsInitialization.cs index 04fec9184e..776129484c 100644 --- a/src/Umbraco.Web/UI/JavaScript/JsInitialization.cs +++ b/src/Umbraco.Web/UI/JavaScript/JsInitialization.cs @@ -61,7 +61,6 @@ namespace Umbraco.Web.UI.JavaScript } return ParseMain( - noCache, result.ToString(), IOHelper.ResolveUrl(SystemDirectories.Umbraco)); } diff --git a/src/Umbraco.Web/UI/JavaScript/JsInitialize.js b/src/Umbraco.Web/UI/JavaScript/JsInitialize.js index 33142b1f49..f301ad8fde 100644 --- a/src/Umbraco.Web/UI/JavaScript/JsInitialize.js +++ b/src/Umbraco.Web/UI/JavaScript/JsInitialize.js @@ -1,13 +1,9 @@ [ - 'lib/jquery/jquery-ui-1.10.3.custom.min.js', + 'lib/jquery/jquery-2.0.3.min.js', + 'lib/angular/1.1.5/angular.min.js', + 'lib/underscore/underscore.js', - /* 'lib/jquery/jquery-ui-1.10.3.custom.min.js', - 'lib/jquery/jquery.ui.core.min.js', - 'lib/jquery/jquery.ui.widget.min.js', - 'lib/jquery/jquery.ui.mouse.min.js', - 'lib/jquery/jquery.ui.sortable.min.js', - */ 'lib/angular/1.1.5/angular-cookies.min.js', 'lib/angular/1.1.5/angular-mobile.js', diff --git a/src/Umbraco.Web/UI/JavaScript/Main.js b/src/Umbraco.Web/UI/JavaScript/Main.js index 06d5cb79e8..520620af7d 100644 --- a/src/Umbraco.Web/UI/JavaScript/Main.js +++ b/src/Umbraco.Web/UI/JavaScript/Main.js @@ -1,22 +1,8 @@ -"##JsNoCache##" -yepnope({ - load: [ - 'lib/jquery/jquery-2.0.3.min.js', - 'lib/angular/1.1.5/angular.min.js', - 'lib/underscore/underscore.js', - ], - complete: function () { - yepnope({ - load: "##JsInitialize##", - complete: function () { +LazyLoad.js("##JsInitialize##", function () { + //we need to set the legacy UmbClientMgr path + UmbClientMgr.setUmbracoPath('"##UmbracoPath##"'); - //we need to set the legacy UmbClientMgr path - UmbClientMgr.setUmbracoPath('"##UmbracoPath##"'); - - jQuery(document).ready(function () { - angular.bootstrap(document, ['umbraco']); - }); - } - }); - } + jQuery(document).ready(function () { + angular.bootstrap(document, ['umbraco']); + }); }); \ No newline at end of file