From dccbea9dec7fd9e552ef352c1105c129d8de33f5 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 13 Jun 2018 11:29:19 +0200 Subject: [PATCH 1/7] Renamed editor.element to editor.sourceElement. Introduced an "element" property to "EditorWithUI" interface. --- src/editor/editorwithui.jsdoc | 7 +++++++ src/editor/utils/attachtoform.js | 10 +++++----- src/editor/utils/elementapimixin.js | 12 ++++++------ tests/editor/utils/attachtoform.js | 14 +++++++------- tests/editor/utils/elementapimixin.js | 6 +++--- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/editor/editorwithui.jsdoc b/src/editor/editorwithui.jsdoc index 37764081..256e0683 100644 --- a/src/editor/editorwithui.jsdoc +++ b/src/editor/editorwithui.jsdoc @@ -28,6 +28,13 @@ * @member {module:core/editor/editorui~EditorUI} #ui */ + /** + * An HTML element that represents the editor with the UI. + * + * @readonly + * @member {HTMLElement} #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..385f8d78 100644 --- a/src/editor/utils/elementapimixin.js +++ b/src/editor/utils/elementapimixin.js @@ -19,8 +19,8 @@ const ElementApiMixin = { /** * @inheritDoc */ - updateElement() { - setDataInElement( this.element, this.data.get() ); + updateSourceElement() { + setDataInElement( this.sourceElement, this.data.get() ); } }; @@ -30,7 +30,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 +39,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 76092452..ef089c8b 100644 --- a/tests/editor/utils/attachtoform.js +++ b/tests/editor/utils/attachtoform.js @@ -52,7 +52,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( '' ); @@ -66,7 +66,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( '' ); @@ -86,7 +86,7 @@ describe( 'attachToForm()', () => { const element = document.createElement( 'div' ); form.appendChild( element ); - editor.element = element; + editor.sourceElement = element; attachToForm( editor ); expect( textarea.value ).to.equal( '' ); @@ -102,7 +102,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( '' ); @@ -117,7 +117,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( '' ); @@ -132,7 +132,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( '' ); @@ -155,7 +155,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..221b471d 100644 --- a/tests/editor/utils/elementapimixin.js +++ b/tests/editor/utils/elementapimixin.js @@ -29,7 +29,7 @@ describe( 'ElementApiMixin', () => { describe( 'updateEditorElement()', () => { 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,9 +37,9 @@ describe( 'ElementApiMixin', () => { editor.data.set( 'foo bar' ); - editor.element = editorElement; + editor.sourceElement = editorElement; - editor.updateElement(); + editor.updateSourceElement(); expect( editorElement.innerHTML ).to.equal( 'foo bar' ); } ); From dd7f715eb060dab640d4ac904d57e8e1471df902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Koszuli=C5=84ski?= Date: Tue, 26 Jun 2018 23:24:41 +0200 Subject: [PATCH 2/7] Improved API docs. --- src/editor/editorwithui.jsdoc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/editor/editorwithui.jsdoc b/src/editor/editorwithui.jsdoc index 256e0683..bb0f93c7 100644 --- a/src/editor/editorwithui.jsdoc +++ b/src/editor/editorwithui.jsdoc @@ -29,10 +29,20 @@ */ /** - * An HTML element that represents the editor with the 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} #element + * @member {HTMLElement|null} #element */ /** From e8cc7eddeb028e5a90edf53c9db4d5cb87823e34 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Wed, 27 Jun 2018 10:53:06 +0200 Subject: [PATCH 3/7] ElementApi#updateSourceElement will throw an error if ElementApi#sourceElement is undefined. --- src/editor/utils/elementapimixin.js | 10 ++++++++++ tests/editor/utils/elementapimixin.js | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/editor/utils/elementapimixin.js b/src/editor/utils/elementapimixin.js index 385f8d78..116df81e 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'; /** @@ -20,6 +21,15 @@ const ElementApiMixin = { * @inheritDoc */ updateSourceElement() { + if ( !this.sourceElement ) { + /** + * The `sourceElement` is required by the `ElementApi` interface. + * + * @error elementapimixin-missing-sourceelement + */ + throw new CKEditorError( 'elementapi-missing-sourceelement: The "sourceElement" is required by the "ElementApi" interface.' ); + } + setDataInElement( this.sourceElement, this.data.get() ); } }; diff --git a/tests/editor/utils/elementapimixin.js b/tests/editor/utils/elementapimixin.js index 221b471d..5027eded 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,7 +28,7 @@ describe( 'ElementApiMixin', () => { editor.destroy(); } ); - describe( 'updateEditorElement()', () => { + describe( 'updateSourceElement()', () => { it( 'should be added to editor interface', () => { expect( editor ).have.property( 'updateSourceElement' ).to.be.a( 'function' ); } ); @@ -43,5 +44,9 @@ describe( 'ElementApiMixin', () => { expect( editorElement.innerHTML ).to.equal( 'foo bar' ); } ); + + it( 'throws an error if "sourceElement" has not set', () => { + expect( () => editor.updateSourceElement() ).to.throw( CKEditorError, /elementapi-missing-sourceelement/ ); + } ); } ); } ); From 84b8c3893f01eae1338dbb2499872ca115b7f6d2 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Thu, 28 Jun 2018 12:13:54 +0200 Subject: [PATCH 4/7] Improved the error desc. --- src/editor/utils/elementapimixin.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/editor/utils/elementapimixin.js b/src/editor/utils/elementapimixin.js index 116df81e..ffbdaca7 100644 --- a/src/editor/utils/elementapimixin.js +++ b/src/editor/utils/elementapimixin.js @@ -23,7 +23,9 @@ const ElementApiMixin = { updateSourceElement() { if ( !this.sourceElement ) { /** - * The `sourceElement` is required by the `ElementApi` interface. + * In case of the editor is creating using an initial data instead of the DOM element, + * the {@link ElementApi~updateSourceElement `updateSourceElement()`} method cannot be called because there is no + * {@link ElementApi~sourceElement `sourceElement`} that could be updated. * * @error elementapimixin-missing-sourceelement */ From a233bcf18b352e8ddc063edaa524eacf4c19104f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Koszuli=C5=84ski?= Date: Thu, 28 Jun 2018 16:33:51 +0200 Subject: [PATCH 5/7] Improved an error message. --- src/editor/utils/elementapimixin.js | 11 ++++++----- tests/editor/utils/elementapimixin.js | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/editor/utils/elementapimixin.js b/src/editor/utils/elementapimixin.js index ffbdaca7..75ab6236 100644 --- a/src/editor/utils/elementapimixin.js +++ b/src/editor/utils/elementapimixin.js @@ -23,13 +23,14 @@ const ElementApiMixin = { updateSourceElement() { if ( !this.sourceElement ) { /** - * In case of the editor is creating using an initial data instead of the DOM element, - * the {@link ElementApi~updateSourceElement `updateSourceElement()`} method cannot be called because there is no - * {@link ElementApi~sourceElement `sourceElement`} that could be updated. + * Cannot update the source element of a detached editor. * - * @error elementapimixin-missing-sourceelement + * 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( 'elementapi-missing-sourceelement: The "sourceElement" is required by the "ElementApi" interface.' ); + throw new CKEditorError( 'editor-missing-sourceelement: Cannot update the source element of a detached editor.' ); } setDataInElement( this.sourceElement, this.data.get() ); diff --git a/tests/editor/utils/elementapimixin.js b/tests/editor/utils/elementapimixin.js index 5027eded..9c543dae 100644 --- a/tests/editor/utils/elementapimixin.js +++ b/tests/editor/utils/elementapimixin.js @@ -45,8 +45,8 @@ describe( 'ElementApiMixin', () => { expect( editorElement.innerHTML ).to.equal( 'foo bar' ); } ); - it( 'throws an error if "sourceElement" has not set', () => { - expect( () => editor.updateSourceElement() ).to.throw( CKEditorError, /elementapi-missing-sourceelement/ ); + it( 'throws an error if "sourceElement" has not been set', () => { + expect( () => editor.updateSourceElement() ).to.throw( CKEditorError, /editor-missing-sourceelement/ ); } ); } ); } ); From 7ee9567ef9ec3e364d1aa78f89de18580945bf61 Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Fri, 29 Jun 2018 12:36:58 +0200 Subject: [PATCH 6/7] Fixed invalid link. --- src/editor/utils/elementapimixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editor/utils/elementapimixin.js b/src/editor/utils/elementapimixin.js index 75ab6236..c1aa7fc7 100644 --- a/src/editor/utils/elementapimixin.js +++ b/src/editor/utils/elementapimixin.js @@ -25,7 +25,7 @@ const ElementApiMixin = { /** * Cannot update the source element of a detached editor. * - * The {@link ElementApi~updateSourceElement `updateSourceElement()`} method cannot be called if you did not + * The {@link ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not * pass an element to `Editor.create()`. * * @error editor-missing-sourceelement From d01f919c487fb6ce41bf93162d210ebb85c956ec Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Fri, 29 Jun 2018 13:22:19 +0200 Subject: [PATCH 7/7] Fixed invalid link (missing module). --- src/editor/utils/elementapimixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editor/utils/elementapimixin.js b/src/editor/utils/elementapimixin.js index c1aa7fc7..48d06f35 100644 --- a/src/editor/utils/elementapimixin.js +++ b/src/editor/utils/elementapimixin.js @@ -25,7 +25,7 @@ const ElementApiMixin = { /** * Cannot update the source element of a detached editor. * - * The {@link ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not + * The {@link ~ElementApi#updateSourceElement `updateSourceElement()`} method cannot be called if you did not * pass an element to `Editor.create()`. * * @error editor-missing-sourceelement