From ea1b4d73affbd833cbfba37ed55c8ce7bfcc2a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Thu, 10 Mar 2022 13:13:54 +0100 Subject: [PATCH 1/4] Updated insert command & UI. --- src/commands/insertMermaidCommand.js | 7 ++++--- src/mermaidui.js | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/commands/insertMermaidCommand.js b/src/commands/insertMermaidCommand.js index bc2552812..65382d493 100644 --- a/src/commands/insertMermaidCommand.js +++ b/src/commands/insertMermaidCommand.js @@ -36,16 +36,17 @@ export default class InsertMermaidCommand extends Command { execute() { const editor = this.editor; const model = editor.model; + let mermaidItem; model.change( writer => { - const item = writer.createElement( 'mermaid', { + mermaidItem = writer.createElement( 'mermaid', { displayMode: 'split', source: MOCK_MERMAID_MARKUP } ); - model.insertContent( item ); + model.insertContent( mermaidItem ); } ); - editor.editing.view.focus(); + return mermaidItem; } } diff --git a/src/mermaidui.js b/src/mermaidui.js index 6a9696d71..09d29be1d 100644 --- a/src/mermaidui.js +++ b/src/mermaidui.js @@ -11,7 +11,7 @@ import splitModeIcon from '../theme/icons/split-mode.svg'; import sourceModeIcon from '../theme/icons/source-mode.svg'; import infoIcon from '../theme/icons/info.svg'; -/* global window */ +/* global window, document */ export default class MermaidUI extends Plugin { /** @@ -51,6 +51,7 @@ export default class MermaidUI extends Plugin { _addInsertMermaidButton() { const editor = this.editor; const t = editor.t; + const view = editor.editing.view; editor.ui.componentFactory.add( 'mermaid', locale => { const buttonView = new ButtonView( locale ); @@ -66,9 +67,16 @@ export default class MermaidUI extends Plugin { // Execute the command when the button is clicked. command.listenTo( buttonView, 'execute', () => { - editor.execute( 'insertMermaidCommand' ); - editor.editing.view.scrollToTheSelection(); - editor.editing.view.focus(); + const mermaidItem = editor.execute( 'insertMermaidCommand' ); + const mermaidItemViewElement = editor.editing.mapper.toViewElement( mermaidItem ); + const mermaidItemDomElement = view.domConverter.viewToDom( mermaidItemViewElement, document ); + + view.scrollToTheSelection(); + view.focus(); + + if ( mermaidItemDomElement ) { + mermaidItemDomElement.querySelector( '.ck-mermaid__editing-view' ).focus(); + } } ); return buttonView; From 88d3d65c30b14529f5f061e7285929acaee267af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Thu, 10 Mar 2022 16:15:22 +0100 Subject: [PATCH 2/4] Test coverage added. --- src/mermaidui.js | 6 +++++- tests/mermaidui.js | 28 +++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/mermaidui.js b/src/mermaidui.js index 09d29be1d..16b0c1b8d 100644 --- a/src/mermaidui.js +++ b/src/mermaidui.js @@ -69,7 +69,11 @@ export default class MermaidUI extends Plugin { command.listenTo( buttonView, 'execute', () => { const mermaidItem = editor.execute( 'insertMermaidCommand' ); const mermaidItemViewElement = editor.editing.mapper.toViewElement( mermaidItem ); - const mermaidItemDomElement = view.domConverter.viewToDom( mermaidItemViewElement, document ); + let mermaidItemDomElement; + + if ( mermaidItemViewElement ) { + mermaidItemDomElement = view.domConverter.viewToDom( mermaidItemViewElement, document ); + } view.scrollToTheSelection(); view.focus(); diff --git a/tests/mermaidui.js b/tests/mermaidui.js index 5b3077853..53d424236 100644 --- a/tests/mermaidui.js +++ b/tests/mermaidui.js @@ -1,4 +1,6 @@ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; +import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import { Paragraph } from '@ckeditor/ckeditor5-paragraph'; import Mermaid from '../src/mermaid'; import MermaidUI from '../src/mermaidui'; @@ -19,7 +21,8 @@ describe( 'MermaidUI', () => { editor = await ClassicEditor.create( domElement, { plugins: [ - Mermaid + Mermaid, + Paragraph ] } ); } ); @@ -61,6 +64,29 @@ describe( 'MermaidUI', () => { } ); } } ); + + it( 'should set focus inside textarea of a newly created mermaid', () => { + const button = editor.ui.componentFactory.create( 'mermaid' ); + + button.fire( 'execute' ); + + expect( document.activeElement.tagName ).to.equal( 'TEXTAREA' ); + } ); + + it( 'should not crash if the button is fired inside model.change()', () => { + const button = editor.ui.componentFactory.create( 'mermaid' ); + + setModelData( editor.model, + '[foo]' + ); + + editor.model.change( () => { + button.fire( 'execute' ); + } ); + // As the conversion is to be executed after the model.change(), we don't have access to the fully prepared view and + // despite that, we should still successfully add mermaid widget to the editor, not requiring the selection change + // to the inside of the nonexisting textarea element. + } ); } ); } ); From 9f843e8a762785e59760a547f792b8f6cf7bf3f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Thu, 10 Mar 2022 16:19:50 +0100 Subject: [PATCH 3/4] Removed unnecessary code from the test. --- tests/mermaidui.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/mermaidui.js b/tests/mermaidui.js index 53d424236..957d9945b 100644 --- a/tests/mermaidui.js +++ b/tests/mermaidui.js @@ -1,6 +1,5 @@ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; -import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; -import { Paragraph } from '@ckeditor/ckeditor5-paragraph'; +import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import Mermaid from '../src/mermaid'; import MermaidUI from '../src/mermaidui'; @@ -21,8 +20,7 @@ describe( 'MermaidUI', () => { editor = await ClassicEditor.create( domElement, { plugins: [ - Mermaid, - Paragraph + Mermaid ] } ); } ); @@ -76,9 +74,7 @@ describe( 'MermaidUI', () => { it( 'should not crash if the button is fired inside model.change()', () => { const button = editor.ui.componentFactory.create( 'mermaid' ); - setModelData( editor.model, - '[foo]' - ); + setModelData( editor.model, '[]' ); editor.model.change( () => { button.fire( 'execute' ); From ac93f2dc3680a19fbe8706d44fceddbc39d574ac Mon Sep 17 00:00:00 2001 From: Marek Lewandowski Date: Mon, 14 Mar 2022 08:33:19 +0100 Subject: [PATCH 4/4] Minor code simplification. --- src/mermaidui.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mermaidui.js b/src/mermaidui.js index 16b0c1b8d..9f3f3c2ef 100644 --- a/src/mermaidui.js +++ b/src/mermaidui.js @@ -69,17 +69,16 @@ export default class MermaidUI extends Plugin { command.listenTo( buttonView, 'execute', () => { const mermaidItem = editor.execute( 'insertMermaidCommand' ); const mermaidItemViewElement = editor.editing.mapper.toViewElement( mermaidItem ); - let mermaidItemDomElement; - - if ( mermaidItemViewElement ) { - mermaidItemDomElement = view.domConverter.viewToDom( mermaidItemViewElement, document ); - } view.scrollToTheSelection(); view.focus(); - if ( mermaidItemDomElement ) { - mermaidItemDomElement.querySelector( '.ck-mermaid__editing-view' ).focus(); + if ( mermaidItemViewElement ) { + const mermaidItemDomElement = view.domConverter.viewToDom( mermaidItemViewElement, document ); + + if ( mermaidItemDomElement ) { + mermaidItemDomElement.querySelector( '.ck-mermaid__editing-view' ).focus(); + } } } );