-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
/
componentfactory.js
146 lines (135 loc) · 4.27 KB
/
componentfactory.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module ui/componentfactory
*/
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
/**
* A helper class implementing the UI component ({@link module:ui/view~View view}) factory.
*
* It allows functions producing specific UI components to be registered under their unique names
* in the factory. A registered component can be then instantiated by providing its name.
* Note that names are case insensitive.
*
* // The editor provides localization tools for the factory.
* const factory = new ComponentFactory( editor );
*
* factory.add( 'foo', locale => new FooView( locale ) );
* factory.add( 'bar', locale => new BarView( locale ) );
*
* // An instance of FooView.
* const fooInstance = factory.create( 'foo' );
*
* // Names are case insensitive so this is also allowed:
* const barInstance = factory.create( 'Bar' );
*
* The {@link module:core/editor/editor~Editor#locale editor locale} is passed to the factory
* function when {@link module:ui/componentfactory~ComponentFactory#create} is called.
*/
export default class ComponentFactory {
/**
* Creates an instance of the factory.
*
* @constructor
* @param {module:core/editor/editor~Editor} editor The editor instance.
*/
constructor( editor ) {
/**
* The editor instance that the factory belongs to.
*
* @readonly
* @member {module:core/editor/editor~Editor}
*/
this.editor = editor;
/**
* Registered component factories.
*
* @private
* @member {Map}
*/
this._components = new Map();
}
/**
* Returns an iterator of registered component names. Names are returned in lower case.
*
* @returns {Iterable.<String>}
*/
* names() {
for ( const value of this._components.values() ) {
yield value.originalName;
}
}
/**
* Registers a component factory function that will be used by the
* {@link #create create} method and called with the
* {@link module:core/editor/editor~Editor#locale editor locale} as an argument,
* allowing localization of the {@link module:ui/view~View view}.
*
* @param {String} name The name of the component.
* @param {Function} callback The callback that returns the component.
*/
add( name, callback ) {
if ( this.has( name ) ) {
/**
* The item already exists in the component factory.
*
* @error componentfactory-item-exists
* @param {String} name The name of the component.
*/
throw new CKEditorError(
'componentfactory-item-exists: The item already exists in the component factory.',
this,
{ name }
);
}
this._components.set( getNormalized( name ), { callback, originalName: name } );
}
/**
* Creates an instance of a component registered in the factory under a specific name.
*
* When called, the {@link module:core/editor/editor~Editor#locale editor locale} is passed to
* the previously {@link #add added} factory function, allowing localization of the
* {@link module:ui/view~View view}.
*
* @param {String} name The name of the component.
* @returns {module:ui/view~View} The instantiated component view.
*/
create( name ) {
if ( !this.has( name ) ) {
/**
* The required component is not registered in the component factory. Please make sure
* the provided name is correct and the component has been correctly
* {@link #add added} to the factory.
*
* @error componentfactory-item-missing
* @param {String} name The name of the missing component.
*/
throw new CKEditorError(
'componentfactory-item-missing: The required component is not registered in the factory.',
this,
{ name }
);
}
return this._components.get( getNormalized( name ) ).callback( this.editor.locale );
}
/**
* Checks if a component of a given name is registered in the factory.
*
* @param {String} name The name of the component.
* @returns {Boolean}
*/
has( name ) {
return this._components.has( getNormalized( name ) );
}
}
//
// Ensures that the component name used as the key in the internal map is in lower case.
//
// @private
// @param {String} name
// @returns {String}
function getNormalized( name ) {
return String( name ).toLowerCase();
}