From 9ce7e9ac99b74a97028804da71333e5843e7074f Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Fri, 20 Oct 2017 13:29:49 +0200 Subject: [PATCH] Aligned the Image package to the View#render API. Internal: Aligned the UI to the latest API of the framework (see ckeditor/ckeditor5-ui#262). --- src/imagetextalternative.js | 3 ++ .../ui/textalternativeformview.js | 27 +++++----- src/imagetoolbar.js | 3 +- .../ui/textalternativeformview.js | 49 ++++++++++--------- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/imagetextalternative.js b/src/imagetextalternative.js index 7481e18b..0d377757 100644 --- a/src/imagetextalternative.js +++ b/src/imagetextalternative.js @@ -102,6 +102,9 @@ export default class ImageTextAlternative extends Plugin { */ this._form = new TextAlternativeFormView( editor.locale ); + // Render the form so its #element is available for clickOutsideHandler. + this._form.render(); + this.listenTo( this._form, 'submit', () => { editor.execute( 'imageTextAlternative', { newValue: this._form.labeledInput.inputView.element.value diff --git a/src/imagetextalternative/ui/textalternativeformview.js b/src/imagetextalternative/ui/textalternativeformview.js index 542f4dc1..78a467cf 100644 --- a/src/imagetextalternative/ui/textalternativeformview.js +++ b/src/imagetextalternative/ui/textalternativeformview.js @@ -8,7 +8,6 @@ */ import View from '@ckeditor/ckeditor5-ui/src/view'; -import Template from '@ckeditor/ckeditor5-ui/src/template'; import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; @@ -101,7 +100,7 @@ export default class TextAlternativeFormView extends View { } } ); - Template.extend( this.saveButtonView.template, { + this.saveButtonView.extendTemplate( { attributes: { class: [ 'ck-button-action' @@ -109,7 +108,7 @@ export default class TextAlternativeFormView extends View { } } ); - this.template = new Template( { + this.setTemplate( { tag: 'form', attributes: { @@ -139,10 +138,17 @@ export default class TextAlternativeFormView extends View { } ] } ); + } - submitHandler( { - view: this - } ); + /** + * @inheritDoc + */ + render() { + super.render(); + + this.keystrokes.listenTo( this.element ); + + submitHandler( { view: this } ); [ this.labeledInput, this.saveButtonView, this.cancelButtonView ] .forEach( v => { @@ -154,15 +160,6 @@ export default class TextAlternativeFormView extends View { } ); } - /** - * @inheritDoc - */ - init() { - super.init(); - - this.keystrokes.listenTo( this.element ); - } - /** * Creates the button view. * diff --git a/src/imagetoolbar.js b/src/imagetoolbar.js index 98b8062e..6eccd1f9 100644 --- a/src/imagetoolbar.js +++ b/src/imagetoolbar.js @@ -7,7 +7,6 @@ * @module image/imagetoolbar */ -import Template from '@ckeditor/ckeditor5-ui/src/template'; import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview'; import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon'; @@ -71,7 +70,7 @@ export default class ImageToolbar extends Plugin { this._toolbar = new ToolbarView(); // Add CSS class to the toolbar. - Template.extend( this._toolbar.template, { + this._toolbar.extendTemplate( { attributes: { class: 'ck-editor-toolbar' } diff --git a/tests/imagetextalternative/ui/textalternativeformview.js b/tests/imagetextalternative/ui/textalternativeformview.js index e6d9b773..f4595c7a 100644 --- a/tests/imagetextalternative/ui/textalternativeformview.js +++ b/tests/imagetextalternative/ui/textalternativeformview.js @@ -21,12 +21,12 @@ describe( 'TextAlternativeFormView', () => { beforeEach( () => { view = new TextAlternativeFormView( { t: () => {} } ); - - view.init(); } ); describe( 'constructor()', () => { it( 'should create element from template', () => { + view.render(); + expect( view.element.classList.contains( 'cke-text-alternative-form' ) ).to.be.true; expect( view.element.getAttribute( 'tabindex' ) ).to.equal( '-1' ); } ); @@ -45,6 +45,14 @@ describe( 'TextAlternativeFormView', () => { expect( view.cancelButtonView ).to.be.instanceOf( View ); } ); + it( 'should create #_focusCycler instance', () => { + expect( view._focusCycler ).to.be.instanceOf( FocusCycler ); + } ); + + it( 'should create #_focusables view collection', () => { + expect( view._focusables ).to.be.instanceOf( ViewCollection ); + } ); + it( 'should fire `cancel` event on cancelButtonView#execute', () => { const spy = sinon.spy(); view.on( 'cancel', spy ); @@ -52,17 +60,21 @@ describe( 'TextAlternativeFormView', () => { sinon.assert.calledOnce( spy ); } ); + } ); - describe( 'focus cycling and management', () => { - it( 'should create #_focusCycler instance', () => { - expect( view._focusCycler ).to.be.instanceOf( FocusCycler ); - } ); + describe( 'render()', () => { + it( 'starts listening for #keystrokes coming from #element', () => { + const spy = sinon.spy( view.keystrokes, 'listenTo' ); - it( 'should create #_focusables view collection', () => { - expect( view._focusables ).to.be.instanceOf( ViewCollection ); - } ); + view.render(); + sinon.assert.calledOnce( spy ); + sinon.assert.calledWithExactly( spy, view.element ); + } ); + describe( 'focus cycling and management', () => { it( 'should register child views in #_focusables', () => { + view.render(); + expect( view._focusables.map( f => f ) ).to.have.members( [ view.labeledInput, view.saveButtonView, @@ -73,7 +85,7 @@ describe( 'TextAlternativeFormView', () => { it( 'should register child views\' #element in #focusTracker', () => { const spy = testUtils.sinon.spy( FocusTracker.prototype, 'add' ); - view = new TextAlternativeFormView( { t: () => {} } ); + view.render(); sinon.assert.calledWithExactly( spy.getCall( 0 ), view.labeledInput.element ); sinon.assert.calledWithExactly( spy.getCall( 1 ), view.saveButtonView.element ); @@ -81,6 +93,10 @@ describe( 'TextAlternativeFormView', () => { } ); describe( 'activates keyboard navigation in the form', () => { + beforeEach( () => { + view.render(); + } ); + it( 'so "tab" focuses the next focusable item', () => { const keyEvtData = { keyCode: keyCodes.tab, @@ -123,23 +139,12 @@ describe( 'TextAlternativeFormView', () => { } ); } ); - describe( 'init()', () => { - it( 'starts listening for #keystrokes coming from #element', () => { - view = new TextAlternativeFormView( { t: () => {} } ); - - const spy = sinon.spy( view.keystrokes, 'listenTo' ); - - view.init(); - sinon.assert.calledOnce( spy ); - sinon.assert.calledWithExactly( spy, view.element ); - } ); - } ); - describe( 'DOM bindings', () => { describe( 'submit event', () => { it( 'should trigger submit event', () => { const spy = sinon.spy(); + view.render(); view.on( 'submit', spy ); view.element.dispatchEvent( new Event( 'submit' ) );