diff --git a/src/Umbraco.Core/Events/EventAggregator.Notifications.cs b/src/Umbraco.Core/Events/EventAggregator.Notifications.cs index d298f5bbec..94d4804cd4 100644 --- a/src/Umbraco.Core/Events/EventAggregator.Notifications.cs +++ b/src/Umbraco.Core/Events/EventAggregator.Notifications.cs @@ -137,7 +137,7 @@ internal class NotificationAsyncHandlerWrapperImpl : Notification /// confusion. /// /// - public override Task HandleAsync( + public override async Task HandleAsync( INotification notification, CancellationToken cancellationToken, ServiceFactory serviceFactory, @@ -155,7 +155,7 @@ internal class NotificationAsyncHandlerWrapperImpl : Notification (theNotification, theToken) => x.HandleAsync((TNotification)theNotification, theToken))); - return publish(handlers, notification, cancellationToken); + await publish(handlers, notification, cancellationToken); } } diff --git a/src/Umbraco.Core/Events/EventAggregator.cs b/src/Umbraco.Core/Events/EventAggregator.cs index 277b24eb06..b5de38c66d 100644 --- a/src/Umbraco.Core/Events/EventAggregator.cs +++ b/src/Umbraco.Core/Events/EventAggregator.cs @@ -50,7 +50,7 @@ public partial class EventAggregator : IEventAggregator => _serviceFactory = serviceFactory; /// - public Task PublishAsync(TNotification notification, CancellationToken cancellationToken = default) + public async Task PublishAsync(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification { // TODO: Introduce codegen efficient Guard classes to reduce noise. @@ -60,7 +60,7 @@ public partial class EventAggregator : IEventAggregator } PublishNotification(notification); - return PublishNotificationAsync(notification, cancellationToken); + await PublishNotificationAsync(notification, cancellationToken); } /// diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index f7c8599099..cee1e5bc01 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1542,7 +1542,7 @@ public class ContentService : RepositoryService, IContentService // handling events, business rules, etc // note: StrategyUnpublish flips the PublishedState to Unpublishing! // note: This unpublishes the entire document (not different variants) - unpublishResult = StrategyCanUnpublish(scope, content, eventMessages); + unpublishResult = StrategyCanUnpublish(scope, content, eventMessages, notificationState); if (unpublishResult.Success) { unpublishResult = StrategyUnpublish(content, eventMessages); @@ -3296,10 +3296,10 @@ public class ContentService : RepositoryService, IContentService /// /// /// - private PublishResult StrategyCanUnpublish(ICoreScope scope, IContent content, EventMessages evtMsgs) + private PublishResult StrategyCanUnpublish(ICoreScope scope, IContent content, EventMessages evtMsgs, IDictionary? notificationState) { // raise Unpublishing notification - if (scope.Notifications.PublishCancelable(new ContentUnpublishingNotification(content, evtMsgs))) + if (scope.Notifications.PublishCancelable(new ContentUnpublishingNotification(content, evtMsgs).WithState(notificationState))) { _logger.LogInformation( "Document {ContentName} (id={ContentId}) cannot be unpublished: unpublishing was cancelled.", content.Name, content.Id); diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs index 3e14154b48..46e06dec6e 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs @@ -607,7 +607,7 @@ public class UsersController : BackOfficeNotificationsController var emailBody = _localizedTextService.Localize("user", "inviteEmailCopyFormat", // Ensure the culture of the found user is used for the email! UmbracoUserExtensions.GetUserCulture(to?.Language, _localizedTextService, _globalSettings), - new[] { userDisplay?.Name, from, message, inviteUri.ToString(), senderEmail }); + new[] { userDisplay?.Name, from, WebUtility.HtmlEncode(message)!.ReplaceLineEndings("
"), inviteUri.ToString(), senderEmail }); // This needs to be in the correct mailto format including the name, else // the name cannot be captured in the email sending notification. diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js index 3ec1756e6c..a3d1ef541c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js @@ -32,16 +32,16 @@ angular.module("umbraco.directives") tree: '=', isDialog: '=' }, - + link: function (scope, element, attrs, umbTreeCtrl) { localizationService.localizeMany(["general_search", "visuallyHiddenTexts_openContextMenu"]).then(function (value) { scope.searchAltText = value[0]; scope.optionsText = value[1]; }); - + // updates the node's DOM/styles function setupNodeDom(node, tree) { - + //get the first div element element.children(":first") //set the padding @@ -61,14 +61,14 @@ angular.module("umbraco.directives") if (!node) { return ''; } - + // TODO: This is called constantly because as a method in a template it's re-evaluated pretty much all the time // it would be better if we could cache the processing. The problem is that some of these things are dynamic. //is this the current action node (this is not the same as the current selected node!) var actionNode = appState.getMenuState("currentNode"); - - var css = []; + + var css = []; if (node.cssClasses) { node.cssClasses.forEach(c => css.push(c)); } @@ -94,8 +94,8 @@ angular.module("umbraco.directives") if (actionNode.id === node.id && String(node.id) !== "-1") { css.push("active"); } - - // special handling of root nodes with id -1 + + // special handling of root nodes with id -1 // as there can be many nodes with id -1 in a tree we need to check the treeAlias instead if (String(node.id) === "-1" && actionNode.metaData.treeAlias === node.metaData.treeAlias) { css.push("active"); @@ -125,7 +125,7 @@ angular.module("umbraco.directives") }; /** - Method called when an item is clicked in the tree, this passes the + Method called when an item is clicked in the tree, this passes the DOM element, the tree node object and the original click and emits it as a treeNodeSelect element if there is a callback object defined on the tree @@ -149,7 +149,7 @@ angular.module("umbraco.directives") }; /** - Method called when an item is right-clicked in the tree, this passes the + Method called when an item is right-clicked in the tree, this passes the DOM element, the tree node object and the original click and emits it as a treeNodeSelect element if there is a callback object defined on the tree @@ -158,13 +158,17 @@ angular.module("umbraco.directives") if(ev.altKey) return false; umbTreeCtrl.emitEvent("treeNodeAltSelect", { element: element, tree: scope.tree, node: n, event: ev }); }; - + /** Method called when a node in the tree is expanded, when clicking the arrow takes the arrow DOM element and node data as parameters emits treeNodeCollapsing event if already expanded and treeNodeExpanding if collapsed */ - scope.load = function (node) { + scope.load = function (node, ev) { + if(ev){ + ev.stopPropagation(); + } + if (node.expanded && !node.metaData.isContainer) { umbTreeCtrl.emitEvent("treeNodeCollapsing", { tree: scope.tree, node: node, element: element }); node.expanded = false; @@ -199,7 +203,7 @@ angular.module("umbraco.directives") })); // Update tree icon if changed - evts.push(eventsService.on("editors.tree.icon.changed", function (e, args) { + evts.push(eventsService.on("editors.tree.icon.changed", function (e, args) { if (args.icon !== scope.node.icon && args.id === scope.node.id) { scope.node.icon = args.icon; } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html b/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html index 3d6e4949c2..bb789d8c98 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html @@ -1,9 +1,9 @@
  • -
    +