浏览代码

Improved ButtonInterface and how other classes implement it.

Piotrek Koszuliński 7 年之前
父节点
当前提交
daa4db752d

+ 8 - 20
packages/ckeditor5-ui/src/button/buttoninterface.jsdoc

@@ -10,26 +10,9 @@
 /**
  * The button interface.
  *
- * @interface module:ui/button/buttoninterface~ButtonInterface
- */
-
-/**
- * The button view class.
- *
- *		const view = new ButtonView();
- *
- *		view.set( {
- *			label: 'A button',
- *			keystroke: 'Ctrl+B',
- *			tooltip: true,
- *			withText: true
- *		} );
+ *		TODO
  *
- *		view.render();
- *
- *		document.body.append( view.element );
- *
- * @extends module:ui/view~View
+ * @interface module:ui/button/buttoninterface~ButtonInterface
  */
 
 /**
@@ -72,7 +55,7 @@
  *
  * @observable
  * @default 's'
- * @member {'s'|'n'} #position
+ * @member {'s'|'n'} #tooltipPosition
  */
 
 /**
@@ -89,6 +72,7 @@
  * To disable the button, use {@link #isEnabled} instead.
  *
  * @observable
+ * @default true
  * @member {Boolean} #isOn
  */
 
@@ -98,6 +82,7 @@
  * To change the "on" state of the button, use {@link #isOn} instead.
  *
  * @observable
+ * @default true
  * @member {Boolean} #isEnabled
  */
 
@@ -106,6 +91,7 @@
  * using a CSS class.
  *
  * @observable
+ * @default true
  * @member {Boolean} #isVisible
  */
 
@@ -113,6 +99,7 @@
  * (Optional) Controls whether the label of the button is hidden (e.g. an icon–only button).
  *
  * @observable
+ * @default false
  * @member {Boolean} #withText
  */
 
@@ -132,6 +119,7 @@
  * @default -1
  * @member {String} #tabindex
  */
+
 /**
  * Fired when the button view is clicked. It won't be fired when the button {@link #isEnabled}
  * is `false`.

+ 14 - 120
packages/ckeditor5-ui/src/button/buttonview.js

@@ -43,119 +43,20 @@ export default class ButtonView extends View {
 
 		const bind = this.bindTemplate;
 
-		/**
-		 * The label of the button view visible to the user when {@link #withText} is `true`.
-		 * It can also be used to create a {@link #tooltip}.
-		 *
-		 * @observable
-		 * @member {String} #label
-		 */
-		this.set( 'label' );
-
-		/**
-		 * (Optional) The keystroke associated with the button, i.e. <kbd>CTRL+B</kbd>,
-		 * in the string format compatible with {@link module:utils/keyboard}.
-		 *
-		 * @observable
-		 * @member {Boolean} #keystroke
-		 */
+		// Implement ButtonInterface.
+		this.set( 'icon' );
+		this.set( 'isEnabled', true );
+		this.set( 'isOn', false );
+		this.set( 'isVisible', true );
 		this.set( 'keystroke' );
-
-		/**
-		 * (Optional) Tooltip of the button, i.e. displayed when hovering the button with the mouse cursor.
-		 *
-		 * * If defined as a `Boolean` (e.g. `true`), then combination of `label` and `keystroke` will be set as a tooltip.
-		 * * If defined as a `String`, tooltip will equal the exact text of that `String`.
-		 * * If defined as a `Function`, `label` and `keystroke` will be passed to that function, which is to return
-		 * a string with the tooltip text.
-		 *
-		 *		const view = new ButtonView( locale );
-		 *		view.tooltip = ( label, keystroke ) => `A tooltip for ${ label } and ${ keystroke }.`
-		 *
-		 * @observable
-		 * @default false
-		 * @member {Boolean|String|Function} #tooltip
-		 */
+		this.set( 'label' );
+		this.set( 'tabindex', -1 );
 		this.set( 'tooltip' );
-
-		/**
-		 * (Optional) The position of the tooltip. See {@link module:ui/tooltip/tooltipview~TooltipView#position}
-		 * to learn more about the available position values.
-		 *
-		 * **Note:** It makes sense only when the {@link #tooltip `tooltip` attribute} is defined.
-		 *
-		 * @observable
-		 * @default 's'
-		 * @member {'s'|'n'} #position
-		 */
 		this.set( 'tooltipPosition', 's' );
-
-		/**
-		 * The HTML type of the button. Default `button`.
-		 *
-		 * @observable
-		 * @member {'button'|'submit'|'reset'|'menu'} #type
-		 */
 		this.set( 'type', 'button' );
-
-		/**
-		 * Controls whether the button view is "on". It makes sense when a feature it represents
-		 * is currently active, e.g. a bold button is "on" when the selection is in the bold text.
-		 *
-		 * To disable the button, use {@link #isEnabled} instead.
-		 *
-		 * @observable
-		 * @member {Boolean} #isOn
-		 */
-		this.set( 'isOn', false );
-
-		/**
-		 * Controls whether the button view is enabled, i.e. it can be clicked and execute an action.
-		 *
-		 * To change the "on" state of the button, use {@link #isOn} instead.
-		 *
-		 * @observable
-		 * @member {Boolean} #isEnabled
-		 */
-		this.set( 'isEnabled', true );
-
-		/**
-		 * Controls whether the button view is visible. Visible by default, buttons are hidden
-		 * using a CSS class.
-		 *
-		 * @observable
-		 * @member {Boolean} #isVisible
-		 */
-		this.set( 'isVisible', true );
-
-		/**
-		 * (Optional) Controls whether the label of the button is hidden (e.g. an icon–only button).
-		 *
-		 * @observable
-		 * @member {Boolean} #withText
-		 */
 		this.set( 'withText', false );
 
 		/**
-		 * (Optional) An XML {@link module:ui/icon/iconview~IconView#content content} of the icon.
-		 * When defined, an {@link #iconView} will be added to the button.
-		 *
-		 * @observable
-		 * @member {String} #icon
-		 */
-		this.set( 'icon' );
-
-		/**
-		 * (Optional) Controls the `tabindex` HTML attribute of the button. By default, the button is focusable
-		 * but does not included in the <kbd>Tab</kbd> order.
-		 *
-		 * @observable
-		 * @default -1
-		 * @member {String} #tabindex
-		 */
-		this.set( 'tabindex', -1 );
-
-		/**
 		 * Collection of the child views inside of the button {@link #element}.
 		 *
 		 * @readonly
@@ -180,6 +81,13 @@ export default class ButtonView extends View {
 		this.labelView = this._createLabelView();
 
 		/**
+		 * (Optional) The icon view of the button. Only present when the {@link #icon icon attribute} is defined.
+		 *
+		 * @readonly
+		 * @member {module:ui/icon/iconview~IconView} #iconView
+		 */
+
+		/**
 		 * Tooltip of the button bound to the template.
 		 *
 		 * @see #tooltip
@@ -195,13 +103,6 @@ export default class ButtonView extends View {
 			this._getTooltipString.bind( this )
 		);
 
-		/**
-		 * (Optional) The icon view of the button. Only present when the {@link #icon icon attribute} is defined.
-		 *
-		 * @readonly
-		 * @member {module:ui/icon/iconview~IconView} #iconView
-		 */
-
 		this.setTemplate( {
 			tag: 'button',
 
@@ -237,13 +138,6 @@ export default class ButtonView extends View {
 				} )
 			}
 		} );
