Przeglądaj źródła

Extract manual decorator class to utils and cover it with tests.

Mateusz Samsel 6 lat temu
rodzic
commit
4f5dc066c2

+ 2 - 17
packages/ckeditor5-link/src/linkediting.js

@@ -12,11 +12,10 @@ import LinkCommand from './linkcommand';
 import UnlinkCommand from './unlinkcommand';
 import { createLinkElement, ensureSafeUrl } from './utils';
 import AutomaticDecorators from './utils/automaticdecorators';
+import ManualDecorator from './utils/manualdecorator';
 import bindTwoStepCaretToAttribute from '@ckeditor/ckeditor5-engine/src/utils/bindtwostepcarettoattribute';
 import findLinkRange from './findlinkrange';
 import '../theme/link.css';
-import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
-import mix from '@ckeditor/ckeditor5-utils/src/mix';
 
 const HIGHLIGHT_CLASS = 'ck-link_selected';
 const AUTO = 'automatic';
@@ -126,7 +125,7 @@ export default class LinkEditing extends Plugin {
 			const decoratorName = `linkManualDecorator${ index }`;
 			editor.model.schema.extend( '$text', { allowAttributes: decoratorName } );
 
-			attrCollection.add( new ManualDecorator( Object.assign( { id: decoratorName, value: undefined }, decorator ) ) );
+			attrCollection.add( new ManualDecorator( Object.assign( { id: decoratorName }, decorator ) ) );
 			editor.conversion.for( 'downcast' ).attributeToElement( {
 				model: decoratorName,
 				view: ( manualDecoratorName, writer ) => {
@@ -202,17 +201,3 @@ export default class LinkEditing extends Plugin {
 		} );
 	}
 }
-
-export class ManualDecorator {
-	constructor( { id, value, label, attributes } ) {
-		this.id = id;
-
-		this.set( 'value', value );
-
-		this.label = label;
-
-		this.attributes = attributes;
-	}
-}
-
-mix( ManualDecorator, ObservableMixin );

+ 62 - 0
packages/ckeditor5-link/src/utils/manualdecorator.js

@@ -0,0 +1,62 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module link/utils/manualdecorator
+ */
+
+import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
+import mix from '@ckeditor/ckeditor5-utils/src/mix';
+
+/**
+ * Class which stores manual decorators with observable {@link module:link/utils/manualdecorator~ManualDecorator#value}
+ * to handle integration with ui state.
+ *
+ * @mixes module:utils/observablemixin~ObservableMixin
+ */
+export default class ManualDecorator {
+	/**
+	 * Creates new instance of {@link module:link/utils/manualdecorator~ManualDecorator}.
+	 *
+	 * @param {Object} config
+	 * @param {String} config.id Manual decorator id, which is a name of attribute in model, for example 'linkManualDecorator0'.
+	 * @param {String} config.label The label used in user interface to switch manual decorator.
+	 * @param {Object} config.attributes Set of attributes added to downcasted data, when decorator is activated for specific link.
+	 * Attributes should be added in a form of attributes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.
+	 */
+	constructor( { id, label, attributes } ) {
+		/**
+		 * Manual decorator id, which is a name of attribute in model, for example 'linkManualDecorator0'.
+		 *
+		 * @type {String}
+		 */
+		this.id = id;
+
+		/**
+		 * Value of current manual decorator. It reflects its state from UI.
+		 *
+		 * @observable
+		 * @member {Boolean} module:link/utils/manualdecorator~ManualDecorator#value
+		 */
+		this.set( 'value' );
+
+		/**
+		 * The label used in user interface to switch manual decorator.
+		 *
+		 * @type {String}
+		 */
+		this.label = label;
+
+		/**
+		 * Set of attributes added to downcasted data, when decorator is activated for specific link.
+		 * Attributes should be added in a form of attributes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.
+		 *
+		 * @type {Object}
+		 */
+		this.attributes = attributes;
+	}
+}
+
+mix( ManualDecorator, ObservableMixin );

+ 1 - 3
packages/ckeditor5-link/tests/linkcommand.js

@@ -5,7 +5,7 @@
 
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
 import LinkCommand from '../src/linkcommand';
-import { ManualDecorator } from '../src/linkediting';
+import ManualDecorator from '../src/utils/manualdecorator';
 import { setData, getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 describe( 'LinkCommand', () => {
@@ -272,7 +272,6 @@ describe( 'LinkCommand', () => {
 
 					command.customAttributes.add( new ManualDecorator( {
 						id: 'linkManualDecorator0',
-						value: undefined,
 						label: 'Foo',
 						attributes: {
 							class: 'Foo'
@@ -280,7 +279,6 @@ describe( 'LinkCommand', () => {
 					} ) );
 					command.customAttributes.add( new ManualDecorator( {
 						id: 'linkManualDecorator1',
-						value: undefined,
 						label: 'Bar',
 						attributes: {
 							target: '_blank'

+ 43 - 0
packages/ckeditor5-link/tests/utils/manualdecorator.js

@@ -0,0 +1,43 @@
+/**
+ * @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 ManualDecorator from '../../src/utils/manualdecorator';
+import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
+
+describe( 'Manual Decorator', () => {
+	let manualDecorator;
+	testUtils.createSinonSandbox();
+
+	beforeEach( () => {
+		manualDecorator = new ManualDecorator( {
+			id: 'foo',
+			label: 'bar',
+			attributes: {
+				one: 'two'
+			}
+		} );
+	} );
+
+	it( 'constructor', () => {
+		expect( manualDecorator.id ).to.equal( 'foo' );
+		expect( manualDecorator.label ).to.equal( 'bar' );
+		expect( manualDecorator.attributes ).to.deep.equal( { one: 'two' } );
+	} );
+
+	it( '#value is observable', () => {
+		const spy = testUtils.sinon.spy();
+		expect( manualDecorator.value ).to.be.undefined;
+
+		manualDecorator.on( 'change:value', spy );
+		manualDecorator.value = true;
+
+		expect( spy.calledOnce ).to.be.true;
+		testUtils.sinon.assert.calledWithExactly( spy.firstCall, testUtils.sinon.match.any, 'value', true, undefined );
+
+		manualDecorator.value = false;
+		expect( spy.calledTwice ).to.be.true;
+		testUtils.sinon.assert.calledWithExactly( spy.secondCall, testUtils.sinon.match.any, 'value', false, true );
+	} );
+} );