@@ -17,6 +17,7 @@ import ClassicEditorUIView from './classiceditoruiview';
1717import ElementReplacer from '@ckeditor/ckeditor5-utils/src/elementreplacer' ;
1818import getDataFromElement from '@ckeditor/ckeditor5-utils/src/dom/getdatafromelement' ;
1919import mix from '@ckeditor/ckeditor5-utils/src/mix' ;
20+ import isElement from '@ckeditor/ckeditor5-utils/src/lib/lodash/isElement' ;
2021
2122/**
2223 * The {@glink builds/guides/overview#classic-editor classic editor} implementation.
@@ -53,23 +54,26 @@ export default class ClassicEditor extends Editor {
5354 * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method instead.
5455 *
5556 * @protected
56- * @param {HTMLElement } element The DOM element that will be the source for the created editor.
57- * The data will be loaded from it and loaded back to it once the editor is destroyed.
57+ * @param {HTMLElement|String } sourceElementOrData The DOM element that will be the source for the created editor
58+ * or editor's initial data. For more information see
59+ * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}.
5860 * @param {module:core/editor/editorconfig~EditorConfig } config The editor configuration.
5961 */
60- constructor ( element , config ) {
62+ constructor ( sourceElementOrData , config ) {
6163 super ( config ) ;
6264
65+ if ( isElement ( sourceElementOrData ) ) {
66+ this . sourceElement = sourceElementOrData ;
67+ }
68+
6369 /**
64- * The element replacer instance used to hide the editor element.
70+ * The element replacer instance used to hide the editor's source element.
6571 *
6672 * @protected
6773 * @member {module:utils/elementreplacer~ElementReplacer}
6874 */
6975 this . _elementReplacer = new ElementReplacer ( ) ;
7076
71- this . element = element ;
72-
7377 this . data . processor = new HtmlDataProcessor ( ) ;
7478
7579 this . model . document . createRoot ( ) ;
@@ -79,15 +83,25 @@ export default class ClassicEditor extends Editor {
7983 attachToForm ( this ) ;
8084 }
8185
86+ /**
87+ * @inheritDoc
88+ */
89+ get element ( ) {
90+ return this . ui . view . element ;
91+ }
92+
8293 /**
8394 * Destroys the editor instance, releasing all resources used by it.
8495 *
85- * Updates the original editor element with the data.
96+ * Updates the editor's source element with the data.
8697 *
8798 * @returns {Promise }
8899 */
89100 destroy ( ) {
90- this . updateElement ( ) ;
101+ if ( this . sourceElement ) {
102+ this . updateSourceElement ( ) ;
103+ }
104+
91105 this . _elementReplacer . restore ( ) ;
92106 this . ui . destroy ( ) ;
93107
@@ -128,25 +142,72 @@ export default class ClassicEditor extends Editor {
128142 * console.error( err.stack );
129143 * } );
130144 *
131- * @param {HTMLElement } element The DOM element that will be the source for the created editor.
132- * The data will be loaded from it and loaded back to it once the editor is destroyed.
145+ * Creating instance when using initial data instead of a DOM element:
146+ *
147+ * import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
148+ * import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
149+ * import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
150+ * import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
151+ * import ...
152+ *
153+ * ClassicEditor
154+ * .create( '<p>Hello world!</p>', {
155+ * plugins: [ Essentials, Bold, Italic, ... ],
156+ * toolbar: [ 'bold', 'italic', ... ]
157+ * } )
158+ * .then( editor => {
159+ * console.log( 'Editor was initialized', editor );
160+ *
161+ * // Initial data was provided so `editor.element` needs to be added manually to the DOM.
162+ * document.body.appendChild( editor.element );
163+ * } )
164+ * .catch( err => {
165+ * console.error( err.stack );
166+ * } );
167+ *
168+ * @param {HTMLElement|String } sourceElementOrData The DOM element that will be the source for the created editor
169+ * or editor's initial data.
170+ *
171+ * If a source element is passed, then its contents will be automatically
172+ * {@link module:editor-classic/classiceditor~ClassicEditor#setData loaded} to the editor on startup
173+ * and the {@link module:core/editor/editorwithui~EditorWithUI#element editor element} will replace the passed element in the DOM
174+ * (the original one will be hidden and editor will be injected next to it).
175+ *
176+ * Moreover, the data will be set back to the source element once the editor is destroyed and
177+ * (if the element is a `<textarea>`) when a form in which this element is contained is submitted (which ensures
178+ * automatic integration with native web forms).
179+ *
180+ * If a data is passed, a detached editor will be created. It means that you need to insert it into the DOM manually
181+ * (by accessing the {@link module:editor-classic/classiceditor~ClassicEditor#element `editor.element`} property).
182+ *
183+ * See the examples above to learn more.
184+ *
133185 * @param {module:core/editor/editorconfig~EditorConfig } config The editor configuration.
134186 * @returns {Promise } A promise resolved once the editor is ready.
135187 * The promise returns the created {@link module:editor-classic/classiceditor~ClassicEditor} instance.
136188 */
137- static create ( element , config ) {
189+ static create ( sourceElementOrData , config ) {
138190 return new Promise ( resolve => {
139- const editor = new this ( element , config ) ;
191+ const editor = new this ( sourceElementOrData , config ) ;
140192
141193 resolve (
142194 editor . initPlugins ( )
143195 . then ( ( ) => editor . ui . init ( ) )
144196 . then ( ( ) => {
145- editor . _elementReplacer . replace ( element , editor . ui . view . element ) ;
197+ if ( isElement ( sourceElementOrData ) ) {
198+ editor . _elementReplacer . replace ( sourceElementOrData , editor . element ) ;
199+ }
200+
146201 editor . fire ( 'uiReady' ) ;
147202 } )
148203 . then ( ( ) => editor . editing . view . attachDomRoot ( editor . ui . view . editableElement ) )
149- . then ( ( ) => editor . data . init ( getDataFromElement ( element ) ) )
204+ . then ( ( ) => {
205+ const initialData = isElement ( sourceElementOrData ) ?
206+ getDataFromElement ( sourceElementOrData ) :
207+ sourceElementOrData ;
208+
209+ return editor . data . init ( initialData ) ;
210+ } )
150211 . then ( ( ) => {
151212 editor . fire ( 'dataReady' ) ;
152213 editor . fire ( 'ready' ) ;
0 commit comments