-
-		/**
-		 * Fired when the button view is clicked. It won't be fired when the button {@link #isEnabled}
-		 * is `false`.
-		 *
-		 * @event execute
-		 */
 	}
 
 	/**

+ 2 - 1
packages/ckeditor5-ui/src/dropdown/button/dropdownbuttoninterface.jsdoc

@@ -15,7 +15,8 @@
  */
 
 /**
- * Fired when the arrow view is clicked. It won't be fired when the button {@link #isEnabled} is `false`.
+ * Fired when the dropdown should be opened.
+ * It will not be fired when the button {@link #isEnabled is disabled}.
  *
  * @event open
  */

+ 4 - 10
packages/ckeditor5-ui/src/dropdown/button/dropdownbuttonview.js

@@ -27,10 +27,10 @@ import IconView from '../../icon/iconview';
  *
  *		document.body.append( view.element );
  *
- * Also see {@link module:ui/dropdown/utils~createDropdown}.
+ * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.
  *
- * @extends module:ui/view~View
  * @implements module:ui/dropdown/button/dropdownbuttoninterface~DropdownButtonInterface
+ * @extends module:ui/button/buttonview~ButtonView
  */
 export default class DropdownButtonView extends ButtonView {
 	/**
@@ -43,18 +43,12 @@ export default class DropdownButtonView extends ButtonView {
 		 * An icon that displays arrow to indicate a dropdown button.
 		 *
 		 * @readonly
-		 * @member {module:ui/dropdown/button/dropdownbuttonview~DropdownButtonView}
+		 * @member {module:ui/icon/iconview~IconView}
 		 */
 		this.arrowView = this._createArrowView();
 
-		// Dropdown expects "open" event on button view upon which the dropdown will open.
+		// DropdownButtonInterface expects the open event upon which the dropdown will open.
 		this.delegate( 'execute' ).to( this, 'open' );
-
-		/**
-		 * Fired when the view is clicked. It won't be fired when the button {@link #isEnabled} is `false`.
-		 *
-		 * @event select
-		 */
 	}
 
 	/**

+ 29 - 74
packages/ckeditor5-ui/src/dropdown/button/splitbuttonview.js

@@ -32,10 +32,10 @@ import '../../../theme/components/dropdown/splitbutton.css';
  *
  *		document.body.append( view.element );
  *
- * Also see {@link module:ui/dropdown/utils~createDropdown}.
+ * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.
  *
- * @extends module:ui/view~View
  * @implements module:ui/dropdown/button/dropdownbuttoninterface~DropdownButtonInterface
+ * @extends module:ui/view~View
  */
 export default class SplitButtonView extends View {
 	/**
@@ -44,79 +44,20 @@ export default class SplitButtonView extends View {
 	constructor( locale ) {
 		super( locale );
 
-		/**
-		 * Controls whether the button view is enabled, i.e. it can be clicked and execute an action.
-		 *
-		 * To change the "on" state of the button, use {@link #isOn} instead.
-		 *
-		 * @observable
-		 * @member {Boolean} #isEnabled
-		 */
-		this.set( 'isEnabled', true );
+		const bind = this.bindTemplate;
 
-		/**
-		 * Used to create a {@link #tooltip}.
-		 *
-		 * @observable
-		 * @member {String} #label
-		 */
-		this.set( 'label' );
-
-		/**
-		 * (Optional) The keystroke associated with the button, i.e. <kbd>Ctrl</kbd>+<kbd>B</kbd>,
-		 * in the string format compatible with {@link module:utils/keyboard}.
-		 *
-		 * @observable
-		 * @member {Boolean} #keystroke
-		 */
-		this.set( 'keystroke' );
-
-		/**
-		 * (Optional) An XML {@link module:ui/icon/iconview~IconView#content content} of the icon.
-		 * When defined, an {@link module:ui/button/buttonview~ButtonView#iconView} will be added to the {@link #actionView} button.
-		 *
-		 * @observable
-		 * @member {String} #icon
-		 */
+		// Implement ButtonInterface.
 		this.set( 'icon' );
-
-		/**
-		 * (Optional) Tooltip of the button, i.e. displayed when hovering the button with the mouse cursor.
-		 *
-		 * * If defined as a `Boolean` (e.g. `true`), then combination of `label` and `keystroke` will be set as a tooltip.
-		 * * If defined as a `String`, tooltip will equal the exact text of that `String`.
-		 * * If defined as a `Function`, `label` and `keystroke` will be passed to that function, which is to return
-		 * a string with the tooltip text.
-		 *
-		 *		const view = new ButtonView( locale );
-		 *		view.tooltip = ( label, keystroke ) => `A tooltip for ${ label } and ${ keystroke }.`
-		 *
-		 * @observable
-		 * @default false
-		 * @member {Boolean|String|Function} #tooltip
-		 */
-		this.set( 'tooltip' );
-
-		/**
-		 * Controls whether the button view is "on". It makes sense when a feature it represents
-		 * is currently active, e.g. a bold button is "on" when the selection is in the bold text.
-		 *
-		 * To disable the button, use {@link #isEnabled} instead.
-		 *
-		 * @observable
-		 * @member {Boolean} #isOn
-		 */
-		this.set( 'isOn', false );
-
-		/**
-		 * Controls whether the button view is enabled, i.e. it can be clicked and execute an action.
-		 *
-		 * To change the "on" state of the button, use {@link #isOn} instead.
-		 *
-		 * @observable
-		 * @member {Boolean} #isEnabled
-		 */
 		this.set( 'isEnabled', true );
+		this.set( 'isOn', false );
+		this.set( 'isVisible', true );
+		this.set( 'keystroke' );
+		this.set( 'label' );
+		this.set( 'tabindex', -1 );
+		this.set( 'tooltip' );
+		this.set( 'tooltipPosition', 's' );
+		this.set( 'type', 'button' );
+		this.set( 'withText', false );
 
 		/**
 		 * Collection of the child views inside of the split button {@link #element}.
@@ -166,7 +107,10 @@ export default class SplitButtonView extends View {
 			tag: 'div',
 
 			attributes: {
-				class: 'ck-splitbutton'
+				class: [
+					'ck-splitbutton',
+					bind.if( 'isVisible', 'ck-hidden', value => !value )
+				]
 			},
 
 			children: this.children
@@ -223,7 +167,18 @@ export default class SplitButtonView extends View {
 	_createActionView() {
 		const buttonView = new ButtonView();
 
-		buttonView.bind( 'icon', 'isEnabled', 'label', 'isOn', 'tooltip', 'keystroke' ).to( this );
+		buttonView.bind(
+			'icon',
+			'isEnabled',
+			'isOn',
+			'keystroke',
+			'label',
+			'tabindex',
+			'tooltip',
+			'tooltipPosition',
+			'type',
+			'withText'
+		).to( this );
 
 		buttonView.delegate( 'execute' ).to( this );
 

+ 44 - 0
packages/ckeditor5-ui/tests/dropdown/button/splitbuttonview.js

@@ -40,6 +40,17 @@ describe( 'SplitButtonView', () => {
 			expect( view.element.classList.contains( 'ck-splitbutton' ) ).to.be.true;
 		} );
 
+		it( 'binds #isVisible to the template', () => {
+			expect( view.element.classList.contains( 'ck-hidden' ) ).to.be.false;
+
+			view.isVisible = false;
+
+			expect( view.element.classList.contains( 'ck-hidden' ) ).to.be.true;
+
+			// There should be no binding to the action view. Only the entire split button should react.
+			expect( view.actionView.element.classList.contains( 'ck-hidden' ) ).to.be.false;
+		} );
+
 		describe( 'activates keyboard navigation for the toolbar', () => {
 			it( 'so "arrowright" on view#arrowView does nothing', () => {
 				const keyEvtData = {
@@ -167,6 +178,39 @@ describe( 'SplitButtonView', () => {
 
 			expect( view.arrowView.isEnabled ).to.be.false;
 		} );
+
+		it( 'binds actionView#tabindex to view', () => {
+			expect( view.actionView.tabindex ).to.equal( -1 );
+
+			view.tabindex = 1;
+
+			expect( view.actionView.tabindex ).to.equal( 1 );
+		} );
+
+		// Makes little sense for split button but ButtonInterface specifies it, so let's support it.
+		it( 'binds actionView#type to view', () => {
+			expect( view.actionView.type ).to.equal( 'button' );
+
+			view.type = 'submit';
+
+			expect( view.actionView.type ).to.equal( 'submit' );
+		} );
+
+		it( 'binds actionView#withText to view', () => {
+			expect( view.actionView.withText ).to.equal( false );
+
+			view.withText = true;
+
+			expect( view.actionView.withText ).to.equal( true );
+		} );
+
+		it( 'binds actionView#tooltipPosition to view', () => {
+			expect( view.actionView.tooltipPosition ).to.equal( 's' );
+
+			view.tooltipPosition = 'n';
+
+			expect( view.actionView.tooltipPosition ).to.equal( 'n' );
+		} );
 	} );
 
 	describe( 'focus()', () => {