浏览代码

Use switch button as toggle option in custom link atributes.

Mateusz Samsel 6 年之前
父节点
当前提交
24a62188a6

+ 7 - 1
packages/ckeditor5-link/src/linkcommand.js

@@ -10,6 +10,7 @@
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import findLinkRange from './findlinkrange';
 import findLinkRange from './findlinkrange';
 import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
 import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
+import Collection from '@ckeditor/ckeditor5-utils/src/collection';
 
 
 /**
 /**
  * The link command. It is used by the {@link module:link/link~Link link feature}.
  * The link command. It is used by the {@link module:link/link~Link link feature}.
@@ -28,7 +29,7 @@ export default class LinkCommand extends Command {
 	constructor( editor ) {
 	constructor( editor ) {
 		super( editor );
 		super( editor );
 
 
-		this.customAttributes = new Map();
+		this.customAttributes = new Collection();
 	}
 	}
 
 
 	/**
 	/**
@@ -39,6 +40,11 @@ export default class LinkCommand extends Command {
 		const doc = model.document;
 		const doc = model.document;
 
 
 		this.value = doc.selection.getAttribute( 'linkHref' );
 		this.value = doc.selection.getAttribute( 'linkHref' );
+
+		for ( const customAttr of this.customAttributes ) {
+			customAttr.value = doc.selection.getAttribute( customAttr.id ) || false;
+		}
+
 		this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'linkHref' );
 		this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'linkHref' );
 	}
 	}
 
 

+ 19 - 3
packages/ckeditor5-link/src/linkediting.js

@@ -15,6 +15,8 @@ import AutomaticDecorators from './utils/automaticdecorators';
 import bindTwoStepCaretToAttribute from '@ckeditor/ckeditor5-engine/src/utils/bindtwostepcarettoattribute';
 import bindTwoStepCaretToAttribute from '@ckeditor/ckeditor5-engine/src/utils/bindtwostepcarettoattribute';
 import findLinkRange from './findlinkrange';
 import findLinkRange from './findlinkrange';
 import '../theme/link.css';
 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 HIGHLIGHT_CLASS = 'ck-link_selected';
 const AUTO = 'automatic';
 const AUTO = 'automatic';
@@ -116,20 +118,20 @@ export default class LinkEditing extends Plugin {
 		}
 		}
 
 
 		const command = editor.commands.get( 'link' );
 		const command = editor.commands.get( 'link' );
-		const attrMap = command.customAttributes;
+		const attrCollection = command.customAttributes;
 
 
 		manualDecoratorDefinitions.forEach( ( decorator, index ) => {
 		manualDecoratorDefinitions.forEach( ( decorator, index ) => {
 			const decoratorName = `linkManualDecorator${ index }`;
 			const decoratorName = `linkManualDecorator${ index }`;
 			editor.model.schema.extend( '$text', { allowAttributes: decoratorName } );
 			editor.model.schema.extend( '$text', { allowAttributes: decoratorName } );
 
 
-			attrMap.set( decoratorName, Object.assign( { value: undefined }, decorator ) );
+			attrCollection.add( new ManualDecorator( Object.assign( { id: decoratorName, value: undefined }, decorator ) ) );
 			editor.conversion.for( 'downcast' ).attributeToElement( {
 			editor.conversion.for( 'downcast' ).attributeToElement( {
 				model: decoratorName,
 				model: decoratorName,
 				view: ( manualDecoratorName, writer ) => {
 				view: ( manualDecoratorName, writer ) => {
 					if ( manualDecoratorName ) {
 					if ( manualDecoratorName ) {
 						const element = writer.createAttributeElement(
 						const element = writer.createAttributeElement(
 							'a',
 							'a',
-							attrMap.get( decoratorName ).attributes,
+							attrCollection.get( decoratorName ).attributes,
 							{
 							{
 								priority: 5
 								priority: 5
 							}
 							}
@@ -198,3 +200,17 @@ export default class LinkEditing extends Plugin {
 		} );
 		} );
 	}
 	}
 }
 }
+
+class ManualDecorator {
+	constructor( { id, value, label, attributes } = {} ) {
+		this.id = id;
+
+		this.set( 'value', value );
+
+		this.label = label;
+
+		this.attributes = attributes;
+	}
+}
+
+mix( ManualDecorator, ObservableMixin );

+ 9 - 2
packages/ckeditor5-link/src/linkui.js

@@ -142,9 +142,10 @@ export default class LinkUI extends Plugin {
 	 */
 	 */
 	_createFormView() {
 	_createFormView() {
 		const editor = this.editor;
 		const editor = this.editor;
-		const formView = new LinkFormView( editor.locale );
 		const linkCommand = editor.commands.get( 'link' );
 		const linkCommand = editor.commands.get( 'link' );
 
 
+		const formView = new LinkFormView( editor.locale, linkCommand.customAttributes );
+
 		formView.urlInputView.bind( 'value' ).to( linkCommand, 'value' );
 		formView.urlInputView.bind( 'value' ).to( linkCommand, 'value' );
 
 
 		// Form elements should be read-only when corresponding commands are disabled.
 		// Form elements should be read-only when corresponding commands are disabled.
@@ -153,7 +154,13 @@ export default class LinkUI extends Plugin {
 
 
 		// Execute link command after clicking the "Save" button.
 		// Execute link command after clicking the "Save" button.
 		this.listenTo( formView, 'submit', () => {
 		this.listenTo( formView, 'submit', () => {
-			editor.execute( 'link', formView.urlInputView.inputView.element.value );
+			const customAttributes = {};
+
+			for ( const switchButton of formView.customAttributesView ) {
+				customAttributes[ switchButton.value ] = switchButton.isOn;
+			}
+
+			editor.execute( 'link', formView.urlInputView.inputView.element.value, customAttributes );
 			this._closeFormView();
 			this._closeFormView();
 		} );
 		} );
 
 

+ 33 - 4
packages/ckeditor5-link/src/ui/linkformview.js

@@ -11,6 +11,7 @@ import View from '@ckeditor/ckeditor5-ui/src/view';
 import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';
 import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';
 
 
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import SwitchButtonView from '@ckeditor/ckeditor5-ui/src/button/switchbuttonview';
 import LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';
 import LabeledInputView from '@ckeditor/ckeditor5-ui/src/labeledinput/labeledinputview';
 import InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';
 import InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';
 
 
@@ -34,7 +35,7 @@ export default class LinkFormView extends View {
 	/**
 	/**
 	 * @inheritDoc
 	 * @inheritDoc
 	 */
 	 */
-	constructor( locale ) {
+	constructor( locale, customAttributes ) {
 		super( locale );
 		super( locale );
 
 
 		const t = locale.t;
 		const t = locale.t;
@@ -77,6 +78,10 @@ export default class LinkFormView extends View {
 		 */
 		 */
 		this.cancelButtonView = this._createButton( t( 'Cancel' ), cancelIcon, 'ck-button-cancel', 'cancel' );
 		this.cancelButtonView = this._createButton( t( 'Cancel' ), cancelIcon, 'ck-button-cancel', 'cancel' );
 
 
+		this.customAttributes = customAttributes;
+
+		this.customAttributesView = this._createCustomAttributesView();
+
 		/**
 		/**
 		 * A collection of views which can be focused in the form.
 		 * A collection of views which can be focused in the form.
 		 *
 		 *
@@ -122,7 +127,8 @@ export default class LinkFormView extends View {
 			children: [
 			children: [
 				this.urlInputView,
 				this.urlInputView,
 				this.saveButtonView,
 				this.saveButtonView,
-				this.cancelButtonView
+				this.cancelButtonView,
+				...this.customAttributesView,
 			]
 			]
 		} );
 		} );
 	}
 	}
@@ -137,10 +143,12 @@ export default class LinkFormView extends View {
 			view: this
 			view: this
 		} );
 		} );
 
 
+		// Focus order should be different than position in DOM. Save/Cancel buttons should be focused at the end.
 		const childViews = [
 		const childViews = [
 			this.urlInputView,
 			this.urlInputView,
+			...this.customAttributesView,
 			this.saveButtonView,
 			this.saveButtonView,
-			this.cancelButtonView
+			this.cancelButtonView,
 		];
 		];
 
 
 		childViews.forEach( v => {
 		childViews.forEach( v => {
@@ -174,7 +182,6 @@ export default class LinkFormView extends View {
 		const labeledInput = new LabeledInputView( this.locale, InputTextView );
 		const labeledInput = new LabeledInputView( this.locale, InputTextView );
 
 
 		labeledInput.label = t( 'Link URL' );
 		labeledInput.label = t( 'Link URL' );
-		labeledInput.inputView.placeholder = 'https://example.com';
 
 
 		return labeledInput;
 		return labeledInput;
 	}
 	}
@@ -210,6 +217,28 @@ export default class LinkFormView extends View {
 
 
 		return button;
 		return button;
 	}
 	}
+
+	_createCustomAttributesView() {
+		const checkboxes = this.createCollection();
+
+		checkboxes.bindTo( this.customAttributes ).using( item => {
+			const checkbox = new SwitchButtonView( this.locale );
+			checkbox.set( {
+				value: item.id,
+				label: item.label,
+				withText: true
+			} );
+
+			checkbox.bind( 'isOn' ).to( item, 'value' );
+
+			checkbox.on( 'execute', () => {
+				this.customAttributes.get( item.id ).set( 'value', !checkbox.isOn );
+			} );
+
+			return checkbox;
+		} );
+		return checkboxes;
+	}
 }
 }
 
 
 /**
 /**

+ 3 - 3
packages/ckeditor5-link/src/unlinkcommand.js

@@ -47,9 +47,9 @@ export default class UnlinkCommand extends Command {
 				writer.removeAttribute( 'linkHref', range );
 				writer.removeAttribute( 'linkHref', range );
 				// If there are registered custom attributes, then remove them during unlink.
 				// If there are registered custom attributes, then remove them during unlink.
 				if ( linkCommand ) {
 				if ( linkCommand ) {
-					linkCommand.customAttributes.forEach( ( val, key ) => {
-						writer.removeAttribute( key, range );
-					} );
+					for ( const manualDecorator of linkCommand.customAttributes ) {
+						writer.removeAttribute( manualDecorator.id, range );
+					}
 				}
 				}
 			}
 			}
 		} );
 		} );

+ 2 - 1
packages/ckeditor5-link/theme/linkform.css

@@ -8,7 +8,8 @@
 .ck.ck-link-form {
 .ck.ck-link-form {
 	display: flex;
 	display: flex;
 	flex-direction: row;
 	flex-direction: row;
-	flex-wrap: nowrap;
+	flex-wrap: wrap;
+	max-width: 500px;
 
 
 	& .ck-label {
 	& .ck-label {
 		display: none;
 		display: none;