diff --git a/src/Umbraco.Core/Assets/AssetFile.cs b/src/Umbraco.Core/Assets/AssetFile.cs deleted file mode 100644 index 9dd269a2a2..0000000000 --- a/src/Umbraco.Core/Assets/AssetFile.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Umbraco.Core.Assets -{ - /// - /// Represents a dependency file - /// - [DebuggerDisplay("Type: {DependencyType}, File: {FilePath}")] - public class AssetFile : IAssetFile - { - #region IAssetFile Members - - public string FilePath { get; set; } - public AssetType DependencyType { get; } - public int Priority { get; set; } - public int Group { get; set; } - public string PathNameAlias { get; set; } - public string ForceProvider { get; set; } - public string Bundle { get; } - - /// - /// Used to store additional attributes in the HTML markup for the item - /// - /// - /// Mostly used for CSS Media, but could be for anything - /// - public IDictionary HtmlAttributes { get; } - - #endregion - - public AssetFile(AssetType type, string bundleName = "unspecfed") - { - DependencyType = type; - HtmlAttributes = new Dictionary(); - // Set to 100 for the case when a developer doesn't specify a priority it will come after all other dependencies that - // have unless the priority is explicitly set above 100. - Priority = 100; - //Unless a group is specified, all dependencies will go into the same, default, group. - Group = 100; - Bundle = bundleName; - } - } -} diff --git a/src/Umbraco.Core/Assets/IAssetFile.cs b/src/Umbraco.Core/Assets/IAssetFile.cs deleted file mode 100644 index da2558c845..0000000000 --- a/src/Umbraco.Core/Assets/IAssetFile.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; - -namespace Umbraco.Core.Assets -{ - public interface IAssetFile - { - string FilePath { get; set; } - AssetType DependencyType { get; } - int Priority { get; set; } - int Group { get; set; } - string PathNameAlias { get; set; } - string ForceProvider { get; set; } - string Bundle { get; } - IDictionary HtmlAttributes { get; } - } -} diff --git a/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs b/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs deleted file mode 100644 index b76f2007b6..0000000000 --- a/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Umbraco.Core.Assets; - -namespace Umbraco.Core.Runtime -{ - public interface IRuntimeMinifier - { - string GetHashValue { get; } - - //return type HtmlHelper - void RequiresCss(string bundleName, params string[] filePaths); - - //return type IHtmlString - //IClientDependencyPath[] - string RenderCssHere(string bundleName); - - // return type HtmlHelper - void RequiresJs(string bundleName, params string[] filePaths); - - // return type IHtmlString - string RenderJsHere(string bundleName); - - Task> GetAssetPathsAsync(AssetType assetType, List attributes); - - Task MinifyAsync(string fileContent, AssetType assetType); - void Reset(); - Task GetScriptForBackOfficeAsync(); - Task> GetAssetListAsync(); - } -} diff --git a/src/Umbraco.Core/WebAssets/AssetFile.cs b/src/Umbraco.Core/WebAssets/AssetFile.cs new file mode 100644 index 0000000000..ceb3816633 --- /dev/null +++ b/src/Umbraco.Core/WebAssets/AssetFile.cs @@ -0,0 +1,23 @@ +using System.Diagnostics; + +namespace Umbraco.Core.WebAssets +{ + /// + /// Represents a dependency file + /// + [DebuggerDisplay("Type: {DependencyType}, File: {FilePath}")] + public class AssetFile : IAssetFile + { + #region IAssetFile Members + + public string FilePath { get; set; } + public AssetType DependencyType { get; } + + #endregion + + public AssetFile(AssetType type) + { + DependencyType = type; + } + } +} diff --git a/src/Umbraco.Core/Assets/AssetType.cs b/src/Umbraco.Core/WebAssets/AssetType.cs similarity index 67% rename from src/Umbraco.Core/Assets/AssetType.cs rename to src/Umbraco.Core/WebAssets/AssetType.cs index 8ec8fc4c21..c08e2be6c1 100644 --- a/src/Umbraco.Core/Assets/AssetType.cs +++ b/src/Umbraco.Core/WebAssets/AssetType.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Assets +namespace Umbraco.Core.WebAssets { public enum AssetType { diff --git a/src/Umbraco.Core/Assets/CssFile.cs b/src/Umbraco.Core/WebAssets/CssFile.cs similarity index 71% rename from src/Umbraco.Core/Assets/CssFile.cs rename to src/Umbraco.Core/WebAssets/CssFile.cs index 3a28117318..42c677807e 100644 --- a/src/Umbraco.Core/Assets/CssFile.cs +++ b/src/Umbraco.Core/WebAssets/CssFile.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Umbraco.Core.Assets +namespace Umbraco.Core.WebAssets { /// /// Represents a CSS asset file diff --git a/src/Umbraco.Core/WebAssets/IAssetFile.cs b/src/Umbraco.Core/WebAssets/IAssetFile.cs new file mode 100644 index 0000000000..721c415ffe --- /dev/null +++ b/src/Umbraco.Core/WebAssets/IAssetFile.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Core.WebAssets +{ + public interface IAssetFile + { + string FilePath { get; set; } + AssetType DependencyType { get; } + } +} diff --git a/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs b/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs new file mode 100644 index 0000000000..3cf2e9d722 --- /dev/null +++ b/src/Umbraco.Core/WebAssets/IRuntimeMinifier.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Umbraco.Core.WebAssets +{ + /// + /// Used for bundling and minifying web assets at runtime + /// + public interface IRuntimeMinifier + { + /// + /// Returns the cache buster value + /// + string CacheBuster { get; } + + /// + /// Creates a css bundle + /// + /// + /// + void CreateCssBundle(string bundleName, params string[] filePaths); + + /// + /// Renders the html link tag for the bundle + /// + /// + /// + /// An html encoded string + /// + string RenderCssHere(string bundleName); + + /// + /// Creates a JS bundle + /// + /// + /// + void CreateJsBundle(string bundleName, params string[] filePaths); + + /// + /// Renders the html script tag for the bundle + /// + /// + /// + /// An html encoded string + /// + string RenderJsHere(string bundleName); + + /// + /// Returns the asset paths for the bundle name + /// + /// + /// + /// If debug mode is enabled this will return all asset paths (not bundled), else it will return a bundle URL + /// + Task> GetAssetPathsAsync(string bundleName); + + Task MinifyAsync(string fileContent, AssetType assetType); + + void Reset(); + + } +} diff --git a/src/Umbraco.Core/Assets/JavascriptFile.cs b/src/Umbraco.Core/WebAssets/JavascriptFile.cs similarity index 72% rename from src/Umbraco.Core/Assets/JavascriptFile.cs rename to src/Umbraco.Core/WebAssets/JavascriptFile.cs index 51d4a26d82..1f5b1a1f77 100644 --- a/src/Umbraco.Core/Assets/JavascriptFile.cs +++ b/src/Umbraco.Core/WebAssets/JavascriptFile.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Umbraco.Core.Assets +namespace Umbraco.Core.WebAssets { /// /// Represents a JS asset file diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/AssetInitialization.cs b/src/Umbraco.Infrastructure/RuntimeMinification/AssetInitialization.cs deleted file mode 100644 index 74931dff54..0000000000 --- a/src/Umbraco.Infrastructure/RuntimeMinification/AssetInitialization.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Umbraco.Core; -using Umbraco.Core.Assets; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Runtime; -using Umbraco.Web.PropertyEditors; - -namespace Umbraco.Web.JavaScript -{ - public abstract class AssetInitialization - { - private readonly IRuntimeMinifier _runtimeMinifier; - private readonly PropertyEditorCollection _propertyEditorCollection; - - public AssetInitialization(IRuntimeMinifier runtimeMinifier, PropertyEditorCollection propertyEditorCollection) - { - _runtimeMinifier = runtimeMinifier; - _propertyEditorCollection = propertyEditorCollection; - } - - protected async Task> ScanPropertyEditorsAsync(AssetType assetType) - { - var attributes = _propertyEditorCollection - .SelectMany(x => x.GetType().GetCustomAttributes(false)) - .Where(x => x.AssetType == assetType) - .Select(x => x.DependencyFile) - .ToList(); - - return await _runtimeMinifier.GetAssetPathsAsync(assetType, attributes); - } - } -} diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/CssInitialization.cs b/src/Umbraco.Infrastructure/RuntimeMinification/CssInitialization.cs deleted file mode 100644 index 000079de5b..0000000000 --- a/src/Umbraco.Infrastructure/RuntimeMinification/CssInitialization.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web; -using Umbraco.Core.Assets; -using Umbraco.Core.Manifest; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Runtime; - -namespace Umbraco.Web.JavaScript -{ - public class CssInitialization : AssetInitialization - { - private readonly IManifestParser _parser; - private readonly IRuntimeMinifier _runtimeMinifier; - - public CssInitialization( - IManifestParser parser, - IRuntimeMinifier runtimeMinifier, - PropertyEditorCollection propertyEditorCollection) - : base(runtimeMinifier, propertyEditorCollection) - { - _parser = parser; - _runtimeMinifier = runtimeMinifier; - } - - /// - /// Processes all found manifest files, and outputs css inject calls for all css files found in all manifests. - /// - public async Task GetStylesheetInitializationAsync(Uri requestUrl) - { - var files = await GetStylesheetFilesAsync(requestUrl); - return WriteScript(files); - } - - public async Task> GetStylesheetFilesAsync(Uri requestUrl) - { - var stylesheets = new HashSet(); - var optimizedManifest = await JavaScriptHelper.OptimizeAssetCollectionAsync(_parser.Manifest.Stylesheets, AssetType.Css, requestUrl, _runtimeMinifier); - foreach (var stylesheet in optimizedManifest) - stylesheets.Add(stylesheet); - - foreach (var stylesheet in await ScanPropertyEditorsAsync(AssetType.Css)) - stylesheets.Add(stylesheet); - - return stylesheets.ToArray(); - } - - internal static string WriteScript(IEnumerable files) - { - var sb = new StringBuilder(); - foreach (var file in files) - sb.AppendFormat("{0}LazyLoad.css('{1}');", Environment.NewLine, file); - return sb.ToString(); - } - - } -} diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/JavaScriptHelper.cs b/src/Umbraco.Infrastructure/RuntimeMinification/JavaScriptHelper.cs deleted file mode 100644 index 0862fd23a5..0000000000 --- a/src/Umbraco.Infrastructure/RuntimeMinification/JavaScriptHelper.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Umbraco.Core; -using Umbraco.Core.Assets; -using Umbraco.Core.Configuration; -using Umbraco.Core.IO; -using Umbraco.Core.Runtime; -using Umbraco.Infrastructure.RuntimeMinification; - -namespace Umbraco.Web.JavaScript -{ - public class JavaScriptHelper - { - // deal with javascript functions inside of json (not a supported json syntax) - private const string PrefixJavaScriptObject = "@@@@"; - private static readonly Regex JsFunctionParser = new Regex($"(\"{PrefixJavaScriptObject}(.*?)\")+", - RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled); - - // replace tokens in the js main - private static readonly Regex Token = new Regex("(\"##\\w+?##\")", RegexOptions.Compiled); - - - /// - /// Gets the JS initialization script to boot the back office application - /// - /// - /// - /// The angular module name to boot - /// - /// - public static string GetJavascriptInitialization(IEnumerable scripts, string angularModule, IGlobalSettings globalSettings, IIOHelper ioHelper) - { - var jarray = new StringBuilder(); - jarray.AppendLine("["); - var first = true; - foreach (var file in scripts) - { - if (first) first = false; - else jarray.AppendLine(","); - jarray.Append("\""); - jarray.Append(file); - jarray.Append("\""); - - } - jarray.Append("]"); - - return WriteScript(jarray.ToString(), ioHelper.ResolveUrl(globalSettings.UmbracoPath), angularModule); - } - - /// - /// Parses the JsResources.Main and replaces the replacement tokens accordingly - /// - /// - /// - /// - /// - internal static string WriteScript(string scripts, string umbracoPath, string angularModule) - { - var count = 0; - var replacements = new[] { scripts, umbracoPath, angularModule }; - // replace, catering for the special syntax when we have - // js function() objects contained in the json - - return Token.Replace(Resources.Main, match => - { - var replacement = replacements[count++]; - return JsFunctionParser.Replace(replacement, "$2"); - }); - } - - internal static IEnumerable GetTinyMceInitialization() - { - var resources = JsonConvert.DeserializeObject(Resources.TinyMceInitialize); - return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); - } - - public static async Task> OptimizeTinyMceScriptFilesAsync(Uri requestUrl, IRuntimeMinifier runtimeMinifier) - { - return await OptimizeScriptFilesAsync(requestUrl, GetTinyMceInitialization(), runtimeMinifier); - } - - - /// - /// Returns the default config as a JArray - /// - /// - public static IEnumerable GetPreviewInitialization() - { - var resources = JsonConvert.DeserializeObject(Resources.PreviewInitialize); - return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); - } - - - /// - /// Returns a list of optimized script paths - /// - /// - /// - /// - /// - /// - /// Used to cache bust and optimize script paths - /// - public static async Task> OptimizeScriptFilesAsync(Uri requestUrl, IEnumerable scriptFiles, IRuntimeMinifier runtimeMinifier) - { - var scripts = new HashSet(); - foreach (var script in scriptFiles) - scripts.Add(script); - - scripts = new HashSet(await OptimizeAssetCollectionAsync(scripts, AssetType.Javascript, requestUrl, runtimeMinifier)); - - return scripts.ToArray(); - } - - internal static async Task> OptimizeAssetCollectionAsync(IEnumerable assets, AssetType assetType, Uri requestUrl, IRuntimeMinifier runtimeMinifier) - { - if (requestUrl == null) throw new ArgumentNullException(nameof(requestUrl)); - - var dependencies = assets.Where(x => x.IsNullOrWhiteSpace() == false).Select(x => - { - // most declarations with be made relative to the /umbraco folder, so things - // like lib/blah/blah.js so we need to turn them into absolutes here - if (x.StartsWith("/") == false && Uri.IsWellFormedUriString(x, UriKind.Relative)) - { - return new AssetFile(assetType) { FilePath = new Uri(requestUrl, x).AbsolutePath }; - } - - return assetType == AssetType.Javascript - ? new JavaScriptFile(x) - : new CssFile(x) as IAssetFile; - }).ToList(); - - - return await runtimeMinifier.GetAssetPathsAsync(assetType, dependencies); - } - } -} diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialization.cs b/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialization.cs deleted file mode 100644 index f32d5c6c92..0000000000 --- a/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialization.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Umbraco.Core.Assets; -using Umbraco.Core.Manifest; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Runtime; -using Umbraco.Infrastructure.RuntimeMinification; - -namespace Umbraco.Web.JavaScript -{ - /// - /// Reads from all defined manifests and ensures that any of their initialization is output with the - /// main Umbraco initialization output. - /// - public class JsInitialization : AssetInitialization - { - private readonly IManifestParser _parser; - private readonly IRuntimeMinifier _runtimeMinifier; - - public JsInitialization(IManifestParser parser, IRuntimeMinifier runtimeMinifier, PropertyEditorCollection propertyEditorCollection) : base(runtimeMinifier, propertyEditorCollection) - { - _parser = parser; - _runtimeMinifier = runtimeMinifier; - } - - /// - /// Returns a list of optimized script paths for the back office - /// - /// - /// - /// - /// - /// Cache busted/optimized script paths for the back office including manifest and property editor scripts - /// - /// - /// Used to cache bust and optimize script paths for the back office - /// - public async Task> OptimizeBackOfficeScriptFilesAsync(Uri requestUrl, IEnumerable umbracoInit, IEnumerable additionalJsFiles = null) - { - var scripts = new HashSet(); - foreach (var script in umbracoInit) - scripts.Add(script); - foreach (var script in _parser.Manifest.Scripts) - scripts.Add(script); - if (additionalJsFiles != null) - foreach (var script in additionalJsFiles) - scripts.Add(script); - - scripts = new HashSet(await JavaScriptHelper.OptimizeAssetCollectionAsync(scripts, AssetType.Javascript, requestUrl, _runtimeMinifier)); - - foreach (var script in await ScanPropertyEditorsAsync(AssetType.Javascript)) - scripts.Add(script); - - return scripts.ToArray(); - } - - /// - /// Returns the default config as a JArray - /// - /// - public static IEnumerable GetDefaultInitialization() - { - var resources = JsonConvert.DeserializeObject(Resources.JsInitialize); - return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); - } - } -} diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 96fc25a527..432033d966 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -43,20 +43,20 @@ - + True True - Resources2.resx + Resources.resx - - - - - + + + + + ResXFileCodeGenerator Resources.Designer.cs diff --git a/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs b/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs new file mode 100644 index 0000000000..cdb34ce567 --- /dev/null +++ b/src/Umbraco.Infrastructure/WebAssets/BackOfficeWebAssets.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Umbraco.Core; +using Umbraco.Core.Hosting; +using Umbraco.Core.Manifest; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.WebAssets; +using Umbraco.Infrastructure.WebAssets; +using Umbraco.Web.PropertyEditors; + +namespace Umbraco.Web.JavaScript +{ + public class BackOfficeWebAssets + { + public const string UmbracoPreviewJsBundleName = "umbraco-preview-js"; + public const string UmbracoPreviewCssBundleName = "umbraco-preview-css"; + public const string UmbracoCssBundleName = "umbraco-backoffice-css"; + public const string UmbracoInitCssBundleName = "umbraco-backoffice-init-css"; + public const string UmbracoJsBundleName = "umbraco-backoffice-js"; + public const string UmbracoTinyMceJsBundleName = "umbraco-tinymce-js"; + public const string UmbracoUpgradeCssBundleName = "umbraco-authorize-upgrade-css"; + + private readonly IHostingEnvironment _hostingEnvironment; + private readonly IRuntimeMinifier _runtimeMinifier; + private readonly IManifestParser _parser; + private readonly PropertyEditorCollection _propertyEditorCollection; + + public BackOfficeWebAssets( + IHostingEnvironment hostingEnvironment, + IRuntimeMinifier runtimeMinifier, + IManifestParser parser, + PropertyEditorCollection propertyEditorCollection) + { + _hostingEnvironment = hostingEnvironment; + _runtimeMinifier = runtimeMinifier; + _parser = parser; + _propertyEditorCollection = propertyEditorCollection; + } + + public void CreateBundles() + { + // Create bundles + + _runtimeMinifier.CreateCssBundle(UmbracoInitCssBundleName, + "lib/bootstrap-social/bootstrap-social.css", + "assets/css/umbraco.css", + "lib/font-awesome/css/font-awesome.min.css"); + + _runtimeMinifier.CreateCssBundle(UmbracoUpgradeCssBundleName, + "assets/css/umbraco.css", + "lib/bootstrap-social/bootstrap-social.css", + "lib/font-awesome/css/font-awesome.min.css"); + + _runtimeMinifier.CreateCssBundle(UmbracoPreviewCssBundleName, + "assets/css/canvasdesigner.css"); + + _runtimeMinifier.CreateJsBundle(UmbracoPreviewJsBundleName, + GetScriptsForPreview().ToArray()); + + _runtimeMinifier.CreateJsBundle(UmbracoTinyMceJsBundleName, + GetScriptsForTinyMce().ToArray()); + + var propertyEditorAssets = ScanPropertyEditors().GroupBy(x => x.AssetType); + foreach (var assetGroup in propertyEditorAssets) + { + switch (assetGroup.Key) + { + case AssetType.Javascript: + _runtimeMinifier.CreateJsBundle( + UmbracoJsBundleName, + GetScriptsForBackoffice(assetGroup.Select(x => x.FilePath)).ToArray()); + break; + case AssetType.Css: + _runtimeMinifier.CreateCssBundle( + UmbracoCssBundleName, + GetStylesheetsForBackoffice(assetGroup.Select(x => x.FilePath)).ToArray()); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + } + + /// + /// Returns scripts used to load the back office + /// + /// + private IEnumerable GetScriptsForBackoffice(IEnumerable propertyEditorScripts) + { + var umbracoInit = JsInitialization.GetDefaultInitialization(); + var scripts = new HashSet(); + foreach (var script in umbracoInit) + scripts.Add(script); + foreach (var script in _parser.Manifest.Scripts) + scripts.Add(script); + foreach (var script in propertyEditorScripts) + scripts.Add(script); + + return new HashSet(FormatPaths(scripts)); + } + + /// + /// Returns stylesheets used to load the back office + /// + /// + private IEnumerable GetStylesheetsForBackoffice(IEnumerable propertyEditorStyles) + { + var stylesheets = new HashSet(); + + foreach (var script in _parser.Manifest.Stylesheets) + stylesheets.Add(script); + foreach (var stylesheet in propertyEditorStyles) + stylesheets.Add(stylesheet); + + return new HashSet(FormatPaths(stylesheets)); + } + + /// + /// Returns the scripts used for tinymce + /// + /// + private IEnumerable GetScriptsForTinyMce() + { + var resources = JsonConvert.DeserializeObject(Resources.TinyMceInitialize); + return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); + } + + /// + /// Returns the scripts used for preview + /// + /// + private IEnumerable GetScriptsForPreview() + { + var resources = JsonConvert.DeserializeObject(Resources.PreviewInitialize); + return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); + } + + /// + /// Re-format asset paths to be absolute paths + /// + /// + /// + private IEnumerable FormatPaths(IEnumerable assets) + { + return assets + .Where(x => x.IsNullOrWhiteSpace() == false) + .Select(x => !x.StartsWith("/") && Uri.IsWellFormedUriString(x, UriKind.Relative) + // most declarations with be made relative to the /umbraco folder, so things + // like lib/blah/blah.js so we need to turn them into absolutes here + ? _hostingEnvironment.ApplicationVirtualPath.EnsureStartsWith('/').TrimEnd("/") + x.EnsureStartsWith('/') + : x).ToList(); + } + + /// + /// Returns the web asset paths to load for property editors that have the attribute applied + /// + /// + private IEnumerable ScanPropertyEditors() + { + return _propertyEditorCollection + .SelectMany(x => x.GetType().GetCustomAttributes(false)); + } + } +} diff --git a/src/Umbraco.Infrastructure/WebAssets/CssInitialization.cs b/src/Umbraco.Infrastructure/WebAssets/CssInitialization.cs new file mode 100644 index 0000000000..1b1d492332 --- /dev/null +++ b/src/Umbraco.Infrastructure/WebAssets/CssInitialization.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core.WebAssets; + +namespace Umbraco.Web.JavaScript +{ + public class CssInitialization + { + private readonly IRuntimeMinifier _runtimeMinifier; + + public CssInitialization(IRuntimeMinifier runtimeMinifier) + { + _runtimeMinifier = runtimeMinifier; + } + + /// + /// Processes all found manifest files, and outputs css inject calls for all css files found in all manifests. + /// + public async Task GetStylesheetInitializationAsync() + { + var files = await _runtimeMinifier.GetAssetPathsAsync(BackOfficeWebAssets.UmbracoCssBundleName); + return WriteScript(files); + } + + internal static string WriteScript(IEnumerable files) + { + var sb = new StringBuilder(); + foreach (var file in files) + sb.AppendFormat("{0}LazyLoad.css('{1}');", Environment.NewLine, file); + return sb.ToString(); + } + + } +} diff --git a/src/Umbraco.Infrastructure/WebAssets/JavaScriptHelper.cs b/src/Umbraco.Infrastructure/WebAssets/JavaScriptHelper.cs new file mode 100644 index 0000000000..833d177ea7 --- /dev/null +++ b/src/Umbraco.Infrastructure/WebAssets/JavaScriptHelper.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; +using Umbraco.Core.IO; +using Umbraco.Core.WebAssets; +using Umbraco.Infrastructure.WebAssets; + +namespace Umbraco.Web.JavaScript +{ + // TODO: Rename this + public class JavaScriptHelper + { + // deal with javascript functions inside of json (not a supported json syntax) + private const string PrefixJavaScriptObject = "@@@@"; + private static readonly Regex JsFunctionParser = new Regex($"(\"{PrefixJavaScriptObject}(.*?)\")+", + RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled); + + // replace tokens in the js main + private static readonly Regex Token = new Regex("(\"##\\w+?##\")", RegexOptions.Compiled); + + + /// + /// Gets the JS initialization script to boot the back office application + /// + /// + /// + /// The angular module name to boot + /// + /// + /// + /// + public static string GetJavascriptInitialization(IEnumerable scripts, string angularModule, IGlobalSettings globalSettings, IIOHelper ioHelper) + { + var jarray = new StringBuilder(); + jarray.AppendLine("["); + var first = true; + foreach (var file in scripts) + { + if (first) first = false; + else jarray.AppendLine(","); + jarray.Append("\""); + jarray.Append(file); + jarray.Append("\""); + + } + jarray.Append("]"); + + return WriteScript(jarray.ToString(), ioHelper.ResolveUrl(globalSettings.UmbracoPath), angularModule); + } + + /// + /// Parses the JsResources.Main and replaces the replacement tokens accordingly + /// + /// + /// + /// + /// + internal static string WriteScript(string scripts, string umbracoPath, string angularModule) + { + var count = 0; + var replacements = new[] { scripts, umbracoPath, angularModule }; + // replace, catering for the special syntax when we have + // js function() objects contained in the json + + return Token.Replace(Resources.Main, match => + { + var replacement = replacements[count++]; + return JsFunctionParser.Replace(replacement, "$2"); + }); + } + + } +} diff --git a/src/Umbraco.Infrastructure/WebAssets/JsInitialization.cs b/src/Umbraco.Infrastructure/WebAssets/JsInitialization.cs new file mode 100644 index 0000000000..27c6e26bd2 --- /dev/null +++ b/src/Umbraco.Infrastructure/WebAssets/JsInitialization.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Umbraco.Core.Hosting; +using Umbraco.Core.Manifest; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.WebAssets; +using Umbraco.Infrastructure.WebAssets; + +namespace Umbraco.Web.JavaScript +{ + /// + /// Reads from all defined manifests and ensures that any of their initialization is output with the + /// main Umbraco initialization output. + /// + public class JsInitialization + { + + /// + /// Returns the default config as a JArray + /// + /// + public static IEnumerable GetDefaultInitialization() + { + var resources = JsonConvert.DeserializeObject(Resources.JsInitialize); + return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); + } + } +} diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialize.js b/src/Umbraco.Infrastructure/WebAssets/JsInitialize.js similarity index 100% rename from src/Umbraco.Infrastructure/RuntimeMinification/JsInitialize.js rename to src/Umbraco.Infrastructure/WebAssets/JsInitialize.js diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/Main.js b/src/Umbraco.Infrastructure/WebAssets/Main.js similarity index 100% rename from src/Umbraco.Infrastructure/RuntimeMinification/Main.js rename to src/Umbraco.Infrastructure/WebAssets/Main.js diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/PreviewInitialize.js b/src/Umbraco.Infrastructure/WebAssets/PreviewInitialize.js similarity index 100% rename from src/Umbraco.Infrastructure/RuntimeMinification/PreviewInitialize.js rename to src/Umbraco.Infrastructure/WebAssets/PreviewInitialize.js diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/PropertyEditorAssetAttribute.cs b/src/Umbraco.Infrastructure/WebAssets/PropertyEditorAssetAttribute.cs similarity index 51% rename from src/Umbraco.Infrastructure/RuntimeMinification/PropertyEditorAssetAttribute.cs rename to src/Umbraco.Infrastructure/WebAssets/PropertyEditorAssetAttribute.cs index c142e31b91..5c6de949ff 100644 --- a/src/Umbraco.Infrastructure/RuntimeMinification/PropertyEditorAssetAttribute.cs +++ b/src/Umbraco.Infrastructure/WebAssets/PropertyEditorAssetAttribute.cs @@ -1,5 +1,5 @@ using System; -using Umbraco.Core.Assets; +using Umbraco.Core.WebAssets; namespace Umbraco.Web.PropertyEditors { @@ -12,23 +12,13 @@ namespace Umbraco.Web.PropertyEditors [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class PropertyEditorAssetAttribute : Attribute { - public AssetType AssetType { get; private set; } - public string FilePath { get; private set; } - public int Priority { get; set; } - - /// - /// Returns a CDF file reference - /// - public IAssetFile DependencyFile => - Priority == int.MinValue - ? new AssetFile(AssetType) {FilePath = FilePath} - : new AssetFile(AssetType) {FilePath = FilePath, Priority = Priority}; + public AssetType AssetType { get; } + public string FilePath { get; } public PropertyEditorAssetAttribute(AssetType assetType, string filePath) { AssetType = assetType; FilePath = filePath; - Priority = int.MinValue; } } } diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/Resources.Designer.cs b/src/Umbraco.Infrastructure/WebAssets/Resources.Designer.cs similarity index 97% rename from src/Umbraco.Infrastructure/RuntimeMinification/Resources.Designer.cs rename to src/Umbraco.Infrastructure/WebAssets/Resources.Designer.cs index 8653210a9d..ad696497d4 100644 --- a/src/Umbraco.Infrastructure/RuntimeMinification/Resources.Designer.cs +++ b/src/Umbraco.Infrastructure/WebAssets/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Umbraco.Infrastructure.RuntimeMinification { +namespace Umbraco.Infrastructure.WebAssets { using System; @@ -19,7 +19,7 @@ namespace Umbraco.Infrastructure.RuntimeMinification { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -39,7 +39,7 @@ namespace Umbraco.Infrastructure.RuntimeMinification { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Infrastructure.RuntimeMinification.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Infrastructure.WebAssets.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/Resources.resx b/src/Umbraco.Infrastructure/WebAssets/Resources.resx similarity index 100% rename from src/Umbraco.Infrastructure/RuntimeMinification/Resources.resx rename to src/Umbraco.Infrastructure/WebAssets/Resources.resx diff --git a/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs b/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs new file mode 100644 index 0000000000..e5c7d20ec5 --- /dev/null +++ b/src/Umbraco.Infrastructure/WebAssets/RuntimeMinifierExtensions.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; +using Umbraco.Core.WebAssets; + +namespace Umbraco.Web.JavaScript +{ + public static class RuntimeMinifierExtensions + { + /// + /// Returns the JavaScript to load the back office's assets + /// + /// + public static async Task GetScriptForLoadingBackOfficeAsync(this IRuntimeMinifier minifier, IGlobalSettings globalSettings, IIOHelper ioHelper) + { + var initCss = new CssInitialization(minifier); + var files = await minifier.GetAssetPathsAsync(BackOfficeWebAssets.UmbracoJsBundleName); + var result = JavaScriptHelper.GetJavascriptInitialization(files, "umbraco", globalSettings, ioHelper); + result += await initCss.GetStylesheetInitializationAsync(); + + return result; + } + } +} diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/ServerVariables.js b/src/Umbraco.Infrastructure/WebAssets/ServerVariables.js similarity index 100% rename from src/Umbraco.Infrastructure/RuntimeMinification/ServerVariables.js rename to src/Umbraco.Infrastructure/WebAssets/ServerVariables.js diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/ServerVariablesParser.cs b/src/Umbraco.Infrastructure/WebAssets/ServerVariablesParser.cs similarity index 93% rename from src/Umbraco.Infrastructure/RuntimeMinification/ServerVariablesParser.cs rename to src/Umbraco.Infrastructure/WebAssets/ServerVariablesParser.cs index 38669c166c..07b29d7098 100644 --- a/src/Umbraco.Infrastructure/RuntimeMinification/ServerVariablesParser.cs +++ b/src/Umbraco.Infrastructure/WebAssets/ServerVariablesParser.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; -using Umbraco.Infrastructure.RuntimeMinification; +using Umbraco.Infrastructure.WebAssets; namespace Umbraco.Web.JavaScript { diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/TinyMceInitialize.js b/src/Umbraco.Infrastructure/WebAssets/TinyMceInitialize.js similarity index 100% rename from src/Umbraco.Infrastructure/RuntimeMinification/TinyMceInitialize.js rename to src/Umbraco.Infrastructure/WebAssets/TinyMceInitialize.js diff --git a/src/Umbraco.Tests/Web/AngularIntegration/JsInitializationTests.cs b/src/Umbraco.Tests/Web/AngularIntegration/JsInitializationTests.cs index 71e7963d61..79b331327e 100644 --- a/src/Umbraco.Tests/Web/AngularIntegration/JsInitializationTests.cs +++ b/src/Umbraco.Tests/Web/AngularIntegration/JsInitializationTests.cs @@ -2,7 +2,6 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Web.JavaScript; -using Umbraco.Web.JavaScript.CDF; namespace Umbraco.Tests.Web.AngularIntegration { diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index ddc1287a42..fdaf131212 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -1,18 +1,26 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using Umbraco.Core.Runtime; +using Umbraco.Core.WebAssets; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.ActionResults; +using Umbraco.Web.JavaScript; namespace Umbraco.Web.BackOffice.Controllers { public class BackOfficeController : Controller { private readonly IRuntimeMinifier _runtimeMinifier; + private readonly IGlobalSettings _globalSettings; + private readonly IIOHelper _ioHelper; - public BackOfficeController(IRuntimeMinifier runtimeMinifier) + public BackOfficeController(IRuntimeMinifier runtimeMinifier, IGlobalSettings globalSettings, IIOHelper ioHelper) { _runtimeMinifier = runtimeMinifier; + _globalSettings = globalSettings; + _ioHelper = ioHelper; } // GET @@ -28,7 +36,7 @@ namespace Umbraco.Web.BackOffice.Controllers [MinifyJavaScriptResult(Order = 0)] public async Task Application() { - var result = await _runtimeMinifier.GetScriptForBackOfficeAsync(); + var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(_globalSettings, _ioHelper); return new JavaScriptResult(result); } diff --git a/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs index 65612a1354..0ed0fd658a 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResultAttribute.cs @@ -2,8 +2,8 @@ using Microsoft.AspNetCore.Mvc.Filters; using Umbraco.Core.Hosting; using Microsoft.Extensions.DependencyInjection; -using Umbraco.Core.Assets; using Umbraco.Core.Runtime; +using Umbraco.Core.WebAssets; using Umbraco.Web.BackOffice.Controllers; using Umbraco.Web.Common.ActionResults; diff --git a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs index 8678451cc6..748f3239e8 100644 --- a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs +++ b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs @@ -1,6 +1,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Runtime; +using Umbraco.Core.WebAssets; namespace Umbraco.Web.Common.RuntimeMinification { diff --git a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs index 64aa984f00..9d6fcc9d22 100644 --- a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs +++ b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs @@ -1,21 +1,16 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; using Smidge; using Smidge.CompositeFiles; using Smidge.FileProcessors; +using Smidge.Models; using Smidge.Nuglify; using Umbraco.Core; -using Umbraco.Core.Assets; using Umbraco.Core.Configuration; using Umbraco.Core.Hosting; using Umbraco.Core.IO; -using Umbraco.Core.Manifest; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Runtime; +using Umbraco.Core.WebAssets; using Umbraco.Web.JavaScript; using CssFile = Smidge.Models.CssFile; using JavaScriptFile = Smidge.Models.JavaScriptFile; @@ -25,36 +20,30 @@ namespace Umbraco.Web.Common.RuntimeMinification public class SmidgeRuntimeMinifier : IRuntimeMinifier { private readonly IGlobalSettings _globalSettings; - private readonly IHttpContextAccessor _httpContextAccessor; private readonly IIOHelper _ioHelper; private readonly IHostingEnvironment _hostingEnvironment; private readonly ISmidgeConfig _smidgeConfig; private readonly IConfigManipulator _configManipulator; - private readonly IManifestParser _manifestParser; private readonly PreProcessPipelineFactory _preProcessPipelineFactory; - private readonly PropertyEditorCollection _propertyEditorCollection; + private readonly BundleManager _bundles; private readonly SmidgeHelper _smidge; private PreProcessPipeline _jsPipeline; private PreProcessPipeline _cssPipeline; public SmidgeRuntimeMinifier( + BundleManager bundles, SmidgeHelper smidge, PreProcessPipelineFactory preProcessPipelineFactory, - IManifestParser manifestParser, - IHttpContextAccessor httpContextAccessor, - PropertyEditorCollection propertyEditorCollection, IGlobalSettings globalSettings, IIOHelper ioHelper, IHostingEnvironment hostingEnvironment, ISmidgeConfig smidgeConfig, IConfigManipulator configManipulator) { + _bundles = bundles; _smidge = smidge; _preProcessPipelineFactory = preProcessPipelineFactory; - _manifestParser = manifestParser; - _httpContextAccessor = httpContextAccessor; - _propertyEditorCollection = propertyEditorCollection; _globalSettings = globalSettings; _ioHelper = ioHelper; _hostingEnvironment = hostingEnvironment; @@ -62,41 +51,42 @@ namespace Umbraco.Web.Common.RuntimeMinification _configManipulator = configManipulator; } - private PreProcessPipeline JsPipeline => _jsPipeline ??= _preProcessPipelineFactory.Create(typeof(JsMinifier)); - private PreProcessPipeline CssPipeline => _cssPipeline ??= _preProcessPipelineFactory.Create(typeof(NuglifyCss)); + private PreProcessPipeline JsPipeline => _jsPipeline ??= _preProcessPipelineFactory.Create(typeof(JsMinifier)); + private PreProcessPipeline CssPipeline => _cssPipeline ??= _preProcessPipelineFactory.Create(typeof(NuglifyCss)); - private Uri GetRequestUrl() => new Uri(_httpContextAccessor.HttpContext.Request.GetEncodedUrl(), UriKind.Absolute); - public string GetHashValue => _smidgeConfig.Version; + public string CacheBuster => _smidgeConfig.Version; - public void RequiresCss(string bundleName, params string[] filePaths) => _smidge.CreateCssBundle(bundleName).RequiresCss(filePaths); - public string RenderCssHere(string bundleName) => _smidge.CssHereAsync(bundleName).ToString(); - public void RequiresJs(string bundleName, params string[] filePaths) => _smidge.CreateJsBundle(bundleName).RequiresJs(filePaths); - public string RenderJsHere(string bundleName) => _smidge.JsHereAsync(bundleName).ToString(); - - public async Task> GetAssetPathsAsync(AssetType assetType, List attributes) + // only issue with creating bundles like this is that we don't have full control over the bundle options, though that could + public void CreateCssBundle(string bundleName, params string[] filePaths) { + if (_bundles.Exists(bundleName)) + throw new InvalidOperationException($"The bundle name {bundleName} already exists"); - var files = attributes - .Where(x => x.DependencyType == assetType) - .Select(x=>x.FilePath) - .ToArray(); + var bundle = _bundles.Create(bundleName, WebFileType.Css, filePaths); - if (files.Length == 0) return Array.Empty(); + // Here we could configure bundle options instead of using smidge's global defaults. + // For example we can use our own custom cache buster for this bundle without having the global one + // affect this or vice versa. + } - if (assetType == AssetType.Javascript) - { - _smidge.RequiresJs(files); + public string RenderCssHere(string bundleName) => _smidge.CssHereAsync(bundleName, _hostingEnvironment.IsDebugMode).ToString(); - return await _smidge.GenerateJsUrlsAsync(JsPipeline, _hostingEnvironment.IsDebugMode); - } - else - { - _smidge.RequiresCss(files); + public void CreateJsBundle(string bundleName, params string[] filePaths) + { + if (_bundles.Exists(bundleName)) + throw new InvalidOperationException($"The bundle name {bundleName} already exists"); - return await _smidge.GenerateCssUrlsAsync(CssPipeline, _hostingEnvironment.IsDebugMode); - } + var bundle = _bundles.Create(bundleName, WebFileType.Js, filePaths); + + // Here we could configure bundle options instead of using smidge's global defaults. + // For example we can use our own custom cache buster for this bundle without having the global one + // affect this or vice versa. } + public string RenderJsHere(string bundleName) => _smidge.JsHereAsync(bundleName, _hostingEnvironment.IsDebugMode).ToString(); + + public async Task> GetAssetPathsAsync(string bundleName) => await _smidge.GenerateJsUrlsAsync(bundleName, _hostingEnvironment.IsDebugMode); + public async Task MinifyAsync(string fileContent, AssetType assetType) { if (assetType == AssetType.Javascript) @@ -126,31 +116,6 @@ namespace Umbraco.Web.Common.RuntimeMinification _configManipulator.SaveConfigValue(Constants.Configuration.ConfigRuntimeMinificationVersion, version.ToString()); } - public async Task GetScriptForBackOfficeAsync() - { - var initJs = new JsInitialization(_manifestParser, this, _propertyEditorCollection); - var initCss = new CssInitialization(_manifestParser, this, _propertyEditorCollection); - - var requestUrl = GetRequestUrl(); - var files = await initJs.OptimizeBackOfficeScriptFilesAsync(requestUrl, JsInitialization.GetDefaultInitialization()); - var result = JavaScriptHelper.GetJavascriptInitialization(files, "umbraco", _globalSettings, _ioHelper); - result += await initCss.GetStylesheetInitializationAsync(requestUrl); - - return result; - } - - public async Task> GetAssetListAsync() - { - var initJs = new JsInitialization(_manifestParser, this, _propertyEditorCollection); - var initCss = new CssInitialization(_manifestParser, this, _propertyEditorCollection); - var assets = new List(); - var requestUrl = GetRequestUrl(); - assets.AddRange(await initJs.OptimizeBackOfficeScriptFilesAsync(requestUrl, Enumerable.Empty())); - assets.AddRange(await initCss.GetStylesheetFilesAsync(requestUrl)); - - return assets; - } - } } diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/EditProfile.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/EditProfile.cshtml index dd71635424..576541ea4a 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/EditProfile.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/EditProfile.cshtml @@ -10,18 +10,12 @@ Html.EnableClientValidation(); Html.EnableUnobtrusiveJavaScript(); - var runtimeMinifier = Current.RuntimeMinifier; - - runtimeMinifier.RequiresJs("umbraco", - "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"); - var success = TempData["ProfileUpdateSuccess"] != null; } -@*NOTE: This RenderJsHere code should be put on your main template page where the rest of your script tags are placed*@ -@Html.Raw(runtimeMinifier.RenderJsHere("umbraco")); + + + @if (Current.MembershipHelper.IsLoggedIn() && profileModel != null) { diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Login.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Login.cshtml index 763033a39d..b50d1ac806 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Login.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/Login.cshtml @@ -12,16 +12,11 @@ Html.EnableClientValidation(); Html.EnableUnobtrusiveJavaScript(); - var runtimeMinifier = Current.RuntimeMinifier; - - runtimeMinifier.RequiresJs("umbraco", - "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"); } -@* NOTE: This RenderJsHere code should be put on your main template page where the rest of your script tags are placed *@ -@Html.Raw(runtimeMinifier.RenderJsHere("umbraco")) + + + @using (Html.BeginUmbracoForm("HandleLogin")) { diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml index abd6283b48..5e6230a294 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml @@ -34,18 +34,12 @@ Html.EnableClientValidation(); Html.EnableUnobtrusiveJavaScript(); - var runtimeMinifier = Current.RuntimeMinifier; - - runtimeMinifier.RequiresJs("umbraco", - "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"); - var success = TempData["FormSuccess"] != null; } -@*NOTE: This RenderJsHere code should be put on your main template page where the rest of your script tags are placed*@ -@Html.Raw(runtimeMinifier.RenderJsHere("umbraco")); + + + @if (success) { diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index ddc046bb38..89cf6f9136 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -1,17 +1,13 @@ @using Umbraco.Core @using Umbraco.Web.Composing @using Umbraco.Web +@using Umbraco.Web.JavaScript @inherits System.Web.Mvc.WebViewPage @{ Layout = null; var runtimeMinifier = Current.RuntimeMinifier; - - runtimeMinifier.RequiresCss("umbraco", - "assets/css/umbraco.css", - "lib/bootstrap-social/bootstrap-social.css", - "lib/font-awesome/css/font-awesome.min.css"); } @@ -23,8 +19,8 @@ Umbraco - - @Html.Raw(runtimeMinifier.RenderJsHere("umbraco")); + + @Html.Raw(runtimeMinifier.RenderCssHere(BackOfficeWebAssets.UmbracoUpgradeCssBundleName)); @*Because we're lazy loading angular js, the embedded cloak style will not be loaded initially, but we need it*@