Merge branch 'v13/dev' into v13/contrib
This commit is contained in:
@@ -5,30 +5,30 @@
|
||||
</PropertyGroup>
|
||||
<!-- Global packages (private, build-time packages for all projects) -->
|
||||
<ItemGroup>
|
||||
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.6.133" />
|
||||
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.6.139" />
|
||||
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.507" />
|
||||
<GlobalPackageReference Include="Umbraco.Code" Version="2.1.0" />
|
||||
<GlobalPackageReference Include="Umbraco.Code" Version="2.2.0" />
|
||||
<GlobalPackageReference Include="Umbraco.GitVersioning.Extensions" Version="0.2.0" />
|
||||
</ItemGroup>
|
||||
<!-- Microsoft packages -->
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.FileProviders.Physical" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Identity.Core" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Identity.Stores" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Identity.Stores" Version="8.0.7" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
@@ -45,13 +45,13 @@
|
||||
<PackageVersion Include="Asp.Versioning.Mvc" Version="7.1.1" />
|
||||
<PackageVersion Include="Asp.Versioning.Mvc.ApiExplorer" Version="7.1.0" />
|
||||
<PackageVersion Include="Dazinator.Extensions.FileProviders" Version="2.0.0" />
|
||||
<PackageVersion Include="Examine" Version="3.2.1" />
|
||||
<PackageVersion Include="Examine.Core" Version="3.2.1" />
|
||||
<PackageVersion Include="HtmlAgilityPack" Version="1.11.61" />
|
||||
<PackageVersion Include="Examine" Version="3.3.0" />
|
||||
<PackageVersion Include="Examine.Core" Version="3.3.0" />
|
||||
<PackageVersion Include="HtmlAgilityPack" Version="1.11.62" />
|
||||
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
|
||||
<PackageVersion Include="MailKit" Version="4.6.0" />
|
||||
<PackageVersion Include="MailKit" Version="4.7.1.1" />
|
||||
<PackageVersion Include="Markdown" Version="2.2.1" />
|
||||
<PackageVersion Include="MessagePack" Version="2.5.168" />
|
||||
<PackageVersion Include="MessagePack" Version="2.5.172" />
|
||||
<PackageVersion Include="MiniProfiler.AspNetCore.Mvc" Version="4.3.8" />
|
||||
<PackageVersion Include="MiniProfiler.Shared" Version="4.3.8" />
|
||||
<PackageVersion Include="ncrontab" Version="3.3.3" />
|
||||
@@ -62,22 +62,22 @@
|
||||
<PackageVersion Include="OpenIddict.AspNetCore" Version="4.10.1" />
|
||||
<PackageVersion Include="OpenIddict.EntityFrameworkCore" Version="4.10.1" />
|
||||
<PackageVersion Include="Serilog" Version="3.1.1" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.2" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Process" Version="2.0.2" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Thread" Version="3.1.0" />
|
||||
<PackageVersion Include="Serilog.Expressions" Version="4.0.0" />
|
||||
<PackageVersion Include="Serilog.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageVersion Include="Serilog.Formatting.Compact" Version="2.0.0" />
|
||||
<PackageVersion Include="Serilog.Formatting.Compact.Reader" Version="3.0.0" />
|
||||
<PackageVersion Include="Serilog.Settings.Configuration" Version="8.0.0" />
|
||||
<PackageVersion Include="Serilog.Settings.Configuration" Version="8.0.2" />
|
||||
<PackageVersion Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Map" Version="1.0.2" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp.Web" Version="3.1.2" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.5" />
|
||||
<PackageVersion Include="SixLabors.ImageSharp.Web" Version="3.1.3" />
|
||||
<PackageVersion Include="Smidge.InMemory" Version="4.4.0" />
|
||||
<PackageVersion Include="Smidge.Nuglify" Version="4.4.0" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.7.0" />
|
||||
</ItemGroup>
|
||||
<!-- Transitive pinned versions (only required because our direct dependencies have vulnerable versions of transitive dependencies) -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -160,11 +160,12 @@ public class MemberController : DeliveryApiControllerBase
|
||||
claim.SetDestinations(OpenIddictConstants.Destinations.AccessToken);
|
||||
}
|
||||
|
||||
if (request.GetScopes().Contains(OpenIddictConstants.Scopes.OfflineAccess))
|
||||
{
|
||||
// "offline_access" scope is required to use refresh tokens
|
||||
memberPrincipal.SetScopes(OpenIddictConstants.Scopes.OfflineAccess);
|
||||
}
|
||||
// "openid" and "offline_access" are the only scopes allowed for members; explicitly ensure we only add those
|
||||
// NOTE: the "offline_access" scope is required to use refresh tokens
|
||||
IEnumerable<string> allowedScopes = request
|
||||
.GetScopes()
|
||||
.Intersect(new[] { OpenIddictConstants.Scopes.OpenId, OpenIddictConstants.Scopes.OfflineAccess });
|
||||
memberPrincipal.SetScopes(allowedScopes);
|
||||
|
||||
return new SignInResult(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, memberPrincipal);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp" VersionOverride="[2.1.8, 3)" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" VersionOverride="[2.1.9, 3)" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Web" VersionOverride="[2.0.2, 3)" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ public abstract class RecurringHostedServiceBase : IHostedService, IDisposable
|
||||
/// Executes the task.
|
||||
/// </summary>
|
||||
/// <param name="state">The task state.</param>
|
||||
public async void ExecuteAsync(object? state)
|
||||
public virtual async void ExecuteAsync(object? state)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -401,8 +401,9 @@
|
||||
// If we are in the document type editor, we need to use -20 as the current page id.
|
||||
// If we are in the content editor, we need to use the current page id or parent id if the current page is new.
|
||||
// We can recognize a content editor context by checking if the current editor state has a contentTypeKey.
|
||||
// If no current is represented, we will use null.
|
||||
const currentEditorState = editorState.getCurrent();
|
||||
const currentPageId = currentEditorState.contentTypeKey ? currentEditorState.id || currentEditorState.parentId || -20 : -20;
|
||||
const currentPageId = currentEditorState ? currentEditorState.contentTypeKey ? currentEditorState.id || currentEditorState.parentId || -20 : -20 : null;
|
||||
|
||||
// Load all scaffolds for the block types.
|
||||
// The currentPageId is used to determine the access level for the current user.
|
||||
|
||||
@@ -1457,12 +1457,13 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
function syncContent() {
|
||||
|
||||
const content = args.editor.getContent()
|
||||
const content = args.editor.getContent();
|
||||
|
||||
if (getPropertyValue() === content) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//stop watching before we update the value
|
||||
stopWatch();
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
@@ -1493,8 +1494,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
const blockEls = args.editor.contentDocument.querySelectorAll('umb-rte-block, umb-rte-block-inline');
|
||||
for (var blockEl of blockEls) {
|
||||
if(!blockEl._isInitializedUmbBlock) {
|
||||
// First time we initialize this block element
|
||||
const blockContentUdi = blockEl.getAttribute('data-content-udi');
|
||||
if(blockContentUdi && !blockEl.$block) {
|
||||
if(blockContentUdi) {
|
||||
const block = args.blockEditorApi.getBlockByContentUdi(blockContentUdi);
|
||||
if(block) {
|
||||
blockEl.removeAttribute('contenteditable');
|
||||
@@ -1533,9 +1535,23 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
} else {
|
||||
args.editor.dom.remove(blockEl);
|
||||
}
|
||||
} else {
|
||||
// Second time we initialize this block element, cause by a new Block Model Object has been initiated. (Mainly cause we re initiate all blocks when there is a value update)
|
||||
const blockContentUdi = blockEl.getAttribute('data-content-udi');
|
||||
const block = args.blockEditorApi.getBlockByContentUdi(blockContentUdi);
|
||||
if(block) {
|
||||
blockEl.$index = block.index;
|
||||
blockEl.$block = block;
|
||||
blockEl.update();
|
||||
} else {
|
||||
console.error('Could not find block with content udi: ' + blockContentUdi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
args.editor.on('updateBlocks', function () {
|
||||
initBlocks();
|
||||
});
|
||||
|
||||
// If we can not find the insert image/media toolbar button
|
||||
// Then we need to add an event listener to the editor
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.services.rte-block-clipboard-service
|
||||
*
|
||||
* Handles clipboard resolvers for Block of RTE properties.
|
||||
*
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* When performing a runtime copy of Block Editors entries, we copy the ElementType Data Model and inner IDs are kept identical, to ensure new IDs are changed on paste we need to provide a resolver for the ClipboardService.
|
||||
*/
|
||||
angular.module('umbraco').run(['clipboardService', 'udiService', function (clipboardService, udiService) {
|
||||
|
||||
function replaceUdi(obj, key, dataObject, markup) {
|
||||
var udi = obj[key];
|
||||
var newUdi = udiService.create("element");
|
||||
obj[key] = newUdi;
|
||||
dataObject.forEach((data) => {
|
||||
if (data.udi === udi) {
|
||||
data.udi = newUdi;
|
||||
}
|
||||
});
|
||||
// make a attribute name of the key, by kebab casing it:
|
||||
var attrName = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
// replace the udi in the markup as well.
|
||||
var regex = new RegExp('data-'+attrName+'="'+udi+'"', "g");
|
||||
markup = markup.replace(regex, 'data-'+attrName+'="'+newUdi+'"');
|
||||
return markup;
|
||||
}
|
||||
function replaceUdisOfObject(obj, propValue, markup) {
|
||||
for (var k in obj) {
|
||||
if(k === "contentUdi") {
|
||||
markup = replaceUdi(obj, k, propValue.contentData, markup);
|
||||
} else if(k === "settingsUdi") {
|
||||
markup = replaceUdi(obj, k, propValue.settingsData, markup);
|
||||
} else {
|
||||
// lets crawl through all properties of layout to make sure get captured all `contentUdi` and `settingsUdi` properties.
|
||||
var propType = typeof obj[k];
|
||||
if(propType != null && (propType === "object" || propType === "array")) {
|
||||
markup = replaceUdisOfObject(obj[k], propValue, markup);
|
||||
}
|
||||
}
|
||||
}
|
||||
return markup
|
||||
}
|
||||
|
||||
|
||||
function rawRteBlockResolver(propertyValue, propPasteResolverMethod) {
|
||||
if (propertyValue != null && typeof propertyValue === "object") {
|
||||
|
||||
// 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)) {
|
||||
|
||||
// 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);
|
||||
|
||||
// run resolvers for inner properties of this Blocks content data.
|
||||
if(value.contentData.length > 0) {
|
||||
value.contentData.forEach((item) => {
|
||||
for (var k in item) {
|
||||
propPasteResolverMethod(item[k], clipboardService.TYPES.RAW);
|
||||
}
|
||||
});
|
||||
}
|
||||
// run resolvers for inner properties of this Blocks settings data.
|
||||
if(value.settingsData.length > 0) {
|
||||
value.settingsData.forEach((item) => {
|
||||
for (var k in item) {
|
||||
propPasteResolverMethod(item[k], clipboardService.TYPES.RAW);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function elementTypeBlockResolver(obj, propPasteResolverMethod) {
|
||||
// we could filter for specific Property Editor Aliases, but as the Block Editor structure can be used by many Property Editor we do not in this code know a good way to detect that this is a Block Editor and will therefor leave it to the value structure to determin this.
|
||||
rawRteBlockResolver(obj.value, propPasteResolverMethod);
|
||||
}
|
||||
|
||||
clipboardService.registerPastePropertyResolver(elementTypeBlockResolver, clipboardService.TYPES.ELEMENT_TYPE);
|
||||
clipboardService.registerPastePropertyResolver(rawRteBlockResolver, clipboardService.TYPES.RAW);
|
||||
|
||||
}]);
|
||||
|
||||
})();
|
||||
@@ -18,7 +18,8 @@
|
||||
}
|
||||
|
||||
function onInit() {
|
||||
$element[0]._isInitializedUmbBlock = true;
|
||||
|
||||
// We might call onInit multiple times(via the update method), so parsing the latest values is needed no matter if it has been initialized before.
|
||||
$scope.block = $element[0].$block;
|
||||
$scope.api = $element[0].$api;
|
||||
$scope.index = $element[0].$index;
|
||||
@@ -27,6 +28,13 @@
|
||||
$scope.parentForm = $element[0].$parentForm;
|
||||
$scope.valFormManager = $element[0].$valFormManager;
|
||||
|
||||
if($element[0]._isInitializedUmbBlock === true) {
|
||||
return;
|
||||
}
|
||||
$element[0]._isInitializedUmbBlock = true;
|
||||
$element[0].update = onInit;
|
||||
|
||||
|
||||
const stylesheet = $scope.block.config.stylesheet;
|
||||
|
||||
var shadowRoot = $element[0].attachShadow({ mode: 'open' });
|
||||
|
||||
@@ -264,7 +264,7 @@
|
||||
},
|
||||
culture: vm.umbProperty?.culture ?? null,
|
||||
segment: vm.umbProperty?.segment ?? null,
|
||||
blockEditorApi: vm.noBlocksMode ? undefined : vm.blockEditorApi,
|
||||
blockEditorApi: vm.noBlocksMode ? undefined : vm.blockEditorApi,
|
||||
parentForm: vm.propertyForm,
|
||||
valFormManager: vm.valFormManager,
|
||||
currentFormInput: $scope.rteForm.modelValue
|
||||
@@ -341,10 +341,14 @@
|
||||
// we need to deal with that here so that our model values are all in sync so we basically re-initialize.
|
||||
function onServerValueChanged(newVal, oldVal) {
|
||||
|
||||
|
||||
ensurePropertyValue(newVal);
|
||||
|
||||
// updating the modelObject with the new value cause a angular compile issue.
|
||||
// But I'm not sure it's needed, as this does not trigger the RTE
|
||||
if(modelObject) {
|
||||
modelObject.update(vm.model.value.blocks, $scope);
|
||||
vm.tinyMceEditor.fire('updateBlocks');
|
||||
}
|
||||
onLoaded();
|
||||
}
|
||||
@@ -944,7 +948,19 @@
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return vm.layout[layoutIndex].$block;
|
||||
var layoutEntry = vm.layout[layoutIndex];
|
||||
if(layoutEntry.$block === undefined || layoutEntry.$block.config === undefined) {
|
||||
// make block model
|
||||
var blockObject = getBlockObject(layoutEntry);
|
||||
if (blockObject === null) {
|
||||
// Initialization of the Block Object didn't go well, therefor we will fail the paste action.
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the BlockObject on our layout entry.
|
||||
layoutEntry.$block = blockObject;
|
||||
}
|
||||
return layoutEntry.$block;
|
||||
}
|
||||
|
||||
vm.blockEditorApi = {
|
||||
|
||||
Reference in New Issue
Block a user