This repository has been archived by the owner on Jun 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
editorui.js
193 lines (169 loc) · 6.01 KB
/
editorui.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* @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 core/editor/editorui
*/
/* globals console */
import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';
import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
import mix from '@ckeditor/ckeditor5-utils/src/mix';
/**
* A class providing the minimal interface that is required to successfully bootstrap any editor UI.
*
* @mixes module:utils/emittermixin~EmitterMixin
*/
export default class EditorUI {
/**
* Creates an instance of the editor UI class.
*
* @param {module:core/editor/editor~Editor} editor The editor instance.
*/
constructor( editor ) {
/**
* The editor that the UI belongs to.
*
* @readonly
* @member {module:core/editor/editor~Editor} #editor
*/
this.editor = editor;
/**
* An instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins
* to register factories of specific UI components.
*
* @readonly
* @member {module:ui/componentfactory~ComponentFactory} #componentFactory
*/
this.componentFactory = new ComponentFactory( editor );
/**
* Stores the information about the editor UI focus and propagates it so various plugins and components
* are unified as a focus group.
*
* @readonly
* @member {module:utils/focustracker~FocusTracker} #focusTracker
*/
this.focusTracker = new FocusTracker();
/**
* Stores all editable elements used by the editor instance.
*
* @private
* @member {Map.<String,HTMLElement>}
*/
this._editableElementsMap = new Map();
// Informs UI components that should be refreshed after layout change.
this.listenTo( editor.editing.view.document, 'layoutChanged', () => this.update() );
}
/**
* The main (outermost) DOM element of the editor UI.
*
* For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `<div>` which
* wraps the editable element and the toolbar. In {@link module:editor-inline/inlineeditor~InlineEditor}
* it is the editable element itself (as there is no other wrapper). However, in
* {@link module:editor-decoupled/decouplededitor~DecoupledEditor} it is set to `null` because this editor does not
* come with a single "main" HTML element (its editable element and toolbar are separate).
*
* This property can be understood as a shorthand for retrieving the element that a specific editor integration
* considers to be its main DOM element.
*
* @readonly
* @member {HTMLElement|null} #element
*/
get element() {
return null;
}
/**
* Fires the {@link module:core/editor/editorui~EditorUI#event:update `update`} event.
*
* This method should be called when the editor UI (e.g. positions of its balloons) needs to be updated due to
* some environmental change which CKEditor 5 is not aware of (e.g. resize of a container in which it is used).
*/
update() {
this.fire( 'update' );
}
/**
* Destroys the UI.
*/
destroy() {
this.stopListening();
this.focusTracker.destroy();
// Clean–up the references to the CKEditor instance stored in the native editable DOM elements.
for ( const domElement of this._editableElementsMap.values() ) {
domElement.ckeditorInstance = null;
}
this._editableElementsMap = new Map();
}
/**
* Store the native DOM editable element used by the editor under
* a unique name.
*
* @param {String} rootName The unique name of the editable element.
* @param {HTMLElement} domElement The native DOM editable element.
*/
setEditableElement( rootName, domElement ) {
this._editableElementsMap.set( rootName, domElement );
// Put a reference to the CKEditor instance in the editable native DOM element.
// It helps 3rd–party software (browser extensions, other libraries) access and recognize
// CKEditor 5 instances (editing roots) and use their API (there is no global editor
// instance registry).
if ( !domElement.ckeditorInstance ) {
domElement.ckeditorInstance = this.editor;
}
}
/**
* Returns the editable editor element with the given name or null if editable does not exist.
*
* @param {String} [rootName=main] The editable name.
* @returns {HTMLElement|undefined}
*/
getEditableElement( rootName = 'main' ) {
return this._editableElementsMap.get( rootName );
}
/**
* Returns array of names of all editor editable elements.
*
* @returns {Iterable.<String>}
*/
getEditableElementsNames() {
return this._editableElementsMap.keys();
}
/**
* Stores all editable elements used by the editor instance.
*
* @protected
* @deprecated
* @member {Map.<String,HTMLElement>}
*/
get _editableElements() {
/**
* The {@link module:core/editor/editorui~EditorUI#_editableElements `EditorUI#_editableElements`} property has been
* deprecated and will be removed in the near future. Please use {@link #setEditableElement `setEditableElement()`} and
* {@link #getEditableElement `getEditableElement()`} methods instead.
*
* @error editor-ui-deprecated-editable-elements
* @param {module:core/editor/editorui~EditorUI} editorUI Editor UI instance the deprecated property belongs to.
*/
console.warn(
'editor-ui-deprecated-editable-elements: ' +
'The EditorUI#_editableElements property has been deprecated and will be removed in the near future.',
{ editorUI: this } );
return this._editableElementsMap;
}
/**
* Fired when the editor UI is ready.
*
* Fired before {@link module:engine/controller/datacontroller~DataController#event:ready}.
*
* @event ready
*/
/**
* Fired whenever the UI (all related components) should be refreshed.
*
* **Note:**: The event is fired after each {@link module:engine/view/document~Document#event:layoutChanged}.
* It can also be fired manually via the {@link module:core/editor/editorui~EditorUI#update} method.
*
* @event update
*/
}
mix( EditorUI, EmitterMixin );