8
0
Просмотр исходного кода

Introduced the "secureSourceElement()" util which checks whether specified sourceElement was used more than once.

Kamil Piechaczek 6 лет назад
Родитель
Сommit
092c48c384

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

@@ -0,0 +1,47 @@
+/**
+ * @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 );
+	} );
+}

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

@@ -0,0 +1,69 @@
+/**
+ * @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/ );
+	} );
+} );