diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml b/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml index 0a688083eb..47a787aada 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/sv.xml @@ -4,9 +4,6 @@ The Umbraco community https://docs.umbraco.com/umbraco-cms/extending/language-files - - InnehÄll - Hantera domÀnnamn Hantera versioner diff --git a/src/Umbraco.Core/Services/LocalizedTextService.cs b/src/Umbraco.Core/Services/LocalizedTextService.cs index 1634f60baa..51012200bd 100644 --- a/src/Umbraco.Core/Services/LocalizedTextService.cs +++ b/src/Umbraco.Core/Services/LocalizedTextService.cs @@ -350,7 +350,13 @@ public class LocalizedTextService : ILocalizedTextService IEnumerable areas = xmlSource[cult].Value.XPathSelectElements("//area"); foreach (XElement area in areas) { - var result = new Dictionary(StringComparer.InvariantCulture); + var areaAlias = area.Attribute("alias")!.Value; + + if (!overallResult.TryGetValue(areaAlias, out IDictionary? result)) + { + result = new Dictionary(StringComparer.InvariantCulture); + } + IEnumerable keys = area.XPathSelectElements("./key"); foreach (XElement key in keys) { @@ -364,7 +370,10 @@ public class LocalizedTextService : ILocalizedTextService } } - overallResult.Add(area.Attribute("alias")!.Value, result); + if (!overallResult.ContainsKey(areaAlias)) + { + overallResult.Add(areaAlias, result); + } } // Merge English Dictionary @@ -374,11 +383,11 @@ public class LocalizedTextService : ILocalizedTextService IEnumerable enUS = xmlSource[englishCulture].Value.XPathSelectElements("//area"); foreach (XElement area in enUS) { - IDictionary - result = new Dictionary(StringComparer.InvariantCulture); - if (overallResult.ContainsKey(area.Attribute("alias")!.Value)) + var areaAlias = area.Attribute("alias")!.Value; + + if (!overallResult.TryGetValue(areaAlias, out IDictionary? result)) { - result = overallResult[area.Attribute("alias")!.Value]; + result = new Dictionary(StringComparer.InvariantCulture); } IEnumerable keys = area.XPathSelectElements("./key"); @@ -394,9 +403,9 @@ public class LocalizedTextService : ILocalizedTextService } } - if (!overallResult.ContainsKey(area.Attribute("alias")!.Value)) + if (!overallResult.ContainsKey(areaAlias)) { - overallResult.Add(area.Attribute("alias")!.Value, result); + overallResult.Add(areaAlias, result); } } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 8a8ae0a36b..e3b3ba413c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -5,7 +5,7 @@ appState, contentResource, entityResource, navigationService, notificationsService, contentAppHelper, serverValidationManager, contentEditingHelper, localizationService, formHelper, umbRequestHelper, editorState, $http, eventsService, overlayService, $location, localStorageService, treeService, - $exceptionHandler, uploadTracker) { + $exceptionHandler, uploadTracker) { var evts = []; var infiniteMode = $scope.infiniteModel && $scope.infiniteModel.infiniteMode; @@ -497,6 +497,7 @@ //Set them all to be invalid var fieldsToRollback = checkValidility(); eventsService.emit("content.saving", { content: $scope.content, action: args.action }); + eventsService.emit("form.lock"); return contentEditingHelper.contentEditorPerformSave({ saveMethod: args.saveMethod, @@ -517,6 +518,7 @@ syncTreeNode($scope.content, data.path, false, args.reloadChildren); eventsService.emit("content.saved", { content: $scope.content, action: args.action, valid: true }); + eventsService.emit("form.unlock"); if($scope.contentForm.$invalid !== true) { resetNestedFieldValiation(fieldsToRollback); @@ -534,6 +536,7 @@ if (err && err.status === 400 && err.data) { // content was saved but is invalid. eventsService.emit("content.saved", { content: $scope.content, action: args.action, valid: false }); + eventsService.emit("form.unlock"); } return $q.reject(err); @@ -1002,7 +1005,7 @@ const openPreviewWindow = (url, target) => { // Chromes popup blocker will kick in if a window is opened // without the initial scoped request. This trick will fix that. - + const previewWindow = $window.open(url, target); previewWindow.addEventListener('load', () => { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js index f003e1afa6..e76da32a54 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js @@ -2,7 +2,7 @@ 'use strict'; /** This directive is used to render out the current variant tabs and properties and exposes an API for other directives to consume */ - function tabbedContentDirective($timeout, $filter, contentEditingHelper, contentTypeHelper) { + function tabbedContentDirective($timeout, $filter, contentEditingHelper, contentTypeHelper, eventsService) { function link($scope, $element) { @@ -156,14 +156,13 @@ } }); - $scope.$on("formSubmitting", function() { - $scope.allowUpdate = false; + eventsService.on("form.lock", function() { + $scope.$evalAsync(() => { + $scope.allowUpdate = false; + }); }); - $scope.$on("formSubmitted", function() { - setAllowUpdate(); - }); - $scope.$on("formSubmittedValidationFailed", function() { + eventsService.on("form.unlock", function() { setAllowUpdate(); }); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/rte-blockeditor-clipboard.service.js b/src/Umbraco.Web.UI.Client/src/common/services/rte-blockeditor-clipboard.service.js index 216b7fe1e8..0a1aee1f27 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/rte-blockeditor-clipboard.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/rte-blockeditor-clipboard.service.js @@ -50,13 +50,13 @@ function rawRteBlockResolver(propertyValue, propPasteResolverMethod) { - if (propertyValue != null && typeof propertyValue === "object") { + if (propertyValue && typeof propertyValue === "object" && propertyValue.markup) { // object property of 'blocks' holds the data for the Block Editor. var value = propertyValue.blocks; // we got an object, and it has these three props then we are most likely dealing with a Block Editor. - if ((value.layout !== undefined && value.contentData !== undefined && value.settingsData !== undefined)) { + if ((value && value.layout !== undefined && value.contentData !== undefined && value.settingsData !== undefined)) { // replaceUdisOfObject replaces udis of the value object(by instance reference), but also returns the updated markup (as we cant update the reference of a string). propertyValue.markup = replaceUdisOfObject(value.layout, value, propertyValue.markup); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 18707c1f60..7ed6b9ee50 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -1056,6 +1056,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s editor.undoManager.clear(); } } + + angularHelper.safeApply($rootScope, function () { + editor.dispatch("Change"); + }); }); });