diff --git a/docs/framework/guides/document-editor.md b/docs/framework/guides/document-editor.md
index 76ec3d5..e2cbd82 100644
--- a/docs/framework/guides/document-editor.md
+++ b/docs/framework/guides/document-editor.md
@@ -19,21 +19,26 @@ The `DecoupledDocumentEditor` includes all the necessary features for the task.
See the {@link builds/guides/quick-start#document-editor quick start guide} to learn how to install the document editor build.
-Unlike the {@link builds/guides/overview#classic-editor classic editor}, the document editor does not require any data container in the DOM. Instead, it accepts a string containing the initial data as the first argument of the static `create()` method. To get the output data, use the {@link module:core/editor/utils/dataapimixin~DataApi#getData `getData`} method.
+The document editor can be created using the existing data container in the DOM. It can also accept a raw data string and create the editable by itself. To get the output data, use the {@link module:core/editor/utils/dataapimixin~DataApi#getData `getData()`} method.
+
+
Initial editor data.
', { - toolbarContainer: document.querySelector( '.document-editor__toolbar' ), - editableContainer: document.querySelector( '.document-editor__editable' ), - + .create( document.querySelector( '.document-editor__editable' ), { cloudServices: { .... } } ) .then( editor => { + const toolbarContainer = document.querySelector( '.document-editor__toolbar' ); + + toolbarContainer.appendChild( editor.ui.view.toolbar.element ); + window.editor = editor; } ) .catch( err => { @@ -41,9 +46,7 @@ DecoupledDocumentEditor } ); ``` -You may have noticed two configuration options used here: {@link module:core/editor/editorconfig~EditorConfig#toolbarContainer `config.toolbarContainer`} and {@link module:core/editor/editorconfig~EditorConfig#editableContainer `config.editableContainer`}. They specify the location of the editor toolbar and editable in your application. - -If you do not specify these configuration options, you have to make sure the editor UI is injected into your application after it fires the {@link module:core/editor/editorwithui~EditorWithUI#event:uiReady `uiReady`} event. The toolbar element is accessible via `editor.ui.view.toolbar.element` and the editable element can be found under `editor.ui.view.editable.element`. +You may have noticed that you have to make sure the editor UI is injected into your application after it fires the {@link module:core/editor/editorwithui~EditorWithUI#event:uiReady `Editor#uiReady`} event. The toolbar element can be found under `editor.ui.view.toolbar.element`.The initial editor data.
+Editor data
', { - * // The location of the toolbar in the DOM. - * toolbarContainer: document.querySelector( 'body div.toolbar-container' ), - * - * // The location of the editable in the DOM. - * editableContainer: document.querySelector( 'body div.editable-container' ) - * } ) + * .create( document.querySelector( '#editor' ) ) * .then( editor => { + * // Append the toolbar to the element. + * document.body.appendChild( editor.ui.view.toolbar.element ); + * * console.log( 'Editor was initialized', editor ); * } ) * .catch( err => { @@ -107,48 +146,48 @@ export default class DecoupledEditor extends Editor { * import ... * * DecoupledEditor - * .create( 'Editor data
', { + * .create( document.querySelector( '#editor' ), { * plugins: [ Essentials, Bold, Italic, ... ], - * toolbar: [ 'bold', 'italic', ... ], - * - * // The location of the toolbar in the DOM. - * toolbarContainer: document.querySelector( 'div.toolbar-container' ), - * - * // The location of the editable in the DOM. - * editableContainer: document.querySelector( 'div.editable-container' ) + * toolbar: [ 'bold', 'italic', ... ] * } ) * .then( editor => { + * // Append the toolbar to the element. + * document.body.appendChild( editor.ui.view.toolbar.element ); + * * console.log( 'Editor was initialized', editor ); * } ) * .catch( err => { * console.error( err.stack ); * } ); * - * **Note**: The {@link module:core/editor/editorconfig~EditorConfig#toolbarContainer `config.toolbarContainer`} and - * {@link module:core/editor/editorconfig~EditorConfig#editableContainer `config.editableContainer`} settings are optional. - * It is possible to define the location of the UI elements manually once the editor is up and running: + * **Note**: It is possible to create the editor out of a pure data string. The editor will then render + * an editable element that must be inserted into the DOM for the editor to work properly: * * DecoupledEditor * .create( 'Editor data
' ) * .then( editor => { - * console.log( 'Editor was initialized', editor ); - * - * // Append the toolbar and editable straight into the element. + * // Append the toolbar to the element. * document.body.appendChild( editor.ui.view.toolbar.element ); + * + * // Append the editable to the element. * document.body.appendChild( editor.ui.view.editable.element ); + * + * console.log( 'Editor was initialized', editor ); * } ) * .catch( err => { * console.error( err.stack ); * } ); * - * @param {String} data The data to be loaded into the editor. + * @param {HTMLElement|String} elementOrData The DOM element that serves as an editable. + * The data will be loaded from it and loaded back to it once the editor is destroyed. + * Alternatively, a data string to be loaded into the editor. * @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-decoupled/decouplededitor~DecoupledEditor} instance. */ - static create( data, config ) { + static create( elementOrData, config ) { return new Promise( resolve => { - const editor = new this( config ); + const editor = new this( elementOrData, config ); resolve( editor.initPlugins() @@ -156,8 +195,9 @@ export default class DecoupledEditor extends Editor { editor.ui.init(); editor.fire( 'uiReady' ); } ) - .then( () => editor.editing.view.attachDomRoot( editor.ui.view.editableElement ) ) - .then( () => editor.data.init( data ) ) + .then( () => { + editor.data.init( editor.element ? getDataFromElement( editor.element ) : elementOrData ); + } ) .then( () => { editor.fire( 'dataReady' ); editor.fire( 'ready' ); @@ -169,51 +209,3 @@ export default class DecoupledEditor extends Editor { } mix( DecoupledEditor, DataApiMixin ); - -/** - * The configuration of the {@link module:editor-decoupled/decouplededitor~DecoupledEditor}. - * - * When specified, it controls the location of the {@link module:editor-decoupled/decouplededitoruiview~DecoupledEditorUIView#toolbar}: - * - * DecoupledEditor - * .create( 'Hello world!
', { - * // Append the toolbar to the element. - * toolbarContainer: document.body - * } ) - * .then( editor => { - * console.log( editor ); - * } ) - * .catch( error => { - * console.error( error ); - * } ); - * - * **Note**: If not specified, the toolbar must be manually injected into the DOM. See - * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`} - * to learn more. - * - * @member {HTMLElement} module:core/editor/editorconfig~EditorConfig#toolbarContainer - */ - -/** - * The configuration of the {@link module:editor-decoupled/decouplededitor~DecoupledEditor}. - * - * When specified, it controls the location of the {@link module:editor-decoupled/decouplededitoruiview~DecoupledEditorUIView#editable}: - * - * DecoupledEditor - * .create( 'Hello world!
', { - * // Append the editable to the element. - * editableContainer: document.body - * } ) - * .then( editor => { - * console.log( editor ); - * } ) - * .catch( error => { - * console.error( error ); - * } ); - * - * **Note**: If not specified, the editable must be manually injected into the DOM. See - * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`} - * to learn more. - * - * @member {HTMLElement} module:core/editor/editorconfig~EditorConfig#editableContainer - */ diff --git a/src/decouplededitorui.js b/src/decouplededitorui.js index f0ae78b..c36a581 100644 --- a/src/decouplededitorui.js +++ b/src/decouplededitorui.js @@ -52,22 +52,6 @@ export default class DecoupledEditorUI { * @private */ this._toolbarConfig = normalizeToolbarConfig( editor.config.get( 'toolbar' ) ); - - /** - * The container for the {@link module:editor-decoupled/decouplededitoruiview~DecoupledEditorUIView#toolbar}. - * - * @type {HTMLElement|String} - * @private - */ - this._toolbarContainer = editor.config.get( 'toolbarContainer' ); - - /** - * The container for the {@link module:editor-decoupled/decouplededitoruiview~DecoupledEditorUIView#editable}. - * - * @type {HTMLElement|String} - * @private - */ - this._editableContainer = editor.config.get( 'editableContainer' ); } /** @@ -83,19 +67,12 @@ export default class DecoupledEditorUI { const editingRoot = editor.editing.view.document.getRoot(); view.editable.bind( 'isReadOnly' ).to( editingRoot ); view.editable.bind( 'isFocused' ).to( editor.editing.view.document ); + editor.editing.view.attachDomRoot( view.editableElement ); view.editable.name = editingRoot.rootName; this.focusTracker.add( this.view.editableElement ); this.view.toolbar.fillFromConfig( this._toolbarConfig.items, this.componentFactory ); - if ( this._toolbarContainer ) { - this._toolbarContainer.appendChild( view.toolbar.element ); - } - - if ( this._editableContainer ) { - this._editableContainer.appendChild( view.editable.element ); - } - enableToolbarKeyboardFocus( { origin: editor.editing.view, originFocusTracker: this.focusTracker, @@ -108,6 +85,6 @@ export default class DecoupledEditorUI { * Destroys the UI. */ destroy() { - this.view.destroy( !!this._toolbarContainer, !!this._editableContainer ); + this.view.destroy(); } } diff --git a/src/decouplededitoruiview.js b/src/decouplededitoruiview.js index 4e8dd74..4e7338e 100644 --- a/src/decouplededitoruiview.js +++ b/src/decouplededitoruiview.js @@ -18,9 +18,8 @@ import Template from '@ckeditor/ckeditor5-ui/src/template'; * {@link module:editor-decoupled/decouplededitoruiview~DecoupledEditorUIView#toolbar}, but without any * specific arrangement of the components in the DOM. * - * See {@link module:core/editor/editorconfig~EditorConfig#toolbarContainer `config.toolbarContainer`} and - * {@link module:core/editor/editorconfig~EditorConfig#editableContainer `config.editableContainer`} to - * learn more about the UI of the decoupled editor. + * See {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`} + * to learn more about this view. * * @extends module:ui/editorui/editoruiview~EditorUIView */ @@ -29,8 +28,9 @@ export default class DecoupledEditorUIView extends EditorUIView { * Creates an instance of the decoupled editor UI view. * * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance. + * @param {HTMLElement} [editableElement] The DOM element to be used as editable. */ - constructor( locale ) { + constructor( locale, editableElement ) { super( locale ); /** @@ -47,7 +47,7 @@ export default class DecoupledEditorUIView extends EditorUIView { * @readonly * @member {module:ui/editableui/inline/inlineeditableuiview~InlineEditableUIView} */ - this.editable = new InlineEditableUIView( locale ); + this.editable = new InlineEditableUIView( locale, editableElement ); // This toolbar may be placed anywhere in the page so things like font size need to be reset in it. Template.extend( this.toolbar.template, { @@ -59,25 +59,6 @@ export default class DecoupledEditorUIView extends EditorUIView { this.registerChildren( [ this.toolbar, this.editable ] ); } - /** - * Destroys the view and removes the {@link #toolbar} and {@link #editable} - * {@link module:ui/view~View#element `element`} from the DOM, if required. - * - * @param {Boolean} [removeToolbar] When `true`, remove the {@link #toolbar} element from the DOM. - * @param {Boolean} [removeEditable] When `true`, remove the {@link #editable} element from the DOM. - */ - destroy( removeToolbar, removeEditable ) { - super.destroy(); - - if ( removeToolbar ) { - this.toolbar.element.remove(); - } - - if ( removeEditable ) { - this.editable.element.remove(); - } - } - /** * @inheritDoc */ diff --git a/tests/decouplededitor.js b/tests/decouplededitor.js index b96d651..95ae304 100644 --- a/tests/decouplededitor.js +++ b/tests/decouplededitor.js @@ -3,6 +3,8 @@ * For licensing, see LICENSE.md. */ +/* globals document */ + import DecoupledEditorUI from '../src/decouplededitorui'; import DecoupledEditorUIView from '../src/decouplededitoruiview'; @@ -19,16 +21,19 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; testUtils.createSinonSandbox(); -describe( 'DecoupledEditor', () => { - let editor, editorData; +const editorData = 'foo bar
'; - beforeEach( () => { - editorData = 'foo bar
'; - } ); +describe( 'DecoupledEditor', () => { + let editor; describe( 'constructor()', () => { beforeEach( () => { editor = new DecoupledEditor(); + editor.ui.init(); + } ); + + afterEach( () => { + return editor.destroy(); } ); it( 'uses HTMLDataProcessor', () => { @@ -52,173 +57,220 @@ describe( 'DecoupledEditor', () => { } ); describe( 'create()', () => { - beforeEach( () => { - return DecoupledEditor - .create( editorData, { - plugins: [ Paragraph, Bold ] - } ) - .then( newEditor => { - editor = newEditor; - } ); - } ); - afterEach( () => { return editor.destroy(); } ); - it( 'creates an instance which inherits from the DecoupledEditor', () => { - expect( editor ).to.be.instanceof( DecoupledEditor ); - } ); + describe( 'editor with data', () => { + beforeEach( () => { + return DecoupledEditor + .create( editorData, { + plugins: [ Paragraph, Bold ] + } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); - it( 'loads the initial data', () => { - expect( editor.getData() ).to.equal( 'foo bar
' ); + test( () => editorData ); } ); - // #53 - it( 'creates an instance of a DecoupledEditor child class', () => { - class CustomDecoupledEditor extends DecoupledEditor {} + describe( 'editor with editable element', () => { + let editableElement; - return CustomDecoupledEditor - .create( editorData, { - plugins: [ Paragraph, Bold ] - } ) - .then( newEditor => { - expect( newEditor ).to.be.instanceof( CustomDecoupledEditor ); - expect( newEditor ).to.be.instanceof( DecoupledEditor ); + beforeEach( () => { + editableElement = document.createElement( 'div' ); + editableElement.innerHTML = editorData; - expect( newEditor.getData() ).to.equal( 'foo bar
' ); + return DecoupledEditor + .create( editableElement, { + plugins: [ Paragraph, Bold ] + } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); - return newEditor.destroy(); - } ); + test( () => editableElement ); } ); - // https://github.com/ckeditor/ckeditor5-editor-decoupled/issues/3 - it( 'initializes the data controller', () => { - let dataInitSpy; + function test( getElementOrData ) { + it( 'creates an instance which inherits from the DecoupledEditor', () => { + expect( editor ).to.be.instanceof( DecoupledEditor ); + } ); - class DataInitAssertPlugin extends Plugin { - constructor( editor ) { - super(); + it( 'loads the initial data', () => { + expect( editor.getData() ).to.equal( 'foo bar
' ); + } ); - this.editor = editor; - } + // https://github.com/ckeditor/ckeditor5-editor-classic/issues/53 + it( 'creates an instance of a DecoupledEditor child class', () => { + class CustomDecoupledEditor extends DecoupledEditor {} - init() { - dataInitSpy = sinon.spy( this.editor.data, 'init' ); - } - } + return CustomDecoupledEditor + .create( getElementOrData(), { + plugins: [ Paragraph, Bold ] + } ) + .then( newEditor => { + expect( newEditor ).to.be.instanceof( CustomDecoupledEditor ); + expect( newEditor ).to.be.instanceof( DecoupledEditor ); - return DecoupledEditor - .create( editorData, { - plugins: [ Paragraph, Bold, DataInitAssertPlugin ] - } ) - .then( newEditor => { - sinon.assert.calledOnce( dataInitSpy ); + expect( newEditor.getData() ).to.equal( 'foo bar
' ); - return newEditor.destroy(); - } ); - } ); - - describe( 'ui', () => { - it( 'attaches editable UI as view\'s DOM root', () => { - expect( editor.editing.view.getDomRoot() ).to.equal( editor.ui.view.editable.element ); + return newEditor.destroy(); + } ); } ); - } ); - } ); - describe( 'create - events', () => { - afterEach( () => { - return editor.destroy(); - } ); + // https://github.com/ckeditor/ckeditor5-editor-decoupled/issues/3 + it( 'initializes the data controller', () => { + let dataInitSpy; - it( 'fires all events in the right order', () => { - const fired = []; + class DataInitAssertPlugin extends Plugin { + constructor( editor ) { + super(); - function spy( evt ) { - fired.push( evt.name ); - } + this.editor = editor; + } - class EventWatcher extends Plugin { - init() { - this.editor.on( 'pluginsReady', spy ); - this.editor.on( 'uiReady', spy ); - this.editor.on( 'dataReady', spy ); - this.editor.on( 'ready', spy ); + init() { + dataInitSpy = sinon.spy( this.editor.data, 'init' ); + } } - } - return DecoupledEditor - .create( editorData, { - plugins: [ EventWatcher ] - } ) - .then( newEditor => { - expect( fired ).to.deep.equal( [ 'pluginsReady', 'uiReady', 'dataReady', 'ready' ] ); + return DecoupledEditor + .create( getElementOrData(), { + plugins: [ Paragraph, Bold, DataInitAssertPlugin ] + } ) + .then( newEditor => { + sinon.assert.calledOnce( dataInitSpy ); + + return newEditor.destroy(); + } ); + } ); - editor = newEditor; + describe( 'events', () => { + it( 'fires all events in the right order', () => { + const fired = []; + + function spy( evt ) { + fired.push( evt.name ); + } + + class EventWatcher extends Plugin { + init() { + this.editor.on( 'pluginsReady', spy ); + this.editor.on( 'uiReady', spy ); + this.editor.on( 'dataReady', spy ); + this.editor.on( 'ready', spy ); + } + } + + return DecoupledEditor + .create( getElementOrData(), { + plugins: [ EventWatcher ] + } ) + .then( newEditor => { + expect( fired ).to.deep.equal( [ 'pluginsReady', 'uiReady', 'dataReady', 'ready' ] ); + + return newEditor.destroy(); + } ); } ); - } ); - it( 'fires dataReady once data is loaded', () => { - let data; + it( 'fires dataReady once data is loaded', () => { + let data; + + class EventWatcher extends Plugin { + init() { + this.editor.on( 'dataReady', () => { + data = this.editor.getData(); + } ); + } + } + + return DecoupledEditor + .create( getElementOrData(), { + plugins: [ EventWatcher, Paragraph, Bold ] + } ) + .then( newEditor => { + expect( data ).to.equal( 'foo bar
' ); + + return newEditor.destroy(); + } ); + } ); - class EventWatcher extends Plugin { - init() { - this.editor.on( 'dataReady', () => { - data = this.editor.getData(); - } ); - } - } + it( 'fires uiReady once UI is rendered', () => { + let isReady; + + class EventWatcher extends Plugin { + init() { + this.editor.on( 'uiReady', () => { + isReady = this.editor.ui.view.isRendered; + } ); + } + } + + return DecoupledEditor + .create( getElementOrData(), { + plugins: [ EventWatcher ] + } ) + .then( newEditor => { + expect( isReady ).to.be.true; + + return newEditor.destroy(); + } ); + } ); + } ); + } + } ); - return DecoupledEditor - .create( editorData, { - plugins: [ EventWatcher, Paragraph, Bold ] - } ) - .then( newEditor => { - expect( data ).to.equal( 'foo bar
' ); + describe( 'destroy', () => { + describe( 'editor with data', () => { + beforeEach( function() { + return DecoupledEditor + .create( editorData, { plugins: [ Paragraph ] } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); - editor = newEditor; - } ); + test( () => editorData ); } ); - it( 'fires uiReady once UI is rendered', () => { - let isReady; + describe( 'editor with editable element', () => { + let editableElement; + + beforeEach( function() { + editableElement = document.createElement( 'div' ); + editableElement.innerHTML = editorData; - class EventWatcher extends Plugin { - init() { - this.editor.on( 'uiReady', () => { - isReady = this.editor.ui.view.isRendered; + return DecoupledEditor + .create( editableElement, { plugins: [ Paragraph ] } ) + .then( newEditor => { + editor = newEditor; } ); - } - } + } ); - return DecoupledEditor - .create( editorData, { - plugins: [ EventWatcher ] - } ) - .then( newEditor => { - expect( isReady ).to.be.true; + it( 'sets data back to the element', () => { + editor.setData( 'foo
' ); - editor = newEditor; - } ); - } ); - } ); + return editor.destroy() + .then( () => { + expect( editableElement.innerHTML ).to.equal( 'foo
' ); + } ); + } ); - describe( 'destroy', () => { - beforeEach( function() { - return DecoupledEditor - .create( editorData, { plugins: [ Paragraph ] } ) - .then( newEditor => { - editor = newEditor; - } ); + test( () => editableElement ); } ); - it( 'destroys the UI', () => { - const spy = sinon.spy( editor.ui, 'destroy' ); + function test() { + it( 'destroys the UI', () => { + const spy = sinon.spy( editor.ui, 'destroy' ); - return editor.destroy() - .then( () => { - sinon.assert.calledOnce( spy ); - } ); - } ); + return editor.destroy() + .then( () => { + sinon.assert.calledOnce( spy ); + } ); + } ); + } } ); } ); diff --git a/tests/decouplededitorui.js b/tests/decouplededitorui.js index 907a2fc..943477b 100644 --- a/tests/decouplededitorui.js +++ b/tests/decouplededitorui.js @@ -63,45 +63,6 @@ describe( 'DecoupledEditorUI', () => { expect( view.isRendered ).to.be.true; } ); - describe( 'config', () => { - it( 'does nothing if not specified', () => { - expect( view.toolbar.element.parentElement ).to.be.null; - expect( view.editable.element.parentElement ).to.be.null; - } ); - - it( 'allocates view#toolbar', () => { - return VirtualDecoupledTestEditor - .create( { - toolbar: [ 'foo', 'bar' ], - toolbarContainer: document.body - } ) - .then( newEditor => { - expect( newEditor.ui.view.toolbar.element.parentElement ).to.equal( document.body ); - - return newEditor; - } ) - .then( newEditor => { - newEditor.destroy(); - } ); - } ); - - it( 'allocates view#editable', () => { - return VirtualDecoupledTestEditor - .create( { - toolbar: [ 'foo', 'bar' ], - editableContainer: document.body - } ) - .then( newEditor => { - expect( newEditor.ui.view.editable.element.parentElement ).to.equal( document.body ); - - return newEditor; - } ) - .then( newEditor => { - newEditor.destroy(); - } ); - } ); - } ); - describe( 'editable', () => { it( 'registers view.editable#element in editor focus tracker', () => { ui.focusTracker.isFocused = false; @@ -139,6 +100,10 @@ describe( 'DecoupledEditorUI', () => { { isReadOnly: true } ); } ); + + it( 'attaches editable UI as view\'s DOM root', () => { + expect( editor.editing.view.getDomRoot() ).to.equal( view.editable.element ); + } ); } ); describe( 'view.toolbar#items', () => { @@ -207,43 +172,7 @@ describe( 'DecoupledEditorUI', () => { return editor.destroy() .then( () => { sinon.assert.calledOnce( spy ); - sinon.assert.calledWithExactly( spy, false, false ); - } ); - } ); - - it( 'removes view#toolbar from DOM, if config.toolbarContainer is specified', () => { - let spy; - - return VirtualDecoupledTestEditor - .create( { - toolbar: [ 'foo', 'bar' ], - toolbarContainer: document.body - } ) - .then( newEditor => { - spy = sinon.spy( newEditor.ui.view, 'destroy' ); - - newEditor.destroy(); - } ) - .then( () => { - sinon.assert.calledWithExactly( spy, true, false ); - } ); - } ); - - it( 'removes view#editable from DOM, if config.editableContainer is specified', () => { - let spy; - - return VirtualDecoupledTestEditor - .create( { - toolbar: [ 'foo', 'bar' ], - editableContainer: document.body - } ) - .then( newEditor => { - spy = sinon.spy( newEditor.ui.view, 'destroy' ); - - newEditor.destroy(); - } ) - .then( () => { - sinon.assert.calledWithExactly( spy, false, true ); + sinon.assert.calledWithExactly( spy ); } ); } ); } ); diff --git a/tests/decouplededitoruiview.js b/tests/decouplededitoruiview.js index bfbcf07..f5a4590 100644 --- a/tests/decouplededitoruiview.js +++ b/tests/decouplededitoruiview.js @@ -53,7 +53,7 @@ describe( 'DecoupledEditorUIView', () => { expect( view.editable ).to.be.instanceof( InlineEditableUIView ); } ); - it( 'is given a locate object', () => { + it( 'is given a locale object', () => { expect( view.editable.locale ).to.equal( locale ); } ); @@ -61,6 +61,17 @@ describe( 'DecoupledEditorUIView', () => { expect( view.isRendered ).to.be.true; expect( view.editable.element.parentElement ).to.be.null; } ); + + it( 'can be created out of an existing DOM element', () => { + const editableElement = document.createElement( 'div' ); + const testView = new DecoupledEditorUIView( locale, editableElement ); + + testView.render(); + + expect( testView.editable.element ).to.equal( editableElement ); + + testView.destroy(); + } ); } ); } ); @@ -87,30 +98,6 @@ describe( 'DecoupledEditorUIView', () => { view.toolbar.element.remove(); view.editable.element.remove(); } ); - - it( 'removes toolbar#element on demand', () => { - document.body.appendChild( view.toolbar.element ); - document.body.appendChild( view.editable.element ); - - view.destroy( true ); - - expect( view.toolbar.element.parentElement ).to.be.null; - expect( view.editable.element.parentElement ).to.equal( document.body ); - - view.editable.element.remove(); - } ); - - it( 'removes editable#element on demand', () => { - document.body.appendChild( view.toolbar.element ); - document.body.appendChild( view.editable.element ); - - view.destroy( false, true ); - - expect( view.toolbar.element.parentElement ).to.equal( document.body ); - expect( view.editable.element.parentElement ).to.be.null; - - view.toolbar.element.remove(); - } ); } ); describe( 'editableElement', () => { diff --git a/tests/manual/decouplededitor-editable.html b/tests/manual/decouplededitor-editable.html new file mode 100644 index 0000000..25498f3 --- /dev/null +++ b/tests/manual/decouplededitor-editable.html @@ -0,0 +1,58 @@ ++ + +
+ +It has the initial editor data. It should keep it after the editor is destroyed too.
+