Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 2e63e70

Browse files
authored
Merge pull request #292 from ckeditor/t/291
Other: `ToolbarView#fillFromConfig()` will warn when the factory does not provide a component. Closes #291. Closes ckeditor/ckeditor5#526.
2 parents 56d0df1 + 6b8be86 commit 2e63e70

File tree

4 files changed

+69
-8
lines changed

4 files changed

+69
-8
lines changed

src/componentfactory.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export default class ComponentFactory {
6161
* i.e. to set attribute values, create attribute bindings, etc.
6262
*/
6363
add( name, callback ) {
64-
if ( this._components.get( name ) ) {
64+
if ( this.has( name ) ) {
6565
/**
6666
* The item already exists in the component factory.
6767
*
@@ -83,9 +83,7 @@ export default class ComponentFactory {
8383
* @returns {module:ui/view~View} The instantiated component view.
8484
*/
8585
create( name ) {
86-
const component = this._components.get( name );
87-
88-
if ( !component ) {
86+
if ( !this.has( name ) ) {
8987
/**
9088
* There is no such UI component in the factory.
9189
*
@@ -97,6 +95,16 @@ export default class ComponentFactory {
9795
);
9896
}
9997

100-
return component( this.editor.locale );
98+
return this._components.get( name )( this.editor.locale );
99+
}
100+
101+
/**
102+
* Checks if a component of a given name is registered in the factory.
103+
*
104+
* @param {String} name The name of the component.
105+
* @returns {Boolean}
106+
*/
107+
has( name ) {
108+
return this._components.has( name );
101109
}
102110
}

src/toolbar/toolbarview.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import FocusCycler from '../focuscycler';
1414
import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
1515
import ToolbarSeparatorView from './toolbarseparatorview';
1616
import preventDefault from '../bindings/preventdefault.js';
17+
import log from '@ckeditor/ckeditor5-utils/src/log';
1718

1819
/**
1920
* The toolbar view class.
@@ -126,9 +127,29 @@ export default class ToolbarView extends View {
126127
}
127128

128129
config.map( name => {
129-
const component = name == '|' ? new ToolbarSeparatorView() : factory.create( name );
130-
131-
this.items.add( component );
130+
if ( name == '|' ) {
131+
this.items.add( new ToolbarSeparatorView() );
132+
} else if ( factory.has( name ) ) {
133+
this.items.add( factory.create( name ) );
134+
} else {
135+
/**
136+
* There was a problem processing the configuration of the toolbar. The item with the given
137+
* name does not exist so it was omitted when rendering the toolbar.
138+
*
139+
* This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed
140+
* to provide a toolbar item has not been loaded or there is a typo in the configuration.
141+
*
142+
* Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration
143+
* is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.
144+
*
145+
* @error toolbarview-item-unavailable
146+
* @param {String} name The name of the component.
147+
*/
148+
log.warn(
149+
'toolbarview-item-unavailable: The requested toolbar item is unavailable.',
150+
{ name }
151+
);
152+
}
132153
} );
133154
}
134155
}

tests/componentfactory.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,15 @@ describe( 'ComponentFactory', () => {
7070
expect( instance.locale ).to.equal( locale );
7171
} );
7272
} );
73+
74+
describe( 'has()', () => {
75+
it( 'checks if the factory contains a component of a given name', () => {
76+
factory.add( 'foo', () => {} );
77+
factory.add( 'bar', () => {} );
78+
79+
expect( factory.has( 'foo' ) ).to.be.true;
80+
expect( factory.has( 'bar' ) ).to.be.true;
81+
expect( factory.has( 'baz' ) ).to.be.false;
82+
} );
83+
} );
7384
} );

tests/toolbar/toolbarview.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
1313
import FocusCycler from '../../src/focuscycler';
1414
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
1515
import ViewCollection from '../../src/viewcollection';
16+
import log from '@ckeditor/ckeditor5-utils/src/log';
1617
import View from '../../src/view';
18+
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
1719

1820
describe( 'ToolbarView', () => {
1921
let locale, view;
2022

23+
testUtils.createSinonSandbox();
24+
2125
beforeEach( () => {
2226
locale = {};
2327
view = new ToolbarView( locale );
@@ -247,6 +251,23 @@ describe( 'ToolbarView', () => {
247251
expect( items.get( 2 ) ).to.be.instanceOf( ToolbarSeparatorView );
248252
expect( items.get( 3 ).name ).to.equal( 'foo' );
249253
} );
254+
255+
it( 'warns if there is no such component in the factory', () => {
256+
const items = view.items;
257+
testUtils.sinon.stub( log, 'warn' );
258+
259+
view.fillFromConfig( [ 'foo', 'bar', 'baz' ], factory );
260+
261+
expect( items ).to.have.length( 2 );
262+
expect( items.get( 0 ).name ).to.equal( 'foo' );
263+
expect( items.get( 1 ).name ).to.equal( 'bar' );
264+
265+
sinon.assert.calledOnce( log.warn );
266+
sinon.assert.calledWithExactly( log.warn,
267+
sinon.match( /^toolbarview-item-unavailable/ ),
268+
{ name: 'baz' }
269+
);
270+
} );
250271
} );
251272
} );
252273

0 commit comments

Comments
 (0)