From 2550263175ae874b6afcc8c55fae0f9d544501d3 Mon Sep 17 00:00:00 2001 From: illia sheremetov Date: Tue, 29 Nov 2022 15:19:57 +0100 Subject: [PATCH 1/3] init commit --- src/app/editor/setupmixin.js | 35 +++++++++++++++++++++++++++++++++ tests/unit/editor/setupmixin.js | 15 ++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/app/editor/setupmixin.js b/src/app/editor/setupmixin.js index ff13991..02ce8aa 100644 --- a/src/app/editor/setupmixin.js +++ b/src/app/editor/setupmixin.js @@ -143,12 +143,19 @@ const SetupMixin = { this.domManipulator.addEventListener( form, 'reset', () => { // We actually want it 'after-reset', so form elements are clean, thus setTimeout. setTimeout( () => { + const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); + this.setCKEditorData( this.dom.textarea.defaultValue ); this._setInitialMode(); // The above setData() locked the form and saved session data. Undo it. unlockForm( this ); sessionStorage.removeItem( this.sessionKey ); + + // Remove submit pending action to undisable actual submit button + if ( this.ckeditor.plugins.get( 'PendingActions' ).hasAny ) { + pendingActions.fire( 'change:removeAction', 'submit' ); + } } ); } ); } @@ -171,6 +178,16 @@ const SetupMixin = { ev.preventDefault(); ev.stopImmediatePropagation(); } + + const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); + + // Add submit pending action to disable actual submit button for preventing possibility + // clicking on that more than one time. + if ( !this.ckeditor.plugins.get( 'PendingActions' ).hasAny ) { + requestIdleCallback( () => { + pendingActions.fire( 'change:addAction', 'submit' ); + } ); + } } } ); } @@ -333,10 +350,28 @@ const SetupMixin = { _setupPendingActions() { if ( this.ckeditor.plugins.has( 'PendingActions' ) ) { const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); + const actions = new Map(); pendingActions.on( 'change:hasAny', () => { this._setSubmitStatus(); } ); + + // Add to PendingActions collection new action. + pendingActions.on( 'change:addAction', ( _, name ) => { + const action = pendingActions.add( name ); + + actions.set( name, action ); + } ); + + // Remove action from PendingActions collection. + pendingActions.on( 'change:removeAction', ( _, name ) => { + const action = actions.get( name ); + + if ( action ) { + pendingActions.remove( action ); + actions.delete( name ); + } + } ); } } }; diff --git a/tests/unit/editor/setupmixin.js b/tests/unit/editor/setupmixin.js index 45fe39b..d5b00f5 100644 --- a/tests/unit/editor/setupmixin.js +++ b/tests/unit/editor/setupmixin.js @@ -631,6 +631,21 @@ describe( 'Editor', () => { expect( editor ).to.be.an.instanceOf( Editor ); } ); } ); + + it( 'should call "change:addAction" action', () => { + const editor = new Editor( GitHubPage.appendRoot( ) ); + + return editor.create() + .then( () => { + const event = new Event( 'submit' ); + const spy = sinon.spy( event, 'change:addAction' ); + + const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); + pendingActions.fire( 'change:addAction', 'submit' ); + + expect( spy.callCount ).to.equals( 1 ); + } ); + } ); } ); } ); } ); From 0aa77eae58fb94084af152b139dd6422888a9502 Mon Sep 17 00:00:00 2001 From: illia sheremetov Date: Wed, 30 Nov 2022 16:22:39 +0100 Subject: [PATCH 2/3] soft check and tests --- src/app/editor/ckeditorgithubeditor.js | 4 +- src/app/editor/setupmixin.js | 31 +++--- tests/unit/editor/setupmixin.js | 138 +++++++++++++++++++++++-- 3 files changed, 150 insertions(+), 23 deletions(-) diff --git a/src/app/editor/ckeditorgithubeditor.js b/src/app/editor/ckeditorgithubeditor.js index 759206e..062fa34 100644 --- a/src/app/editor/ckeditorgithubeditor.js +++ b/src/app/editor/ckeditorgithubeditor.js @@ -8,6 +8,7 @@ import GFMDataProcessor from '@ckeditor/ckeditor5-markdown-gfm/src/gfmdataproces import CKEditorInspector from '@ckeditor/ckeditor5-inspector'; import AttributeElement from '@ckeditor/ckeditor5-engine/src/view/attributeelement'; +import PendingActions from '@ckeditor/ckeditor5-core/src/pendingactions'; import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Enter from '../plugins/enter'; @@ -118,5 +119,6 @@ CKEditorGitHubEditor.builtinPlugins = [ QuoteSelection, SavedReplies, Messenger, EditorExtras, ControlClick, SmartCaret, CodeBlockLanguageSelector, LiveModelData, - Mermaid + Mermaid, + PendingActions ]; diff --git a/src/app/editor/setupmixin.js b/src/app/editor/setupmixin.js index 02ce8aa..3e8aa42 100644 --- a/src/app/editor/setupmixin.js +++ b/src/app/editor/setupmixin.js @@ -141,21 +141,22 @@ const SetupMixin = { // Reset the rte editor on form reset (e.g. after a new comment is added). { this.domManipulator.addEventListener( form, 'reset', () => { + if ( this.ckeditor.plugins.has( 'PendingActions' ) ) { + const pendingActions = ckeditor.plugins.get( 'PendingActions' ); + + // Remove submit pending action to undisable actual submit button + if ( pendingActions.hasAny ) { + pendingActions.fire( 'change:removeAction', 'submit' ); + } + } // We actually want it 'after-reset', so form elements are clean, thus setTimeout. setTimeout( () => { - const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); - this.setCKEditorData( this.dom.textarea.defaultValue ); this._setInitialMode(); // The above setData() locked the form and saved session data. Undo it. unlockForm( this ); sessionStorage.removeItem( this.sessionKey ); - - // Remove submit pending action to undisable actual submit button - if ( this.ckeditor.plugins.get( 'PendingActions' ).hasAny ) { - pendingActions.fire( 'change:removeAction', 'submit' ); - } } ); } ); } @@ -179,14 +180,16 @@ const SetupMixin = { ev.stopImmediatePropagation(); } - const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); + if ( this.ckeditor.plugins.has( 'PendingActions' ) ) { + const pendingActions = ckeditor.plugins.get( 'PendingActions' ); - // Add submit pending action to disable actual submit button for preventing possibility - // clicking on that more than one time. - if ( !this.ckeditor.plugins.get( 'PendingActions' ).hasAny ) { - requestIdleCallback( () => { - pendingActions.fire( 'change:addAction', 'submit' ); - } ); + // Add submit pending action to disable actual submit button for preventing possibility + // clicking on that more than one time. + if ( !this.ckeditor.plugins.get( 'PendingActions' ).hasAny ) { + setTimeout( () => { + pendingActions.fire( 'change:addAction', 'submit' ); + } ); + } } } } ); diff --git a/tests/unit/editor/setupmixin.js b/tests/unit/editor/setupmixin.js index d5b00f5..e67fdf8 100644 --- a/tests/unit/editor/setupmixin.js +++ b/tests/unit/editor/setupmixin.js @@ -258,18 +258,18 @@ describe( 'Editor', () => { } ); it( 'should unlock the form during submit', () => { - const editor = new Editor( GitHubPage.appendRoot( { text: 'test' } ) ); + const editor = new Editor( GitHubPage.appendRoot( ) ); const textarea = editor.dom.root.querySelector( 'textarea' ); return editor.create() .then( () => { - expect( textarea.validity.customError ).to.be.false; + expect( textarea.validity.customError, '1' ).to.be.false; editor.setData( 'Changed data' ); - expect( textarea.validity.customError ).to.be.true; + expect( textarea.validity.customError, '2' ).to.be.true; editor.dom.getSubmitBtn().dispatchEvent( new Event( 'click' ) ); - expect( textarea.validity.customError ).to.be.false; + expect( textarea.validity.customError, '3' ).to.be.false; } ); } ); @@ -632,20 +632,142 @@ describe( 'Editor', () => { } ); } ); - it( 'should call "change:addAction" action', () => { + it( 'should call "change:addAction" event', () => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + + const editor = new Editor( GitHubPage.appendRoot( ) ); + + return editor.create() + .then( () => { + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + const spy = sinon.spy( pendingActions, 'add' ); + + pendingActions.fire( 'change:addAction', 'submit' ); + + expect( spy.callCount ).to.equals( 1 ); + } ); + } ); + + it( 'should call "change:removeAction" event', () => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + const editor = new Editor( GitHubPage.appendRoot( ) ); return editor.create() .then( () => { - const event = new Event( 'submit' ); - const spy = sinon.spy( event, 'change:addAction' ); + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + const spy = sinon.spy( pendingActions, 'remove' ); - const pendingActions = this.ckeditor.plugins.get( 'PendingActions' ); pendingActions.fire( 'change:addAction', 'submit' ); + pendingActions.fire( 'change:removeAction', 'submit' ); + expect( spy.callCount ).to.equals( 1 ); } ); } ); + + it( 'should not call "change:removeAction" event if the are no pending action', () => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + + const editor = new Editor( GitHubPage.appendRoot( ) ); + + return editor.create() + .then( () => { + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + const spy = sinon.spy( pendingActions, 'remove' ); + + pendingActions.fire( 'change:removeAction', 'submit' ); + + expect( spy.callCount ).to.equals( 0 ); + } ); + } ); + + it( 'should not remove pending action', done => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + const editor = new Editor( GitHubPage.appendRoot() ); + editor.dom.root.querySelector( 'textarea' ).defaultValue = 'Test'; + + editor.create() + .then( () => { + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + const spy = sinon.spy( pendingActions, 'remove' ); + + editor.setData( 'Changed data' ); + editor.dom.textarea.form.dispatchEvent( new Event( 'reset' ) ); + + setTimeout( () => { + expect( spy.callCount ).to.equals( 0 ); + done(); + }, 1 ); + } ); + } ); + + it( 'should remove pending action', done => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + const editor = new Editor( GitHubPage.appendRoot() ); + editor.dom.root.querySelector( 'textarea' ).defaultValue = 'Test'; + + editor.create() + .then( () => { + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + const spy = sinon.spy( pendingActions, 'remove' ); + + pendingActions.fire( 'change:addAction', 'submit' ); + editor.setData( 'Changed data' ); + editor.dom.textarea.form.dispatchEvent( new Event( 'reset' ) ); + + setTimeout( () => { + expect( spy.callCount ).to.equals( 1 ); + done(); + }, 1 ); + } ); + } ); + + it( 'should sync editors on submit.click', () => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + const editor = new Editor( GitHubPage.appendRoot() ); + + return editor.create() + .then( () => { + const spy = sinon.spy( editor, 'syncData' ); + editor.dom.getSubmitBtn().dispatchEvent( new Event( 'click' ) ); + + expect( spy.callCount ).to.equals( 1 ); + } ); + } ); + + it( 'should add new pending action', () => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + const editor = new Editor( GitHubPage.appendRoot() ); + + return editor.create() + .then( () => { + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + const spy = sinon.spy( editor, 'syncData' ); + + pendingActions.fire( 'change:addAction', 'submit' ); + editor.dom.getSubmitBtn().dispatchEvent( new Event( 'click' ) ); + + expect( spy.callCount ).to.equals( 1 ); + } ); + } ); + + it( 'should not add new pending action if any action exist', () => { + CKEditorConfig.get.returns( { plugins: [ QuoteSelection, PendingActions ] } ); + const editor = new Editor( GitHubPage.appendRoot() ); + + return editor.create() + .then( () => { + const pendingActions = editor.ckeditor.plugins.get( 'PendingActions' ); + pendingActions.fire( 'change:addAction', 'submit' ); + + const spy = sinon.spy( pendingActions, 'add' ); + + editor.dom.getSubmitBtn().dispatchEvent( new Event( 'click' ) ); + + expect( spy.callCount ).to.equals( 0 ); + } ); + } ); } ); } ); } ); From 1bee890ce0056d050f65e1345e730bf14cacbc1e Mon Sep 17 00:00:00 2001 From: illia sheremetov Date: Wed, 30 Nov 2022 16:35:48 +0100 Subject: [PATCH 3/3] reverse test changes --- tests/unit/editor/setupmixin.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/editor/setupmixin.js b/tests/unit/editor/setupmixin.js index e67fdf8..9bdf78e 100644 --- a/tests/unit/editor/setupmixin.js +++ b/tests/unit/editor/setupmixin.js @@ -258,18 +258,18 @@ describe( 'Editor', () => { } ); it( 'should unlock the form during submit', () => { - const editor = new Editor( GitHubPage.appendRoot( ) ); + const editor = new Editor( GitHubPage.appendRoot( { text: 'test' } ) ); const textarea = editor.dom.root.querySelector( 'textarea' ); return editor.create() .then( () => { - expect( textarea.validity.customError, '1' ).to.be.false; + expect( textarea.validity.customError ).to.be.false; editor.setData( 'Changed data' ); - expect( textarea.validity.customError, '2' ).to.be.true; + expect( textarea.validity.customError ).to.be.true; editor.dom.getSubmitBtn().dispatchEvent( new Event( 'click' ) ); - expect( textarea.validity.customError, '3' ).to.be.false; + expect( textarea.validity.customError ).to.be.false; } ); } );