From a9732cb2334868190cd19abecc7a31885591bae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 6 Feb 2020 14:57:25 +0100 Subject: [PATCH 01/14] corrected button style to match new style --- .../src/views/propertyeditors/listview/listview.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index ee1847b430..55adb18c6e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -21,7 +21,7 @@
- From 312dc1d9a757469daa209fe99f66abc5b0dc2309 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe Date: Tue, 15 Sep 2020 12:54:00 -0400 Subject: [PATCH 02/14] Change wrong URL in KeepAlive XML Comments The XML comments for KeepAlive mention the URL for the KeepAlive.Ping action but incorrectly omits 'umbraco' from the path. The change adds the 'umbraco' section to the path. --- src/Umbraco.Web.UI/config/umbracoSettings.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 73a5143a20..d723b9c7c0 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -259,7 +259,7 @@ Defaults to "false". @keepAlivePingUrl The url of the KeepAlivePing action. By default, the url will use the umbracoApplicationUrl setting as the basis. - Change this setting to specify an alternative url to reach the KeepAlivePing action. eg http://localhost/api/keepalive/ping + Change this setting to specify an alternative url to reach the KeepAlivePing action. eg http://localhost/umbraco/api/keepalive/ping Defaults to "{umbracoApplicationUrl}/api/keepalive/ping". --> From 5a37854dd5d3412cc0ac18dfed003b212ac192c7 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 14 Sep 2020 12:02:26 +0100 Subject: [PATCH 03/14] Merge pull request #7599 from umbraco/v8/feature/ui-media-create-button-style UI: corrected button style to match new style (cherry picked from commit 2e055ca146a7ab1814ce232ccc97fa07571733df) --- .../src/views/propertyeditors/listview/listview.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index 05a294cc1c..e72b81b019 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -21,7 +21,7 @@
- From 6d2135edd5b0c92560492ee6417d136740a0d07b Mon Sep 17 00:00:00 2001 From: Niels Swimberghe Date: Tue, 15 Sep 2020 12:54:00 -0400 Subject: [PATCH 04/14] Change wrong URL in KeepAlive XML Comments The XML comments for KeepAlive mention the URL for the KeepAlive.Ping action but incorrectly omits 'umbraco' from the path. The change adds the 'umbraco' section to the path. (cherry picked from commit 312dc1d9a757469daa209fe99f66abc5b0dc2309) --- src/Umbraco.Web.UI/config/umbracoSettings.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 73a5143a20..d723b9c7c0 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -259,7 +259,7 @@ Defaults to "false". @keepAlivePingUrl The url of the KeepAlivePing action. By default, the url will use the umbracoApplicationUrl setting as the basis. - Change this setting to specify an alternative url to reach the KeepAlivePing action. eg http://localhost/api/keepalive/ping + Change this setting to specify an alternative url to reach the KeepAlivePing action. eg http://localhost/umbraco/api/keepalive/ping Defaults to "{umbracoApplicationUrl}/api/keepalive/ping". --> From deb03e4d82e48674c6d8bdc7926e820e17454d9e Mon Sep 17 00:00:00 2001 From: Lars-Erik Aabech Date: Thu, 17 Sep 2020 11:32:52 +0200 Subject: [PATCH 05/14] Eliminates error/no-preview when grid media picker have no crop set (#8620) --- .../mediapicker/overlays/mediacropdetails.controller.js | 5 +++++ .../mediapicker/overlays/mediacropdetails.html | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js index d9ea5a7a09..030200e1e6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js @@ -6,6 +6,7 @@ vm.submit = submit; vm.close = close; + vm.cropSet = cropSet; if (!$scope.model.target.coordinates && !$scope.model.target.focalPoint) { $scope.model.target.focalPoint = { left: .5, top: .5 }; @@ -56,4 +57,8 @@ } } + function cropSet() { + var model = $scope.model; + return (model.cropSize || {}).width && model.target.thumbnail; + } }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html index 3814ac851e..cda42043c1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html @@ -26,7 +26,7 @@
-
+
Preview
@@ -34,7 +34,7 @@ {{model.target.name}}
-
+
Crop section
From 6d15a2fce3ba8e0585b5b6df45d1a274daf76a46 Mon Sep 17 00:00:00 2001 From: Lars-Erik Aabech Date: Thu, 17 Sep 2020 11:32:52 +0200 Subject: [PATCH 06/14] Eliminates error/no-preview when grid media picker have no crop set (#8620) (cherry picked from commit deb03e4d82e48674c6d8bdc7926e820e17454d9e) --- .../mediapicker/overlays/mediacropdetails.controller.js | 5 +++++ .../mediapicker/overlays/mediacropdetails.html | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js index d9ea5a7a09..030200e1e6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.controller.js @@ -6,6 +6,7 @@ vm.submit = submit; vm.close = close; + vm.cropSet = cropSet; if (!$scope.model.target.coordinates && !$scope.model.target.focalPoint) { $scope.model.target.focalPoint = { left: .5, top: .5 }; @@ -56,4 +57,8 @@ } } + function cropSet() { + var model = $scope.model; + return (model.cropSize || {}).width && model.target.thumbnail; + } }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html index 3814ac851e..cda42043c1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/overlays/mediacropdetails.html @@ -26,7 +26,7 @@
-
+
Preview
@@ -34,7 +34,7 @@ {{model.target.name}}
-
+
Crop section
From 6b0539fefcf2f7e103a38638c0328f2a418cb520 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 17 Sep 2020 12:19:07 +0200 Subject: [PATCH 07/14] Set version to RC --- src/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 3f512bc65a..26496aa9e6 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -19,4 +19,4 @@ using System.Resources; // these are FYI and changed automatically [assembly: AssemblyFileVersion("8.8.0")] -[assembly: AssemblyInformationalVersion("8.8.0")] +[assembly: AssemblyInformationalVersion("8.8.0-rc")] From 0506c8c555e5398591afd84277e0f48a69673415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 17 Sep 2020 14:59:12 +0200 Subject: [PATCH 08/14] defineIcon method --- .../src/common/services/iconhelper.service.js | 53 +++++++++---------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js index 0d0135fff8..f714cba4ad 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js @@ -31,7 +31,7 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { { oldIcon: ".sprToPublish", newIcon: "mail-forward" }, { oldIcon: ".sprTranslate", newIcon: "comments" }, { oldIcon: ".sprUpdate", newIcon: "save" }, - + { oldIcon: ".sprTreeSettingDomain", newIcon: "icon-home" }, { oldIcon: ".sprTreeDoc", newIcon: "icon-document" }, { oldIcon: ".sprTreeDoc2", newIcon: "icon-diploma-alt" }, @@ -39,21 +39,21 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { { oldIcon: ".sprTreeDoc4", newIcon: "icon-newspaper-alt" }, { oldIcon: ".sprTreeDoc5", newIcon: "icon-notepad-alt" }, - { oldIcon: ".sprTreeDocPic", newIcon: "icon-picture" }, + { oldIcon: ".sprTreeDocPic", newIcon: "icon-picture" }, { oldIcon: ".sprTreeFolder", newIcon: "icon-folder" }, { oldIcon: ".sprTreeFolder_o", newIcon: "icon-folder" }, { oldIcon: ".sprTreeMediaFile", newIcon: "icon-music" }, { oldIcon: ".sprTreeMediaMovie", newIcon: "icon-movie" }, { oldIcon: ".sprTreeMediaPhoto", newIcon: "icon-picture" }, - + { oldIcon: ".sprTreeMember", newIcon: "icon-user" }, { oldIcon: ".sprTreeMemberGroup", newIcon: "icon-users" }, { oldIcon: ".sprTreeMemberType", newIcon: "icon-users" }, - + { oldIcon: ".sprTreeNewsletter", newIcon: "icon-file-text-alt" }, { oldIcon: ".sprTreePackage", newIcon: "icon-box" }, { oldIcon: ".sprTreeRepository", newIcon: "icon-server-alt" }, - + { oldIcon: ".sprTreeSettingDataType", newIcon: "icon-autofill" }, // TODO: Something needs to be done with the old tree icons that are commented out. @@ -61,7 +61,7 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { { oldIcon: ".sprTreeSettingAgent", newIcon: "" }, { oldIcon: ".sprTreeSettingCss", newIcon: "" }, { oldIcon: ".sprTreeSettingCssItem", newIcon: "" }, - + { oldIcon: ".sprTreeSettingDataTypeChild", newIcon: "" }, { oldIcon: ".sprTreeSettingDomain", newIcon: "" }, { oldIcon: ".sprTreeSettingLanguage", newIcon: "" }, @@ -94,9 +94,9 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { var iconCache = []; var liveRequests = []; var allIconsRequested = false; - + return { - + /** Used by the create dialogs for content/media types to format the data so that the thumbnails are styled properly */ formatContentTypeThumbnails: function (contentTypes) { for (var i = 0; i < contentTypes.length; i++) { @@ -209,15 +209,11 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { ,'Failed to retrieve icon: ' + iconName) .then(icon => { if(icon) { - var trustedIcon = { - name: icon.Name, - svgString: $sce.trustAsHtml(icon.SvgString) - }; - this._cacheIcon(trustedIcon); + var trustedIcon = this.defineIcon(icon.name, icon.SvgString); - liveRequests = _.filter(liveRequests, iconRequestPath); + liveRequests = _.filter(liveRequests, iconRequestPath); - resolve(trustedIcon); + resolve(trustedIcon); } }) .catch(err => { @@ -240,15 +236,10 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { ,'Failed to retrieve icons') .then(icons => { icons.forEach(icon => { - var trustedIcon = { - name: icon.Name, - svgString: $sce.trustAsHtml(icon.SvgString) - }; - - this._cacheIcon(trustedIcon); + this.defineIcon(icon.Name, icon.SvgString); }); - resolve(iconCache); + resolve(iconCache); }) .catch(err => { console.warn(err); @@ -278,7 +269,7 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { console.warn("Can't read the css rules of: " + document.styleSheets[i].href, e); continue; } - + if (classes !== null) { for(var x=0;x x.name === name); + if(icon === undefined) { + icon = { + name: name, + svgString: $sce.trustAsHtml(svg) + }; + iconCache.push(icon); + } + return icon; }, /** Returns the cached icon or undefined */ From e2957bb715d797299d5cc65c8d073fd17bb15441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 17 Sep 2020 14:59:49 +0200 Subject: [PATCH 09/14] inject icons to iconHelper to avoid making requests to the icon controller --- .../Umbraco/Views/Default.cshtml | 286 +++++++++--------- 1 file changed, 148 insertions(+), 138 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml index 616763c06f..d0f0fd2cc8 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml @@ -1,138 +1,148 @@ -@using Umbraco.Core -@using ClientDependency.Core -@using ClientDependency.Core.Mvc -@using Umbraco.Core.Composing -@using Umbraco.Core.IO -@using Umbraco.Web -@using Umbraco.Core.Configuration - -@inherits WebViewPage - -@{ - var isDebug = false; - if (Request.RawUrl.IndexOf('?') >= 0) - { - var parsed = HttpUtility.ParseQueryString(Request.RawUrl.Split('?')[1]); - var attempt = parsed["umbDebug"].TryConvertTo(); - if (attempt && attempt.Result) - { - isDebug = true; - } - } - - Html - .RequiresCss("assets/css/umbraco.css", "Umbraco") - .RequiresCss("lib/bootstrap-social/bootstrap-social.css", "Umbraco") - .RequiresCss("lib/font-awesome/css/font-awesome.min.css", "Umbraco"); -} - - - - - - - - - - - - - - Umbraco - - @Html.RenderCssHere( - new BasicPath("Umbraco", IOHelper.ResolveUrl(SystemDirectories.Umbraco))) - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - - - - @Html.BareMinimumServerVariablesScript(Url, Url.Action("ExternalLogin", "BackOffice", new { area = ViewData.GetUmbracoPath() }), Model.Features, Current.Configs.Global()) - - - - - - - @if (isDebug) - { - @Html.RenderProfiler() - } - - - +@using Umbraco.Core +@using ClientDependency.Core +@using ClientDependency.Core.Mvc +@using Umbraco.Core.Composing +@using Umbraco.Core.IO +@using Umbraco.Web +@using Umbraco.Core.Configuration + +@inherits WebViewPage + +@{ + var isDebug = false; + if (Request.RawUrl.IndexOf('?') >= 0) + { + var parsed = HttpUtility.ParseQueryString(Request.RawUrl.Split('?')[1]); + var attempt = parsed["umbDebug"].TryConvertTo(); + if (attempt && attempt.Result) + { + isDebug = true; + } + } + + Html + .RequiresCss("assets/css/umbraco.css", "Umbraco") + .RequiresCss("lib/bootstrap-social/bootstrap-social.css", "Umbraco") + .RequiresCss("lib/font-awesome/css/font-awesome.min.css", "Umbraco"); +} + + + + + + + + + + + + + + Umbraco + + @Html.RenderCssHere( + new BasicPath("Umbraco", IOHelper.ResolveUrl(SystemDirectories.Umbraco))) + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + @Html.BareMinimumServerVariablesScript(Url, Url.Action("ExternalLogin", "BackOffice", new { area = ViewData.GetUmbracoPath() }), Model.Features, Current.Configs.Global()) + + + + + + + @if (isDebug) + { + @Html.RenderProfiler() + } + + + From b327399cd2c637a715792dc1d40ac1e6253ae3eb Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 22 Sep 2020 08:11:58 +0200 Subject: [PATCH 10/14] adding icon svg data from IconController. --- src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml | 8 ++------ src/Umbraco.Web/Editors/BackOfficeModel.cs | 6 ++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml index d0f0fd2cc8..666f7a64f5 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml @@ -4,7 +4,6 @@ @using Umbraco.Core.Composing @using Umbraco.Core.IO @using Umbraco.Web -@using Umbraco.Core.Configuration @inherits WebViewPage @@ -122,12 +121,9 @@ @Html.AngularValueTinyMceAssets() app.run(["iconHelper", function (iconHelper) { - @* We inject icons to the icon helper(service), since icons can only be loaded if user is authorized. By injecting these to the service they will not be requested as they will become cached. *@ - - iconHelper.defineIcon("icon-check", ''); - iconHelper.defineIcon("icon-delete", ''); - + iconHelper.defineIcon("icon-check", '@Html.Raw(Model.IconCheckData)'); + iconHelper.defineIcon("icon-delete", '@Html.Raw(Model.IconDeleteData)'); }]); //required for the noscript trick diff --git a/src/Umbraco.Web/Editors/BackOfficeModel.cs b/src/Umbraco.Web/Editors/BackOfficeModel.cs index 9833121301..b11ea6a5d1 100644 --- a/src/Umbraco.Web/Editors/BackOfficeModel.cs +++ b/src/Umbraco.Web/Editors/BackOfficeModel.cs @@ -6,13 +6,19 @@ namespace Umbraco.Web.Editors public class BackOfficeModel { + private IconController IconController { get; } public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings) { Features = features; GlobalSettings = globalSettings; + IconController = new IconController(); + IconCheckData = IconController.GetIcon("icon-check")?.SvgString; + IconDeleteData = IconController.GetIcon("icon-delete")?.SvgString; } public UmbracoFeatures Features { get; } public IGlobalSettings GlobalSettings { get; } + public string IconCheckData { get; } + public string IconDeleteData { get; } } } From 6e56b16342571935c38f06fcb131694265ea295b Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 22 Sep 2020 08:57:48 +0200 Subject: [PATCH 11/14] adding IconService --- src/Umbraco.Web/Composing/Current.cs | 3 + .../Editors/BackOfficeController.cs | 23 +++- src/Umbraco.Web/Editors/BackOfficeModel.cs | 8 +- src/Umbraco.Web/Editors/IconController.cs | 81 ++------------ src/Umbraco.Web/Runtime/WebInitialComposer.cs | 2 +- src/Umbraco.Web/Services/IIconService.cs | 29 +++++ src/Umbraco.Web/Services/IconService.cs | 100 ++++++++++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 2 + 8 files changed, 166 insertions(+), 82 deletions(-) create mode 100644 src/Umbraco.Web/Services/IIconService.cs create mode 100644 src/Umbraco.Web/Services/IconService.cs diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 2419eaa6d4..14898d0c02 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -146,6 +146,9 @@ namespace Umbraco.Web.Composing public static ISectionService SectionService => Factory.GetInstance(); + public static IIconService IconService + => Factory.GetInstance(); + #endregion #region Web Constants diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index e77a1b70f2..3e16dd9692 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -15,7 +14,6 @@ using Newtonsoft.Json; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; -using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Models.Identity; @@ -26,6 +24,7 @@ using Umbraco.Web.Composing; using Umbraco.Web.Features; using Umbraco.Web.JavaScript; using Umbraco.Web.Security; +using Umbraco.Web.Services; using Constants = Umbraco.Core.Constants; using JArray = Newtonsoft.Json.Linq.JArray; @@ -42,6 +41,7 @@ namespace Umbraco.Web.Editors private readonly ManifestParser _manifestParser; private readonly UmbracoFeatures _features; private readonly IRuntimeState _runtimeState; + private readonly IIconService _iconService; private BackOfficeUserManager _userManager; private BackOfficeSignInManager _signInManager; @@ -51,6 +51,16 @@ namespace Umbraco.Web.Editors _manifestParser = manifestParser; _features = features; _runtimeState = runtimeState; + _iconService = Current.IconService; + } + + public BackOfficeController(ManifestParser manifestParser, UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper, IIconService iconService) + : base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger, umbracoHelper) + { + _manifestParser = manifestParser; + _features = features; + _runtimeState = runtimeState; + _iconService = iconService; } protected BackOfficeSignInManager SignInManager => _signInManager ?? (_signInManager = OwinContext.GetBackOfficeSignInManager()); @@ -65,9 +75,14 @@ namespace Umbraco.Web.Editors /// public async Task Default() { + var backofficeModel = new BackOfficeModel(_features, GlobalSettings) + { + IconCheckData = _iconService.GetIcon("icon-check")?.SvgString, + IconDeleteData = _iconService.GetIcon("icon-delete")?.SvgString + }; return await RenderDefaultOrProcessExternalLoginAsync( - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings)), - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings))); + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", backofficeModel), + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", backofficeModel)); } [HttpGet] diff --git a/src/Umbraco.Web/Editors/BackOfficeModel.cs b/src/Umbraco.Web/Editors/BackOfficeModel.cs index b11ea6a5d1..ba85a64b42 100644 --- a/src/Umbraco.Web/Editors/BackOfficeModel.cs +++ b/src/Umbraco.Web/Editors/BackOfficeModel.cs @@ -6,19 +6,15 @@ namespace Umbraco.Web.Editors public class BackOfficeModel { - private IconController IconController { get; } public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings) { Features = features; GlobalSettings = globalSettings; - IconController = new IconController(); - IconCheckData = IconController.GetIcon("icon-check")?.SvgString; - IconDeleteData = IconController.GetIcon("icon-delete")?.SvgString; } public UmbracoFeatures Features { get; } public IGlobalSettings GlobalSettings { get; } - public string IconCheckData { get; } - public string IconDeleteData { get; } + public string IconCheckData { get; set; } + public string IconDeleteData { get; set; } } } diff --git a/src/Umbraco.Web/Editors/IconController.cs b/src/Umbraco.Web/Editors/IconController.cs index 72af2194ae..2554f633df 100644 --- a/src/Umbraco.Web/Editors/IconController.cs +++ b/src/Umbraco.Web/Editors/IconController.cs @@ -1,21 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; -using Umbraco.Core.Logging; using Umbraco.Web.Models; -using System.IO; -using Umbraco.Core; -using Umbraco.Core.IO; -using Ganss.XSS; -using Umbraco.Core.Cache; +using Umbraco.Web.Services; namespace Umbraco.Web.Editors { [PluginController("UmbracoApi")] public class IconController : UmbracoAuthorizedApiController { + private readonly IIconService _iconService; + + public IconController(IIconService iconService) + { + _iconService = iconService; + } /// /// Gets an IconModel containing the icon name and SvgString according to an icon name found at the global icons path @@ -24,21 +23,7 @@ namespace Umbraco.Web.Editors /// public IconModel GetIcon(string iconName) { - return string.IsNullOrWhiteSpace(iconName) - ? null - : CreateIconModel(iconName.StripFileExtension(), IOHelper.MapPath($"{GlobalSettings.IconsPath}/{iconName}.svg")); - } - - /// - /// Gets an IconModel using values from a FileInfo model - /// - /// - /// - public IconModel GetIcon(FileInfo fileInfo) - { - return fileInfo == null || string.IsNullOrWhiteSpace(fileInfo.Name) - ? null - : CreateIconModel(fileInfo.Name.StripFileExtension(), fileInfo.FullName); + return _iconService.GetIcon(iconName); } /// @@ -47,53 +32,7 @@ namespace Umbraco.Web.Editors /// public List GetAllIcons() { - var icons = new List(); - var directory = new DirectoryInfo(IOHelper.MapPath($"{GlobalSettings.IconsPath}/")); - var iconNames = directory.GetFiles("*.svg"); - - iconNames.OrderBy(f => f.Name).ToList().ForEach(iconInfo => - { - var icon = GetIcon(iconInfo); - - if (icon != null) - { - icons.Add(icon); - } - }); - - return icons; - } - - /// - /// Gets an IconModel containing the icon name and SvgString - /// - /// - /// - /// - private IconModel CreateIconModel(string iconName, string iconPath) - { - var sanitizer = new HtmlSanitizer(); - sanitizer.AllowedAttributes.UnionWith(Core.Constants.SvgSanitizer.Attributes); - sanitizer.AllowedCssProperties.UnionWith(Core.Constants.SvgSanitizer.Attributes); - sanitizer.AllowedTags.UnionWith(Core.Constants.SvgSanitizer.Tags); - - try - { - var svgContent = File.ReadAllText(iconPath); - var sanitizedString = sanitizer.Sanitize(svgContent); - - var svg = new IconModel - { - Name = iconName, - SvgString = sanitizedString - }; - - return svg; - } - catch - { - return null; - } + return _iconService.GetAllIcons(); } } } diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 135d54560b..112910930e 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -137,8 +137,8 @@ namespace Umbraco.Web.Runtime composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); - composition.RegisterUnique(); + composition.RegisterUnique(); composition.RegisterUnique(factory => ExamineManager.Instance); diff --git a/src/Umbraco.Web/Services/IIconService.cs b/src/Umbraco.Web/Services/IIconService.cs new file mode 100644 index 0000000000..cdd75f8d4b --- /dev/null +++ b/src/Umbraco.Web/Services/IIconService.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.IO; +using Umbraco.Web.Models; + +namespace Umbraco.Web.Services +{ + public interface IIconService + { + /// + /// Gets an IconModel containing the icon name and SvgString according to an icon name found at the global icons path + /// + /// + /// + IconModel GetIcon(string iconName); + + /// + /// Gets an IconModel using values from a FileInfo model + /// + /// + /// + IconModel GetIcon(FileInfo fileInfo); + + /// + /// Gets a list of all svg icons found at at the global icons path. + /// + /// + List GetAllIcons(); + } +} diff --git a/src/Umbraco.Web/Services/IconService.cs b/src/Umbraco.Web/Services/IconService.cs new file mode 100644 index 0000000000..4093f69174 --- /dev/null +++ b/src/Umbraco.Web/Services/IconService.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Ganss.XSS; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; +using Umbraco.Web.Models; + +namespace Umbraco.Web.Services +{ + internal class IconService : IIconService + { + private readonly IGlobalSettings _globalSettings; + + public IconService(IGlobalSettings globalSettings) + { + _globalSettings = globalSettings; + } + + /// + /// Gets an IconModel containing the icon name and SvgString according to an icon name found at the global icons path + /// + /// + /// + public IconModel GetIcon(string iconName) + { + return string.IsNullOrWhiteSpace(iconName) + ? null + : CreateIconModel(iconName.StripFileExtension(), IOHelper.MapPath($"{_globalSettings.IconsPath}/{iconName}.svg")); + } + + /// + /// Gets an IconModel using values from a FileInfo model + /// + /// + /// + public IconModel GetIcon(FileInfo fileInfo) + { + return fileInfo == null || string.IsNullOrWhiteSpace(fileInfo.Name) + ? null + : CreateIconModel(fileInfo.Name.StripFileExtension(), fileInfo.FullName); + } + + /// + /// Gets a list of all svg icons found at at the global icons path. + /// + /// + public List GetAllIcons() + { + var icons = new List(); + var directory = new DirectoryInfo(IOHelper.MapPath($"{_globalSettings.IconsPath}/")); + var iconNames = directory.GetFiles("*.svg"); + + iconNames.OrderBy(f => f.Name).ToList().ForEach(iconInfo => + { + var icon = GetIcon(iconInfo); + + if (icon != null) + { + icons.Add(icon); + } + }); + + return icons; + } + + /// + /// Gets an IconModel containing the icon name and SvgString + /// + /// + /// + /// + private IconModel CreateIconModel(string iconName, string iconPath) + { + var sanitizer = new HtmlSanitizer(); + sanitizer.AllowedAttributes.UnionWith(Core.Constants.SvgSanitizer.Attributes); + sanitizer.AllowedCssProperties.UnionWith(Core.Constants.SvgSanitizer.Attributes); + sanitizer.AllowedTags.UnionWith(Core.Constants.SvgSanitizer.Tags); + + try + { + var svgContent = File.ReadAllText(iconPath); + var sanitizedString = sanitizer.Sanitize(svgContent); + + var svg = new IconModel + { + Name = iconName, + SvgString = sanitizedString + }; + + return svg; + } + catch + { + return null; + } + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 33051671ee..2efc6fdd56 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -284,10 +284,12 @@ + + From ccc0e82579617f7706dd1561ae6b211bcda97de0 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 22 Sep 2020 08:58:16 +0200 Subject: [PATCH 12/14] #8919 - Avoid having fat controller and do not new up a controller in a model --- src/Umbraco.Web/Composing/Current.cs | 3 + .../Editors/BackOfficeController.cs | 48 +++++++++- src/Umbraco.Web/Editors/BackOfficeModel.cs | 22 +++-- .../Editors/BackOfficePreviewModel.cs | 22 ++++- src/Umbraco.Web/Editors/IconController.cs | 83 +++------------- src/Umbraco.Web/Editors/PreviewController.cs | 23 ++++- src/Umbraco.Web/Runtime/WebInitialComposer.cs | 1 + src/Umbraco.Web/Services/IIconService.cs | 21 +++++ src/Umbraco.Web/Services/IconService.cs | 94 +++++++++++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 4 +- 10 files changed, 234 insertions(+), 87 deletions(-) create mode 100644 src/Umbraco.Web/Services/IIconService.cs create mode 100644 src/Umbraco.Web/Services/IconService.cs diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 2419eaa6d4..14898d0c02 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -146,6 +146,9 @@ namespace Umbraco.Web.Composing public static ISectionService SectionService => Factory.GetInstance(); + public static IIconService IconService + => Factory.GetInstance(); + #endregion #region Web Constants diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index e77a1b70f2..c9106cffb5 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -26,6 +26,7 @@ using Umbraco.Web.Composing; using Umbraco.Web.Features; using Umbraco.Web.JavaScript; using Umbraco.Web.Security; +using Umbraco.Web.Services; using Constants = Umbraco.Core.Constants; using JArray = Newtonsoft.Json.Linq.JArray; @@ -42,15 +43,54 @@ namespace Umbraco.Web.Editors private readonly ManifestParser _manifestParser; private readonly UmbracoFeatures _features; private readonly IRuntimeState _runtimeState; + private readonly IIconService _iconService; private BackOfficeUserManager _userManager; private BackOfficeSignInManager _signInManager; - public BackOfficeController(ManifestParser manifestParser, UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) + [Obsolete("Use the constructor that injects IIconService.")] + public BackOfficeController( + ManifestParser manifestParser, + UmbracoFeatures features, + IGlobalSettings globalSettings, + IUmbracoContextAccessor umbracoContextAccessor, + ServiceContext services, + AppCaches appCaches, + IProfilingLogger profilingLogger, + IRuntimeState runtimeState, + UmbracoHelper umbracoHelper) + : this(manifestParser, + features, + globalSettings, + umbracoContextAccessor, + services, + appCaches, + profilingLogger, + runtimeState, + umbracoHelper, + Current.IconService) + { + _manifestParser = manifestParser; + _features = features; + _runtimeState = runtimeState; + } + + public BackOfficeController( + ManifestParser manifestParser, + UmbracoFeatures features, + IGlobalSettings globalSettings, + IUmbracoContextAccessor umbracoContextAccessor, + ServiceContext services, + AppCaches appCaches, + IProfilingLogger profilingLogger, + IRuntimeState runtimeState, + UmbracoHelper umbracoHelper, + IIconService iconService) : base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger, umbracoHelper) { _manifestParser = manifestParser; _features = features; _runtimeState = runtimeState; + _iconService = iconService; } protected BackOfficeSignInManager SignInManager => _signInManager ?? (_signInManager = OwinContext.GetBackOfficeSignInManager()); @@ -66,8 +106,8 @@ namespace Umbraco.Web.Editors public async Task Default() { return await RenderDefaultOrProcessExternalLoginAsync( - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings)), - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings))); + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _iconService)), + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _iconService))); } [HttpGet] @@ -150,7 +190,7 @@ namespace Umbraco.Web.Editors { return await RenderDefaultOrProcessExternalLoginAsync( //The default view to render when there is no external login info or errors - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings)), + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings, _iconService)), //The ActionResult to perform if external login is successful () => Redirect("/")); } diff --git a/src/Umbraco.Web/Editors/BackOfficeModel.cs b/src/Umbraco.Web/Editors/BackOfficeModel.cs index b11ea6a5d1..b620d893e3 100644 --- a/src/Umbraco.Web/Editors/BackOfficeModel.cs +++ b/src/Umbraco.Web/Editors/BackOfficeModel.cs @@ -1,21 +1,29 @@ -using Umbraco.Core.Configuration; +using System; +using Umbraco.Core.Configuration; +using Umbraco.Web.Composing; using Umbraco.Web.Features; +using Umbraco.Web.Services; namespace Umbraco.Web.Editors { public class BackOfficeModel { - private IconController IconController { get; } - public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings) + + + [Obsolete("Use the overload that injects IIconService.")] + public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings) : this(features, globalSettings, Current.IconService) + { + + } + public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings, IIconService iconService) { Features = features; GlobalSettings = globalSettings; - IconController = new IconController(); - IconCheckData = IconController.GetIcon("icon-check")?.SvgString; - IconDeleteData = IconController.GetIcon("icon-delete")?.SvgString; + IconCheckData = iconService.GetIcon("icon-check")?.SvgString; + IconDeleteData = iconService.GetIcon("icon-delete")?.SvgString; } - + public UmbracoFeatures Features { get; } public IGlobalSettings GlobalSettings { get; } public string IconCheckData { get; } diff --git a/src/Umbraco.Web/Editors/BackOfficePreviewModel.cs b/src/Umbraco.Web/Editors/BackOfficePreviewModel.cs index b66e432699..7239bba8f7 100644 --- a/src/Umbraco.Web/Editors/BackOfficePreviewModel.cs +++ b/src/Umbraco.Web/Editors/BackOfficePreviewModel.cs @@ -1,7 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; + using Umbraco.Core.Configuration; using Umbraco.Core.Models; +using Umbraco.Web.Composing; using Umbraco.Web.Features; +using Umbraco.Web.Services; namespace Umbraco.Web.Editors { @@ -10,7 +14,21 @@ namespace Umbraco.Web.Editors private readonly UmbracoFeatures _features; public IEnumerable Languages { get; } - public BackOfficePreviewModel(UmbracoFeatures features, IGlobalSettings globalSettings, IEnumerable languages) : base(features, globalSettings) + [Obsolete("Use the overload that injects IIconService.")] + public BackOfficePreviewModel( + UmbracoFeatures features, + IGlobalSettings globalSettings, + IEnumerable languages) + : this(features, globalSettings, languages, Current.IconService) + { + } + + public BackOfficePreviewModel( + UmbracoFeatures features, + IGlobalSettings globalSettings, + IEnumerable languages, + IIconService iconService) + : base(features, globalSettings, iconService) { _features = features; Languages = languages; diff --git a/src/Umbraco.Web/Editors/IconController.cs b/src/Umbraco.Web/Editors/IconController.cs index 72af2194ae..b45b0948c8 100644 --- a/src/Umbraco.Web/Editors/IconController.cs +++ b/src/Umbraco.Web/Editors/IconController.cs @@ -1,21 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; -using Umbraco.Core.Logging; using Umbraco.Web.Models; -using System.IO; -using Umbraco.Core; -using Umbraco.Core.IO; -using Ganss.XSS; -using Umbraco.Core.Cache; +using Umbraco.Web.Services; namespace Umbraco.Web.Editors { [PluginController("UmbracoApi")] public class IconController : UmbracoAuthorizedApiController { + private readonly IIconService _iconService; + + public IconController(IIconService iconService) + { + _iconService = iconService; + } /// /// Gets an IconModel containing the icon name and SvgString according to an icon name found at the global icons path @@ -24,76 +23,16 @@ namespace Umbraco.Web.Editors /// public IconModel GetIcon(string iconName) { - return string.IsNullOrWhiteSpace(iconName) - ? null - : CreateIconModel(iconName.StripFileExtension(), IOHelper.MapPath($"{GlobalSettings.IconsPath}/{iconName}.svg")); - } - - /// - /// Gets an IconModel using values from a FileInfo model - /// - /// - /// - public IconModel GetIcon(FileInfo fileInfo) - { - return fileInfo == null || string.IsNullOrWhiteSpace(fileInfo.Name) - ? null - : CreateIconModel(fileInfo.Name.StripFileExtension(), fileInfo.FullName); + return _iconService.GetIcon(iconName); } /// /// Gets a list of all svg icons found at at the global icons path. /// /// - public List GetAllIcons() + public IList GetAllIcons() { - var icons = new List(); - var directory = new DirectoryInfo(IOHelper.MapPath($"{GlobalSettings.IconsPath}/")); - var iconNames = directory.GetFiles("*.svg"); - - iconNames.OrderBy(f => f.Name).ToList().ForEach(iconInfo => - { - var icon = GetIcon(iconInfo); - - if (icon != null) - { - icons.Add(icon); - } - }); - - return icons; - } - - /// - /// Gets an IconModel containing the icon name and SvgString - /// - /// - /// - /// - private IconModel CreateIconModel(string iconName, string iconPath) - { - var sanitizer = new HtmlSanitizer(); - sanitizer.AllowedAttributes.UnionWith(Core.Constants.SvgSanitizer.Attributes); - sanitizer.AllowedCssProperties.UnionWith(Core.Constants.SvgSanitizer.Attributes); - sanitizer.AllowedTags.UnionWith(Core.Constants.SvgSanitizer.Tags); - - try - { - var svgContent = File.ReadAllText(iconPath); - var sanitizedString = sanitizer.Sanitize(svgContent); - - var svg = new IconModel - { - Name = iconName, - SvgString = sanitizedString - }; - - return svg; - } - catch - { - return null; - } + return _iconService.GetAllIcons(); } } } diff --git a/src/Umbraco.Web/Editors/PreviewController.cs b/src/Umbraco.Web/Editors/PreviewController.cs index c1848419dc..f148655acd 100644 --- a/src/Umbraco.Web/Editors/PreviewController.cs +++ b/src/Umbraco.Web/Editors/PreviewController.cs @@ -12,6 +12,7 @@ using Umbraco.Web.JavaScript; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; using Umbraco.Web.PublishedCache; +using Umbraco.Web.Services; using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Editors @@ -24,19 +25,39 @@ namespace Umbraco.Web.Editors private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly ILocalizationService _localizationService; + private readonly IIconService _iconService; + [Obsolete("Use the constructor that injects IIconService.")] public PreviewController( UmbracoFeatures features, IGlobalSettings globalSettings, IPublishedSnapshotService publishedSnapshotService, IUmbracoContextAccessor umbracoContextAccessor, ILocalizationService localizationService) + :this(features, + globalSettings, + publishedSnapshotService, + umbracoContextAccessor, + localizationService, + Current.IconService) + { + + } + + public PreviewController( + UmbracoFeatures features, + IGlobalSettings globalSettings, + IPublishedSnapshotService publishedSnapshotService, + IUmbracoContextAccessor umbracoContextAccessor, + ILocalizationService localizationService, + IIconService iconService) { _features = features; _globalSettings = globalSettings; _publishedSnapshotService = publishedSnapshotService; _umbracoContextAccessor = umbracoContextAccessor; _localizationService = localizationService; + _iconService = iconService; } [UmbracoAuthorize(redirectToUmbracoLogin: true)] @@ -45,7 +66,7 @@ namespace Umbraco.Web.Editors { var availableLanguages = _localizationService.GetAllLanguages(); - var model = new BackOfficePreviewModel(_features, _globalSettings, availableLanguages); + var model = new BackOfficePreviewModel(_features, _globalSettings, availableLanguages, _iconService); if (model.PreviewExtendedHeaderView.IsNullOrWhiteSpace() == false) { diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 135d54560b..d9a8ee37f2 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -139,6 +139,7 @@ namespace Umbraco.Web.Runtime composition.RegisterUnique(); composition.RegisterUnique(); + composition.RegisterUnique(); composition.RegisterUnique(factory => ExamineManager.Instance); diff --git a/src/Umbraco.Web/Services/IIconService.cs b/src/Umbraco.Web/Services/IIconService.cs new file mode 100644 index 0000000000..177921ceae --- /dev/null +++ b/src/Umbraco.Web/Services/IIconService.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Umbraco.Web.Models; + +namespace Umbraco.Web.Services +{ + public interface IIconService + { + /// + /// Gets an IconModel containing the icon name and SvgString according to an icon name found at the global icons path + /// + /// + /// + IconModel GetIcon(string iconName); + + /// + /// Gets a list of all svg icons found at at the global icons path. + /// + /// + IList GetAllIcons(); + } +} diff --git a/src/Umbraco.Web/Services/IconService.cs b/src/Umbraco.Web/Services/IconService.cs new file mode 100644 index 0000000000..93389668b6 --- /dev/null +++ b/src/Umbraco.Web/Services/IconService.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Ganss.XSS; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; +using Umbraco.Web.Models; + +namespace Umbraco.Web.Services +{ + public class IconService : IIconService + { + private readonly IGlobalSettings _globalSettings; + + public IconService(IGlobalSettings globalSettings) + { + _globalSettings = globalSettings; + } + + + /// + public IList GetAllIcons() + { + var icons = new List(); + var directory = new DirectoryInfo(IOHelper.MapPath($"{_globalSettings.IconsPath}/")); + var iconNames = directory.GetFiles("*.svg"); + + iconNames.OrderBy(f => f.Name).ToList().ForEach(iconInfo => + { + var icon = GetIcon(iconInfo); + + if (icon != null) + { + icons.Add(icon); + } + }); + + return icons; + } + + /// + public IconModel GetIcon(string iconName) + { + return string.IsNullOrWhiteSpace(iconName) + ? null + : CreateIconModel(iconName.StripFileExtension(), IOHelper.MapPath($"{_globalSettings.IconsPath}/{iconName}.svg")); + } + + /// + /// Gets an IconModel using values from a FileInfo model + /// + /// + /// + private IconModel GetIcon(FileInfo fileInfo) + { + return fileInfo == null || string.IsNullOrWhiteSpace(fileInfo.Name) + ? null + : CreateIconModel(fileInfo.Name.StripFileExtension(), fileInfo.FullName); + } + + /// + /// Gets an IconModel containing the icon name and SvgString + /// + /// + /// + /// + private IconModel CreateIconModel(string iconName, string iconPath) + { + var sanitizer = new HtmlSanitizer(); + sanitizer.AllowedAttributes.UnionWith(Core.Constants.SvgSanitizer.Attributes); + sanitizer.AllowedCssProperties.UnionWith(Core.Constants.SvgSanitizer.Attributes); + sanitizer.AllowedTags.UnionWith(Core.Constants.SvgSanitizer.Tags); + + try + { + var svgContent = File.ReadAllText(iconPath); + var sanitizedString = sanitizer.Sanitize(svgContent); + + var svg = new IconModel + { + Name = iconName, + SvgString = sanitizedString + }; + + return svg; + } + catch + { + return null; + } + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 33051671ee..ff67493aaa 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -238,8 +238,8 @@ - + @@ -284,10 +284,12 @@ + + From 164fa24ef3269c5c6f397fb6d07a3b785c70c970 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 22 Sep 2020 10:04:55 +0200 Subject: [PATCH 13/14] #8919 - Fix issue with wrong casing of variable name --- .../src/common/services/iconhelper.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js index f714cba4ad..5034de67eb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js @@ -209,7 +209,7 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) { ,'Failed to retrieve icon: ' + iconName) .then(icon => { if(icon) { - var trustedIcon = this.defineIcon(icon.name, icon.SvgString); + var trustedIcon = this.defineIcon(icon.Name, icon.SvgString); liveRequests = _.filter(liveRequests, iconRequestPath); From 1badb69481ef82cc09990a79c642a0f406f9e384 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 22 Sep 2020 10:14:34 +0200 Subject: [PATCH 14/14] #8919 - Clean up obsolete ctor --- src/Umbraco.Web/Editors/BackOfficeController.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 71bda4bfd2..cd5a3a50b6 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -67,9 +67,7 @@ namespace Umbraco.Web.Editors umbracoHelper, Current.IconService) { - _manifestParser = manifestParser; - _features = features; - _runtimeState = runtimeState; + } public BackOfficeController(