Explorar el Código

Moved secureSourceElement() to ElementApiMixin.

Aleksander Nowodzinski hace 6 años
padre
commit
867cfe2013

+ 39 - 0
packages/ckeditor5-core/src/editor/utils/elementapimixin.js

@@ -10,6 +10,8 @@ import setDataInElement from '@ckeditor/ckeditor5-utils/src/dom/setdatainelement
  * @module core/editor/utils/elementapimixin
  */
 
+const SECURE_SOURCE_ELEMENT_ATTRIBUTE = 'data-ckeditor5-element';
+
 /**
  * Implementation of the {@link module:core/editor/utils/elementapimixin~ElementApi}.
  *
@@ -37,6 +39,43 @@ const ElementApiMixin = {
 		}
 
 		setDataInElement( this.sourceElement, this.data.get() );
+	},
+
+	/**
+	 * Marks the source element the editor was initialized on preventing other editor instances from
+	 * using this element.
+	 *
+	 * Running multiple editor instances on the same source element causes various issues and it is
+	 * crucial this helper is called as soon as the source element is known to prevent collisions.
+	 */
+	secureSourceElement() {
+		const sourceElement = this.sourceElement;
+
+		// If the editor was initialized without specifying an element, we don't need to secure anything.
+		if ( !sourceElement ) {
+			return;
+		}
+
+		if ( sourceElement.hasAttribute( SECURE_SOURCE_ELEMENT_ATTRIBUTE ) ) {
+			/**
+			 * A DOM element used to create the editor (e.g.
+			 * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`})
+			 * has already been used to create another editor instance. Make sure each editor is
+			 * created with an unique DOM element.
+			 *
+			 * @error editor-source-element-used-more-than-once
+			 */
+			throw new CKEditorError(
+				'editor-source-element-used-more-than-once: ' +
+				'The DOM source element cannot be used to create an editor more than once.'
+			);
+		}
+
+		sourceElement.setAttribute( SECURE_SOURCE_ELEMENT_ATTRIBUTE, 'true' );
+
+		this.once( 'destroy', () => {
+			sourceElement.removeAttribute( SECURE_SOURCE_ELEMENT_ATTRIBUTE );
+		} );
 	}
 };
 

+ 0 - 47
packages/ckeditor5-core/src/editor/utils/securesourceelement.js

@@ -1,47 +0,0 @@
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
-
-/**
- * @module core/editor/utils/securesourceelement
- */
-
-const SECURE_ATTRIBUTE = 'data-ckeditor5';
-
-/**
- * Checks if the editor was initialized using a source element. If yes, it prevents to creating another editor
- * using the same source element. In other words, you cannot use the same source element more than once.
- *
- * @param {module:core/editor/editor~Editor} editor Editor instance.
- */
-export default function secureSourceElement( editor ) {
-	const sourceElement = editor.sourceElement;
-
-	// If the editor was initialized without specifying an element, we don't need to secure anything.
-	if ( !sourceElement ) {
-		return;
-	}
-
-	if ( sourceElement.hasAttribute( SECURE_ATTRIBUTE ) ) {
-		/**
-		 * An element passed to the editor creator has been passed more than once. The element can be used only once.
-		 *
-		 * @error securesourceelement-source-element-used-more-than-once
-		 */
-		throw new CKEditorError(
-			'securesourceelement-source-element-used-more-than-once: ' +
-			'The editor cannot be initialized using the same source element more than once.'
-		);
-	}
-
-	// Mark the source element.
-	sourceElement.setAttribute( SECURE_ATTRIBUTE, 'true' );
-
-	// Remove the attribute when the editor is being destroyed.
-	editor.once( 'destroy', () => {
-		sourceElement.removeAttribute( SECURE_ATTRIBUTE );
-	} );
-}

+ 48 - 0
packages/ckeditor5-core/tests/editor/utils/elementapimixin.js

@@ -53,4 +53,52 @@ describe( 'ElementApiMixin', () => {
 			);
 		} );
 	} );
+
+	describe( 'secureSourceElement()', () => {
+		let sourceElement;
+
+		beforeEach( () => {
+			sourceElement = document.createElement( 'div' );
+
+			editor.sourceElement = sourceElement;
+			editor.state = 'ready';
+		} );
+
+		it( 'does not throw if the editor was not initialized using the source element', () => {
+			delete editor.sourceElement;
+
+			expect( () => {
+				editor.secureSourceElement();
+			} ).to.not.throw();
+		} );
+
+		it( 'does not throw if the editor was initialized using the element for the first time', () => {
+			expect( () => {
+				editor.secureSourceElement();
+			} ).to.not.throw();
+		} );
+
+		it( 'sets the data attribute after initializing the editor', () => {
+			editor.secureSourceElement();
+
+			expect( sourceElement.hasAttribute( 'data-ckeditor5-element' ) ).to.equal( true );
+		} );
+
+		it( 'removes the data attribute after destroying the editor', () => {
+			editor.secureSourceElement();
+
+			return editor.destroy()
+				.then( () => {
+					expect( sourceElement.hasAttribute( 'data-ckeditor5-element' ) ).to.equal( false );
+				} );
+		} );
+
+		it( 'throws an error if the same element was used twice', () => {
+			sourceElement.setAttribute( 'data-ckeditor5-element', 'true' );
+
+			expectToThrowCKEditorError(
+				() => editor.secureSourceElement(),
+				/^editor-source-element-used-more-than-once/ );
+		} );
+	} );
 } );

+ 0 - 69
packages/ckeditor5-core/tests/editor/utils/securesourceelement.js

@@ -1,69 +0,0 @@
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/* global document */
-
-import secureSourceElement from '../../../src/editor/utils/securesourceelement';
-import Editor from '../../../src/editor/editor';
-import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
-
-describe( 'secureSourceElement()', () => {
-	let editor, sourceElement;
-
-	beforeEach( () => {
-		class CustomEditor extends Editor {}
-
-		sourceElement = document.createElement( 'div' );
-		editor = new CustomEditor();
-
-		editor.sourceElement = sourceElement;
-		editor.state = 'ready';
-	} );
-
-	afterEach( () => {
-		if ( editor ) {
-			return editor.destroy();
-		}
-	} );
-
-	it( 'does nothing if the editor was not initialized using the source element', () => {
-		delete editor.sourceElement;
-
-		expect( () => {
-			secureSourceElement( editor );
-		} ).to.not.throw();
-	} );
-
-	it( 'does nothing if the editor was initialized using the element for the first time', () => {
-		expect( () => {
-			secureSourceElement( editor );
-		} ).to.not.throw();
-	} );
-
-	it( 'sets the data attribute after initializing the editor', () => {
-		secureSourceElement( editor );
-
-		expect( sourceElement.hasAttribute( 'data-ckeditor5' ) ).to.equal( true );
-	} );
-
-	it( 'removes the data attribute after destroying the editor', () => {
-		secureSourceElement( editor );
-
-		return editor.destroy()
-			.then( () => {
-				editor = null;
-
-				expect( sourceElement.hasAttribute( 'data-ckeditor5' ) ).to.equal( false );
-			} );
-	} );
-
-	it( 'throws an error if the same element was used twice', () => {
-		sourceElement.setAttribute( 'data-ckeditor5', 'true' );
-
-		expect( () => {
-			secureSourceElement( editor );
-		} ).to.throw( CKEditorError, /^securesourceelement-source-element-used-more-than-once/ );
-	} );
-} );