From 65319149c06619003c3675f5c4ea8ff3388b3206 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Thu, 4 Aug 2022 20:17:50 +0900 Subject: [PATCH] Issue #3292780 by nod_, Spokje: Move Quick Edit related Javascript from core/modules/ckeditor5/js/ckeditor5.es6.js::detach() to the Quick Edit module --- core/modules/ckeditor5/js/ckeditor5.es6.js | 33 ++----------- core/modules/ckeditor5/js/ckeditor5.js | 17 +------ .../js/editors/formattedTextEditor.es6.js | 49 +++++++++++++++++++ .../js/editors/formattedTextEditor.js | 24 +++++++++ 4 files changed, 77 insertions(+), 46 deletions(-) diff --git a/core/modules/ckeditor5/js/ckeditor5.es6.js b/core/modules/ckeditor5/js/ckeditor5.es6.js index 92f3ec634d87..5a33141260ce 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 5f0690fefd75..e4990cfb1016 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 05bc4e7168ea..fad6a3fe0ad7 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 139429710a63..b193275354a5 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() { -- GitLab