@ckeditor/ckeditor5-editor-inline 41.4.1 → 42.0.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -9,12 +9,18 @@ The inline editor implementation for CKEditor 5.
9
9
 
10
10
  This package exposes the [`InlineEditor`](https://ckeditor.com/docs/ckeditor5/latest/api/module_editor-inline_inlineeditor-InlineEditor.html) class. Follow there to learn more about this type of editor and how to initialize it.
11
11
 
12
- This package contains the source version of the inline editor. This kind of editor implementation is also available as a ready-to-use [inline build](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline). Read more about [CKEditor 5 predefined builds](https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/alternative-setups/predefined-builds.html) in the CKEditor 5 documentation.
12
+ This package contains the source version of the inline editor. This kind of editor implementation is also available as a ready-to-use [inline build](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-inline). Read more about [CKEditor 5 predefined builds](https://ckeditor.com/docs/ckeditor5/latest/getting-started/legacy/advanced/alternative-setups/predefined-builds.html) in the CKEditor 5 documentation.
13
13
 
14
14
  ## Documentation
15
15
 
16
16
  See the [`@ckeditor/ckeditor5-editor-inline` package](https://ckeditor.com/docs/ckeditor5/latest/api/editor-inline.html) page in [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
17
17
 
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install ckeditor5
22
+ ```
23
+
18
24
  ## License
19
25
 
20
26
  Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md.
4
- */(()=>{var t={782:(t,e,o)=>{t.exports=o(237)("./src/core.js")},783:(t,e,o)=>{t.exports=o(237)("./src/engine.js")},311:(t,e,o)=>{t.exports=o(237)("./src/ui.js")},584:(t,e,o)=>{t.exports=o(237)("./src/utils.js")},602:(t,e,o)=>{t.exports=o(237)("./src/watchdog.js")},237:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function o(i){var r=e[i];if(void 0!==r)return r.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,o),n.exports}o.d=(t,e)=>{for(var i in e)o.o(e,i)&&!o.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var i={};(()=>{"use strict";o.r(i),o.d(i,{InlineEditor:()=>W});var t=o(782),e=o(584),r=o(602),n=o(311),s=o(783);class l extends n.EditorUI{constructor(t,e){super(t),this.view=e,this._toolbarConfig=(0,n.normalizeToolbarConfig)(t.config.get("toolbar"))}get element(){return this.view.editable.element}init(){const t=this.editor,e=this.view,o=t.editing.view,i=e.editable,r=o.document.getRoot();i.name=r.rootName,e.render();const n=i.element;this.setEditableElement(i.name,n),i.bind("isFocused").to(this.focusTracker),o.attachDomRoot(n),this._initPlaceholder(),this._initToolbar(),this.fire("ready")}destroy(){super.destroy();const t=this.view;this.editor.editing.view.detachDomRoot(t.editable.name),t.destroy()}_initToolbar(){const t=this.editor,e=this.view,o=e.editable.element,i=e.toolbar;e.panel.bind("isVisible").to(this.focusTracker,"isFocused"),e.bind("viewportTopOffset").to(this,"viewportOffset",(({top:t})=>t||0)),e.listenTo(t.ui,"update",(()=>{e.panel.isVisible&&e.panel.pin({target:o,positions:e.panelPositions})})),i.fillFromConfig(this._toolbarConfig,this.componentFactory),this.addToolbar(i)}_initPlaceholder(){const t=this.editor,e=t.editing.view,o=e.document.getRoot(),i=t.config.get("placeholder");if(i){const t="string"==typeof i?i:i[o.rootName];t&&(o.placeholder=t)}(0,s.enablePlaceholder)({view:e,element:o,isDirectHost:!1,keepOnFocus:!0})}}const a=(0,e.toUnit)("px");class c extends n.EditorUIView{constructor(t,e,o,i={}){super(t);const r=t.t;this.toolbar=new n.ToolbarView(t,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull,isFloating:!0}),this.set("viewportTopOffset",0),this.panel=new n.BalloonPanelView(t),this.panelPositions=this._getPanelPositions(),this.panel.extendTemplate({attributes:{class:"ck-toolbar-container"}}),this.editable=new n.InlineEditableUIView(t,e,o,{label:t=>r("Rich Text Editor. Editing area: %0",t.name)}),this._resizeObserver=null}render(){super.render(),this.body.add(this.panel),this.registerChild(this.editable),this.panel.content.add(this.toolbar);if(this.toolbar.options.shouldGroupWhenFull){const t=this.editable.element;this._resizeObserver=new e.ResizeObserver(t,(()=>{this.toolbar.maxWidth=a(new e.Rect(t).width)}))}}destroy(){super.destroy(),this._resizeObserver&&this._resizeObserver.destroy()}_getPanelPositionTop(t,e){let o;return o=t.top>e.height+this.viewportTopOffset?t.top-e.height:t.bottom>e.height+this.viewportTopOffset+50?this.viewportTopOffset:t.bottom,o}_getPanelPositions(){const t=[(t,e)=>({top:this._getPanelPositionTop(t,e),left:t.left,name:"toolbar_west",config:{withArrow:!1}}),(t,e)=>({top:this._getPanelPositionTop(t,e),left:t.left+t.width-e.width,name:"toolbar_east",config:{withArrow:!1}})];return"ltr"===this.locale.uiLanguageDirection?t:t.reverse()}}const d=function(t){return null!=t&&"object"==typeof t};const h="object"==typeof global&&global&&global.Object===Object&&global;var u="object"==typeof self&&self&&self.Object===Object&&self;const p=(h||u||Function("return this")()).Symbol;var b=Object.prototype,f=b.hasOwnProperty,g=b.toString,w=p?p.toStringTag:void 0;const v=function(t){var e=f.call(t,w),o=t[w];try{t[w]=void 0;var i=!0}catch(t){}var r=g.call(t);return i&&(e?t[w]=o:delete t[w]),r};var m=Object.prototype.toString;const y=function(t){return m.call(t)};var O=p?p.toStringTag:void 0;const T=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":O&&O in Object(t)?v(t):y(t)};const j=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var E=Function.prototype,P=Object.prototype,x=E.toString,_=P.hasOwnProperty,F=x.call(Object);const C=function(t){if(!d(t)||"[object Object]"!=T(t))return!1;var e=j(t);if(null===e)return!0;var o=_.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&x.call(o)==F};const S=function(t){return d(t)&&1===t.nodeType&&!C(t)};class D extends((0,t.ElementApiMixin)(t.Editor)){constructor(o,i={}){if(!R(o)&&void 0!==i.initialData)throw new e.CKEditorError("editor-create-initial-data",null);super(i),void 0===this.config.get("initialData")&&this.config.set("initialData",function(t){return R(t)?(0,e.getDataFromElement)(t):t}(o)),this.model.document.createRoot(),R(o)&&(this.sourceElement=o,(0,t.secureSourceElement)(this,o));const r=!this.config.get("toolbar.shouldNotGroupWhenFull"),n=new c(this.locale,this.editing.view,this.sourceElement,{shouldToolbarGroupWhenFull:r});this.ui=new l(this,n),(0,t.attachToForm)(this)}destroy(){const t=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(t)}))}static create(t,o={}){return new Promise((i=>{if(R(t)&&"TEXTAREA"===t.tagName)throw new e.CKEditorError("editor-wrong-element",null);const r=new this(t,o);i(r.initPlugins().then((()=>r.ui.init())).then((()=>r.data.init(r.config.get("initialData")))).then((()=>r.fire("ready"))).then((()=>r)))}))}}D.Context=t.Context,D.EditorWatchdog=r.EditorWatchdog,D.ContextWatchdog=r.ContextWatchdog;const W=D;function R(t){return S(t)}})(),(window.CKEditor5=window.CKEditor5||{}).editorInline=i})();
4
+ */(()=>{var t={782:(t,e,o)=>{t.exports=o(237)("./src/core.js")},783:(t,e,o)=>{t.exports=o(237)("./src/engine.js")},311:(t,e,o)=>{t.exports=o(237)("./src/ui.js")},584:(t,e,o)=>{t.exports=o(237)("./src/utils.js")},237:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function o(i){var r=e[i];if(void 0!==r)return r.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,o),n.exports}o.d=(t,e)=>{for(var i in e)o.o(e,i)&&!o.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var i={};(()=>{"use strict";o.r(i),o.d(i,{InlineEditor:()=>C});var t=o(782),e=o(584),r=o(311),n=o(783);class s extends r.EditorUI{constructor(t,e){super(t),this.view=e,this._toolbarConfig=(0,r.normalizeToolbarConfig)(t.config.get("toolbar"))}get element(){return this.view.editable.element}init(){const t=this.editor,e=this.view,o=t.editing.view,i=e.editable,r=o.document.getRoot();i.name=r.rootName,e.render();const n=i.element;this.setEditableElement(i.name,n),i.bind("isFocused").to(this.focusTracker),o.attachDomRoot(n),this._initPlaceholder(),this._initToolbar(),this.fire("ready")}destroy(){super.destroy();const t=this.view;this.editor.editing.view.detachDomRoot(t.editable.name),t.destroy()}_initToolbar(){const t=this.editor,e=this.view,o=e.editable.element,i=e.toolbar;e.panel.bind("isVisible").to(this.focusTracker,"isFocused"),e.bind("viewportTopOffset").to(this,"viewportOffset",(({top:t})=>t||0)),e.listenTo(t.ui,"update",(()=>{e.panel.isVisible&&e.panel.pin({target:o,positions:e.panelPositions})})),i.fillFromConfig(this._toolbarConfig,this.componentFactory),this.addToolbar(i)}_initPlaceholder(){const t=this.editor,e=t.editing.view,o=e.document.getRoot(),i=t.config.get("placeholder");if(i){const t="string"==typeof i?i:i[o.rootName];t&&(o.placeholder=t)}(0,n.enablePlaceholder)({view:e,element:o,isDirectHost:!1,keepOnFocus:!0})}}const l=(0,e.toUnit)("px");class a extends r.EditorUIView{constructor(t,e,o,i={}){super(t);const n=t.t;this.toolbar=new r.ToolbarView(t,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull,isFloating:!0}),this.set("viewportTopOffset",0),this.panel=new r.BalloonPanelView(t),this.panelPositions=this._getPanelPositions(),this.panel.extendTemplate({attributes:{class:"ck-toolbar-container"}}),this.editable=new r.InlineEditableUIView(t,e,o,{label:t=>n("Rich Text Editor. Editing area: %0",t.name)}),this._resizeObserver=null}render(){super.render(),this.body.add(this.panel),this.registerChild(this.editable),this.panel.content.add(this.toolbar);if(this.toolbar.options.shouldGroupWhenFull){const t=this.editable.element;this._resizeObserver=new e.ResizeObserver(t,(()=>{this.toolbar.maxWidth=l(new e.Rect(t).width)}))}}destroy(){super.destroy(),this._resizeObserver&&this._resizeObserver.destroy()}_getPanelPositionTop(t,e){let o;return o=t.top>e.height+this.viewportTopOffset?t.top-e.height:t.bottom>e.height+this.viewportTopOffset+50?this.viewportTopOffset:t.bottom,o}_getPanelPositions(){const t=[(t,e)=>({top:this._getPanelPositionTop(t,e),left:t.left,name:"toolbar_west",config:{withArrow:!1}}),(t,e)=>({top:this._getPanelPositionTop(t,e),left:t.left+t.width-e.width,name:"toolbar_east",config:{withArrow:!1}})];return"ltr"===this.locale.uiLanguageDirection?t:t.reverse()}}const c=function(t){return null!=t&&"object"==typeof t};const d="object"==typeof global&&global&&global.Object===Object&&global;var h="object"==typeof self&&self&&self.Object===Object&&self;const u=(d||h||Function("return this")()).Symbol;var p=Object.prototype,b=p.hasOwnProperty,f=p.toString,g=u?u.toStringTag:void 0;const w=function(t){var e=b.call(t,g),o=t[g];try{t[g]=void 0;var i=!0}catch(t){}var r=f.call(t);return i&&(e?t[g]=o:delete t[g]),r};var v=Object.prototype.toString;const m=function(t){return v.call(t)};var y=u?u.toStringTag:void 0;const O=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":y&&y in Object(t)?w(t):m(t)};const T=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var j=Function.prototype,E=Object.prototype,P=j.toString,_=E.hasOwnProperty,x=P.call(Object);const F=function(t){if(!c(t)||"[object Object]"!=O(t))return!1;var e=T(t);if(null===e)return!0;var o=_.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&P.call(o)==x};const S=function(t){return c(t)&&1===t.nodeType&&!F(t)};class C extends((0,t.ElementApiMixin)(t.Editor)){constructor(o,i={}){if(!D(o)&&void 0!==i.initialData)throw new e.CKEditorError("editor-create-initial-data",null);super(i),void 0===this.config.get("initialData")&&this.config.set("initialData",function(t){return D(t)?(0,e.getDataFromElement)(t):t}(o)),this.model.document.createRoot(),D(o)&&(this.sourceElement=o,(0,t.secureSourceElement)(this,o));const r=!this.config.get("toolbar.shouldNotGroupWhenFull"),n=new a(this.locale,this.editing.view,this.sourceElement,{shouldToolbarGroupWhenFull:r});this.ui=new s(this,n),(0,t.attachToForm)(this)}destroy(){const t=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(t)}))}static create(t,o={}){return new Promise((i=>{if(D(t)&&"TEXTAREA"===t.tagName)throw new e.CKEditorError("editor-wrong-element",null);const r=new this(t,o);i(r.initPlugins().then((()=>r.ui.init())).then((()=>r.data.init(r.config.get("initialData")))).then((()=>r.fire("ready"))).then((()=>r)))}))}}function D(t){return S(t)}})(),(window.CKEditor5=window.CKEditor5||{}).editorInline=i})();
package/dist/index.js CHANGED
@@ -2,22 +2,41 @@
2
2
  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
- import { ElementApiMixin, Editor, secureSourceElement, attachToForm, Context } from '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { toUnit, ResizeObserver, Rect, CKEditorError, getDataFromElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
7
- import { EditorWatchdog, ContextWatchdog } from '@ckeditor/ckeditor5-watchdog/dist/index.js';
5
+ import { ElementApiMixin, Editor, secureSourceElement, attachToForm } from '@ckeditor/ckeditor5-core/dist/index.js';
6
+ import { ResizeObserver, Rect, toUnit, CKEditorError, getDataFromElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
8
7
  import { EditorUI, normalizeToolbarConfig, EditorUIView, ToolbarView, BalloonPanelView, InlineEditableUIView } from '@ckeditor/ckeditor5-ui/dist/index.js';
9
8
  import { enablePlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';
10
9
  import { isElement as isElement$1 } from 'lodash-es';
11
10
 
12
- class InlineEditorUI extends EditorUI {
11
+ /**
12
+ * The inline editor UI class.
13
+ *
14
+ * @extends module:ui/editorui/editorui~EditorUI
15
+ */ class InlineEditorUI extends EditorUI {
16
+ /**
17
+ * The main (top–most) view of the editor UI.
18
+ */ view;
19
+ /**
20
+ * A normalized `config.toolbar` object.
21
+ */ _toolbarConfig;
13
22
  /**
14
- * @inheritDoc
15
- */ get element() {
23
+ * Creates an instance of the inline editor UI class.
24
+ *
25
+ * @param editor The editor instance.
26
+ * @param view The view of the UI.
27
+ */ constructor(editor, view){
28
+ super(editor);
29
+ this.view = view;
30
+ this._toolbarConfig = normalizeToolbarConfig(editor.config.get('toolbar'));
31
+ }
32
+ /**
33
+ * @inheritDoc
34
+ */ get element() {
16
35
  return this.view.editable.element;
17
36
  }
18
37
  /**
19
- * Initializes the UI.
20
- */ init() {
38
+ * Initializes the UI.
39
+ */ init() {
21
40
  const editor = this.editor;
22
41
  const view = this.view;
23
42
  const editingView = editor.editing.view;
@@ -49,8 +68,8 @@ class InlineEditorUI extends EditorUI {
49
68
  this.fire('ready');
50
69
  }
51
70
  /**
52
- * @inheritDoc
53
- */ destroy() {
71
+ * @inheritDoc
72
+ */ destroy() {
54
73
  super.destroy();
55
74
  const view = this.view;
56
75
  const editingView = this.editor.editing.view;
@@ -58,8 +77,8 @@ class InlineEditorUI extends EditorUI {
58
77
  view.destroy();
59
78
  }
60
79
  /**
61
- * Initializes the inline editor toolbar and its panel.
62
- */ _initToolbar() {
80
+ * Initializes the inline editor toolbar and its panel.
81
+ */ _initToolbar() {
63
82
  const editor = this.editor;
64
83
  const view = this.view;
65
84
  const editableElement = view.editable.element;
@@ -83,8 +102,8 @@ class InlineEditorUI extends EditorUI {
83
102
  this.addToolbar(toolbar);
84
103
  }
85
104
  /**
86
- * Enable the placeholder text on the editing root.
87
- */ _initPlaceholder() {
105
+ * Enable the placeholder text on the editing root.
106
+ */ _initPlaceholder() {
88
107
  const editor = this.editor;
89
108
  const editingView = editor.editing.view;
90
109
  const editingRoot = editingView.document.getRoot();
@@ -102,23 +121,111 @@ class InlineEditorUI extends EditorUI {
102
121
  keepOnFocus: true
103
122
  });
104
123
  }
105
- /**
106
- * Creates an instance of the inline editor UI class.
107
- *
108
- * @param editor The editor instance.
109
- * @param view The view of the UI.
110
- */ constructor(editor, view){
111
- super(editor);
112
- this.view = view;
113
- this._toolbarConfig = normalizeToolbarConfig(editor.config.get('toolbar'));
114
- }
115
124
  }
116
125
 
117
- const toPx = toUnit('px');
118
- class InlineEditorUIView extends EditorUIView {
126
+ const toPx = /* #__PURE__ */ toUnit('px');
127
+ /**
128
+ * Inline editor UI view. Uses an nline editable and a floating toolbar.
129
+ */ class InlineEditorUIView extends EditorUIView {
119
130
  /**
120
- * @inheritDoc
121
- */ render() {
131
+ * A floating toolbar view instance.
132
+ */ toolbar;
133
+ /**
134
+ * A balloon panel view instance.
135
+ */ panel;
136
+ /**
137
+ * A set of positioning functions used by the {@link #panel} to float around
138
+ * {@link #element editableElement}.
139
+ *
140
+ * The positioning functions are as follows:
141
+ *
142
+ * * West:
143
+ *
144
+ * ```
145
+ * [ Panel ]
146
+ * +------------------+
147
+ * | #editableElement |
148
+ * +------------------+
149
+ *
150
+ * +------------------+
151
+ * | #editableElement |
152
+ * |[ Panel ] |
153
+ * | |
154
+ * +------------------+
155
+ *
156
+ * +------------------+
157
+ * | #editableElement |
158
+ * +------------------+
159
+ * [ Panel ]
160
+ * ```
161
+ *
162
+ * * East:
163
+ *
164
+ * ```
165
+ * [ Panel ]
166
+ * +------------------+
167
+ * | #editableElement |
168
+ * +------------------+
169
+ *
170
+ * +------------------+
171
+ * | #editableElement |
172
+ * | [ Panel ]|
173
+ * | |
174
+ * +------------------+
175
+ *
176
+ * +------------------+
177
+ * | #editableElement |
178
+ * +------------------+
179
+ * [ Panel ]
180
+ * ```
181
+ *
182
+ * See: {@link module:utils/dom/position~Options#positions}.
183
+ */ panelPositions;
184
+ /**
185
+ * Editable UI view.
186
+ */ editable;
187
+ /**
188
+ * An instance of the resize observer that helps dynamically determine the geometry of the toolbar
189
+ * and manage items that do not fit into a single row.
190
+ *
191
+ * **Note:** Created in {@link #render}.
192
+ */ _resizeObserver;
193
+ /**
194
+ * Creates an instance of the inline editor UI view.
195
+ *
196
+ * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
197
+ * @param editingView The editing view instance this view is related to.
198
+ * @param editableElement The editable element. If not specified, it will be automatically created by
199
+ * {@link module:ui/editableui/editableuiview~EditableUIView}. Otherwise, the given element will be used.
200
+ * @param options Configuration options for the view instance.
201
+ * @param options.shouldToolbarGroupWhenFull When set `true` enables automatic items grouping
202
+ * in the main {@link module:editor-inline/inlineeditoruiview~InlineEditorUIView#toolbar toolbar}.
203
+ * See {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull} to learn more.
204
+ */ constructor(locale, editingView, editableElement, options = {}){
205
+ super(locale);
206
+ const t = locale.t;
207
+ this.toolbar = new ToolbarView(locale, {
208
+ shouldGroupWhenFull: options.shouldToolbarGroupWhenFull,
209
+ isFloating: true
210
+ });
211
+ this.set('viewportTopOffset', 0);
212
+ this.panel = new BalloonPanelView(locale);
213
+ this.panelPositions = this._getPanelPositions();
214
+ this.panel.extendTemplate({
215
+ attributes: {
216
+ class: 'ck-toolbar-container'
217
+ }
218
+ });
219
+ this.editable = new InlineEditableUIView(locale, editingView, editableElement, {
220
+ label: (editableView)=>{
221
+ return t('Rich Text Editor. Editing area: %0', editableView.name);
222
+ }
223
+ });
224
+ this._resizeObserver = null;
225
+ }
226
+ /**
227
+ * @inheritDoc
228
+ */ render() {
122
229
  super.render();
123
230
  this.body.add(this.panel);
124
231
  this.registerChild(this.editable);
@@ -134,19 +241,19 @@ class InlineEditorUIView extends EditorUIView {
134
241
  }
135
242
  }
136
243
  /**
137
- * @inheritDoc
138
- */ destroy() {
244
+ * @inheritDoc
245
+ */ destroy() {
139
246
  super.destroy();
140
247
  if (this._resizeObserver) {
141
248
  this._resizeObserver.destroy();
142
249
  }
143
250
  }
144
251
  /**
145
- * Determines the panel top position of the {@link #panel} in {@link #panelPositions}.
146
- *
147
- * @param editableRect Rect of the {@link #element}.
148
- * @param panelRect Rect of the {@link #panel}.
149
- */ _getPanelPositionTop(editableRect, panelRect) {
252
+ * Determines the panel top position of the {@link #panel} in {@link #panelPositions}.
253
+ *
254
+ * @param editableRect Rect of the {@link #element}.
255
+ * @param panelRect Rect of the {@link #panel}.
256
+ */ _getPanelPositionTop(editableRect, panelRect) {
150
257
  let top;
151
258
  if (editableRect.top > panelRect.height + this.viewportTopOffset) {
152
259
  top = editableRect.top - panelRect.height;
@@ -158,10 +265,10 @@ class InlineEditorUIView extends EditorUIView {
158
265
  return top;
159
266
  }
160
267
  /**
161
- * Returns the positions for {@link #panelPositions}.
162
- *
163
- * See: {@link module:utils/dom/position~Options#positions}.
164
- */ _getPanelPositions() {
268
+ * Returns the positions for {@link #panelPositions}.
269
+ *
270
+ * See: {@link module:utils/dom/position~Options#positions}.
271
+ */ _getPanelPositions() {
165
272
  const positions = [
166
273
  (editableRect, panelRect)=>{
167
274
  return {
@@ -190,198 +297,29 @@ class InlineEditorUIView extends EditorUIView {
190
297
  return positions.reverse();
191
298
  }
192
299
  }
193
- /**
194
- * Creates an instance of the inline editor UI view.
195
- *
196
- * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
197
- * @param editingView The editing view instance this view is related to.
198
- * @param editableElement The editable element. If not specified, it will be automatically created by
199
- * {@link module:ui/editableui/editableuiview~EditableUIView}. Otherwise, the given element will be used.
200
- * @param options Configuration options for the view instance.
201
- * @param options.shouldToolbarGroupWhenFull When set `true` enables automatic items grouping
202
- * in the main {@link module:editor-inline/inlineeditoruiview~InlineEditorUIView#toolbar toolbar}.
203
- * See {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull} to learn more.
204
- */ constructor(locale, editingView, editableElement, options = {}){
205
- super(locale);
206
- const t = locale.t;
207
- this.toolbar = new ToolbarView(locale, {
208
- shouldGroupWhenFull: options.shouldToolbarGroupWhenFull,
209
- isFloating: true
210
- });
211
- this.set('viewportTopOffset', 0);
212
- this.panel = new BalloonPanelView(locale);
213
- this.panelPositions = this._getPanelPositions();
214
- this.panel.extendTemplate({
215
- attributes: {
216
- class: 'ck-toolbar-container'
217
- }
218
- });
219
- this.editable = new InlineEditableUIView(locale, editingView, editableElement, {
220
- label: (editableView)=>{
221
- return t('Rich Text Editor. Editing area: %0', editableView.name);
222
- }
223
- });
224
- this._resizeObserver = null;
225
- }
226
300
  }
227
301
 
228
302
  /**
229
- * The {@glink installation/getting-started/predefined-builds#inline-editor inline editor} implementation.
230
- * It uses an inline editable and a floating toolbar.
303
+ * The inline editor implementation. It uses an inline editable and a floating toolbar.
231
304
  * See the {@glink examples/builds/inline-editor demo}.
232
305
  *
233
306
  * In order to create a inline editor instance, use the static
234
307
  * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`} method.
235
- *
236
- * # Inline editor and inline build
237
- *
238
- * The inline editor can be used directly from source (if you installed the
239
- * [`@ckeditor/ckeditor5-editor-inline`](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-inline) package)
240
- * but it is also available in the {@glink installation/getting-started/predefined-builds#inline-editor inline build}.
241
- *
242
- * {@glink installation/getting-started/predefined-builds Builds}
243
- * are ready-to-use editors with plugins bundled in. When using the editor from
244
- * source you need to take care of loading all plugins by yourself
245
- * (through the {@link module:core/editor/editorconfig~EditorConfig#plugins `config.plugins`} option).
246
- * Using the editor from source gives much better flexibility and allows easier customization.
247
- *
248
- * Read more about initializing the editor from source or as a build in
249
- * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}.
250
- */ class InlineEditor extends ElementApiMixin(Editor) {
308
+ */ class InlineEditor extends /* #__PURE__ */ ElementApiMixin(Editor) {
251
309
  /**
252
- * Destroys the editor instance, releasing all resources used by it.
253
- *
254
- * Updates the original editor element with the data if the
255
- * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}
256
- * configuration option is set to `true`.
257
- */ destroy() {
258
- // Cache the data, then destroy.
259
- // It's safe to assume that the model->view conversion will not work after super.destroy().
260
- const data = this.getData();
261
- this.ui.destroy();
262
- return super.destroy().then(()=>{
263
- if (this.sourceElement) {
264
- this.updateSourceElement(data);
265
- }
266
- });
267
- }
268
- /**
269
- * Creates a new inline editor instance.
270
- *
271
- * There are three general ways how the editor can be initialized.
272
- *
273
- * # Using an existing DOM element (and loading data from it)
274
- *
275
- * You can initialize the editor using an existing DOM element:
276
- *
277
- * ```ts
278
- * InlineEditor
279
- * .create( document.querySelector( '#editor' ) )
280
- * .then( editor => {
281
- * console.log( 'Editor was initialized', editor );
282
- * } )
283
- * .catch( err => {
284
- * console.error( err.stack );
285
- * } );
286
- * ```
287
- *
288
- * The element's content will be used as the editor data and the element will become the editable element.
289
- *
290
- * # Creating a detached editor
291
- *
292
- * Alternatively, you can initialize the editor by passing the initial data directly as a `String`.
293
- * In this case, the editor will render an element that must be inserted into the DOM for the editor to work properly:
294
- *
295
- * ```ts
296
- * InlineEditor
297
- * .create( '<p>Hello world!</p>' )
298
- * .then( editor => {
299
- * console.log( 'Editor was initialized', editor );
300
- *
301
- * // Initial data was provided so the editor UI element needs to be added manually to the DOM.
302
- * document.body.appendChild( editor.ui.element );
303
- * } )
304
- * .catch( err => {
305
- * console.error( err.stack );
306
- * } );
307
- * ```
308
- *
309
- * This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your
310
- * web page content is generated on the client side and the DOM structure is not ready at the moment when you initialize the editor.
311
- *
312
- * # Using an existing DOM element (and data provided in `config.initialData`)
313
- *
314
- * You can also mix these two ways by providing a DOM element to be used and passing the initial data through the configuration:
315
- *
316
- * ```ts
317
- * InlineEditor
318
- * .create( document.querySelector( '#editor' ), {
319
- * initialData: '<h2>Initial data</h2><p>Foo bar.</p>'
320
- * } )
321
- * .then( editor => {
322
- * console.log( 'Editor was initialized', editor );
323
- * } )
324
- * .catch( err => {
325
- * console.error( err.stack );
326
- * } );
327
- * ```
328
- *
329
- * This method can be used to initialize the editor on an existing element with the specified content in case if your integration
330
- * makes it difficult to set the content of the source element.
331
- *
332
- * Note that an error will be thrown if you pass the initial data both as the first parameter and also in the configuration.
333
- *
334
- * # Configuring the editor
335
- *
336
- * See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about
337
- * customizing plugins, toolbar and more.
338
- *
339
- * # Using the editor from source
340
- *
341
- * The code samples listed in the previous sections of this documentation assume that you are using an
342
- * {@glink installation/getting-started/predefined-builds editor build} (for example – `@ckeditor/ckeditor5-build-inline`).
343
- *
344
- * If you want to use the inline editor from source (`@ckeditor/ckeditor5-editor-inline/src/inlineeditor`),
345
- * you need to define the list of
346
- * {@link module:core/editor/editorconfig~EditorConfig#plugins plugins to be initialized} and
347
- * {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar items}. Read more about using the editor from
348
- * source in the {@glink installation/advanced/alternative-setups/integrating-from-source-webpack dedicated guide}.
349
- *
350
- * @param sourceElementOrData The DOM element that will be the source for the created editor
351
- * or the editor's initial data.
352
- *
353
- * If a DOM element is passed, its content will be automatically loaded to the editor upon initialization.
354
- * The editor data will be set back to the original element once the editor is destroyed only if the
355
- * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy updateSourceElementOnDestroy}
356
- * option is set to `true`.
357
- *
358
- * If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.
359
- * It is available under the {@link module:editor-inline/inlineeditorui~InlineEditorUI#element `editor.ui.element`} property.
360
- *
361
- * @param config The editor configuration.
362
- * @returns A promise resolved once the editor is ready. The promise resolves with the created editor instance.
363
- */ static create(sourceElementOrData, config = {}) {
364
- return new Promise((resolve)=>{
365
- if (isElement(sourceElementOrData) && sourceElementOrData.tagName === 'TEXTAREA') {
366
- // Documented in core/editor/editor.js
367
- // eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
368
- throw new CKEditorError('editor-wrong-element', null);
369
- }
370
- const editor = new this(sourceElementOrData, config);
371
- resolve(editor.initPlugins().then(()=>editor.ui.init()).then(()=>editor.data.init(editor.config.get('initialData'))).then(()=>editor.fire('ready')).then(()=>editor));
372
- });
373
- }
310
+ * @inheritDoc
311
+ */ ui;
374
312
  /**
375
- * Creates an instance of the inline editor.
376
- *
377
- * **Note:** Do not use the constructor to create editor instances. Use the static
378
- * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`} method instead.
379
- *
380
- * @param sourceElementOrData The DOM element that will be the source for the created editor
381
- * (on which the editor will be initialized) or initial data for the editor. For more information see
382
- * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}.
383
- * @param config The editor configuration.
384
- */ constructor(sourceElementOrData, config = {}){
313
+ * Creates an instance of the inline editor.
314
+ *
315
+ * **Note:** Do not use the constructor to create editor instances. Use the static
316
+ * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`} method instead.
317
+ *
318
+ * @param sourceElementOrData The DOM element that will be the source for the created editor
319
+ * (on which the editor will be initialized) or initial data for the editor. For more information see
320
+ * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}.
321
+ * @param config The editor configuration.
322
+ */ constructor(sourceElementOrData, config = {}){
385
323
  // If both `config.initialData` and initial data parameter in `create()` are set, then throw.
386
324
  if (!isElement(sourceElementOrData) && config.initialData !== undefined) {
387
325
  // Documented in core/editor/editorconfig.jsdoc.
@@ -404,22 +342,119 @@ class InlineEditorUIView extends EditorUIView {
404
342
  this.ui = new InlineEditorUI(this, view);
405
343
  attachToForm(this);
406
344
  }
345
+ /**
346
+ * Destroys the editor instance, releasing all resources used by it.
347
+ *
348
+ * Updates the original editor element with the data if the
349
+ * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}
350
+ * configuration option is set to `true`.
351
+ */ destroy() {
352
+ // Cache the data, then destroy.
353
+ // It's safe to assume that the model->view conversion will not work after super.destroy().
354
+ const data = this.getData();
355
+ this.ui.destroy();
356
+ return super.destroy().then(()=>{
357
+ if (this.sourceElement) {
358
+ this.updateSourceElement(data);
359
+ }
360
+ });
361
+ }
362
+ /**
363
+ * Creates a new inline editor instance.
364
+ *
365
+ * There are three general ways how the editor can be initialized.
366
+ *
367
+ * # Using an existing DOM element (and loading data from it)
368
+ *
369
+ * You can initialize the editor using an existing DOM element:
370
+ *
371
+ * ```ts
372
+ * InlineEditor
373
+ * .create( document.querySelector( '#editor' ) )
374
+ * .then( editor => {
375
+ * console.log( 'Editor was initialized', editor );
376
+ * } )
377
+ * .catch( err => {
378
+ * console.error( err.stack );
379
+ * } );
380
+ * ```
381
+ *
382
+ * The element's content will be used as the editor data and the element will become the editable element.
383
+ *
384
+ * # Creating a detached editor
385
+ *
386
+ * Alternatively, you can initialize the editor by passing the initial data directly as a `String`.
387
+ * In this case, the editor will render an element that must be inserted into the DOM for the editor to work properly:
388
+ *
389
+ * ```ts
390
+ * InlineEditor
391
+ * .create( '<p>Hello world!</p>' )
392
+ * .then( editor => {
393
+ * console.log( 'Editor was initialized', editor );
394
+ *
395
+ * // Initial data was provided so the editor UI element needs to be added manually to the DOM.
396
+ * document.body.appendChild( editor.ui.element );
397
+ * } )
398
+ * .catch( err => {
399
+ * console.error( err.stack );
400
+ * } );
401
+ * ```
402
+ *
403
+ * This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your
404
+ * web page content is generated on the client side and the DOM structure is not ready at the moment when you initialize the editor.
405
+ *
406
+ * # Using an existing DOM element (and data provided in `config.initialData`)
407
+ *
408
+ * You can also mix these two ways by providing a DOM element to be used and passing the initial data through the configuration:
409
+ *
410
+ * ```ts
411
+ * InlineEditor
412
+ * .create( document.querySelector( '#editor' ), {
413
+ * initialData: '<h2>Initial data</h2><p>Foo bar.</p>'
414
+ * } )
415
+ * .then( editor => {
416
+ * console.log( 'Editor was initialized', editor );
417
+ * } )
418
+ * .catch( err => {
419
+ * console.error( err.stack );
420
+ * } );
421
+ * ```
422
+ *
423
+ * This method can be used to initialize the editor on an existing element with the specified content in case if your integration
424
+ * makes it difficult to set the content of the source element.
425
+ *
426
+ * Note that an error will be thrown if you pass the initial data both as the first parameter and also in the configuration.
427
+ *
428
+ * # Configuring the editor
429
+ *
430
+ * See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about
431
+ * customizing plugins, toolbar and more.
432
+ *
433
+ * @param sourceElementOrData The DOM element that will be the source for the created editor
434
+ * or the editor's initial data.
435
+ *
436
+ * If a DOM element is passed, its content will be automatically loaded to the editor upon initialization.
437
+ * The editor data will be set back to the original element once the editor is destroyed only if the
438
+ * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy updateSourceElementOnDestroy}
439
+ * option is set to `true`.
440
+ *
441
+ * If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.
442
+ * It is available under the {@link module:editor-inline/inlineeditorui~InlineEditorUI#element `editor.ui.element`} property.
443
+ *
444
+ * @param config The editor configuration.
445
+ * @returns A promise resolved once the editor is ready. The promise resolves with the created editor instance.
446
+ */ static create(sourceElementOrData, config = {}) {
447
+ return new Promise((resolve)=>{
448
+ if (isElement(sourceElementOrData) && sourceElementOrData.tagName === 'TEXTAREA') {
449
+ // Documented in core/editor/editor.js
450
+ // eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
451
+ throw new CKEditorError('editor-wrong-element', null);
452
+ }
453
+ const editor = new this(sourceElementOrData, config);
454
+ resolve(editor.initPlugins().then(()=>editor.ui.init()).then(()=>editor.data.init(editor.config.get('initialData'))).then(()=>editor.fire('ready')).then(()=>editor));
455
+ });
456
+ }
407
457
  }
408
- /**
409
- * The {@link module:core/context~Context} class.
410
- *
411
- * Exposed as static editor field for easier access in editor builds.
412
- */ InlineEditor.Context = Context;
413
- /**
414
- * The {@link module:watchdog/editorwatchdog~EditorWatchdog} class.
415
- *
416
- * Exposed as static editor field for easier access in editor builds.
417
- */ InlineEditor.EditorWatchdog = EditorWatchdog;
418
- /**
419
- * The {@link module:watchdog/contextwatchdog~ContextWatchdog} class.
420
- *
421
- * Exposed as static editor field for easier access in editor builds.
422
- */ InlineEditor.ContextWatchdog = ContextWatchdog;
423
458
  function getInitialData(sourceElementOrData) {
424
459
  return isElement(sourceElementOrData) ? getDataFromElement(sourceElementOrData) : sourceElementOrData;
425
460
  }