From 884ce13c32f5db8e92f145ffff9f2ad02d69c55f Mon Sep 17 00:00:00 2001 From: Kamil Piechaczek Date: Tue, 4 Jun 2019 16:13:29 +0200 Subject: [PATCH 1/4] Introduced a check that prevents creating the editor using the same element more than once. --- src/decouplededitor.js | 3 +++ tests/decouplededitor.js | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/decouplededitor.js b/src/decouplededitor.js index 0f6f9b4..1f9f718 100644 --- a/src/decouplededitor.js +++ b/src/decouplededitor.js @@ -17,6 +17,7 @@ import setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement import mix from '@ckeditor/ckeditor5-utils/src/mix'; import { isElement } from 'lodash-es'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; +import secureSourceElement from '@ckeditor/ckeditor5-core/src/editor/utils/securesourceelement'; /** * The {@glink builds/guides/overview#document-editor decoupled editor} implementation. @@ -76,6 +77,8 @@ export default class DecoupledEditor extends Editor { const view = new DecoupledEditorUIView( this.locale, this.editing.view, this.sourceElement ); this.ui = new DecoupledEditorUI( this, view ); + + secureSourceElement( this ); } /** diff --git a/tests/decouplededitor.js b/tests/decouplededitor.js index 8e40316..48de0c7 100644 --- a/tests/decouplededitor.js +++ b/tests/decouplededitor.js @@ -22,6 +22,7 @@ import log from '@ckeditor/ckeditor5-utils/src/log'; import { describeMemoryUsage, testMemoryUsage } from '@ckeditor/ckeditor5-core/tests/_utils/memory'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; +import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; const editorData = '

foo bar

'; @@ -125,6 +126,20 @@ describe( 'DecoupledEditor', () => { } ); } ); + // See: https://github.com/ckeditor/ckeditor5/issues/746 + it( 'should throw when trying to create the editor using the same source element more than once', () => { + const sourceElement = document.createElement( 'div' ); + + return DecoupledEditor.create( sourceElement ) + .then( editor => { + expect( () => { + new DecoupledEditor( sourceElement ); // eslint-disable-line no-new + } ).to.throw( CKEditorError, /^securesourceelement-source-element-used-more-than-once/ ); + + return editor.destroy(); + } ); + } ); + it( 'throws if initial data is passed in Editor#create and config.initialData is also used', done => { DecoupledEditor.create( '

Hello world!

', { initialData: '

I am evil!

', From ed1073c2ae71e20ed08926f4f6a5c9c1408a2d34 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Fri, 19 Jul 2019 17:05:18 +0200 Subject: [PATCH 2/4] Updated the ElementApiMixin#secureSourceElement error message to the latest API. --- tests/decouplededitor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/decouplededitor.js b/tests/decouplededitor.js index 722075f..ff6a82f 100644 --- a/tests/decouplededitor.js +++ b/tests/decouplededitor.js @@ -134,7 +134,7 @@ describe( 'DecoupledEditor', () => { .then( editor => { expect( () => { new DecoupledEditor( sourceElement ); // eslint-disable-line no-new - } ).to.throw( CKEditorError, /^securesourceelement-source-element-used-more-than-once/ ); + } ).to.throw( CKEditorError, /^editor-source-element-used-more-than-once/ ); return editor.destroy(); } ); From 000f09dfd622f61f11a49976f24831c890f379d2 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Fri, 19 Jul 2019 17:12:32 +0200 Subject: [PATCH 3/4] Mixed the ElementApiMixin. Used the ElementApiMixin#secureSourceElement(). --- src/decouplededitor.js | 6 ++++-- tests/decouplededitor.js | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/decouplededitor.js b/src/decouplededitor.js index 7a7b407..f1fcfdc 100644 --- a/src/decouplededitor.js +++ b/src/decouplededitor.js @@ -14,10 +14,10 @@ import DecoupledEditorUI from './decouplededitorui'; import DecoupledEditorUIView from './decouplededitoruiview'; import getDataFromElement from '@ckeditor/ckeditor5-utils/src/dom/getdatafromelement'; import setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement'; +import ElementApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin'; import mix from '@ckeditor/ckeditor5-utils/src/mix'; import { isElement } from 'lodash-es'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import secureSourceElement from '@ckeditor/ckeditor5-core/src/editor/utils/securesourceelement'; /** * The {@glink builds/guides/overview#document-editor decoupled editor} implementation. @@ -48,6 +48,7 @@ import secureSourceElement from '@ckeditor/ckeditor5-core/src/editor/utils/secur * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`}. * * @mixes module:core/editor/utils/dataapimixin~DataApiMixin + * @mixes module:core/editor/utils/elementapimixin~ElementApiMixin * @implements module:core/editor/editorwithui~EditorWithUI * @extends module:core/editor/editor~Editor */ @@ -78,7 +79,7 @@ export default class DecoupledEditor extends Editor { const view = new DecoupledEditorUIView( this.locale, this.editing.view, this.sourceElement ); this.ui = new DecoupledEditorUI( this, view ); - secureSourceElement( this ); + this.secureSourceElement(); } /** @@ -254,6 +255,7 @@ export default class DecoupledEditor extends Editor { } mix( DecoupledEditor, DataApiMixin ); +mix( DecoupledEditor, ElementApiMixin ); function getInitialData( sourceElementOrData ) { return isElement( sourceElementOrData ) ? getDataFromElement( sourceElementOrData ) : sourceElementOrData; diff --git a/tests/decouplededitor.js b/tests/decouplededitor.js index ff6a82f..39c3377 100644 --- a/tests/decouplededitor.js +++ b/tests/decouplededitor.js @@ -15,6 +15,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import DataApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin'; +import ElementApiMixin from '@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin'; import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; @@ -48,6 +49,10 @@ describe( 'DecoupledEditor', () => { expect( testUtils.isMixed( DecoupledEditor, DataApiMixin ) ).to.be.true; } ); + it( 'has an Element Interface', () => { + testUtils.isMixed( DecoupledEditor, ElementApiMixin ); + } ); + it( 'creates main root element', () => { expect( editor.model.document.getRoot( 'main' ) ).to.instanceof( RootElement ); } ); From dad8e423f0d9ba3a6ead5f8e078380a1276c3315 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Fri, 19 Jul 2019 17:14:37 +0200 Subject: [PATCH 4/4] Code refactoring. --- src/decouplededitor.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/decouplededitor.js b/src/decouplededitor.js index f1fcfdc..8cd0524 100644 --- a/src/decouplededitor.js +++ b/src/decouplededitor.js @@ -70,6 +70,7 @@ export default class DecoupledEditor extends Editor { if ( isElement( sourceElementOrData ) ) { this.sourceElement = sourceElementOrData; + this.secureSourceElement(); } this.data.processor = new HtmlDataProcessor(); @@ -78,8 +79,6 @@ export default class DecoupledEditor extends Editor { const view = new DecoupledEditorUIView( this.locale, this.editing.view, this.sourceElement ); this.ui = new DecoupledEditorUI( this, view ); - - this.secureSourceElement(); } /**