Adds bundle options to the package manifest
to more control over how bundling works for static file processing for app_plugins
This commit is contained in:
@@ -64,7 +64,7 @@ namespace Umbraco.Cms.Core.Configuration.Grid
|
||||
}
|
||||
|
||||
// add manifest editors, skip duplicates
|
||||
foreach (var gridEditor in _manifestParser.Manifest.GridEditors)
|
||||
foreach (var gridEditor in _manifestParser.CombinedManifest.GridEditors)
|
||||
{
|
||||
if (editors.Contains(gridEditor) == false) editors.Add(gridEditor);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.ContentApps
|
||||
// its dependencies too, and that can create cycles or other oddities
|
||||
var manifestParser = factory.GetRequiredService<IManifestParser>();
|
||||
var ioHelper = factory.GetRequiredService<IIOHelper>();
|
||||
return base.CreateItems(factory).Concat(manifestParser.Manifest.ContentApps.Select(x => new ManifestContentAppFactory(x, ioHelper)));
|
||||
return base.CreateItems(factory).Concat(manifestParser.CombinedManifest.ContentApps.Select(x => new ManifestContentAppFactory(x, ioHelper)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.Dashboards
|
||||
// its dependencies too, and that can create cycles or other oddities
|
||||
var manifestParser = factory.GetRequiredService<IManifestParser>();
|
||||
|
||||
var dashboardSections = Merge(base.CreateItems(factory), manifestParser.Manifest.Dashboards);
|
||||
var dashboardSections = Merge(base.CreateItems(factory), manifestParser.CombinedManifest.Dashboards);
|
||||
|
||||
return dashboardSections;
|
||||
}
|
||||
|
||||
26
src/Umbraco.Core/Manifest/BundleOptions.cs
Normal file
26
src/Umbraco.Core/Manifest/BundleOptions.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace Umbraco.Cms.Core.Manifest
|
||||
{
|
||||
public enum BundleOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The default bundling behavior for assets in the package folder.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The assets will be bundled with the typical packages bundle.
|
||||
/// </remarks>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The assets in the package will not be processed at all and will all be requested as individual assets.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will essentially be a bundle that has composite processing turned off for both debug and production.
|
||||
/// </remarks>
|
||||
None = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The packages assets will be processed as it's own separate bundle. (in debug, files will not be processed)
|
||||
/// </summary>
|
||||
Independent = 2
|
||||
}
|
||||
}
|
||||
67
src/Umbraco.Core/Manifest/CompositePackageManifest.cs
Normal file
67
src/Umbraco.Core/Manifest/CompositePackageManifest.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Cms.Core.Manifest
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A package manifest made up of all combined manifests
|
||||
/// </summary>
|
||||
public class CompositePackageManifest
|
||||
{
|
||||
public CompositePackageManifest(
|
||||
IReadOnlyList<IDataEditor> propertyEditors,
|
||||
IReadOnlyList<IDataEditor> parameterEditors,
|
||||
IReadOnlyList<GridEditor> gridEditors,
|
||||
IReadOnlyList<ManifestContentAppDefinition> contentApps,
|
||||
IReadOnlyList<ManifestDashboard> dashboards,
|
||||
IReadOnlyList<ManifestSection> sections,
|
||||
IReadOnlyDictionary<BundleOptions, IReadOnlyList<ManifestAssets>> scripts,
|
||||
IReadOnlyDictionary<BundleOptions, IReadOnlyList<ManifestAssets>> stylesheets)
|
||||
{
|
||||
PropertyEditors = propertyEditors ?? throw new ArgumentNullException(nameof(propertyEditors));
|
||||
ParameterEditors = parameterEditors ?? throw new ArgumentNullException(nameof(parameterEditors));
|
||||
GridEditors = gridEditors ?? throw new ArgumentNullException(nameof(gridEditors));
|
||||
ContentApps = contentApps ?? throw new ArgumentNullException(nameof(contentApps));
|
||||
Dashboards = dashboards ?? throw new ArgumentNullException(nameof(dashboards));
|
||||
Sections = sections ?? throw new ArgumentNullException(nameof(sections));
|
||||
Scripts = scripts ?? throw new ArgumentNullException(nameof(scripts));
|
||||
Stylesheets = stylesheets ?? throw new ArgumentNullException(nameof(stylesheets));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property editors listed in the manifest.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IDataEditor> PropertyEditors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter editors listed in the manifest.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IDataEditor> ParameterEditors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the grid editors listed in the manifest.
|
||||
/// </summary>
|
||||
public IReadOnlyList<GridEditor> GridEditors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content apps listed in the manifest.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ManifestContentAppDefinition> ContentApps { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the dashboards listed in the manifest.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ManifestDashboard> Dashboards { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sections listed in the manifest.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<ManifestSection> Sections { get; }
|
||||
|
||||
public IReadOnlyDictionary<BundleOptions, IReadOnlyList<ManifestAssets>> Scripts { get; }
|
||||
|
||||
public IReadOnlyDictionary<BundleOptions, IReadOnlyList<ManifestAssets>> Stylesheets { get; }
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
{
|
||||
public interface IManifestParser
|
||||
{
|
||||
string Path { get; set; }
|
||||
//string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all manifests, merged into a single manifest object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
PackageManifest Manifest { get; }
|
||||
CompositePackageManifest CombinedManifest { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Parses a manifest.
|
||||
|
||||
17
src/Umbraco.Core/Manifest/ManifestAssets.cs
Normal file
17
src/Umbraco.Core/Manifest/ManifestAssets.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Cms.Core.Manifest
|
||||
{
|
||||
public class ManifestAssets
|
||||
{
|
||||
public ManifestAssets(string packageName, IReadOnlyList<string> assets)
|
||||
{
|
||||
PackageName = packageName ?? throw new ArgumentNullException(nameof(packageName));
|
||||
Assets = assets ?? throw new ArgumentNullException(nameof(assets));
|
||||
}
|
||||
|
||||
public string PackageName { get; }
|
||||
public IReadOnlyList<string> Assets { get; }
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.Manifest
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Represents the content of a package manifest.
|
||||
/// </summary>
|
||||
@@ -47,6 +48,8 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
public string Source { get; set; }
|
||||
[DataMember(Name = "bundleOptions")]
|
||||
public BundleOptions BundleOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scripts listed in the manifest.
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
|
||||
public ParameterEditorCollection(DataEditorCollection dataEditors, IManifestParser manifestParser)
|
||||
: base(() => dataEditors
|
||||
.Where(x => (x.Type & EditorType.MacroParameter) > 0)
|
||||
.Union(manifestParser.Manifest.PropertyEditors))
|
||||
.Union(manifestParser.CombinedManifest.PropertyEditors))
|
||||
{ }
|
||||
|
||||
// note: virtual so it can be mocked
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.PropertyEditors
|
||||
public PropertyEditorCollection(DataEditorCollection dataEditors, IManifestParser manifestParser)
|
||||
: base(() => dataEditors
|
||||
.Where(x => (x.Type & EditorType.PropertyValue) > 0)
|
||||
.Union(manifestParser.Manifest.PropertyEditors))
|
||||
.Union(manifestParser.CombinedManifest.PropertyEditors))
|
||||
{ }
|
||||
|
||||
public PropertyEditorCollection(DataEditorCollection dataEditors)
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Cms.Core.Sections
|
||||
// its dependencies too, and that can create cycles or other oddities
|
||||
var manifestParser = factory.GetRequiredService<IManifestParser>();
|
||||
|
||||
return base.CreateItems(factory).Concat(manifestParser.Manifest.Sections);
|
||||
return base.CreateItems(factory).Concat(manifestParser.CombinedManifest.Sections);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,22 +62,22 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger<ManifestParser> logger, IIOHelper ioHelper, IHostingEnvironment hostingEnvironment)
|
||||
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string appPluginsPath, ILogger<ManifestParser> logger, IIOHelper ioHelper, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
|
||||
_cache = appCaches.RuntimeCache;
|
||||
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
|
||||
_filters = filters ?? throw new ArgumentNullException(nameof(filters));
|
||||
if (path == null) throw new ArgumentNullException(nameof(path));
|
||||
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(path));
|
||||
if (appPluginsPath == null) throw new ArgumentNullException(nameof(appPluginsPath));
|
||||
if (string.IsNullOrWhiteSpace(appPluginsPath)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(appPluginsPath));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_ioHelper = ioHelper;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
|
||||
Path = path;
|
||||
AppPluginsPath = appPluginsPath;
|
||||
}
|
||||
|
||||
public string Path
|
||||
public string AppPluginsPath
|
||||
{
|
||||
get => _path;
|
||||
set => _path = value.StartsWith("~/") ? _hostingEnvironment.MapPathContentRoot(value) : value;
|
||||
@@ -87,11 +87,12 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
/// Gets all manifests, merged into a single manifest object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public PackageManifest Manifest
|
||||
=> _cache.GetCacheItem<PackageManifest>("Umbraco.Core.Manifest.ManifestParser::Manifests", () =>
|
||||
public CompositePackageManifest CombinedManifest
|
||||
=> _cache.GetCacheItem<CompositePackageManifest>("Umbraco.Core.Manifest.ManifestParser::Manifests", () =>
|
||||
{
|
||||
var manifests = GetManifests();
|
||||
IEnumerable<PackageManifest> manifests = GetManifests();
|
||||
return MergeManifests(manifests);
|
||||
|
||||
}, new TimeSpan(0, 4, 0));
|
||||
|
||||
/// <summary>
|
||||
@@ -130,10 +131,10 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
/// <summary>
|
||||
/// Merges all manifests into one.
|
||||
/// </summary>
|
||||
private static PackageManifest MergeManifests(IEnumerable<PackageManifest> manifests)
|
||||
private static CompositePackageManifest MergeManifests(IEnumerable<PackageManifest> manifests)
|
||||
{
|
||||
var scripts = new HashSet<string>();
|
||||
var stylesheets = new HashSet<string>();
|
||||
var scripts = new Dictionary<BundleOptions, List<ManifestAssets>>();
|
||||
var stylesheets = new Dictionary<BundleOptions, List<ManifestAssets>>();
|
||||
var propertyEditors = new List<IDataEditor>();
|
||||
var parameterEditors = new List<IDataEditor>();
|
||||
var gridEditors = new List<GridEditor>();
|
||||
@@ -141,10 +142,28 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
var dashboards = new List<ManifestDashboard>();
|
||||
var sections = new List<ManifestSection>();
|
||||
|
||||
foreach (var manifest in manifests)
|
||||
foreach (PackageManifest manifest in manifests)
|
||||
{
|
||||
if (manifest.Scripts != null) foreach (var script in manifest.Scripts) scripts.Add(script);
|
||||
if (manifest.Stylesheets != null) foreach (var stylesheet in manifest.Stylesheets) stylesheets.Add(stylesheet);
|
||||
if (manifest.Scripts != null)
|
||||
{
|
||||
if (!scripts.TryGetValue(manifest.BundleOptions, out List<ManifestAssets> scriptsPerBundleOption))
|
||||
{
|
||||
scriptsPerBundleOption = new List<ManifestAssets>();
|
||||
scripts[manifest.BundleOptions] = scriptsPerBundleOption;
|
||||
}
|
||||
scriptsPerBundleOption.Add(new ManifestAssets(manifest.PackageName, manifest.Scripts));
|
||||
}
|
||||
|
||||
if (manifest.Stylesheets != null)
|
||||
{
|
||||
if (!stylesheets.TryGetValue(manifest.BundleOptions, out List<ManifestAssets> stylesPerBundleOption))
|
||||
{
|
||||
stylesPerBundleOption = new List<ManifestAssets>();
|
||||
stylesheets[manifest.BundleOptions] = stylesPerBundleOption;
|
||||
}
|
||||
stylesPerBundleOption.Add(new ManifestAssets(manifest.PackageName, manifest.Stylesheets));
|
||||
}
|
||||
|
||||
if (manifest.PropertyEditors != null) propertyEditors.AddRange(manifest.PropertyEditors);
|
||||
if (manifest.ParameterEditors != null) parameterEditors.AddRange(manifest.ParameterEditors);
|
||||
if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors);
|
||||
@@ -153,17 +172,15 @@ namespace Umbraco.Cms.Core.Manifest
|
||||
if (manifest.Sections != null) sections.AddRange(manifest.Sections.DistinctBy(x => x.Alias.ToLowerInvariant()));
|
||||
}
|
||||
|
||||
return new PackageManifest
|
||||
{
|
||||
Scripts = scripts.ToArray(),
|
||||
Stylesheets = stylesheets.ToArray(),
|
||||
PropertyEditors = propertyEditors.ToArray(),
|
||||
ParameterEditors = parameterEditors.ToArray(),
|
||||
GridEditors = gridEditors.ToArray(),
|
||||
ContentApps = contentApps.ToArray(),
|
||||
Dashboards = dashboards.ToArray(),
|
||||
Sections = sections.ToArray()
|
||||
};
|
||||
return new CompositePackageManifest(
|
||||
propertyEditors,
|
||||
parameterEditors,
|
||||
gridEditors,
|
||||
contentApps,
|
||||
dashboards,
|
||||
sections,
|
||||
scripts.ToDictionary(x => x.Key, x => (IReadOnlyList<ManifestAssets>)x.Value),
|
||||
stylesheets.ToDictionary(x => x.Key, x => (IReadOnlyList<ManifestAssets>)x.Value));
|
||||
}
|
||||
|
||||
// gets all manifest files (recursively)
|
||||
|
||||
@@ -73,25 +73,66 @@ namespace Umbraco.Cms.Infrastructure.WebAssets
|
||||
_runtimeMinifier.CreateJsBundle(UmbracoCoreJsBundleName, false,
|
||||
FormatPaths(GetScriptsForBackOfficeCore()));
|
||||
|
||||
|
||||
// get the property editor assets
|
||||
var propertyEditorAssets = ScanPropertyEditors()
|
||||
.GroupBy(x => x.AssetType)
|
||||
.ToDictionary(x => x.Key, x => x.Select(c => c.FilePath));
|
||||
|
||||
// get the back office custom assets
|
||||
var customAssets = _customBackOfficeAssetsCollection.GroupBy(x => x.DependencyType).ToDictionary(x => x.Key, x => x.Select(c => c.FilePath));
|
||||
|
||||
var jsAssets = (customAssets.TryGetValue(AssetType.Javascript, out var customScripts) ? customScripts : Enumerable.Empty<string>())
|
||||
.Union(propertyEditorAssets.TryGetValue(AssetType.Javascript, out var scripts) ? scripts : Enumerable.Empty<string>());
|
||||
// This bundle includes all scripts from property editor assets,
|
||||
// custom back office assets, and any scripts found in package manifests
|
||||
// that have the default bundle options.
|
||||
|
||||
IEnumerable<string> jsAssets = (customAssets.TryGetValue(AssetType.Javascript, out IEnumerable<string> customScripts) ? customScripts : Enumerable.Empty<string>())
|
||||
.Union(propertyEditorAssets.TryGetValue(AssetType.Javascript, out IEnumerable<string> scripts) ? scripts : Enumerable.Empty<string>());
|
||||
|
||||
_runtimeMinifier.CreateJsBundle(
|
||||
UmbracoExtensionsJsBundleName, true,
|
||||
UmbracoExtensionsJsBundleName,
|
||||
true,
|
||||
FormatPaths(
|
||||
GetScriptsForBackOfficeExtensions(jsAssets)));
|
||||
|
||||
var cssAssets = (customAssets.TryGetValue(AssetType.Css, out var customStyles) ? customStyles : Enumerable.Empty<string>())
|
||||
.Union(propertyEditorAssets.TryGetValue(AssetType.Css, out var styles) ? styles : Enumerable.Empty<string>());
|
||||
// Create a bundle per package manifest that is declaring an Independent bundle type
|
||||
RegisterPackageBundlesForIndependentOptions(_parser.CombinedManifest.Scripts, AssetType.Javascript);
|
||||
|
||||
// This bundle includes all CSS from property editor assets,
|
||||
// custom back office assets, and any CSS found in package manifests
|
||||
// that have the default bundle options.
|
||||
|
||||
IEnumerable<string> cssAssets = (customAssets.TryGetValue(AssetType.Css, out IEnumerable<string> customStyles) ? customStyles : Enumerable.Empty<string>())
|
||||
.Union(propertyEditorAssets.TryGetValue(AssetType.Css, out IEnumerable<string> styles) ? styles : Enumerable.Empty<string>());
|
||||
|
||||
_runtimeMinifier.CreateCssBundle(
|
||||
UmbracoCssBundleName, true,
|
||||
UmbracoCssBundleName,
|
||||
true,
|
||||
FormatPaths(
|
||||
GetStylesheetsForBackOffice(cssAssets)));
|
||||
|
||||
// Create a bundle per package manifest that is declaring an Independent bundle type
|
||||
RegisterPackageBundlesForIndependentOptions(_parser.CombinedManifest.Stylesheets, AssetType.Css);
|
||||
}
|
||||
|
||||
public static string GetIndependentPackageBundleName(ManifestAssets manifestAssets, AssetType assetType)
|
||||
=> $"{manifestAssets.PackageName.ToLowerInvariant()}-{(assetType == AssetType.Css ? "css" : "js")}";
|
||||
|
||||
private void RegisterPackageBundlesForIndependentOptions(
|
||||
IReadOnlyDictionary<BundleOptions, IReadOnlyList<ManifestAssets>> combinedPackageManifestAssets,
|
||||
AssetType assetType)
|
||||
{
|
||||
// Create a bundle per package manifest that is declaring the matching BundleOptions
|
||||
if (combinedPackageManifestAssets.TryGetValue(BundleOptions.Independent, out IReadOnlyList<ManifestAssets> manifestAssetList))
|
||||
{
|
||||
foreach (ManifestAssets manifestAssets in manifestAssetList)
|
||||
{
|
||||
_runtimeMinifier.CreateJsBundle(
|
||||
GetIndependentPackageBundleName(manifestAssets, assetType),
|
||||
true,
|
||||
FormatPaths(manifestAssets.Assets.ToArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -100,10 +141,15 @@ namespace Umbraco.Cms.Infrastructure.WebAssets
|
||||
/// <returns></returns>
|
||||
private string[] GetScriptsForBackOfficeExtensions(IEnumerable<string> propertyEditorScripts)
|
||||
{
|
||||
var scripts = new HashSet<string>();
|
||||
foreach (string script in _parser.Manifest.Scripts)
|
||||
var scripts = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
// only include scripts with the default bundle options here
|
||||
if (_parser.CombinedManifest.Scripts.TryGetValue(BundleOptions.Default, out IReadOnlyList<ManifestAssets> manifestAssets))
|
||||
{
|
||||
scripts.Add(script);
|
||||
foreach (string script in manifestAssets.SelectMany(x => x.Assets))
|
||||
{
|
||||
scripts.Add(script);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string script in propertyEditorScripts)
|
||||
@@ -130,11 +176,15 @@ namespace Umbraco.Cms.Infrastructure.WebAssets
|
||||
/// <returns></returns>
|
||||
private string[] GetStylesheetsForBackOffice(IEnumerable<string> propertyEditorStyles)
|
||||
{
|
||||
var stylesheets = new HashSet<string>();
|
||||
var stylesheets = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
foreach (string script in _parser.Manifest.Stylesheets)
|
||||
// only include css with the default bundle options here
|
||||
if (_parser.CombinedManifest.Stylesheets.TryGetValue(BundleOptions.Default, out IReadOnlyList<ManifestAssets> manifestAssets))
|
||||
{
|
||||
stylesheets.Add(script);
|
||||
foreach (string script in manifestAssets.SelectMany(x => x.Assets))
|
||||
{
|
||||
stylesheets.Add(script);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string stylesheet in propertyEditorStyles)
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.WebAssets;
|
||||
using Umbraco.Cms.Infrastructure.WebAssets;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
public static class RuntimeMinifierExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the JavaScript to load the back office's assets
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> GetScriptForLoadingBackOfficeAsync(this IRuntimeMinifier minifier, GlobalSettings globalSettings, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
var coreScripts = await minifier.GetJsAssetPathsAsync(BackOfficeWebAssets.UmbracoCoreJsBundleName);
|
||||
var extensionsScripts = await minifier.GetJsAssetPathsAsync(BackOfficeWebAssets.UmbracoExtensionsJsBundleName);
|
||||
var result = BackOfficeJavaScriptInitializer.GetJavascriptInitialization(coreScripts.Union(extensionsScripts), "umbraco", globalSettings, hostingEnvironment);
|
||||
result += await GetStylesheetInitializationAsync(minifier);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the back office css bundle paths and formats a JS call to lazy load them
|
||||
/// </summary>
|
||||
private static async Task<string> GetStylesheetInitializationAsync(IRuntimeMinifier minifier)
|
||||
{
|
||||
var files = await minifier.GetCssAssetPathsAsync(BackOfficeWebAssets.UmbracoCssBundleName);
|
||||
var sb = new StringBuilder();
|
||||
foreach (var file in files)
|
||||
sb.AppendFormat("{0}LazyLoad.css('{1}');", Environment.NewLine, file);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Grid;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Manifest;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
@@ -63,6 +64,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
private readonly IBackOfficeExternalLoginProviders _externalLogins;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IBackOfficeTwoFactorOptions _backOfficeTwoFactorOptions;
|
||||
private readonly IManifestParser _manifestParser;
|
||||
private readonly ServerVariablesParser _serverVariables;
|
||||
|
||||
public BackOfficeController(
|
||||
@@ -81,6 +83,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
IBackOfficeExternalLoginProviders externalLogins,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions,
|
||||
IManifestParser manifestParser,
|
||||
ServerVariablesParser serverVariables)
|
||||
{
|
||||
_userManager = userManager;
|
||||
@@ -98,6 +101,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
_externalLogins = externalLogins;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_backOfficeTwoFactorOptions = backOfficeTwoFactorOptions;
|
||||
_manifestParser = manifestParser;
|
||||
_serverVariables = serverVariables;
|
||||
}
|
||||
|
||||
@@ -213,7 +217,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Application()
|
||||
{
|
||||
var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(_globalSettings, _hostingEnvironment);
|
||||
var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(
|
||||
_globalSettings,
|
||||
_hostingEnvironment,
|
||||
_manifestParser,
|
||||
Url);
|
||||
|
||||
return new JavaScriptResult(result);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Manifest;
|
||||
using Umbraco.Cms.Core.WebAssets;
|
||||
using Umbraco.Cms.Infrastructure.WebAssets;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
public static class RuntimeMinifierExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the JavaScript to load the back office's assets
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> GetScriptForLoadingBackOfficeAsync(
|
||||
this IRuntimeMinifier minifier,
|
||||
GlobalSettings globalSettings,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IManifestParser manifestParser,
|
||||
IUrlHelper urlHelper)
|
||||
{
|
||||
var files = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach(var file in await minifier.GetJsAssetPathsAsync(BackOfficeWebAssets.UmbracoCoreJsBundleName))
|
||||
{
|
||||
files.Add(file);
|
||||
}
|
||||
|
||||
foreach (var file in await minifier.GetJsAssetPathsAsync(BackOfficeWebAssets.UmbracoExtensionsJsBundleName))
|
||||
{
|
||||
files.Add(file);
|
||||
}
|
||||
|
||||
// process the independent bundles
|
||||
if (manifestParser.CombinedManifest.Scripts.TryGetValue(BundleOptions.Independent, out IReadOnlyList<ManifestAssets> independentManifestAssetsList))
|
||||
{
|
||||
foreach (ManifestAssets manifestAssets in independentManifestAssetsList)
|
||||
{
|
||||
var bundleName = BackOfficeWebAssets.GetIndependentPackageBundleName(manifestAssets, AssetType.Javascript);
|
||||
foreach(var asset in await minifier.GetJsAssetPathsAsync(bundleName))
|
||||
{
|
||||
files.Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process the "None" bundles, meaning we'll just render the script as-is
|
||||
if (manifestParser.CombinedManifest.Scripts.TryGetValue(BundleOptions.None, out IReadOnlyList<ManifestAssets> noneManifestAssetsList))
|
||||
{
|
||||
foreach (ManifestAssets manifestAssets in noneManifestAssetsList)
|
||||
{
|
||||
foreach(var asset in manifestAssets.Assets)
|
||||
{
|
||||
files.Add(urlHelper.Content(asset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = BackOfficeJavaScriptInitializer.GetJavascriptInitialization(
|
||||
files,
|
||||
"umbraco",
|
||||
globalSettings,
|
||||
hostingEnvironment);
|
||||
|
||||
result += await GetStylesheetInitializationAsync(minifier, manifestParser, urlHelper);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the back office css bundle paths and formats a JS call to lazy load them
|
||||
/// </summary>
|
||||
private static async Task<string> GetStylesheetInitializationAsync(
|
||||
IRuntimeMinifier minifier,
|
||||
IManifestParser manifestParser,
|
||||
IUrlHelper urlHelper)
|
||||
{
|
||||
var files = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach(var file in await minifier.GetCssAssetPathsAsync(BackOfficeWebAssets.UmbracoCssBundleName))
|
||||
{
|
||||
files.Add(file);
|
||||
}
|
||||
|
||||
// process the independent bundles
|
||||
if (manifestParser.CombinedManifest.Stylesheets.TryGetValue(BundleOptions.Independent, out IReadOnlyList<ManifestAssets> independentManifestAssetsList))
|
||||
{
|
||||
foreach (ManifestAssets manifestAssets in independentManifestAssetsList)
|
||||
{
|
||||
var bundleName = BackOfficeWebAssets.GetIndependentPackageBundleName(manifestAssets, AssetType.Css);
|
||||
foreach (var asset in await minifier.GetCssAssetPathsAsync(bundleName))
|
||||
{
|
||||
files.Add(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process the "None" bundles, meaning we'll just render the script as-is
|
||||
if (manifestParser.CombinedManifest.Stylesheets.TryGetValue(BundleOptions.None, out IReadOnlyList<ManifestAssets> noneManifestAssetsList))
|
||||
{
|
||||
foreach (ManifestAssets manifestAssets in noneManifestAssetsList)
|
||||
{
|
||||
foreach (var asset in manifestAssets.Assets)
|
||||
{
|
||||
files.Add(urlHelper.Content(asset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (string file in files)
|
||||
{
|
||||
sb.AppendFormat("{0}LazyLoad.css('{1}');", Environment.NewLine, file);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -60,9 +60,21 @@ namespace Umbraco.Cms.Web.Common.RuntimeMinification
|
||||
// replace the default JsMinifier with NuglifyJs and CssMinifier with NuglifyCss in the default pipelines
|
||||
// for use with our bundles only (not modifying global options)
|
||||
_jsOptimizedPipeline = new Lazy<PreProcessPipeline>(() => bundles.PipelineFactory.DefaultJs().Replace<JsMinifier, SmidgeNuglifyJs>(_bundles.PipelineFactory));
|
||||
_jsNonOptimizedPipeline = new Lazy<PreProcessPipeline>(() => bundles.PipelineFactory.DefaultJs());
|
||||
_jsNonOptimizedPipeline = new Lazy<PreProcessPipeline>(() =>
|
||||
{
|
||||
PreProcessPipeline defaultJs = bundles.PipelineFactory.DefaultJs();
|
||||
// remove minification from this pipeline
|
||||
defaultJs.Processors.RemoveAll(x => x is JsMinifier);
|
||||
return defaultJs;
|
||||
});
|
||||
_cssOptimizedPipeline = new Lazy<PreProcessPipeline>(() => bundles.PipelineFactory.DefaultCss().Replace<CssMinifier, NuglifyCss>(_bundles.PipelineFactory));
|
||||
_cssNonOptimizedPipeline = new Lazy<PreProcessPipeline>(() => bundles.PipelineFactory.DefaultCss());
|
||||
_cssNonOptimizedPipeline = new Lazy<PreProcessPipeline>(() =>
|
||||
{
|
||||
PreProcessPipeline defaultCss = bundles.PipelineFactory.DefaultCss();
|
||||
// remove minification from this pipeline
|
||||
defaultCss.Processors.RemoveAll(x => x is CssMinifier);
|
||||
return defaultCss;
|
||||
});
|
||||
|
||||
Type cacheBusterType = _runtimeMinificationSettings.CacheBuster switch
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user