From 57ed4698f01be40328698c991c88de4e8a495064 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 19 Apr 2021 17:31:09 +0200 Subject: [PATCH 01/23] Revert "Revert "The Value() method for IPublishedContent was not working with the defaultValue parameter" (#9989)" This reverts commit 156c1c94161171f9592923f20de4e142c845469a. --- src/Umbraco.Web/PublishedContentExtensions.cs | 6 ++-- src/Umbraco.Web/PublishedPropertyExtension.cs | 33 ++++++------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index c851894149..6384b0f8d4 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -173,8 +173,8 @@ namespace Umbraco.Web return value; // else... if we have a property, at least let the converter return its own - // vision of 'no value' (could be an empty enumerable) - otherwise, default - return property == null ? default : property.Value(culture, segment, fallback, defaultValue); + // vision of 'no value' (could be an empty enumerable) - otherwise, defaultValue + return property == null ? defaultValue : property.Value(culture, segment, defaultValue: defaultValue); } #endregion diff --git a/src/Umbraco.Web/PublishedPropertyExtension.cs b/src/Umbraco.Web/PublishedPropertyExtension.cs index 6e8647db47..0c3aa57cc2 100644 --- a/src/Umbraco.Web/PublishedPropertyExtension.cs +++ b/src/Umbraco.Web/PublishedPropertyExtension.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Models.PublishedContent; @@ -36,20 +37,13 @@ namespace Umbraco.Web // we have a value // try to cast or convert it var value = property.GetValue(culture, segment); - if (value is T valueAsT) - { - return valueAsT; - } - + if (value is T valueAsT) return valueAsT; var valueConverted = value.TryConvertTo(); - if (valueConverted) - { - return valueConverted.Result; - } + if (valueConverted) return valueConverted.Result; - // cannot cast nor convert the value, nothing we can return but 'default' + // cannot cast nor convert the value, nothing we can return but 'defaultValue' // note: we don't want to fallback in that case - would make little sense - return default; + return defaultValue; } // we don't have a value, try fallback @@ -63,22 +57,15 @@ namespace Umbraco.Web var noValue = property.GetValue(culture, segment); if (noValue == null) { - return default; - } - - if (noValue is T noValueAsT) - { - return noValueAsT; + return defaultValue; } + if (noValue is T noValueAsT) return noValueAsT; var noValueConverted = noValue.TryConvertTo(); - if (noValueConverted) - { - return noValueConverted.Result; - } + if (noValueConverted) return noValueConverted.Result; - // cannot cast noValue nor convert it, nothing we can return but 'default' - return default; + // cannot cast noValue nor convert it, nothing we can return but 'defaultValue' + return defaultValue; } #endregion From f1e4fec4c4ad0299a787d350ea32e6ff2d26cf4e Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 19 Apr 2021 17:31:53 +0200 Subject: [PATCH 02/23] Revert "The Value() method for IPublishedContent was not working with the defaultValue parameter (#9888)" This reverts commit 52b670973d562b86a89665dd4b1b23fba8ec3900. --- src/Umbraco.Web/PublishedContentExtensions.cs | 4 ++-- src/Umbraco.Web/PublishedPropertyExtension.cs | 15 ++++----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 6384b0f8d4..b43717d418 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -173,8 +173,8 @@ namespace Umbraco.Web return value; // else... if we have a property, at least let the converter return its own - // vision of 'no value' (could be an empty enumerable) - otherwise, defaultValue - return property == null ? defaultValue : property.Value(culture, segment, defaultValue: defaultValue); + // vision of 'no value' (could be an empty enumerable) - otherwise, default + return property == null ? default : property.Value(culture, segment); } #endregion diff --git a/src/Umbraco.Web/PublishedPropertyExtension.cs b/src/Umbraco.Web/PublishedPropertyExtension.cs index 0c3aa57cc2..b431f24828 100644 --- a/src/Umbraco.Web/PublishedPropertyExtension.cs +++ b/src/Umbraco.Web/PublishedPropertyExtension.cs @@ -41,31 +41,24 @@ namespace Umbraco.Web var valueConverted = value.TryConvertTo(); if (valueConverted) return valueConverted.Result; - // cannot cast nor convert the value, nothing we can return but 'defaultValue' + // cannot cast nor convert the value, nothing we can return but 'default' // note: we don't want to fallback in that case - would make little sense - return defaultValue; + return default; } // we don't have a value, try fallback if (PublishedValueFallback.TryGetValue(property, culture, segment, fallback, defaultValue, out var fallbackValue)) - { return fallbackValue; - } // we don't have a value - neither direct nor fallback // give a chance to the converter to return something (eg empty enumerable) var noValue = property.GetValue(culture, segment); - if (noValue == null) - { - return defaultValue; - } if (noValue is T noValueAsT) return noValueAsT; - var noValueConverted = noValue.TryConvertTo(); if (noValueConverted) return noValueConverted.Result; - // cannot cast noValue nor convert it, nothing we can return but 'defaultValue' - return defaultValue; + // cannot cast noValue nor convert it, nothing we can return but 'default' + return default; } #endregion From a3e3e83a3df2f450106c41909cf92eb1300c5104 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 19 Apr 2021 17:34:01 +0200 Subject: [PATCH 03/23] Bump version to 8.13.0 --- src/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 2a7386cb45..1009ec125b 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.13.0")] -[assembly: AssemblyInformationalVersion("8.13.0-rc")] +[assembly: AssemblyInformationalVersion("8.13.0")] From df8b2d5580bf8589119b629ff5870122728cc96c Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 17 May 2021 10:50:25 +0200 Subject: [PATCH 04/23] Bump version to 8.14.0-rc --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 2a7386cb45..91918498f9 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.13.0")] -[assembly: AssemblyInformationalVersion("8.13.0-rc")] +[assembly: AssemblyFileVersion("8.14.0")] +[assembly: AssemblyInformationalVersion("8.14.0-rc")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 707c773dc6..a887159256 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -348,9 +348,9 @@ False True - 8130 + 8140 / - http://localhost:8130 + http://localhost:8140 False False From 36c49b0a2592758e2f525588047fe3b89b976844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 May 2021 11:08:00 +0200 Subject: [PATCH 05/23] #10274 Variant sorting should take into account that there might not be any language (#10278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Variant sorting should take into account that there might not be any language available * fix languages Co-authored-by: Niels Lyngsø Co-authored-by: Mads Rasmussen (cherry picked from commit e19a5989e9a9c77f1d35622fe70b0fe573df59c9) --- .../services/contenteditinghelper.service.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 8524b960c6..26f8dc86ea 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -775,10 +775,10 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt */ sortVariants: function (a, b) { const statesOrder = {'PublishedPendingChanges':1, 'Published': 1, 'Draft': 2, 'NotCreated': 3}; - const compareDefault = (a,b) => (!a.language.isDefault ? 1 : -1) - (!b.language.isDefault ? 1 : -1); + const compareDefault = (a,b) => (a.language && a.language.isDefault ? -1 : 1) - (b.language && b.language.isDefault ? -1 : 1); // Make sure mandatory variants goes on top, unless they are published, cause then they already goes to the top and then we want to mix them with other published variants. - const compareMandatory = (a,b) => (a.state === 'PublishedPendingChanges' || a.state === 'Published') ? 0 : (!a.language.isMandatory ? 1 : -1) - (!b.language.isMandatory ? 1 : -1); + const compareMandatory = (a,b) => (a.state === 'PublishedPendingChanges' || a.state === 'Published') ? 0 : (a.language && a.language.isMandatory ? -1 : 1) - (b.language && b.language.isMandatory ? -1 : 1); const compareState = (a, b) => (statesOrder[a.state] || 99) - (statesOrder[b.state] || 99); const compareName = (a, b) => a.displayName.localeCompare(b.displayName); @@ -799,17 +799,18 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt */ getSortedVariantsAndSegments: function (variantsAndSegments) { const sortedVariants = variantsAndSegments.filter(variant => !variant.segment).sort(this.sortVariants); - let segments = variantsAndSegments.filter(variant => variant.segment); + let variantsWithSegments = variantsAndSegments.filter(variant => variant.segment); let sortedAvailableVariants = []; sortedVariants.forEach((variant) => { - const sortedMatchedSegments = segments.filter(segment => segment.language.culture === variant.language.culture).sort(this.sortVariants); - segments = segments.filter(segment => segment.language.culture !== variant.language.culture); + const sortedMatchedSegments = variantsWithSegments.filter(segment => segment.language && variant.language && segment.language.culture === variant.language.culture).sort(this.sortVariants); + // remove variants for this culture + variantsWithSegments = variantsWithSegments.filter(segment => !segment.language || segment.language && variant.language && segment.language.culture !== variant.language.culture); sortedAvailableVariants = [...sortedAvailableVariants, ...[variant], ...sortedMatchedSegments]; }) - // if we have segments without a parent language variant we need to add the remaining segments to the array - sortedAvailableVariants = [...sortedAvailableVariants, ...segments.sort(this.sortVariants)]; + // if we have segments without a parent language variant we need to add the remaining variantsWithSegments to the array + sortedAvailableVariants = [...sortedAvailableVariants, ...variantsWithSegments.sort(this.sortVariants)]; return sortedAvailableVariants; } From 7c2f95613030b2e52f3ce66629916ef095ac3601 Mon Sep 17 00:00:00 2001 From: Mike Chambers Date: Tue, 27 Apr 2021 13:56:31 +0100 Subject: [PATCH 06/23] Update ModelsBuilderComposer.cs issue #10186 typo in IsExternalModelsBuilderInstalled -> Umbraco.ModelsBuider (cherry picked from commit b783399c5cd730cfcbff3fdcedf2f7a4ab2eb25c) --- .../Compose/ModelsBuilderComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs b/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs index 01010cca66..fee9b6f62e 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs @@ -47,7 +47,7 @@ namespace Umbraco.ModelsBuilder.Embedded.Compose { var assemblyNames = new[] { - "Umbraco.ModelsBuider", + "Umbraco.ModelsBuilder", "ModelsBuilder.Umbraco" }; From 9730a18c9b3bad19d9415af49e17977bda375ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 19 May 2021 12:06:17 +0200 Subject: [PATCH 07/23] #10274 Variant sorting should take into account that there might not be any language (#10278) (#10284) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niels Lyngsø Co-authored-by: Mads Rasmussen (cherry picked from commit 017b56eee1b45cdca44e14510e72dd675412b0b5) --- .../forms/umbfocuslock.directive.js | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbfocuslock.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbfocuslock.directive.js index 03d376e36a..e1639dde26 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbfocuslock.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbfocuslock.directive.js @@ -40,7 +40,9 @@ function getDomNodes(){ infiniteEditorsWrapper = document.querySelector('.umb-editors'); - infiniteEditors = Array.from(infiniteEditorsWrapper.querySelectorAll('.umb-editor')); + if(infiniteEditorsWrapper) { + infiniteEditors = Array.from(infiniteEditorsWrapper.querySelectorAll('.umb-editor') || []); + } } function getFocusableElements(targetElm) { @@ -84,22 +86,24 @@ var defaultFocusedElement = getAutoFocusElement(focusableElements); var lastKnownElement; - // If an inifite editor is being closed then we reset the focus to the element that triggered the the overlay + // If an infinite editor is being closed then we reset the focus to the element that triggered the the overlay if(closingEditor){ - var lastItemIndex = $rootScope.lastKnownFocusableElements.length - 1; - var editorInfo = infiniteEditors[0].querySelector('.editor-info'); // If there is only one editor open, search for the "editor-info" inside it and set focus on it // This is relevant when a property editor has been selected and the editor where we selected it from // is closed taking us back to the first layer // Otherwise set it to the last element in the lastKnownFocusedElements array - if(infiniteEditors.length === 1 && editorInfo !== null){ - lastKnownElement = editorInfo; + if(infiniteEditors && infiniteEditors.length === 1){ + var editorInfo = infiniteEditors[0].querySelector('.editor-info'); + if(infiniteEditors && infiniteEditors.length === 1 && editorInfo !== null) { + lastKnownElement = editorInfo; - // Clear the array - clearLastKnownFocusedElements(); + // Clear the array + clearLastKnownFocusedElements(); + } } else { + var lastItemIndex = $rootScope.lastKnownFocusableElements.length - 1; lastKnownElement = $rootScope.lastKnownFocusableElements[lastItemIndex]; // Remove the last item from the array so we always set the correct lastKnowFocus for each layer @@ -149,20 +153,24 @@ } function cleanupEventHandlers() { - var activeEditor = infiniteEditors[infiniteEditors.length - 1]; - var inactiveEditors = infiniteEditors.filter(editor => editor !== activeEditor); + //if we're in infinite editing mode + if(infiniteEditors.length > 0) { + var activeEditor = infiniteEditors[infiniteEditors.length - 1]; + var inactiveEditors = infiniteEditors.filter(editor => editor !== activeEditor); - if(inactiveEditors.length > 0) { - for (var index = 0; index < inactiveEditors.length; index++) { - var inactiveEditor = inactiveEditors[index]; + if(inactiveEditors.length > 0) { + for (var index = 0; index < inactiveEditors.length; index++) { + var inactiveEditor = inactiveEditors[index]; - // Remove event handlers from inactive editors - inactiveEditor.removeEventListener('keydown', handleKeydown); + // Remove event handlers from inactive editors + inactiveEditor.removeEventListener('keydown', handleKeydown); + } + } + else { + // Why is this one only begin called if there is no other infinite editors, wouldn't it make sense always to clean this up? + // Remove event handlers from the active editor + activeEditor.removeEventListener('keydown', handleKeydown); } - } - else { - // Remove event handlers from the active editor - activeEditor.removeEventListener('keydown', handleKeydown); } } @@ -173,10 +181,7 @@ // Fetch the DOM nodes we need getDomNodes(); - // Cleanup event handlers if we're in infinite editing mode - if(infiniteEditors.length > 0){ - cleanupEventHandlers(); - } + cleanupEventHandlers(); getFocusableElements(targetElm); @@ -204,17 +209,19 @@ // Make sure to disconnect the observer so we potentially don't end up with having many active ones disconnectObserver = true; - // Pass the correct editor in order to find the focusable elements - var newTarget = infiniteEditors[infiniteEditors.length - 2]; + if(infiniteEditors && infiniteEditors.length > 1) { + // Pass the correct editor in order to find the focusable elements + var newTarget = infiniteEditors[infiniteEditors.length - 2]; - if(infiniteEditors.length > 1){ - // Setting closing till true will let us re-apply the last known focus to then opened layer that then becomes - // active - closingEditor = true; + if(infiniteEditors.length > 1) { + // Setting closing till true will let us re-apply the last known focus to then opened layer that then becomes + // active + closingEditor = true; - onInit(newTarget); + onInit(newTarget); - return; + return; + } } // Clear lastKnownFocusableElements From 3f596e27ccba6f30bd17779a94a41f9633d6f68e Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 19 May 2021 16:31:52 +0200 Subject: [PATCH 08/23] Bump version to 8.13.1 --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 1009ec125b..451a4b0d77 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.13.0")] -[assembly: AssemblyInformationalVersion("8.13.0")] +[assembly: AssemblyFileVersion("8.13.1")] +[assembly: AssemblyInformationalVersion("8.13.1")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 58baadcb35..f69fdf7026 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -348,9 +348,9 @@ False True - 8130 + 8131 / - http://localhost:8130 + http://localhost:8131 False False From 9bf01741b64bdbd43ced0d6ed28d20c450e330e8 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 20 May 2021 09:29:45 +0200 Subject: [PATCH 09/23] Fix invalid XML --- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 08448fa355..8e33f102c7 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -1907,7 +1907,6 @@ Mange hilsner fra Umbraco robotten Tilføj indhold Tilføj %0% Feltet %0% bruger editor %1% som ikke er supporteret for blokke. - Hvad er Indholdsskabeloner? From 71a1817a061983bbdb0d8ece856a634e4f028ff2 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 11 May 2021 17:28:11 +0200 Subject: [PATCH 10/23] Fixed issue with data types not being cleared in cache refresh operations. --- src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index c9caf5aaa7..37d36fca45 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -3,6 +3,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Services; using Umbraco.Web.PublishedCache; @@ -56,6 +57,11 @@ namespace Umbraco.Web.Cache foreach (var payload in payloads) { _idkMap.ClearCache(payload.Id); + + if (dataTypeCache.Success) + { + dataTypeCache.Result.Clear(RepositoryCacheKeys.GetKey(payload.Id)); + } } // TODO: not sure I like these? From 12328ba2f761b4c20b50df3dc83bb85b5f652cf6 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 11 May 2021 17:28:11 +0200 Subject: [PATCH 11/23] Fixed issue with data types not being cleared in cache refresh operations. (cherry picked from commit 71a1817a061983bbdb0d8ece856a634e4f028ff2) --- src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index c9caf5aaa7..37d36fca45 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -3,6 +3,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Services; using Umbraco.Web.PublishedCache; @@ -56,6 +57,11 @@ namespace Umbraco.Web.Cache foreach (var payload in payloads) { _idkMap.ClearCache(payload.Id); + + if (dataTypeCache.Success) + { + dataTypeCache.Result.Clear(RepositoryCacheKeys.GetKey(payload.Id)); + } } // TODO: not sure I like these? From 008480a17b652bc2c267ab2bfd68c4ae70162394 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 21 May 2021 15:01:51 +0200 Subject: [PATCH 12/23] Can't use optimized version of this method call until 8.14 --- src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs index 37d36fca45..431f560400 100644 --- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs @@ -60,7 +60,7 @@ namespace Umbraco.Web.Cache if (dataTypeCache.Success) { - dataTypeCache.Result.Clear(RepositoryCacheKeys.GetKey(payload.Id)); + dataTypeCache.Result.Clear(RepositoryCacheKeys.GetKey(payload.Id)); } } From ecdc687e39846908f44552d3c65de2dbc6cbafa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 25 May 2021 15:02:55 +0200 Subject: [PATCH 13/23] use label --- .../infiniteeditors/mediaentryeditor/mediaentryeditor.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html index afa3451899..f4302551ab 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html @@ -35,7 +35,7 @@ width="{{crop.width}}" max-size="75"> - {{crop.alias}} + {{crop.label}} From a68a6b2ac29ea4eab94b92101c301ce60af979d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 25 May 2021 14:58:07 +0200 Subject: [PATCH 14/23] added windowResizeListener --- .../directives/components/imaging/umbimagecrop.directive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js index 744e4280db..60ba71d7a5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js @@ -26,7 +26,7 @@ angular.module("umbraco.directives") forceUpdate: '@?' }, - link: function (scope, element, attrs) { + link: function (scope, element, attrs, windowResizeListener) { var unsubscribe = []; let sliderRef = null; From 630fa6a98906fa005d8eb796255594e97e6d2058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 25 May 2021 14:57:19 +0200 Subject: [PATCH 15/23] dont remove outline --- .../src/less/components/umb-range-slider.less | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less index cc5c17ba70..6c1980a6e4 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less @@ -19,7 +19,6 @@ padding: 2px 6px; } .umb-range-slider .noUi-handle { - outline: none; cursor: grab; border-radius: 100px; border: none; From 0a9c1c7c8ebc899525ac5b0333be39704419ded9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 26 May 2021 13:08:25 +0200 Subject: [PATCH 16/23] Complex validation for RTE property editor (#10328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niels Lyngsø --- .../services/contenteditinghelper.service.js | 2 -- .../src/common/services/tinymce.service.js | 36 ++++++++++++------- .../propertyeditors/rte/rte.controller.js | 36 +++++++++---------- .../src/views/propertyeditors/rte/rte.html | 10 +++--- 4 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 67e466af35..faa0d2a3c0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -48,8 +48,6 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt }); } else if (value[0]) { - //notificationsService.error("Validation", value[0]); - console.log({type:messageType, header:"Validation", message:value[0]}) notificationsService.showNotification({type:messageType, header:"Validation", message:value[0]}) } } 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 1d7154288f..9b5d240776 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 @@ -436,7 +436,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s // We are not ready to limit the pasted elements further than default, we will return to this feature. ( TODO: Make this feature an option. ) // We keep spans here, cause removing spans here also removes b-tags inside of them, instead we strip them out later. (TODO: move this definition to the config file... ) var validPasteElements = "-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody,img[src|alt|width|height],ul,ol,li,hr,pre,dl,dt,figure,figcaption,wbr" - + // add elements from user configurated styleFormats to our list of validPasteElements. // (This means that we only allow H3-element if its configured as a styleFormat on this specific propertyEditor.) var style, i = 0; @@ -605,7 +605,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s 'contenteditable': false }, embed.preview); - + // Only replace if activeElement is an Embed element. if (activeElement && activeElement.nodeName.toUpperCase() === "DIV" && activeElement.classList.contains("embeditem")){ activeElement.replaceWith(wrapper); // directly replaces the html node @@ -733,9 +733,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s id: "__mcenew", "data-udi": img.udi }; - + editor.selection.setContent(editor.dom.createHTML('img', data)); - + // Using settimeout to wait for a DoM-render, so we can find the new element by ID. $timeout(function () { @@ -756,7 +756,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s } }); - + } } }, @@ -1396,11 +1396,26 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s function syncContent() { + if(args.model.value === args.editor.getContent()) { + return; + } + //stop watching before we update the value stopWatch(); angularHelper.safeApply($rootScope, function () { args.model.value = args.editor.getContent(); + + //make the form dirty manually so that the track changes works, setting our model doesn't trigger + // the angular bits because tinymce replaces the textarea. + if (args.currentForm) { + args.currentForm.$setDirty(); + } + // With complex validation we need to set a input field to dirty, not the form. but we will keep the old code for backwards compatibility. + if (args.currentFormInput) { + args.currentFormInput.$setDirty(); + } }); + //re-watch the value startWatch(); } @@ -1425,7 +1440,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s // Upload BLOB images (dragged/pasted ones) // find src attribute where value starts with `blob:` - // search is case-insensitive and allows single or double quotes + // search is case-insensitive and allows single or double quotes if(content.search(/src=["']blob:.*?["']/gi) !== -1){ args.editor.uploadImages(function(data) { // Once all images have been uploaded @@ -1491,6 +1506,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s args.editor.on('Change', function (e) { syncContent(); }); + args.editor.on('Keyup', function (e) { + syncContent(); + }); //when we leave the editor (maybe) args.editor.on('blur', function (e) { @@ -1508,12 +1526,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s args.editor.on('Dirty', function (e) { syncContent(); // Set model.value to the RTE's content - - //make the form dirty manually so that the track changes works, setting our model doesn't trigger - // the angular bits because tinymce replaces the textarea. - if (args.currentForm) { - args.currentForm.$setDirty(); - } }); let self = this; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 74a70118eb..9faa012a4d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -5,12 +5,12 @@ angular.module("umbraco") // TODO: A lot of the code below should be shared between the grid rte and the normal rte $scope.isLoading = true; - + //To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias // because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because // we have this mini content editor panel that can be launched with MNTP. $scope.textAreaHtmlId = $scope.model.alias + "_" + String.CreateGuid(); - + var editorConfig = $scope.model.config ? $scope.model.config.editor : null; if (!editorConfig || Utilities.isString(editorConfig)) { editorConfig = tinyMceService.defaultPrevalues(); @@ -28,14 +28,14 @@ angular.module("umbraco") $scope.containerOverflow = editorConfig.mode === "distraction-free" ? (height ? "auto" : "inherit") : "inherit"; var promises = []; - + // we need to make sure that the element is initialized before we can init TinyMCE, because we find the placeholder by ID, so it needs to be appended to document before. var initPromise = $q((resolve, reject) => { this.$onInit = resolve; }); - + promises.push(initPromise); - + //queue file loading tinyMceAssets.forEach(function (tinyJsAsset) { promises.push(assetsService.loadJs(tinyJsAsset, $scope)); @@ -50,50 +50,50 @@ angular.module("umbraco") toolbar: editorConfig.toolbar, mode: editorConfig.mode })); - + //wait for queue to end $q.all(promises).then(function (result) { - + var standardConfig = result[promises.length - 1]; - + if (height !== null) { standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1); } - + //create a baseline Config to extend upon var baseLineConfigObj = { maxImageSize: editorConfig.maxImageSize, width: width, height: height }; - + baseLineConfigObj.setup = function (editor) { - + //set the reference tinyMceEditor = editor; - + tinyMceEditor.on('init', function (e) { $timeout(function () { $scope.isLoading = false; }); }); - + //initialize the standard editor functionality for Umbraco tinyMceService.initializeEditor({ editor: editor, model: $scope.model, - currentForm: angularHelper.getCurrentForm($scope) + currentFormInput: $scope.rteForm.modelValue }); - + }; - + angular.extend(baseLineConfigObj, standardConfig); - + // We need to wait for DOM to have rendered before we can find the element by ID. $timeout(function () { tinymce.init(baseLineConfigObj); }, 150); - + //listen for formSubmitting event (the result is callback used to remove the event subscription) var unsubscribe = $scope.$on("formSubmitting", function () { if (tinyMceEditor !== undefined && tinyMceEditor != null && !$scope.isLoading) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html index d0b5823f74..21e9065d92 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html @@ -1,8 +1,10 @@
-
- -
-
+ +
+ +
+
+
From 1ac44542f6542a916537d0605881e1e7e3fe9b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 26 May 2021 13:08:25 +0200 Subject: [PATCH 17/23] Complex validation for RTE property editor (#10328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niels Lyngsø (cherry picked from commit 0a9c1c7c8ebc899525ac5b0333be39704419ded9) # Conflicts: # src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js --- .../src/common/services/tinymce.service.js | 36 ++++++++++++------- .../propertyeditors/rte/rte.controller.js | 36 +++++++++---------- .../src/views/propertyeditors/rte/rte.html | 10 +++--- 3 files changed, 48 insertions(+), 34 deletions(-) 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 1d7154288f..9b5d240776 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 @@ -436,7 +436,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s // We are not ready to limit the pasted elements further than default, we will return to this feature. ( TODO: Make this feature an option. ) // We keep spans here, cause removing spans here also removes b-tags inside of them, instead we strip them out later. (TODO: move this definition to the config file... ) var validPasteElements = "-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody,img[src|alt|width|height],ul,ol,li,hr,pre,dl,dt,figure,figcaption,wbr" - + // add elements from user configurated styleFormats to our list of validPasteElements. // (This means that we only allow H3-element if its configured as a styleFormat on this specific propertyEditor.) var style, i = 0; @@ -605,7 +605,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s 'contenteditable': false }, embed.preview); - + // Only replace if activeElement is an Embed element. if (activeElement && activeElement.nodeName.toUpperCase() === "DIV" && activeElement.classList.contains("embeditem")){ activeElement.replaceWith(wrapper); // directly replaces the html node @@ -733,9 +733,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s id: "__mcenew", "data-udi": img.udi }; - + editor.selection.setContent(editor.dom.createHTML('img', data)); - + // Using settimeout to wait for a DoM-render, so we can find the new element by ID. $timeout(function () { @@ -756,7 +756,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s } }); - + } } }, @@ -1396,11 +1396,26 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s function syncContent() { + if(args.model.value === args.editor.getContent()) { + return; + } + //stop watching before we update the value stopWatch(); angularHelper.safeApply($rootScope, function () { args.model.value = args.editor.getContent(); + + //make the form dirty manually so that the track changes works, setting our model doesn't trigger + // the angular bits because tinymce replaces the textarea. + if (args.currentForm) { + args.currentForm.$setDirty(); + } + // With complex validation we need to set a input field to dirty, not the form. but we will keep the old code for backwards compatibility. + if (args.currentFormInput) { + args.currentFormInput.$setDirty(); + } }); + //re-watch the value startWatch(); } @@ -1425,7 +1440,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s // Upload BLOB images (dragged/pasted ones) // find src attribute where value starts with `blob:` - // search is case-insensitive and allows single or double quotes + // search is case-insensitive and allows single or double quotes if(content.search(/src=["']blob:.*?["']/gi) !== -1){ args.editor.uploadImages(function(data) { // Once all images have been uploaded @@ -1491,6 +1506,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s args.editor.on('Change', function (e) { syncContent(); }); + args.editor.on('Keyup', function (e) { + syncContent(); + }); //when we leave the editor (maybe) args.editor.on('blur', function (e) { @@ -1508,12 +1526,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s args.editor.on('Dirty', function (e) { syncContent(); // Set model.value to the RTE's content - - //make the form dirty manually so that the track changes works, setting our model doesn't trigger - // the angular bits because tinymce replaces the textarea. - if (args.currentForm) { - args.currentForm.$setDirty(); - } }); let self = this; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 74a70118eb..9faa012a4d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -5,12 +5,12 @@ angular.module("umbraco") // TODO: A lot of the code below should be shared between the grid rte and the normal rte $scope.isLoading = true; - + //To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias // because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because // we have this mini content editor panel that can be launched with MNTP. $scope.textAreaHtmlId = $scope.model.alias + "_" + String.CreateGuid(); - + var editorConfig = $scope.model.config ? $scope.model.config.editor : null; if (!editorConfig || Utilities.isString(editorConfig)) { editorConfig = tinyMceService.defaultPrevalues(); @@ -28,14 +28,14 @@ angular.module("umbraco") $scope.containerOverflow = editorConfig.mode === "distraction-free" ? (height ? "auto" : "inherit") : "inherit"; var promises = []; - + // we need to make sure that the element is initialized before we can init TinyMCE, because we find the placeholder by ID, so it needs to be appended to document before. var initPromise = $q((resolve, reject) => { this.$onInit = resolve; }); - + promises.push(initPromise); - + //queue file loading tinyMceAssets.forEach(function (tinyJsAsset) { promises.push(assetsService.loadJs(tinyJsAsset, $scope)); @@ -50,50 +50,50 @@ angular.module("umbraco") toolbar: editorConfig.toolbar, mode: editorConfig.mode })); - + //wait for queue to end $q.all(promises).then(function (result) { - + var standardConfig = result[promises.length - 1]; - + if (height !== null) { standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1); } - + //create a baseline Config to extend upon var baseLineConfigObj = { maxImageSize: editorConfig.maxImageSize, width: width, height: height }; - + baseLineConfigObj.setup = function (editor) { - + //set the reference tinyMceEditor = editor; - + tinyMceEditor.on('init', function (e) { $timeout(function () { $scope.isLoading = false; }); }); - + //initialize the standard editor functionality for Umbraco tinyMceService.initializeEditor({ editor: editor, model: $scope.model, - currentForm: angularHelper.getCurrentForm($scope) + currentFormInput: $scope.rteForm.modelValue }); - + }; - + angular.extend(baseLineConfigObj, standardConfig); - + // We need to wait for DOM to have rendered before we can find the element by ID. $timeout(function () { tinymce.init(baseLineConfigObj); }, 150); - + //listen for formSubmitting event (the result is callback used to remove the event subscription) var unsubscribe = $scope.$on("formSubmitting", function () { if (tinyMceEditor !== undefined && tinyMceEditor != null && !$scope.isLoading) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html index d0b5823f74..21e9065d92 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html @@ -1,8 +1,10 @@
-
- -
-
+ +
+ +
+
+
From 008e76c08f72a2e009e3518f13c2896b3677d7e7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 26 May 2021 11:42:06 +0200 Subject: [PATCH 18/23] fixes #10297 8.14-RC - A few areas where focus lock doesn't work properly --- .../components/editor/umbeditors.directive.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js index 231ee4e866..590f9627ab 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js @@ -12,6 +12,11 @@ var isLeftColumnAbove = false; scope.editors = []; + /* we need to keep a count of open editors because the length of the editors array is first changed when animations are done + we do this because some infinite editors close more than one editor at the time and we get the wrong count from editors.length + because of the animation */ + let editorCount = 0; + function addEditor(editor) { editor.inFront = true; editor.moveRight = true; @@ -51,13 +56,16 @@ updateEditors(-1); - if(scope.editors.length === 1){ + if(scope.editors.length === 1) { if(isLeftColumnAbove){ $('#leftcolumn').addClass(aboveBackDropCssClass); } isLeftColumnAbove = false; + } + // when the last editor is closed remove the focus lock + if (editorCount === 0) { // Remove the inert attribute from the #mainwrapper focusLockService.removeInertAttribute(); } @@ -105,16 +113,19 @@ } evts.push(eventsService.on("appState.editors.open", function (name, args) { + editorCount = editorCount + 1; addEditor(args.editor); })); evts.push(eventsService.on("appState.editors.close", function (name, args) { // remove the closed editor if (args && args.editor) { + editorCount = editorCount - 1; removeEditor(args.editor); } // close all editors if (args && !args.editor && args.editors.length === 0) { + editorCount = 0; scope.editors = []; } })); From 9ef806d4e9544173b185c4702644ae7233eca5b5 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 26 May 2021 15:13:25 +0100 Subject: [PATCH 19/23] Rename Media Picker 3 and make current Media Picker Obsolete (#10332) --- .../Migrations/Install/DatabaseDataCreator.cs | 15 +++++++-------- src/Umbraco.Tests/Services/ContentServiceTests.cs | 2 +- .../TestHelpers/Entities/MockedContent.cs | 2 +- .../TestHelpers/Entities/MockedContentTypes.cs | 2 +- .../PropertyEditors/MediaPicker3PropertyEditor.cs | 2 +- .../PropertyEditors/MediaPickerPropertyEditor.cs | 6 ++++-- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 264733e5b9..6a56141491 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -141,14 +141,14 @@ namespace Umbraco.Core.Migrations.Install //New UDI pickers with newer Ids _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1046, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1046", SortOrder = 2, UniqueId = new Guid("FD1E0DA5-5606-4862-B679-5D0CF3A52A59"), Text = "Content Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1047, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1047", SortOrder = 2, UniqueId = new Guid("1EA2E01F-EBD8-4CE1-8D71-6B1149E63548"), Text = "Member Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "(Obsolete) Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "(Obsolete) Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Multi URL Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); } @@ -350,8 +350,7 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1046, EditorAlias = Constants.PropertyEditors.Aliases.ContentPicker, DbType = "Nvarchar" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1047, EditorAlias = Constants.PropertyEditors.Aliases.MemberPicker, DbType = "Nvarchar" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1048, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext" }); - _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext", - Configuration = "{\"multiPicker\":1}" }); + _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext", Configuration = "{\"multiPicker\":1}" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.MultiUrlPicker, DbType = "Ntext" }); _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 008c24fcbf..d9a90b74d8 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -2470,7 +2470,7 @@ namespace Umbraco.Tests.Services Assert.That(sut.GetValue("ddl"), Is.EqualTo("1234")); Assert.That(sut.GetValue("chklist"), Is.EqualTo("randomc")); Assert.That(sut.GetValue("contentPicker"), Is.EqualTo(Udi.Create(Constants.UdiEntityType.Document, new Guid("74ECA1D4-934E-436A-A7C7-36CC16D4095C")))); - Assert.That(sut.GetValue("mediaPicker"), Is.EqualTo(Udi.Create(Constants.UdiEntityType.Media, new Guid("44CB39C8-01E5-45EB-9CF8-E70AAF2D1691")))); + Assert.That(sut.GetValue("mediapicker3"), Is.EqualTo("[{\"key\": \"8f78ce9e-8fe0-4500-a52d-4c4f35566ba9\",\"mediaKey\": \"44CB39C8-01E5-45EB-9CF8-E70AAF2D1691\",\"crops\": [],\"focalPoint\": {\"left\": 0.5,\"top\": 0.5}}]")); Assert.That(sut.GetValue("memberPicker"), Is.EqualTo(Udi.Create(Constants.UdiEntityType.Member, new Guid("9A50A448-59C0-4D42-8F93-4F1D55B0F47D")))); Assert.That(sut.GetValue("multiUrlPicker"), Is.EqualTo("[{\"name\":\"https://test.com\",\"url\":\"https://test.com\"}]")); Assert.That(sut.GetValue("tags"), Is.EqualTo("this,is,tags")); diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs index 19a57d7775..d8902d2d62 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs @@ -130,7 +130,7 @@ namespace Umbraco.Tests.TestHelpers.Entities content.SetValue("ddl", "1234"); content.SetValue("chklist", "randomc"); content.SetValue("contentPicker", Udi.Create(Constants.UdiEntityType.Document, new Guid("74ECA1D4-934E-436A-A7C7-36CC16D4095C")).ToString()); - content.SetValue("mediaPicker", Udi.Create(Constants.UdiEntityType.Media, new Guid("44CB39C8-01E5-45EB-9CF8-E70AAF2D1691")).ToString()); + content.SetValue("mediaPicker3", "[{\"key\": \"8f78ce9e-8fe0-4500-a52d-4c4f35566ba9\",\"mediaKey\": \"44CB39C8-01E5-45EB-9CF8-E70AAF2D1691\",\"crops\": [],\"focalPoint\": {\"left\": 0.5,\"top\": 0.5}}]"); content.SetValue("memberPicker", Udi.Create(Constants.UdiEntityType.Member, new Guid("9A50A448-59C0-4D42-8F93-4F1D55B0F47D")).ToString()); content.SetValue("multiUrlPicker", "[{\"name\":\"https://test.com\",\"url\":\"https://test.com\"}]"); content.SetValue("tags", "this,is,tags"); diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 1b85787fee..9271486f2b 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -368,7 +368,7 @@ namespace Umbraco.Tests.TestHelpers.Entities contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.CheckBoxList, ValueStorageType.Nvarchar) { Alias = "chklist", Name = "Checkbox List", Mandatory = false, SortOrder = 15, DataTypeId = -43 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ContentPicker, ValueStorageType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeId = 1046 }); - contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MediaPicker, ValueStorageType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeId = 1048 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MediaPicker3, ValueStorageType.Integer) { Alias = "mediapicker3", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeId = 1051 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MemberPicker, ValueStorageType.Integer) { Alias = "memberPicker", Name = "Member Picker", Mandatory = false, SortOrder = 18, DataTypeId = 1047 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MultiUrlPicker, ValueStorageType.Nvarchar) { Alias = "multiUrlPicker", Name = "Multi URL Picker", Mandatory = false, SortOrder = 21, DataTypeId = 1050 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Tags, ValueStorageType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeId = 1041 }); diff --git a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs index 526b4830c8..4ce376f543 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -14,7 +14,7 @@ namespace Umbraco.Web.PropertyEditors [DataEditor( Constants.PropertyEditors.Aliases.MediaPicker3, EditorType.PropertyValue, - "Media Picker v3", + "Media Picker", "mediapicker3", ValueType = ValueTypes.Json, Group = Constants.PropertyEditors.Groups.Media, diff --git a/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs index 493fc96f76..499737f3b7 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs @@ -8,15 +8,17 @@ namespace Umbraco.Web.PropertyEditors { /// /// Represents a media picker property editor. + /// Marked as Deprecated as best to use the NEW Media Picker aka MediaPicker3 /// [DataEditor( Constants.PropertyEditors.Aliases.MediaPicker, EditorType.PropertyValue | EditorType.MacroParameter, - "Media Picker", + "(Obsolete) Media Picker", "mediapicker", ValueType = ValueTypes.Text, Group = Constants.PropertyEditors.Groups.Media, - Icon = Constants.Icons.MediaImage)] + Icon = Constants.Icons.MediaImage, + IsDeprecated = true)] public class MediaPickerPropertyEditor : DataEditor { From a845d2bffd76434e9af42b83ce820298cfe49f16 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 26 May 2021 16:18:10 +0200 Subject: [PATCH 20/23] Shows a warning for people tempted to switch to the new media picker --- .../src/views/prevalueeditors/obsoletemediapickernotice.html | 1 + src/Umbraco.Web/PropertyEditors/MediaPickerConfiguration.cs | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/views/prevalueeditors/obsoletemediapickernotice.html diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/obsoletemediapickernotice.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/obsoletemediapickernotice.html new file mode 100644 index 0000000000..cc861dcb4b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/obsoletemediapickernotice.html @@ -0,0 +1 @@ +

Important: switching from the (Obsolete) Media Picker to Media Picker will mean all data (references to previously selected media items) will be deleted and no longer available.

\ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/MediaPickerConfiguration.cs b/src/Umbraco.Web/PropertyEditors/MediaPickerConfiguration.cs index b8b9476184..7266be9c26 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPickerConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPickerConfiguration.cs @@ -8,6 +8,9 @@ namespace Umbraco.Web.PropertyEditors /// public class MediaPickerConfiguration : IIgnoreUserStartNodesConfig { + [ConfigurationField("notice", "You can NOT change the property editor", "obsoletemediapickernotice")] + public bool Notice { get; set; } + [ConfigurationField("multiPicker", "Pick multiple items", "boolean")] public bool Multiple { get; set; } From d81fac9753591415fd8418fdcdb89d5445957888 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 27 May 2021 10:42:13 +0200 Subject: [PATCH 21/23] Bump version to 8.14.0 --- src/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 91918498f9..3619dc1371 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.14.0")] -[assembly: AssemblyInformationalVersion("8.14.0-rc")] +[assembly: AssemblyInformationalVersion("8.14.0")] From fc417e8ed811cf30c140c040ef07eecd9130c7ce Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 31 May 2021 09:18:12 +0200 Subject: [PATCH 22/23] Bump version to 8.11.3 --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index ca9d596415..e4becddab0 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.11.2")] -[assembly: AssemblyInformationalVersion("8.11.2")] +[assembly: AssemblyFileVersion("8.11.3")] +[assembly: AssemblyInformationalVersion("8.11.3")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 366a852a96..3b7286c293 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -347,9 +347,9 @@ False True - 8112 + 8113 / - http://localhost:8112 + http://localhost:8113 False False From 042e296d8f596f784c9c18333d507e45f02ff9d6 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 31 May 2021 09:21:44 +0200 Subject: [PATCH 23/23] Bump version to 8.12.3 --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 4162f47da6..cf8bde8057 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.12.2")] -[assembly: AssemblyInformationalVersion("8.12.2")] +[assembly: AssemblyFileVersion("8.12.3")] +[assembly: AssemblyInformationalVersion("8.12.3")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 2ad23e1b73..0454ba6c12 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -347,9 +347,9 @@ False True - 8122 + 8123 / - http://localhost:8122 + http://localhost:8123 False False