From ffc6ce6553adb8c6bef36e7361a8a579f66b565c Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 30 Mar 2020 21:27:35 +0200 Subject: [PATCH] AB#8522 - Smidge implementation of the Runtime Minifier --- .../Models/HostingSettings.cs | 2 +- src/Umbraco.Core/CompositionExtensions.cs | 73 +++++++++ .../HybridUmbracoContextAccessor.cs | 2 +- src/Umbraco.Core/Runtime/IRuntimeMinifier.cs | 17 +- ...ator.cs => ImageSharpImageUrlGenerator.cs} | 2 +- .../AssetInitialization.cs | 20 +-- .../RuntimeMinification}/CssInitialization.cs | 20 ++- .../RuntimeMinification}/JavaScriptHelper.cs | 27 ++-- .../RuntimeMinification}/JsInitialization.cs | 21 +-- .../RuntimeMinification}/JsInitialize.js | 0 .../RuntimeMinification}/Main.js | 0 .../RuntimeMinification}/PreviewInitialize.js | 0 .../PropertyEditorAssetAttribute.cs | 0 .../Resources.Designer.cs | 25 ++- .../RuntimeMinification/Resources.resx | 37 +++++ .../RuntimeMinification}/ServerVariables.js | 0 .../ServerVariablesParser.cs | 3 +- .../RuntimeMinification}/TinyMceInitialize.js | 0 .../Umbraco.Infrastructure.csproj | 13 ++ .../ImageProcessorImageUrlGeneratorTest.cs | 2 +- .../AspNetCore/AspNetCoreComposer.cs | 39 +++++ .../AspNetCore/AspNetCorePasswordHasher.cs | 20 +++ .../UmbracoCoreServiceCollectionExtensions.cs | 2 + ...inificationApplicationBuilderExtensions.cs | 18 +++ .../Controllers/BackOfficeController.cs | 44 ++++++ .../Filters/MinifyJavaScriptResult.cs | 52 +++++++ .../Smidge/SmidgeComponent.cs | 4 +- .../Smidge/SmidgeComposer.cs | 7 +- .../Smidge/SmidgeRuntimeMinifier.cs | 147 ++++++++++++------ src/Umbraco.Web.UI.NetCore/Program.cs | 2 + src/Umbraco.Web.UI.NetCore/Startup.cs | 16 +- .../Umbraco.Web.UI.NetCore.csproj | 21 ++- src/Umbraco.Web.UI.NetCore/appsettings.json | 18 ++- .../Umbraco/Views/AuthorizeUpgrade.cshtml | 4 +- .../Umbraco/Views/Default.cshtml | 5 +- .../Umbraco/Views/Preview/Index.cshtml | 2 +- src/Umbraco.Web/CompositionExtensions.cs | 65 +------- .../Editors/BackOfficeController.cs | 15 +- src/Umbraco.Web/Editors/PreviewController.cs | 9 +- .../HtmlHelperBackOfficeExtensions.cs | 2 +- .../CDF/ClientDependencyRuntimeMinifier.cs | 63 +++++--- src/Umbraco.Web/JavaScript/Resources.resx | 136 ---------------- .../Mvc/MinifyJavaScriptResultAttribute.cs | 2 +- src/Umbraco.Web/Runtime/WebInitialComposer.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 31 ---- 45 files changed, 586 insertions(+), 404 deletions(-) rename src/{Umbraco.Web => Umbraco.Core}/HybridUmbracoContextAccessor.cs (87%) rename src/Umbraco.Infrastructure/Models/{ImageProcessorImageUrlGenerator.cs => ImageSharpImageUrlGenerator.cs} (98%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/AssetInitialization.cs (52%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/CssInitialization.cs (59%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/JavaScriptHelper.cs (76%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/JsInitialization.cs (68%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/JsInitialize.js (100%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/Main.js (100%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/PreviewInitialize.js (100%) rename src/{Umbraco.Web/PropertyEditors => Umbraco.Infrastructure/RuntimeMinification}/PropertyEditorAssetAttribute.cs (100%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/Resources.Designer.cs (84%) create mode 100644 src/Umbraco.Infrastructure/RuntimeMinification/Resources.resx rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/ServerVariables.js (100%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/ServerVariablesParser.cs (85%) rename src/{Umbraco.Web/JavaScript => Umbraco.Infrastructure/RuntimeMinification}/TinyMceInitialize.js (100%) create mode 100644 src/Umbraco.Web.BackOffice/AspNetCore/AspNetCorePasswordHasher.cs create mode 100644 src/Umbraco.Web.BackOffice/AspNetCore/UmbracoRuntimeMinificationApplicationBuilderExtensions.cs create mode 100644 src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs create mode 100644 src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResult.cs delete mode 100644 src/Umbraco.Web/JavaScript/Resources.resx diff --git a/src/Umbraco.Configuration/Models/HostingSettings.cs b/src/Umbraco.Configuration/Models/HostingSettings.cs index 4a156cee6a..7cfc08d2d4 100644 --- a/src/Umbraco.Configuration/Models/HostingSettings.cs +++ b/src/Umbraco.Configuration/Models/HostingSettings.cs @@ -22,6 +22,6 @@ namespace Umbraco.Configuration.Models /// Gets a value indicating whether umbraco is running in [debug mode]. /// /// true if [debug mode]; otherwise, false. - public bool DebugMode => _configuration.GetValue(Prefix+":Debug", false); + public bool DebugMode => _configuration.GetValue(Prefix+"Debug", false); } } diff --git a/src/Umbraco.Core/CompositionExtensions.cs b/src/Umbraco.Core/CompositionExtensions.cs index bea78f82ed..a16abf76ac 100644 --- a/src/Umbraco.Core/CompositionExtensions.cs +++ b/src/Umbraco.Core/CompositionExtensions.cs @@ -1,6 +1,13 @@ using Umbraco.Core.Composing; using Umbraco.Core.PropertyEditors; +using Umbraco.Web.Actions; +using Umbraco.Web.ContentApps; using Umbraco.Web.Dashboards; +using Umbraco.Web.Editors; +using Umbraco.Web.HealthCheck; +using Umbraco.Web.Routing; +using Umbraco.Web.Sections; +using Umbraco.Web.Tour; namespace Umbraco.Core { @@ -9,6 +16,72 @@ namespace Umbraco.Core #region Collection Builders + /// + /// Gets the actions collection builder. + /// + /// The composition. + /// + internal static ActionCollectionBuilder Actions(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the content apps collection builder. + /// + /// The composition. + /// + public static ContentAppFactoryCollectionBuilder ContentApps(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the content finders collection builder. + /// + /// The composition. + /// + public static ContentFinderCollectionBuilder ContentFinders(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the editor validators collection builder. + /// + /// The composition. + /// + internal static EditorValidatorCollectionBuilder EditorValidators(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the health checks collection builder. + /// + /// The composition. + public static HealthCheckCollectionBuilder HealthChecks(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the TourFilters collection builder. + /// + public static TourFilterCollectionBuilder TourFilters(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the url providers collection builder. + /// + /// The composition. + public static UrlProviderCollectionBuilder UrlProviders(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the media url providers collection builder. + /// + /// The composition. + public static MediaUrlProviderCollectionBuilder MediaUrlProviders(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the backoffice sections/applications collection builder. + /// + /// The composition. + public static SectionCollectionBuilder Sections(this Composition composition) + => composition.WithCollectionBuilder(); + /// /// Gets the components collection builder. /// diff --git a/src/Umbraco.Web/HybridUmbracoContextAccessor.cs b/src/Umbraco.Core/HybridUmbracoContextAccessor.cs similarity index 87% rename from src/Umbraco.Web/HybridUmbracoContextAccessor.cs rename to src/Umbraco.Core/HybridUmbracoContextAccessor.cs index bb8e2d6993..1ad4777460 100644 --- a/src/Umbraco.Web/HybridUmbracoContextAccessor.cs +++ b/src/Umbraco.Core/HybridUmbracoContextAccessor.cs @@ -5,7 +5,7 @@ namespace Umbraco.Web /// /// Implements a hybrid . /// - internal class HybridUmbracoContextAccessor : HybridAccessorBase, IUmbracoContextAccessor + public class HybridUmbracoContextAccessor : HybridAccessorBase, IUmbracoContextAccessor { /// /// Initializes a new instance of the class. diff --git a/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs b/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs index 53d9bda179..b76f2007b6 100644 --- a/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs +++ b/src/Umbraco.Core/Runtime/IRuntimeMinifier.cs @@ -1,6 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Web; +using System.Collections.Generic; +using System.Threading.Tasks; using Umbraco.Core.Assets; namespace Umbraco.Core.Runtime @@ -10,23 +9,23 @@ namespace Umbraco.Core.Runtime string GetHashValue { get; } //return type HtmlHelper - void RequiresCss(string filePath, string bundleName); + void RequiresCss(string bundleName, params string[] filePaths); //return type IHtmlString //IClientDependencyPath[] string RenderCssHere(string bundleName); // return type HtmlHelper - void RequiresJs(string filePath, string bundleName); + void RequiresJs(string bundleName, params string[] filePaths); // return type IHtmlString string RenderJsHere(string bundleName); - IEnumerable GetAssetPaths(AssetType assetType, List attributes); + Task> GetAssetPathsAsync(AssetType assetType, List attributes); - string Minify(string src, AssetType assetType); + Task MinifyAsync(string fileContent, AssetType assetType); void Reset(); - string GetScriptForBackOffice(); - IEnumerable GetAssetList(); + Task GetScriptForBackOfficeAsync(); + Task> GetAssetListAsync(); } } diff --git a/src/Umbraco.Infrastructure/Models/ImageProcessorImageUrlGenerator.cs b/src/Umbraco.Infrastructure/Models/ImageSharpImageUrlGenerator.cs similarity index 98% rename from src/Umbraco.Infrastructure/Models/ImageProcessorImageUrlGenerator.cs rename to src/Umbraco.Infrastructure/Models/ImageSharpImageUrlGenerator.cs index f88309d7e3..72652ab236 100644 --- a/src/Umbraco.Infrastructure/Models/ImageProcessorImageUrlGenerator.cs +++ b/src/Umbraco.Infrastructure/Models/ImageSharpImageUrlGenerator.cs @@ -5,7 +5,7 @@ using Umbraco.Core.Models; namespace Umbraco.Web.Models { - public class ImageProcessorImageUrlGenerator : IImageUrlGenerator + public class ImageSharpImageUrlGenerator : IImageUrlGenerator { public string GetImageUrl(ImageUrlGenerationOptions options) { diff --git a/src/Umbraco.Web/JavaScript/AssetInitialization.cs b/src/Umbraco.Infrastructure/RuntimeMinification/AssetInitialization.cs similarity index 52% rename from src/Umbraco.Web/JavaScript/AssetInitialization.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/AssetInitialization.cs index e80fd5e7d7..74931dff54 100644 --- a/src/Umbraco.Web/JavaScript/AssetInitialization.cs +++ b/src/Umbraco.Infrastructure/RuntimeMinification/AssetInitialization.cs @@ -1,34 +1,34 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Web; +using System.Threading.Tasks; using Umbraco.Core; using Umbraco.Core.Assets; +using Umbraco.Core.PropertyEditors; using Umbraco.Core.Runtime; -using Umbraco.Web.Composing; using Umbraco.Web.PropertyEditors; namespace Umbraco.Web.JavaScript { - internal abstract class AssetInitialization + public abstract class AssetInitialization { private readonly IRuntimeMinifier _runtimeMinifier; + private readonly PropertyEditorCollection _propertyEditorCollection; - public AssetInitialization(IRuntimeMinifier runtimeMinifier) + public AssetInitialization(IRuntimeMinifier runtimeMinifier, PropertyEditorCollection propertyEditorCollection) { _runtimeMinifier = runtimeMinifier; + _propertyEditorCollection = propertyEditorCollection; } - protected IEnumerable ScanPropertyEditors(AssetType assetType, HttpContextBase httpContext) + protected async Task> ScanPropertyEditorsAsync(AssetType assetType) { - if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); - var attributes = Current.PropertyEditors + var attributes = _propertyEditorCollection .SelectMany(x => x.GetType().GetCustomAttributes(false)) .Where(x => x.AssetType == assetType) .Select(x => x.DependencyFile) .ToList(); - return _runtimeMinifier.GetAssetPaths(assetType, attributes); + return await _runtimeMinifier.GetAssetPathsAsync(assetType, attributes); } } } diff --git a/src/Umbraco.Web/JavaScript/CssInitialization.cs b/src/Umbraco.Infrastructure/RuntimeMinification/CssInitialization.cs similarity index 59% rename from src/Umbraco.Web/JavaScript/CssInitialization.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/CssInitialization.cs index 76b42e336e..000079de5b 100644 --- a/src/Umbraco.Web/JavaScript/CssInitialization.cs +++ b/src/Umbraco.Infrastructure/RuntimeMinification/CssInitialization.cs @@ -2,19 +2,25 @@ 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 { - internal class CssInitialization : AssetInitialization + public class CssInitialization : AssetInitialization { private readonly IManifestParser _parser; private readonly IRuntimeMinifier _runtimeMinifier; - public CssInitialization(IManifestParser parser, IRuntimeMinifier runtimeMinifier) : base(runtimeMinifier) + public CssInitialization( + IManifestParser parser, + IRuntimeMinifier runtimeMinifier, + PropertyEditorCollection propertyEditorCollection) + : base(runtimeMinifier, propertyEditorCollection) { _parser = parser; _runtimeMinifier = runtimeMinifier; @@ -23,20 +29,20 @@ namespace Umbraco.Web.JavaScript /// /// Processes all found manifest files, and outputs css inject calls for all css files found in all manifests. /// - public string GetStylesheetInitialization(HttpContextBase httpContext) + public async Task GetStylesheetInitializationAsync(Uri requestUrl) { - var files = GetStylesheetFiles(httpContext); + var files = await GetStylesheetFilesAsync(requestUrl); return WriteScript(files); } - public IEnumerable GetStylesheetFiles(HttpContextBase httpContext) + public async Task> GetStylesheetFilesAsync(Uri requestUrl) { var stylesheets = new HashSet(); - var optimizedManifest = JavaScriptHelper.OptimizeAssetCollection(_parser.Manifest.Stylesheets, AssetType.Css, httpContext, _runtimeMinifier); + var optimizedManifest = await JavaScriptHelper.OptimizeAssetCollectionAsync(_parser.Manifest.Stylesheets, AssetType.Css, requestUrl, _runtimeMinifier); foreach (var stylesheet in optimizedManifest) stylesheets.Add(stylesheet); - foreach (var stylesheet in ScanPropertyEditors(AssetType.Css, httpContext)) + foreach (var stylesheet in await ScanPropertyEditorsAsync(AssetType.Css)) stylesheets.Add(stylesheet); return stylesheets.ToArray(); diff --git a/src/Umbraco.Web/JavaScript/JavaScriptHelper.cs b/src/Umbraco.Infrastructure/RuntimeMinification/JavaScriptHelper.cs similarity index 76% rename from src/Umbraco.Web/JavaScript/JavaScriptHelper.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/JavaScriptHelper.cs index 3ee6767b68..0862fd23a5 100644 --- a/src/Umbraco.Web/JavaScript/JavaScriptHelper.cs +++ b/src/Umbraco.Infrastructure/RuntimeMinification/JavaScriptHelper.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; -using System.Web; +using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core; @@ -11,6 +11,7 @@ using Umbraco.Core.Assets; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Runtime; +using Umbraco.Infrastructure.RuntimeMinification; namespace Umbraco.Web.JavaScript { @@ -28,13 +29,12 @@ namespace Umbraco.Web.JavaScript /// /// Gets the JS initialization script to boot the back office application /// - /// /// /// /// The angular module name to boot /// /// - public static string GetJavascriptInitialization(HttpContextBase httpContext, IEnumerable scripts, string angularModule, IGlobalSettings globalSettings, IIOHelper ioHelper) + public static string GetJavascriptInitialization(IEnumerable scripts, string angularModule, IGlobalSettings globalSettings, IIOHelper ioHelper) { var jarray = new StringBuilder(); jarray.AppendLine("["); @@ -80,9 +80,9 @@ namespace Umbraco.Web.JavaScript return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); } - internal static IEnumerable OptimizeTinyMceScriptFiles(HttpContextBase httpContext, IRuntimeMinifier runtimeMinifier) + public static async Task> OptimizeTinyMceScriptFilesAsync(Uri requestUrl, IRuntimeMinifier runtimeMinifier) { - return OptimizeScriptFiles(httpContext, GetTinyMceInitialization(), runtimeMinifier); + return await OptimizeScriptFilesAsync(requestUrl, GetTinyMceInitialization(), runtimeMinifier); } @@ -90,7 +90,7 @@ namespace Umbraco.Web.JavaScript /// Returns the default config as a JArray /// /// - internal static IEnumerable GetPreviewInitialization() + public static IEnumerable GetPreviewInitialization() { var resources = JsonConvert.DeserializeObject(Resources.PreviewInitialize); return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString()); @@ -100,30 +100,27 @@ namespace Umbraco.Web.JavaScript /// /// Returns a list of optimized script paths /// - /// + /// /// /// /// /// /// Used to cache bust and optimize script paths /// - public static IEnumerable OptimizeScriptFiles(HttpContextBase httpContext, IEnumerable scriptFiles, IRuntimeMinifier runtimeMinifier) + 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(OptimizeAssetCollection(scripts, AssetType.Javascript, httpContext, runtimeMinifier)); + scripts = new HashSet(await OptimizeAssetCollectionAsync(scripts, AssetType.Javascript, requestUrl, runtimeMinifier)); return scripts.ToArray(); } - internal static IEnumerable OptimizeAssetCollection(IEnumerable assets, AssetType assetType, HttpContextBase httpContext, IRuntimeMinifier runtimeMinifier) + internal static async Task> OptimizeAssetCollectionAsync(IEnumerable assets, AssetType assetType, Uri requestUrl, IRuntimeMinifier runtimeMinifier) { - if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); - - var requestUrl = httpContext.Request.Url; - if (requestUrl == null) throw new ArgumentException("HttpContext.Request.Url is null.", nameof(httpContext)); + if (requestUrl == null) throw new ArgumentNullException(nameof(requestUrl)); var dependencies = assets.Where(x => x.IsNullOrWhiteSpace() == false).Select(x => { @@ -140,7 +137,7 @@ namespace Umbraco.Web.JavaScript }).ToList(); - return runtimeMinifier.GetAssetPaths(assetType, dependencies);; + return await runtimeMinifier.GetAssetPathsAsync(assetType, dependencies); } } } diff --git a/src/Umbraco.Web/JavaScript/JsInitialization.cs b/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialization.cs similarity index 68% rename from src/Umbraco.Web/JavaScript/JsInitialization.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/JsInitialization.cs index 3183ae03c2..f32d5c6c92 100644 --- a/src/Umbraco.Web/JavaScript/JsInitialization.cs +++ b/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialization.cs @@ -1,11 +1,14 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; -using System.Web; +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 { @@ -13,12 +16,12 @@ namespace Umbraco.Web.JavaScript /// Reads from all defined manifests and ensures that any of their initialization is output with the /// main Umbraco initialization output. /// - internal class JsInitialization : AssetInitialization + public class JsInitialization : AssetInitialization { private readonly IManifestParser _parser; private readonly IRuntimeMinifier _runtimeMinifier; - public JsInitialization(IManifestParser parser, IRuntimeMinifier runtimeMinifier) : base(runtimeMinifier) + public JsInitialization(IManifestParser parser, IRuntimeMinifier runtimeMinifier, PropertyEditorCollection propertyEditorCollection) : base(runtimeMinifier, propertyEditorCollection) { _parser = parser; _runtimeMinifier = runtimeMinifier; @@ -27,7 +30,7 @@ namespace Umbraco.Web.JavaScript /// /// Returns a list of optimized script paths for the back office /// - /// + /// /// /// /// @@ -36,7 +39,7 @@ namespace Umbraco.Web.JavaScript /// /// Used to cache bust and optimize script paths for the back office /// - public IEnumerable OptimizeBackOfficeScriptFiles(HttpContextBase httpContext, IEnumerable umbracoInit, IEnumerable additionalJsFiles = null) + public async Task> OptimizeBackOfficeScriptFilesAsync(Uri requestUrl, IEnumerable umbracoInit, IEnumerable additionalJsFiles = null) { var scripts = new HashSet(); foreach (var script in umbracoInit) @@ -47,9 +50,9 @@ namespace Umbraco.Web.JavaScript foreach (var script in additionalJsFiles) scripts.Add(script); - scripts = new HashSet(JavaScriptHelper.OptimizeAssetCollection(scripts, AssetType.Javascript, httpContext, _runtimeMinifier)); + scripts = new HashSet(await JavaScriptHelper.OptimizeAssetCollectionAsync(scripts, AssetType.Javascript, requestUrl, _runtimeMinifier)); - foreach (var script in ScanPropertyEditors(AssetType.Javascript, httpContext)) + foreach (var script in await ScanPropertyEditorsAsync(AssetType.Javascript)) scripts.Add(script); return scripts.ToArray(); @@ -59,7 +62,7 @@ namespace Umbraco.Web.JavaScript /// Returns the default config as a JArray /// /// - internal static IEnumerable GetDefaultInitialization() + 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.Web/JavaScript/JsInitialize.js b/src/Umbraco.Infrastructure/RuntimeMinification/JsInitialize.js similarity index 100% rename from src/Umbraco.Web/JavaScript/JsInitialize.js rename to src/Umbraco.Infrastructure/RuntimeMinification/JsInitialize.js diff --git a/src/Umbraco.Web/JavaScript/Main.js b/src/Umbraco.Infrastructure/RuntimeMinification/Main.js similarity index 100% rename from src/Umbraco.Web/JavaScript/Main.js rename to src/Umbraco.Infrastructure/RuntimeMinification/Main.js diff --git a/src/Umbraco.Web/JavaScript/PreviewInitialize.js b/src/Umbraco.Infrastructure/RuntimeMinification/PreviewInitialize.js similarity index 100% rename from src/Umbraco.Web/JavaScript/PreviewInitialize.js rename to src/Umbraco.Infrastructure/RuntimeMinification/PreviewInitialize.js diff --git a/src/Umbraco.Web/PropertyEditors/PropertyEditorAssetAttribute.cs b/src/Umbraco.Infrastructure/RuntimeMinification/PropertyEditorAssetAttribute.cs similarity index 100% rename from src/Umbraco.Web/PropertyEditors/PropertyEditorAssetAttribute.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/PropertyEditorAssetAttribute.cs diff --git a/src/Umbraco.Web/JavaScript/Resources.Designer.cs b/src/Umbraco.Infrastructure/RuntimeMinification/Resources.Designer.cs similarity index 84% rename from src/Umbraco.Web/JavaScript/Resources.Designer.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/Resources.Designer.cs index f11839f6ca..8653210a9d 100644 --- a/src/Umbraco.Web/JavaScript/Resources.Designer.cs +++ b/src/Umbraco.Infrastructure/RuntimeMinification/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Umbraco.Web.JavaScript { +namespace Umbraco.Infrastructure.RuntimeMinification { using System; @@ -19,7 +19,7 @@ namespace Umbraco.Web.JavaScript { // 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", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -39,7 +39,7 @@ namespace Umbraco.Web.JavaScript { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Web.JavaScript.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Infrastructure.RuntimeMinification.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; @@ -76,9 +76,9 @@ namespace Umbraco.Web.JavaScript { /// /// 'lib/angular-route/angular-route.js', /// 'lib/angular-cookies/angular-cookies.js', + /// 'lib/angular-aria/angular-aria.min.js', /// 'lib/angular-touch/angular-touch.js', - /// 'lib/angular-sanitize/angular-sanitize.js', - /// 'lib/an [rest of string was truncated]";. + /// 'lib/angula [rest of string was truncated]";. /// internal static string JsInitialize { get { @@ -149,9 +149,18 @@ namespace Umbraco.Web.JavaScript { /// /// Looks up a localized string similar to [ - /// '../lib/tinymce/tinymce.min.js', - ///] - ///. + /// 'lib/tinymce/tinymce.min.js', + /// + /// 'lib/tinymce/plugins/paste/plugin.min.js', + /// 'lib/tinymce/plugins/anchor/plugin.min.js', + /// 'lib/tinymce/plugins/charmap/plugin.min.js', + /// 'lib/tinymce/plugins/table/plugin.min.js', + /// 'lib/tinymce/plugins/lists/plugin.min.js', + /// 'lib/tinymce/plugins/advlist/plugin.min.js', + /// 'lib/tinymce/plugins/hr/plugin.min.js', + /// 'lib/tinymce/plugins/autolink/plugin.min.js', + /// 'lib/tinymce/plugins/directionality/plugin.min.js', + /// 'lib/tinymce/plugins/t [rest of string was truncated]";. /// internal static string TinyMceInitialize { get { diff --git a/src/Umbraco.Infrastructure/RuntimeMinification/Resources.resx b/src/Umbraco.Infrastructure/RuntimeMinification/Resources.resx new file mode 100644 index 0000000000..e51c3b9d92 --- /dev/null +++ b/src/Umbraco.Infrastructure/RuntimeMinification/Resources.resx @@ -0,0 +1,37 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + jsinitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + Main.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + previewinitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + servervariables.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + TinyMceInitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + diff --git a/src/Umbraco.Web/JavaScript/ServerVariables.js b/src/Umbraco.Infrastructure/RuntimeMinification/ServerVariables.js similarity index 100% rename from src/Umbraco.Web/JavaScript/ServerVariables.js rename to src/Umbraco.Infrastructure/RuntimeMinification/ServerVariables.js diff --git a/src/Umbraco.Web/JavaScript/ServerVariablesParser.cs b/src/Umbraco.Infrastructure/RuntimeMinification/ServerVariablesParser.cs similarity index 85% rename from src/Umbraco.Web/JavaScript/ServerVariablesParser.cs rename to src/Umbraco.Infrastructure/RuntimeMinification/ServerVariablesParser.cs index 8f27f58143..38669c166c 100644 --- a/src/Umbraco.Web/JavaScript/ServerVariablesParser.cs +++ b/src/Umbraco.Infrastructure/RuntimeMinification/ServerVariablesParser.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; +using Umbraco.Infrastructure.RuntimeMinification; namespace Umbraco.Web.JavaScript { @@ -13,7 +14,7 @@ namespace Umbraco.Web.JavaScript internal const string Token = "##Variables##"; - internal static string Parse(Dictionary items) + public static string Parse(Dictionary items) { var vars = Resources.ServerVariables; diff --git a/src/Umbraco.Web/JavaScript/TinyMceInitialize.js b/src/Umbraco.Infrastructure/RuntimeMinification/TinyMceInitialize.js similarity index 100% rename from src/Umbraco.Web/JavaScript/TinyMceInitialize.js rename to src/Umbraco.Infrastructure/RuntimeMinification/TinyMceInitialize.js diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 3d99c4918f..96fc25a527 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -43,10 +43,23 @@ + + True + True + Resources2.resx + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + diff --git a/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs b/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs index 30ead90de9..fd6e48fc06 100644 --- a/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs +++ b/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs @@ -30,7 +30,7 @@ namespace Umbraco.Tests.Models private static readonly ImageUrlGenerationOptions.CropCoordinates Crop = new ImageUrlGenerationOptions.CropCoordinates(0.58729977382575338m, 0.055768992440203169m, 0m, 0.32457553600198386m); private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus1 = new ImageUrlGenerationOptions.FocalPointPosition(0.80827067669172936m, 0.96m); private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus2 = new ImageUrlGenerationOptions.FocalPointPosition(0.41m, 0.4275m); - private static readonly ImageProcessorImageUrlGenerator Generator = new ImageProcessorImageUrlGenerator(); + private static readonly ImageSharpImageUrlGenerator Generator = new ImageSharpImageUrlGenerator(); [Test] public void GetCropUrl_CropAliasTest() diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs index fc38e429a0..ec10ced961 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs @@ -2,8 +2,16 @@ using Microsoft.AspNetCore.Http; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Hosting; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Net; using Umbraco.Core.Runtime; +using Umbraco.Core.Security; +using Umbraco.Web.Models; +using Umbraco.Web.Models.PublishedContent; +using Umbraco.Web.PropertyEditors; +using Umbraco.Web.Routing; +using Umbraco.Web.Templates; namespace Umbraco.Web.BackOffice.AspNetCore { @@ -22,6 +30,37 @@ namespace Umbraco.Web.BackOffice.AspNetCore // Our own netcore implementations composition.RegisterUnique(); composition.RegisterUnique(); + composition.RegisterUnique(); + + + // register the http context and umbraco context accessors + // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when + // we have no http context, eg when booting Umbraco or in background threads, so instead + // let's use an hybrid accessor that can fall back to a ThreadStatic context. + composition.RegisterUnique(); + + // register the umbraco context factory + // composition.RegisterUnique(); + composition.RegisterUnique(); + + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + + composition.UrlProviders() + .Append() + .Append(); + + composition.MediaUrlProviders() + .Append(); + + composition.RegisterUnique(); + + // register properties fallback + composition.RegisterUnique(); + + composition.RegisterUnique(); } } } diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCorePasswordHasher.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCorePasswordHasher.cs new file mode 100644 index 0000000000..7a26dac8e5 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCorePasswordHasher.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Identity; +using IPasswordHasher = Umbraco.Core.Security.IPasswordHasher; + +namespace Umbraco.Web.BackOffice.AspNetCore +{ + public class AspNetCorePasswordHasher : IPasswordHasher + { + private PasswordHasher _underlyingHasher; + + public AspNetCorePasswordHasher() + { + _underlyingHasher = new PasswordHasher(); + } + + public string HashPassword(string password) + { + return _underlyingHasher.HashPassword(null, password); + } + } +} diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs index 2e45ed0ea2..c06af6f9f1 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Smidge; +using Smidge.Nuglify; using Umbraco.Composing; using Umbraco.Configuration; using Umbraco.Core; @@ -166,6 +167,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore IConfiguration configuration) { services.AddSmidge(configuration.GetSection(Constants.Configuration.ConfigPrefix+"RuntimeMinification")); + services.AddSmidgeNuglify(); return services; } diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoRuntimeMinificationApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoRuntimeMinificationApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..e16de7889e --- /dev/null +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoRuntimeMinificationApplicationBuilderExtensions.cs @@ -0,0 +1,18 @@ +using System; +using Microsoft.AspNetCore.Builder; +using Smidge; + +namespace Umbraco.Web.Common.AspNetCore +{ + public static class UmbracoRuntimeMinificationApplicationBuilderExtensions + { + public static IApplicationBuilder UseUmbracoRuntimeMinification(this IApplicationBuilder app) + { + if (app == null) throw new ArgumentNullException(nameof(app)); + + app.UseSmidge(); + + return app; + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs new file mode 100644 index 0000000000..7045674d33 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -0,0 +1,44 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Core.Runtime; +using Umbraco.Web.BackOffice.Filters; + +namespace Umbraco.Web.BackOffice.Controllers +{ + public class BackOfficeController : Controller + { + private readonly IRuntimeMinifier _runtimeMinifier; + + public BackOfficeController(IRuntimeMinifier runtimeMinifier) + { + _runtimeMinifier = runtimeMinifier; + } + + // GET + public IActionResult Index() + { + return View(); + } + + /// + /// Returns the JavaScript main file including all references found in manifests + /// + /// + [MinifyJavaScriptResult(Order = 0)] + public async Task Application() + { + var result = await _runtimeMinifier.GetScriptForBackOfficeAsync(); + + return new JavaScriptResult(result); + } + } + + public class JavaScriptResult : ContentResult + { + public JavaScriptResult(string script) + { + this.Content = script; + this.ContentType = "application/javascript"; + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResult.cs b/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResult.cs new file mode 100644 index 0000000000..f1402bbd0b --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Filters/MinifyJavaScriptResult.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Filters; +using Umbraco.Core.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Assets; +using Umbraco.Core.Runtime; +using Umbraco.Web.BackOffice.Controllers; + +namespace Umbraco.Web.BackOffice.Filters +{ + public class MinifyJavaScriptResult : ActionFilterAttribute + { + public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + // logic before action goes here + var hostingEnvironment = context.HttpContext.RequestServices.GetService(); + if (!hostingEnvironment.IsDebugMode) + { + var runtimeMinifier = context.HttpContext.RequestServices.GetService(); + + if (context.Result is JavaScriptResult jsResult) + { + + + var result = jsResult.Content; + var minified = await runtimeMinifier.MinifyAsync(result, AssetType.Javascript); + jsResult.Content = minified; + } + } + + + + + + await next(); // the actual action + + // logic after the action goes here + } + + public override void OnResultExecuting(ResultExecutingContext context) + { + base.OnResultExecuting(context); + + + + + + //minify the result + + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Smidge/SmidgeComponent.cs b/src/Umbraco.Web.BackOffice/Smidge/SmidgeComponent.cs index 55b3641319..6671473fbb 100644 --- a/src/Umbraco.Web.BackOffice/Smidge/SmidgeComponent.cs +++ b/src/Umbraco.Web.BackOffice/Smidge/SmidgeComponent.cs @@ -8,12 +8,12 @@ namespace Umbraco.Web.BackOffice.Smidge { public void Initialize() { - throw new NotImplementedException(); + } public void Terminate() { - throw new NotImplementedException(); + } } } diff --git a/src/Umbraco.Web.BackOffice/Smidge/SmidgeComposer.cs b/src/Umbraco.Web.BackOffice/Smidge/SmidgeComposer.cs index 61257a9a46..5fa954a6d2 100644 --- a/src/Umbraco.Web.BackOffice/Smidge/SmidgeComposer.cs +++ b/src/Umbraco.Web.BackOffice/Smidge/SmidgeComposer.cs @@ -7,12 +7,11 @@ using Umbraco.Core.Runtime; namespace Umbraco.Web.BackOffice.Smidge { - public sealed class SmidgeComposer : ComponentComposer + public sealed class SmidgeComposer : IComposer { - public override void Compose(Composition composition) + public void Compose(Composition composition) { - base.Compose(composition); - composition.RegisterUnique(); + composition.Register(Lifetime.Scope); } } } diff --git a/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs b/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs index 75d2d314b4..305caccd23 100644 --- a/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs +++ b/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs @@ -1,92 +1,145 @@ using System; using System.Collections.Generic; -using System.Configuration; -using System.IO; -using System.Text; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.Configuration; using Smidge; -using Smidge.Cache; +using Smidge.CompositeFiles; using Smidge.FileProcessors; using Smidge.Nuglify; -using Smidge.Models; +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.Web.JavaScript; +using CssFile = Smidge.Models.CssFile; +using JavaScriptFile = Smidge.Models.JavaScriptFile; namespace Umbraco.Web.BackOffice.Smidge { 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 IManifestParser _manifestParser; + private readonly PreProcessPipelineFactory _preProcessPipelineFactory; + private readonly PropertyEditorCollection _propertyEditorCollection; private readonly SmidgeHelper _smidge; - // TODO: We need to use IConfiguration to get the section (ConfigurationManager is not the way to do it) - public string GetHashValue => new SmidgeConfig((IConfiguration)ConfigurationManager.GetSection("Umbraco:Smidge")).Version; + private PreProcessPipeline _jsPipeline; + private PreProcessPipeline _cssPipeline; - public SmidgeRuntimeMinifier(SmidgeHelper smidge) + public SmidgeRuntimeMinifier( + SmidgeHelper smidge, + PreProcessPipelineFactory preProcessPipelineFactory, + IManifestParser manifestParser, + IHttpContextAccessor httpContextAccessor, + PropertyEditorCollection propertyEditorCollection, + IGlobalSettings globalSettings, + IIOHelper ioHelper, + IHostingEnvironment hostingEnvironment, + ISmidgeConfig smidgeConfig) { _smidge = smidge; - } - public void RequiresCss(string filePath, string bundleName) - { - throw new NotImplementedException(); + _preProcessPipelineFactory = preProcessPipelineFactory; + _manifestParser = manifestParser; + _httpContextAccessor = httpContextAccessor; + _propertyEditorCollection = propertyEditorCollection; + _globalSettings = globalSettings; + _ioHelper = ioHelper; + _hostingEnvironment = hostingEnvironment; + _smidgeConfig = smidgeConfig; } - public string RenderCssHere(string bundleName) + 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 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) { - return _smidge.CssHereAsync(bundleName).ToString(); - } - public void RequiresJs(string filePath, string bundleName) - { - throw new NotImplementedException(); - } + var files = attributes + .Where(x => x.DependencyType == assetType) + .Select(x=>x.FilePath) + .ToArray(); - public string RenderJsHere(string bundleName) - { - return _smidge.JsHereAsync(bundleName).ToString(); - } + if (files.Length == 0) return Array.Empty(); - public IEnumerable GetAssetPaths(AssetType assetType, List attributes) - { - var parsed = new List(); - - if (assetType == AssetType.Javascript) - attributes.ForEach(x => parsed.AddRange(_smidge.GenerateJsUrlsAsync(x.Bundle).Result)); - else - attributes.ForEach(x => parsed.AddRange(_smidge.GenerateCssUrlsAsync(x.Bundle).Result)); - - return parsed; - } - - public string Minify(string src, AssetType assetType) - { if (assetType == AssetType.Javascript) { + _smidge.RequiresJs(files); - // TODO: use NuglifyJs to minify JS files (https://github.com/Shazwazza/Smidge/blob/master/src/Smidge.Nuglify/NuglifyJs.cs) + return await _smidge.GenerateJsUrlsAsync(JsPipeline, _hostingEnvironment.IsDebugMode); } else { - // TODO: use NuglifyCss to minify CSS files (https://github.com/Shazwazza/Smidge/blob/master/src/Smidge.Nuglify/NuglifyCss.cs) - } + _smidge.RequiresCss(files); - throw new NotImplementedException(); + return await _smidge.GenerateJsUrlsAsync(CssPipeline, _hostingEnvironment.IsDebugMode); + } + } + + public async Task MinifyAsync(string fileContent, AssetType assetType) + { + if (assetType == AssetType.Javascript) + { + return await JsPipeline + .ProcessAsync( + new FileProcessContext(fileContent, new JavaScriptFile(), BundleContext.CreateEmpty())); + } + else + { + return await CssPipeline + .ProcessAsync(new FileProcessContext(fileContent, new CssFile(), BundleContext.CreateEmpty())); + } } public void Reset() { // TODO: Need to figure out how to delete temp directories to make sure we get fresh caches - - throw new NotImplementedException(); } - public string GetScriptForBackOffice() + public async Task GetScriptForBackOfficeAsync() { - throw new NotImplementedException(); + 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 IEnumerable GetAssetList() + public async Task> GetAssetListAsync() { - throw new NotImplementedException(); + 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.NetCore/Program.cs b/src/Umbraco.Web.UI.NetCore/Program.cs index 1151f16be8..f0504d77e3 100644 --- a/src/Umbraco.Web.UI.NetCore/Program.cs +++ b/src/Umbraco.Web.UI.NetCore/Program.cs @@ -1,5 +1,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; using Umbraco.Core.Composing; namespace Umbraco.Web.UI.BackOffice diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 2ae1e58a9d..7d5dd98351 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -8,7 +8,9 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Smidge; using Umbraco.Web.BackOffice.AspNetCore; +using Umbraco.Web.Common.AspNetCore; using Umbraco.Web.Website.AspNetCore; @@ -41,6 +43,8 @@ namespace Umbraco.Web.UI.BackOffice services.AddUmbracoRuntimeMinifier(_config); services.AddUmbracoCore(_webHostEnvironment); services.AddUmbracoWebsite(); + + services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -50,14 +54,22 @@ namespace Umbraco.Web.UI.BackOffice { app.UseDeveloperExceptionPage(); } + app.Use(async (context, next) => + { + await next(); + }); app.UseUmbracoWebsite(); app.UseUmbracoBackOffice(); - app.UseRouting(); - + app.UseUmbracoRuntimeMinification(); app.UseEndpoints(endpoints => { + endpoints.MapControllerRoute("Backoffice", "/umbraco/{Action}", new + { + Controller = "BackOffice", + Action = "Default" + }); endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); }); } diff --git a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj index ca7c3e26fa..ee76e33725 100644 --- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj +++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj @@ -2,7 +2,7 @@ netcoreapp3.1 - Umbraco.Web.UI.BackOffice + Umbraco.Web.UI.NetCore @@ -15,8 +15,23 @@ - <_ContentIncludedByDefault Remove="wwwroot\~\App_Data\TEMP\TypesCache\umbraco-types.DESKTOP-2016.hash" /> - <_ContentIncludedByDefault Remove="wwwroot\~\App_Data\TEMP\TypesCache\umbraco-types.DESKTOP-2016.list" /> + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.json b/src/Umbraco.Web.UI.NetCore/appsettings.json index 10bf35df78..f20a0f4962 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.json @@ -2,20 +2,24 @@ "ConnectionStrings": { "umbracoDbDSN": "" }, - "RuntimeMinification": { - "dataFolder" : "../App_Data/Smidge", - "version" : "1" - }, + "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" + "Default": "Trace", + "Microsoft": "Trace", + "Microsoft.Hosting.Lifetime": "Trace" } }, "AllowedHosts": "*", "Umbraco": { "CMS": { + "Hosting": { + "Debug" : false + }, + "RuntimeMinification": { + "dataFolder" : "App_Data/TEMP/Smidge", + "version" : "1" + }, "Imaging": { "Resize": { "MaxWidth": 5000, diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 7e4657a33d..25a0084971 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -8,9 +8,7 @@ var runtimeMinifier = Current.RuntimeMinifier; - runtimeMinifier.RequiresCss("assets/css/umbraco.css", "umbraco"); - runtimeMinifier.RequiresCss("lib/bootstrap-social/bootstrap-social.css", "umbraco"); - runtimeMinifier.RequiresCss("lib/font-awesome/css/font-awesome.min.css", "umbraco"); + runtimeMinifier.RequiresCss("umbraco", "assets/css/umbraco.css", "lib/bootstrap-social/bootstrap-social.css", "lib/font-awesome/css/font-awesome.min.css"); } diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml index 0c314dbea4..a048569760 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml @@ -18,10 +18,7 @@ } var runtimeMinifier = Current.RuntimeMinifier; - runtimeMinifier.RequiresCss("assets/css/umbraco.css", "Umbraco"); - runtimeMinifier.RequiresCss("lib/bootstrap-social/bootstrap-social.css", "Umbraco"); - runtimeMinifier.RequiresCss("assets/css/umbraco.css", "Umbraco"); - runtimeMinifier.RequiresCss("lib/font-awesome/css/font-awesome.min.css", "Umbraco"); + runtimeMinifier.RequiresCss("Umbraco", "assets/css/umbraco.css", "lib/bootstrap-social/bootstrap-social.css", "assets/css/umbraco.css", "lib/font-awesome/css/font-awesome.min.css"); // Html // .RequiresCss("assets/css/umbraco.css", "Umbraco") diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml index 020f6e74e6..d2707101d3 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml @@ -6,7 +6,7 @@ var runtimeMinifier = Current.RuntimeMinifier; - runtimeMinifier.RequiresCss("assets/css/canvasdesigner.css", "Umbraco"); + runtimeMinifier.RequiresCss("Umbraco", "assets/css/canvasdesigner.css"); } diff --git a/src/Umbraco.Web/CompositionExtensions.cs b/src/Umbraco.Web/CompositionExtensions.cs index c7c1da4ca9..35e60740dd 100644 --- a/src/Umbraco.Web/CompositionExtensions.cs +++ b/src/Umbraco.Web/CompositionExtensions.cs @@ -30,37 +30,6 @@ namespace Umbraco.Web { #region Collection Builders - /// - /// Gets the actions collection builder. - /// - /// The composition. - /// - internal static ActionCollectionBuilder Actions(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the content apps collection builder. - /// - /// The composition. - /// - public static ContentAppFactoryCollectionBuilder ContentApps(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the content finders collection builder. - /// - /// The composition. - /// - public static ContentFinderCollectionBuilder ContentFinders(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the editor validators collection builder. - /// - /// The composition. - /// - internal static EditorValidatorCollectionBuilder EditorValidators(this Composition composition) - => composition.WithCollectionBuilder(); /// /// Gets the filtered controller factories collection builder. @@ -70,39 +39,6 @@ namespace Umbraco.Web public static FilteredControllerFactoryCollectionBuilder FilteredControllerFactory(this Composition composition) => composition.WithCollectionBuilder(); - /// - /// Gets the health checks collection builder. - /// - /// The composition. - public static HealthCheckCollectionBuilder HealthChecks(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the TourFilters collection builder. - /// - public static TourFilterCollectionBuilder TourFilters(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the url providers collection builder. - /// - /// The composition. - public static UrlProviderCollectionBuilder UrlProviders(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the media url providers collection builder. - /// - /// The composition. - public static MediaUrlProviderCollectionBuilder MediaUrlProviders(this Composition composition) - => composition.WithCollectionBuilder(); - - /// - /// Gets the backoffice sections/applications collection builder. - /// - /// The composition. - public static SectionCollectionBuilder Sections(this Composition composition) - => composition.WithCollectionBuilder(); /// /// Gets the backoffice OEmbed Providers collection builder. @@ -127,6 +63,7 @@ namespace Umbraco.Web public static SearchableTreeCollectionBuilder SearchableTrees(this Composition composition) => composition.WithCollectionBuilder(); + #endregion #region Uniques diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index d9103e3715..6ffe2e7210 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -242,9 +242,9 @@ namespace Umbraco.Web.Editors /// [MinifyJavaScriptResult(Order = 0)] [OutputCache(Order = 1, VaryByParam = "none", Location = OutputCacheLocation.Server, Duration = 5000)] - public JavaScriptResult Application() + public async Task Application() { - var result = _runtimeMinifier.GetScriptForBackOffice(); + var result = await _runtimeMinifier.GetScriptForBackOfficeAsync(); return JavaScript(result); } @@ -255,21 +255,22 @@ namespace Umbraco.Web.Editors /// [UmbracoAuthorize(Order = 0)] [HttpGet] - public JsonNetResult GetManifestAssetList() + public async Task GetManifestAssetList() { - JArray GetAssetList() + async Task GetAssetList() { - var assets = _runtimeMinifier.GetAssetList(); + var assets = new JArray(await _runtimeMinifier.GetAssetListAsync()); return new JArray(assets); } + var assetList = await GetAssetList(); //cache the result if debugging is disabled var result = _hostingEnvironment.IsDebugMode - ? GetAssetList() + ? assetList : AppCaches.RuntimeCache.GetCacheItem( "Umbraco.Web.Editors.BackOfficeController.GetManifestAssetList", - GetAssetList, + () => assetList, new TimeSpan(0, 2, 0)); return new JsonNetResult { Data = result, Formatting = Formatting.None }; diff --git a/src/Umbraco.Web/Editors/PreviewController.cs b/src/Umbraco.Web/Editors/PreviewController.cs index 39ca087ab5..9c67e34f69 100644 --- a/src/Umbraco.Web/Editors/PreviewController.cs +++ b/src/Umbraco.Web/Editors/PreviewController.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Web.UI; @@ -99,10 +100,12 @@ namespace Umbraco.Web.Editors /// [MinifyJavaScriptResult(Order = 0)] [OutputCache(Order = 1, VaryByParam = "none", Location = OutputCacheLocation.Server, Duration = 5000)] - public JavaScriptResult Application() + public async Task Application() { - var files = JavaScriptHelper.OptimizeScriptFiles(HttpContext, JavaScriptHelper.GetPreviewInitialization(), _runtimeMinifier); - var result = JavaScriptHelper.GetJavascriptInitialization(HttpContext, files, "umbraco.preview", _globalSettings, _ioHelper); + + + var files = await JavaScriptHelper.OptimizeScriptFilesAsync(HttpContext.Request.Url, JavaScriptHelper.GetPreviewInitialization(), _runtimeMinifier); + var result = JavaScriptHelper.GetJavascriptInitialization(files, "umbraco.preview", _globalSettings, _ioHelper); return JavaScript(result); } diff --git a/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs b/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs index 2093984e54..a0b774550b 100644 --- a/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs +++ b/src/Umbraco.Web/HtmlHelperBackOfficeExtensions.cs @@ -130,7 +130,7 @@ namespace Umbraco.Web public static IHtmlString AngularValueTinyMceAssets(this HtmlHelper html, IRuntimeMinifier runtimeMinifier) { var ctx = new HttpContextWrapper(HttpContext.Current); - var files = JavaScriptHelper.OptimizeTinyMceScriptFiles(ctx, runtimeMinifier); + var files = JavaScriptHelper.OptimizeTinyMceScriptFilesAsync(ctx.Request.Url, runtimeMinifier).GetAwaiter().GetResult(); var sb = new StringBuilder(); diff --git a/src/Umbraco.Web/JavaScript/CDF/ClientDependencyRuntimeMinifier.cs b/src/Umbraco.Web/JavaScript/CDF/ClientDependencyRuntimeMinifier.cs index 994c7253f0..a1c8165460 100644 --- a/src/Umbraco.Web/JavaScript/CDF/ClientDependencyRuntimeMinifier.cs +++ b/src/Umbraco.Web/JavaScript/CDF/ClientDependencyRuntimeMinifier.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Threading.Tasks; using System.Web.Mvc; using ClientDependency.Core; using ClientDependency.Core.CompositeFiles; @@ -13,6 +14,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; +using Umbraco.Core.PropertyEditors; using Umbraco.Core.Runtime; namespace Umbraco.Web.JavaScript.CDF @@ -25,11 +27,18 @@ namespace Umbraco.Web.JavaScript.CDF private readonly IUmbracoVersion _umbracoVersion; private readonly IManifestParser _manifestParser; private readonly IGlobalSettings _globalSettings; - private readonly HtmlHelper _htmlHelper; + private readonly PropertyEditorCollection _propertyEditorCollection; public string GetHashValue => ClientDependencySettings.Instance.Version.ToString(); - public ClientDependencyRuntimeMinifier(IHttpContextAccessor httpContextAccessor, IIOHelper ioHelper, ILogger logger, IUmbracoVersion umbracoVersion, IManifestParser manifestParser, IGlobalSettings globalSettings) + public ClientDependencyRuntimeMinifier( + IHttpContextAccessor httpContextAccessor, + IIOHelper ioHelper, + ILogger logger, + IUmbracoVersion umbracoVersion, + IManifestParser manifestParser, + IGlobalSettings globalSettings, + PropertyEditorCollection propertyEditorCollection) { _httpContextAccessor = httpContextAccessor; _ioHelper = ioHelper; @@ -37,7 +46,7 @@ namespace Umbraco.Web.JavaScript.CDF _umbracoVersion = umbracoVersion; _manifestParser = manifestParser; _globalSettings = globalSettings; - _htmlHelper = new HtmlHelper(new ViewContext(), new ViewPage()); + _propertyEditorCollection = propertyEditorCollection; } private DependencyRenderer GetDependencyRenderer @@ -55,9 +64,12 @@ namespace Umbraco.Web.JavaScript.CDF } - public void RequiresCss(string filePath, string bundleName) + public void RequiresCss(string bundleName, params string[] filePaths) { - GetDependencyRenderer.RegisterDependency(filePath, bundleName, ClientDependencyType.Css); + foreach (var filePath in filePaths) + { + GetDependencyRenderer.RegisterDependency(filePath, bundleName, ClientDependencyType.Css); + } } public string RenderCssHere(string bundleName) @@ -79,9 +91,12 @@ namespace Umbraco.Web.JavaScript.CDF // ClientDependencyType.Css, path)); } - public void RequiresJs(string filePath, string bundleName) + public void RequiresJs(string bundleName, params string[] filePaths) { - GetDependencyRenderer.RegisterDependency(filePath, bundleName, ClientDependencyType.Javascript); + foreach (var filePath in filePaths) + { + GetDependencyRenderer.RegisterDependency(filePath, bundleName, ClientDependencyType.Javascript); + } } public string RenderJsHere(string bundleName) @@ -101,7 +116,7 @@ namespace Umbraco.Web.JavaScript.CDF } - public IEnumerable GetAssetPaths(AssetType assetType, List attributes) + public Task> GetAssetPathsAsync(AssetType assetType, List attributes) { // get the output string for these registrations which will be processed by CDF correctly to stagger the output based // on internal vs external resources. The output will be delimited based on our custom Umbraco.Web.JavaScript.DependencyPathRenderer @@ -117,12 +132,12 @@ namespace Umbraco.Web.JavaScript.CDF renderer.RegisterDependencies(dependencies, new HashSet(), out var scripts, out var stylesheets, _httpContextAccessor.HttpContext); var toParse = assetType == AssetType.Javascript ? scripts : stylesheets; - return toParse.Split(new[] { DependencyPathRenderer.Delimiter }, StringSplitOptions.RemoveEmptyEntries); + return Task.FromResult>(toParse.Split(new[] { DependencyPathRenderer.Delimiter }, StringSplitOptions.RemoveEmptyEntries)); } - public string Minify(string src, AssetType assetType) + public async Task MinifyAsync(string fileContent, AssetType assetType) { - TextReader reader = new StringReader(src); + TextReader reader = new StringReader(fileContent); if (assetType == AssetType.Javascript) { @@ -145,27 +160,27 @@ namespace Umbraco.Web.JavaScript.CDF var clientDependencyTempFilesDeleted = clientDependencyConfig.ClearTempFiles(_httpContextAccessor.HttpContext); } - public string GetScriptForBackOffice() + public async Task GetScriptForBackOfficeAsync() { - var initJs = new JsInitialization(_manifestParser, this); - var initCss = new CssInitialization(_manifestParser, this); + var initJs = new JsInitialization(_manifestParser, this, _propertyEditorCollection); + var initCss = new CssInitialization(_manifestParser, this, _propertyEditorCollection); - var httpContext = _httpContextAccessor.GetRequiredHttpContext(); - var files = initJs.OptimizeBackOfficeScriptFiles(httpContext, JsInitialization.GetDefaultInitialization()); - var result = JavaScriptHelper.GetJavascriptInitialization(httpContext, files, "umbraco", _globalSettings, _ioHelper); - result += initCss.GetStylesheetInitialization(httpContext); + var requestUrl = _httpContextAccessor.GetRequiredHttpContext().Request.Url; + var files = await initJs.OptimizeBackOfficeScriptFilesAsync(requestUrl, JsInitialization.GetDefaultInitialization()); + var result = JavaScriptHelper.GetJavascriptInitialization(files, "umbraco", _globalSettings, _ioHelper); + result += await initCss.GetStylesheetInitializationAsync(requestUrl); return result; } - public IEnumerable GetAssetList() + public async Task> GetAssetListAsync() { - var initJs = new JsInitialization(_manifestParser, this); - var initCss = new CssInitialization(_manifestParser, this); + var initJs = new JsInitialization(_manifestParser, this, _propertyEditorCollection); + var initCss = new CssInitialization(_manifestParser, this, _propertyEditorCollection); var assets = new List(); - var httpContext = _httpContextAccessor.GetRequiredHttpContext(); - assets.AddRange(initJs.OptimizeBackOfficeScriptFiles(httpContext, Enumerable.Empty())); - assets.AddRange(initCss.GetStylesheetFiles(httpContext)); + var requestUrl = _httpContextAccessor.GetRequiredHttpContext().Request.Url; + assets.AddRange(await initJs.OptimizeBackOfficeScriptFilesAsync(requestUrl, Enumerable.Empty())); + assets.AddRange(await initCss.GetStylesheetFilesAsync(requestUrl)); return assets; } diff --git a/src/Umbraco.Web/JavaScript/Resources.resx b/src/Umbraco.Web/JavaScript/Resources.resx deleted file mode 100644 index 1adcaeeb4a..0000000000 --- a/src/Umbraco.Web/JavaScript/Resources.resx +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - jsinitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - - Main.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 - - - previewinitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - - servervariables.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - - TinyMceInitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/MinifyJavaScriptResultAttribute.cs b/src/Umbraco.Web/Mvc/MinifyJavaScriptResultAttribute.cs index a4fb38a625..ee8a6303b5 100644 --- a/src/Umbraco.Web/Mvc/MinifyJavaScriptResultAttribute.cs +++ b/src/Umbraco.Web/Mvc/MinifyJavaScriptResultAttribute.cs @@ -44,7 +44,7 @@ namespace Umbraco.Web.Mvc //minify the result var result = jsResult.Script; - var minified = _runtimeMinifier.Minify(result, AssetType.Javascript); + var minified = _runtimeMinifier.MinifyAsync(result, AssetType.Javascript).GetAwaiter().GetResult(); jsResult.Script = minified; } } diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 68960b9e75..14e504b74d 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -209,7 +209,7 @@ namespace Umbraco.Web.Runtime composition.MediaUrlProviders() .Append(); - composition.RegisterUnique(); + composition.RegisterUnique(); composition.RegisterUnique(); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index efc13d9dd7..c0c43b4df8 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -39,9 +39,6 @@ - - C:\Users\Berg\.nuget\packages\clientdependency-mvc5\1.9.3\lib\net45\ClientDependency.Core.Mvc.dll - @@ -58,9 +55,6 @@ - - C:\Users\Bjarke\.nuget\packages\microsoft.aspnet.mvc\5.2.7\lib\net45\System.Web.Mvc.dll - @@ -150,11 +144,7 @@ - - - - @@ -277,7 +267,6 @@ - @@ -388,7 +377,6 @@ - @@ -471,12 +459,6 @@ - - True - True - Resources.resx - - @@ -570,23 +552,10 @@ - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - ResXFileCodeGenerator Strings.Designer.cs - - - - - - - -