-
Notifications
You must be signed in to change notification settings - Fork 84
Allow to pass initial data to the editor constructor #73
Changes from 9 commits
3015814
5af49aa
633b5d3
f38aec7
3232bfb
8a7ea54
ffdede7
216cd88
a9497d2
674c3b0
51cdeee
22b6f4f
4a13075
c210e56
46d2f71
6df6ba9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ import ClassicEditorUIView from './classiceditoruiview'; | |
import ElementReplacer from '@ckeditor/ckeditor5-utils/src/elementreplacer'; | ||
import getDataFromElement from '@ckeditor/ckeditor5-utils/src/dom/getdatafromelement'; | ||
import mix from '@ckeditor/ckeditor5-utils/src/mix'; | ||
import isElement from '@ckeditor/ckeditor5-utils/src/lib/lodash/isElement'; | ||
|
||
/** | ||
* The {@glink builds/guides/overview#classic-editor classic editor} implementation. | ||
|
@@ -53,13 +54,18 @@ export default class ClassicEditor extends Editor { | |
* {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method instead. | ||
* | ||
* @protected | ||
* @param {HTMLElement} element The DOM element that will be the source for the created editor. | ||
* The data will be loaded from it and loaded back to it once the editor is destroyed. | ||
* @param {HTMLElement|String} elementOrData The DOM element that will be the source for the created editor | ||
* or editor's initial data. For more information see | ||
* {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}. | ||
* @param {module:core/editor/editorconfig~EditorConfig} config The editor configuration. | ||
*/ | ||
constructor( element, config ) { | ||
constructor( elementOrData, config ) { | ||
super( config ); | ||
|
||
if ( isElement( elementOrData ) ) { | ||
this.element = elementOrData; | ||
} | ||
|
||
/** | ||
* The element replacer instance used to hide the editor element. | ||
* | ||
|
@@ -68,8 +74,6 @@ export default class ClassicEditor extends Editor { | |
*/ | ||
this._elementReplacer = new ElementReplacer(); | ||
|
||
this.element = element; | ||
|
||
this.data.processor = new HtmlDataProcessor(); | ||
|
||
this.model.document.createRoot(); | ||
|
@@ -128,25 +132,72 @@ export default class ClassicEditor extends Editor { | |
* console.error( err.stack ); | ||
* } ); | ||
* | ||
* @param {HTMLElement} element The DOM element that will be the source for the created editor. | ||
* The data will be loaded from it and loaded back to it once the editor is destroyed. | ||
* Creating instance when using initial data instead of a DOM element: | ||
* | ||
* import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; | ||
* import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'; | ||
* import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; | ||
* import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; | ||
* import ... | ||
* | ||
* ClassicEditor | ||
* .create( '<p>Hello world!</p>', { | ||
* plugins: [ Essentials, Bold, Italic, ... ], | ||
* toolbar: [ 'bold', 'italic', ... ] | ||
* } ) | ||
* .then( editor => { | ||
* console.log( 'Editor was initialized', editor ); | ||
* | ||
* // Initial data was provided so `editor.element` needs to be added manually to the DOM. | ||
* document.body.appendChild( editor.element ); | ||
* } ) | ||
* .catch( err => { | ||
* console.error( err.stack ); | ||
* } ); | ||
* | ||
* @param {HTMLElement|String} elementOrData The DOM element that will be the source for the created editor | ||
* or editor's initial data. | ||
* | ||
* If an element is passed, then it contents will be automatically | ||
* {@link module:editor-classic/classiceditor~ClassicEditor#setData loaded} to the editor on startup | ||
* and the editor element will replace the passed element in the DOM (the original one will be hidden and editor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "editor element" -> link to the new property |
||
* will be injected next to it). | ||
* | ||
* Moreover, the data will be set back to the original element once the editor is destroyed and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. original => source |
||
* (if the element is a `<textarea>`) when a form in which this element is contained is submitted (which ensures | ||
* automatic integration with native web forms). | ||
* | ||
* If a data is passed, a detached editor will be created. It means that you need to insert it into the DOM manually | ||
* (by accessing the {@link module:editor-classic/classiceditor~ClassicEditor#element `editor.element`} property). | ||
* | ||
* See the examples above to learn more. | ||
* @param {module:core/editor/editorconfig~EditorConfig} config The editor configuration. | ||
* @returns {Promise} A promise resolved once the editor is ready. | ||
* The promise returns the created {@link module:editor-classic/classiceditor~ClassicEditor} instance. | ||
*/ | ||
static create( element, config ) { | ||
static create( elementOrData, config ) { | ||
return new Promise( resolve => { | ||
const editor = new this( element, config ); | ||
const editor = new this( elementOrData, config ); | ||
|
||
resolve( | ||
editor.initPlugins() | ||
.then( () => editor.ui.init() ) | ||
.then( () => { | ||
editor._elementReplacer.replace( element, editor.ui.view.element ); | ||
if ( isElement( elementOrData ) ) { | ||
editor._elementReplacer.replace( elementOrData, editor.ui.view.element ); | ||
} | ||
|
||
editor.fire( 'uiReady' ); | ||
} ) | ||
.then( () => editor.editing.view.attachDomRoot( editor.ui.view.editableElement ) ) | ||
.then( () => editor.data.init( getDataFromElement( element ) ) ) | ||
.then( () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be easier to read if it was written like this: const initialData = isElement( sourceElementOrData ) ? getDataFromElement( sourceElementOrData ) : sourceElementOrData;
editor.data.init( initialData ); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The point is – what differs these two scenarios isn't how or whether you call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that the code you committed isn't equal to what I proposed: editor.data.init(
isElement( sourceElementOrData ) ? getDataFromElement( sourceElementOrData ) : sourceElementOrData
); In this case, we lose the information what do we call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, |
||
if ( editor.element ) { | ||
editor.data.init( getDataFromElement( editor.element ) ); | ||
} else { | ||
editor.data.init( elementOrData ); | ||
editor.element = editor.ui.view.element; | ||
} | ||
} ) | ||
.then( () => { | ||
editor.fire( 'dataReady' ); | ||
editor.fire( 'ready' ); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<p> | ||
<button id="destroyEditors">Destroy editors</button> | ||
<button id="initEditor">Init editor</button> | ||
</p> | ||
|
||
<div class="container"></div> | ||
|
||
<style> | ||
body { | ||
width: 10000px; | ||
height: 10000px; | ||
} | ||
|
||
.container { | ||
padding: 20px; | ||
width: 500px; | ||
} | ||
</style> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/** | ||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
/* globals console:false, document, window */ | ||
|
||
import ClassicEditor from '../../src/classiceditor'; | ||
import Enter from '@ckeditor/ckeditor5-enter/src/enter'; | ||
import Typing from '@ckeditor/ckeditor5-typing/src/typing'; | ||
import Heading from '@ckeditor/ckeditor5-heading/src/heading'; | ||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; | ||
import Undo from '@ckeditor/ckeditor5-undo/src/undo'; | ||
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; | ||
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; | ||
|
||
window.editors = []; | ||
let counter = 1; | ||
|
||
const container = document.querySelector( '.container' ); | ||
|
||
function initEditor() { | ||
ClassicEditor | ||
.create( `<h2>Hello world! #${ counter }</h2><p>This is an editor instance.</p>`, { | ||
plugins: [ Enter, Typing, Paragraph, Undo, Heading, Bold, Italic ], | ||
toolbar: [ 'heading', '|', 'bold', 'italic', 'undo', 'redo' ] | ||
} ) | ||
.then( editor => { | ||
counter += 1; | ||
window.editors.push( editor ); | ||
container.appendChild( editor.element ); | ||
} ) | ||
.catch( err => { | ||
console.error( err.stack ); | ||
} ); | ||
} | ||
|
||
function destroyEditors() { | ||
window.editors.forEach( editor => { | ||
editor.destroy() | ||
.then( () => { | ||
editor.element.remove(); | ||
} ); | ||
} ); | ||
window.editors = []; | ||
counter = 1; | ||
} | ||
|
||
document.getElementById( 'initEditor' ).addEventListener( 'click', initEditor ); | ||
document.getElementById( 'destroyEditors' ).addEventListener( 'click', destroyEditors ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
1. Click "Init editor". | ||
2. New editor instance should be appended to the document with initial data in it. You can create more than one editor. | ||
3. After clicking "Destroy editor" all editors should be removed from the document. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its contents