diff --git a/core/modules/ckeditor5/js/ckeditor5.es6.js b/core/modules/ckeditor5/js/ckeditor5.es6.js index 92f3ec634d87486a9f02974accdb68e96f319c66..5a33141260ceb190d464d4f7a5cb29fcbcf8b7b1 100644 --- a/core/modules/ckeditor5/js/ckeditor5.es6.js +++ b/core/modules/ckeditor5/js/ckeditor5.es6.js @@ -497,38 +497,11 @@ editor.updateSourceElement(); } else { element.removeAttribute('contentEditable'); - - // Prepare variables that will be used when discarding Quickedit changes. - let textElement = null; - let originalValue = null; - const usingQuickEdit = (((Drupal || {}).quickedit || {}).editors || {}) - .editor; - if (usingQuickEdit) { - // The revert() function in QuickEdit's text editor does not work with - // CKEditor 5, as it is triggered before CKEditor 5 is fully - // destroyed. This function is overridden so the functionality it - // provides can happen after the CKEditor destroy() promise is - // fulfilled. - // This pulls the necessary values from the QuickEdit Backbone Model - // before it is destroyed, so they can be used by - // `editor.destroy().then()` to perform the expected revert. - Drupal.quickedit.editors.editor.prototype.revert = - function revertQuickeditChanges() { - textElement = this.$textElement[0]; - originalValue = this.model.get('originalValue'); - }; - } - - editor + // Return the promise to allow external code to queue code to + // execute after the destroy is complete. + return editor .destroy() .then(() => { - // If textElement and originalValue are not null, a QuickEdit - // revert has been requested. Perform the revert here as it - // can't happen until the CKEditor instance is destroyed. - if (textElement && originalValue) { - textElement.innerHTML = originalValue; - } - // Clean up stored references. Drupal.CKEditor5Instances.delete(id); callbacks.delete(id); diff --git a/core/modules/ckeditor5/js/ckeditor5.js b/core/modules/ckeditor5/js/ckeditor5.js index 5f0690fefd75ca0d61f61f0756cf950ee9145c5f..e4990cfb10169eed452dd10caf7d3e365d66e641 100644 --- a/core/modules/ckeditor5/js/ckeditor5.js +++ b/core/modules/ckeditor5/js/ckeditor5.js @@ -237,22 +237,7 @@ editor.updateSourceElement(); } else { element.removeAttribute('contentEditable'); - let textElement = null; - let originalValue = null; - const usingQuickEdit = (((Drupal || {}).quickedit || {}).editors || {}).editor; - - if (usingQuickEdit) { - Drupal.quickedit.editors.editor.prototype.revert = function revertQuickeditChanges() { - textElement = this.$textElement[0]; - originalValue = this.model.get('originalValue'); - }; - } - - editor.destroy().then(() => { - if (textElement && originalValue) { - textElement.innerHTML = originalValue; - } - + return editor.destroy().then(() => { Drupal.CKEditor5Instances.delete(id); callbacks.delete(id); diff --git a/core/modules/quickedit/js/editors/formattedTextEditor.es6.js b/core/modules/quickedit/js/editors/formattedTextEditor.es6.js index 05bc4e7168ea4684e420e30e9afc1c5c84e0679b..fad6a3fe0ad7f6f27a7b7539020f7ef1b46f0018 100644 --- a/core/modules/quickedit/js/editors/formattedTextEditor.es6.js +++ b/core/modules/quickedit/js/editors/formattedTextEditor.es6.js @@ -70,6 +70,55 @@ this.$textElement = this.$el; } this.model.set('originalValue', this.$textElement.html()); + + if ( + Drupal.editors && + Drupal.editors.ckeditor5 && + once('quickedit-ckeditor5-destroy', 'body').length + ) { + /** + * CKEditor 5 destroy lifecycle is different because is uses Promises. + */ + const ckeditor5Detach = Drupal.editors.ckeditor5.detach; + Drupal.editors.ckeditor5.detach = function quickeditDetach( + element, + format, + trigger, + ) { + const destroyPromise = ckeditor5Detach.call( + this, + element, + format, + trigger, + ); + if (destroyPromise && destroyPromise.then) { + let textElement = null; + let originalValue = null; + // The revert() function in QuickEdit's text editor does not work with + // CKEditor 5, as it is triggered before CKEditor 5 is fully + // destroyed. This function is overridden so the functionality it + // provides can happen after the CKEditor destroy() promise is + // fulfilled. + // This pulls the necessary values from the QuickEdit Backbone Model + // before it is destroyed, so they can be used by + // `editor.destroy().then()` to perform the expected revert. + Drupal.quickedit.editors.editor.prototype.revert = + function revertQuickeditChanges() { + textElement = this.$textElement[0]; + originalValue = this.model.get('originalValue'); + }; + + destroyPromise.then(() => { + // If textElement and originalValue are not null, a QuickEdit + // revert has been requested. Perform the revert here as it + // can't happen until the CKEditor instance is destroyed. + if (textElement && originalValue) { + textElement.innerHTML = originalValue; + } + }); + } + }; + } }, /** diff --git a/core/modules/quickedit/js/editors/formattedTextEditor.js b/core/modules/quickedit/js/editors/formattedTextEditor.js index 139429710a638ae1ae5f382c1f69ef7e8ebea3b3..b193275354a58a6369a42ed5d261df4e7cbf41cc 100644 --- a/core/modules/quickedit/js/editors/formattedTextEditor.js +++ b/core/modules/quickedit/js/editors/formattedTextEditor.js @@ -27,6 +27,30 @@ } this.model.set('originalValue', this.$textElement.html()); + + if (Drupal.editors && Drupal.editors.ckeditor5 && once('quickedit-ckeditor5-destroy', 'body').length) { + const ckeditor5Detach = Drupal.editors.ckeditor5.detach; + + Drupal.editors.ckeditor5.detach = function quickeditDetach(element, format, trigger) { + const destroyPromise = ckeditor5Detach.call(this, element, format, trigger); + + if (destroyPromise && destroyPromise.then) { + let textElement = null; + let originalValue = null; + + Drupal.quickedit.editors.editor.prototype.revert = function revertQuickeditChanges() { + textElement = this.$textElement[0]; + originalValue = this.model.get('originalValue'); + }; + + destroyPromise.then(() => { + if (textElement && originalValue) { + textElement.innerHTML = originalValue; + } + }); + } + }; + } }, getEditedElement() {