diff --git a/src/editor/editorwithui.jsdoc b/src/editor/editorwithui.jsdoc index 37764081..bb0f93c7 100644 --- a/src/editor/editorwithui.jsdoc +++ b/src/editor/editorwithui.jsdoc @@ -28,6 +28,23 @@ * @member {module:core/editor/editorui~EditorUI} #ui */ + /** + * The main (outermost) DOM element of the editor's UI. + * + * For example, in the {@link module:editor-classic/classiceditor~ClassicEditor} it is a `
` which + * wraps the editable element and the toolbar. In the {@link module:editor-inline/inlineeditor~InlineEditor} + * it is the editable element itself (as there is no other wrapper). However, in the + * {@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 which specific editor integration + * considers to be its main DOM element. There are always other ways to access these elements too + * (e.g. via {@link #ui `editor.ui`}). + * + * @readonly + * @member {HTMLElement|null} #element + */ + /** * Fired when the editor UI is ready. * diff --git a/src/editor/utils/attachtoform.js b/src/editor/utils/attachtoform.js index feccdee6..0da91318 100644 --- a/src/editor/utils/attachtoform.js +++ b/src/editor/utils/attachtoform.js @@ -19,7 +19,7 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; * @param {module:core/editor/editor~Editor} editor Editor instance. */ export default function attachToForm( editor ) { - if ( !isFunction( editor.updateElement ) ) { + if ( !isFunction( editor.updateSourceElement ) ) { /** * {@link module:core/editor/utils/elementapimixin~ElementApi ElementApi interface} is required. * @@ -28,13 +28,13 @@ export default function attachToForm( editor ) { throw new CKEditorError( 'attachtoform-missing-elementapi-interface: ElementApi interface is required.' ); } - const element = editor.element; + const sourceElement = editor.sourceElement; // Only when replacing a textarea which is inside of a form element. - if ( element && element.tagName.toLowerCase() === 'textarea' && element.form ) { + if ( sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.form ) { let originalSubmit; - const form = element.form; - const onSubmit = () => editor.updateElement(); + const form = sourceElement.form; + const onSubmit = () => editor.updateSourceElement(); // Replace the original form#submit() to call a custom submit function first. // Check if #submit is a function because the form might have an input named "submit". diff --git a/src/editor/utils/elementapimixin.js b/src/editor/utils/elementapimixin.js index ed86f43a..48d06f35 100644 --- a/src/editor/utils/elementapimixin.js +++ b/src/editor/utils/elementapimixin.js @@ -3,6 +3,7 @@ * For licensing, see LICENSE.md. */ +import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement'; /** @@ -19,8 +20,20 @@ const ElementApiMixin = { /** * @inheritDoc */ - updateElement() { - setDataInElement( this.element, this.data.get() ); + updateSourceElement() { + if ( !this.sourceElement ) { + /** + * Cannot update the source element of a detached editor. + * + * The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not + * pass an element to `Editor.create()`. + * + * @error editor-missing-sourceelement + */ + throw new CKEditorError( 'editor-missing-sourceelement: Cannot update the source element of a detached editor.' ); + } + + setDataInElement( this.sourceElement, this.data.get() ); } }; @@ -30,7 +43,7 @@ export default ElementApiMixin; * Interface describing an editor which replaced a DOM element (was "initialized on an element"). * * Such an editor should provide a method to - * {@link module:core/editor/utils/elementapimixin~ElementApi#updateElement update the replaced element with the current data}. + * {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement update the replaced element with the current data}. * * @interface ElementApi */ @@ -39,11 +52,11 @@ export default ElementApiMixin; * The element on which the editor has been initialized. * * @readonly - * @member {HTMLElement} #element + * @member {HTMLElement} #sourceElement */ /** - * Updates the {@link #element editor element}'s content with the data. + * Updates the {@link #sourceElement editor source element}'s content with the data. * - * @method #updateElement + * @method #updateSourceElement */ diff --git a/tests/editor/utils/attachtoform.js b/tests/editor/utils/attachtoform.js index 55fb2f9c..6cb928c4 100644 --- a/tests/editor/utils/attachtoform.js +++ b/tests/editor/utils/attachtoform.js @@ -53,7 +53,7 @@ describe( 'attachToForm()', () => { } ); it( 'should update editor#element after the "submit" event', () => { - editor.element = textarea; + editor.sourceElement = textarea; attachToForm( editor ); expect( textarea.value ).to.equal( '' ); @@ -67,7 +67,7 @@ describe( 'attachToForm()', () => { } ); it( 'should update editor#element after calling the submit() method', () => { - editor.element = textarea; + editor.sourceElement = textarea; attachToForm( editor ); expect( textarea.value ).to.equal( '' ); @@ -87,7 +87,7 @@ describe( 'attachToForm()', () => { const element = document.createElement( 'div' ); form.appendChild( element ); - editor.element = element; + editor.sourceElement = element; attachToForm( editor ); expect( textarea.value ).to.equal( '' ); @@ -103,7 +103,7 @@ describe( 'attachToForm()', () => { const standaloneTextarea = document.createElement( 'textarea' ); document.body.appendChild( standaloneTextarea ); - editor.element = standaloneTextarea; + editor.sourceElement = standaloneTextarea; attachToForm( editor ); expect( standaloneTextarea.value ).to.equal( '' ); @@ -118,7 +118,7 @@ describe( 'attachToForm()', () => { } ); it( 'should not update editor#element after destruction of the editor - form.submit()', () => { - editor.element = textarea; + editor.sourceElement = textarea; attachToForm( editor ); expect( textarea.value ).to.equal( '' ); @@ -133,7 +133,7 @@ describe( 'attachToForm()', () => { } ); it( 'should not update the editor#element after destruction of the editor - "submit" event', () => { - editor.element = textarea; + editor.sourceElement = textarea; attachToForm( editor ); expect( textarea.value ).to.equal( '' ); @@ -156,7 +156,7 @@ describe( 'attachToForm()', () => { input.setAttribute( 'name', 'submit' ); form.appendChild( input ); - editor.element = textarea; + editor.sourceElement = textarea; attachToForm( editor ); expect( form.submit ).to.equal( input ); diff --git a/tests/editor/utils/elementapimixin.js b/tests/editor/utils/elementapimixin.js index 3c8583db..9c543dae 100644 --- a/tests/editor/utils/elementapimixin.js +++ b/tests/editor/utils/elementapimixin.js @@ -9,6 +9,7 @@ import ElementApiMixin from '../../../src/editor/utils/elementapimixin'; import Editor from '../../../src/editor/editor'; import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor'; import mix from '@ckeditor/ckeditor5-utils/src/mix'; +import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; describe( 'ElementApiMixin', () => { let editor; @@ -27,9 +28,9 @@ describe( 'ElementApiMixin', () => { editor.destroy(); } ); - describe( 'updateEditorElement()', () => { + describe( 'updateSourceElement()', () => { it( 'should be added to editor interface', () => { - expect( editor ).have.property( 'updateElement' ).to.be.a( 'function' ); + expect( editor ).have.property( 'updateSourceElement' ).to.be.a( 'function' ); } ); it( 'sets data to editor element', () => { @@ -37,11 +38,15 @@ describe( 'ElementApiMixin', () => { editor.data.set( 'foo bar' ); - editor.element = editorElement; + editor.sourceElement = editorElement; - editor.updateElement(); + editor.updateSourceElement(); expect( editorElement.innerHTML ).to.equal( 'foo bar' ); } ); + + it( 'throws an error if "sourceElement" has not been set', () => { + expect( () => editor.updateSourceElement() ).to.throw( CKEditorError, /editor-missing-sourceelement/ ); + } ); } ); } );