diff --git a/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js b/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js index ab6c176c854f..85ca297e69fd 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/blockeditormodelobject.service.js @@ -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. 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 ebf759c20c30..df5b0d51bb9e 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 @@ -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 diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/blocks/umb-rte-block.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/blocks/umb-rte-block.component.js index 0c4c8e2e50be..7738a73c9f3c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/blocks/umb-rte-block.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/blocks/umb-rte-block.component.js @@ -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' }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.component.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.component.js index 7f0621514840..d499f47a9cc2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.component.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.component.js @@ -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 = {