浏览代码

Merge pull request #517 from ckeditor/t/ckeditor5/1403

Improve the functionality of `aria-pressed` attribute in button elements
Aleksander Nowodzinski 6 年之前
父节点
当前提交
27343f60f3

+ 8 - 0
packages/ckeditor5-ui/src/button/button.jsdoc

@@ -96,6 +96,14 @@
  */
 
 /**
+ * Controls whether the button view is a toggle button (two–state) for assistive technologies.
+ *
+ * @observable
+ * @default false
+ * @member {Boolean} #isToggleable
+ */
+
+/**
  * (Optional) Controls whether the label of the button is hidden (e.g. an icon–only button).
  *
  * @observable

+ 2 - 1
packages/ckeditor5-ui/src/button/buttonview.js

@@ -52,6 +52,7 @@ export default class ButtonView extends View {
 		this.set( 'isEnabled', true );
 		this.set( 'isOn', false );
 		this.set( 'isVisible', true );
+		this.set( 'isToggleable', false );
 		this.set( 'keystroke' );
 		this.set( 'label' );
 		this.set( 'tabindex', -1 );
@@ -132,7 +133,7 @@ export default class ButtonView extends View {
 				tabindex: bind.to( 'tabindex' ),
 				'aria-labelledby': `ck-editor__aria-label_${ ariaLabelUid }`,
 				'aria-disabled': bind.if( 'isEnabled', true, value => !value ),
-				'aria-pressed': bind.if( 'isOn', true )
+				'aria-pressed': bind.to( 'isOn', value => this.isToggleable ? String( value ) : false )
 			},
 
 			children: this.children,

+ 2 - 0
packages/ckeditor5-ui/src/button/switchbuttonview.js

@@ -35,6 +35,8 @@ export default class SwitchButtonView extends ButtonView {
 	constructor( locale ) {
 		super( locale );
 
+		this.isToggleable = true;
+
 		/**
 		 * The toggle switch of the button.
 		 *

+ 5 - 1
packages/ckeditor5-ui/src/dropdown/button/splitbuttonview.js

@@ -50,6 +50,7 @@ export default class SplitButtonView extends View {
 		this.set( 'icon' );
 		this.set( 'isEnabled', true );
 		this.set( 'isOn', false );
+		this.set( 'isToggleable', false );
 		this.set( 'isVisible', true );
 		this.set( 'keystroke' );
 		this.set( 'label' );
@@ -173,6 +174,7 @@ export default class SplitButtonView extends View {
 			'icon',
 			'isEnabled',
 			'isOn',
+			'isToggleable',
 			'keystroke',
 			'label',
 			'tabindex',
@@ -202,13 +204,15 @@ export default class SplitButtonView extends View {
 	 */
 	_createArrowView() {
 		const arrowView = new ButtonView();
+		const bind = arrowView.bindTemplate;
 
 		arrowView.icon = dropdownArrowIcon;
 
 		arrowView.extendTemplate( {
 			attributes: {
 				class: 'ck-splitbutton__arrow',
-				'aria-haspopup': true
+				'aria-haspopup': true,
+				'aria-expanded': bind.to( 'isOn', value => String( value ) )
 			}
 		} );
 

+ 2 - 0
packages/ckeditor5-ui/src/toolbar/block/blockbuttonview.js

@@ -34,6 +34,8 @@ export default class BlockButtonView extends ButtonView {
 		// Hide button on init.
 		this.isVisible = false;
 
+		this.isToggleable = true;
+
 		/**
 		 * Top offset.
 		 *

+ 10 - 1
packages/ckeditor5-ui/tests/button/buttonview.js

@@ -245,11 +245,20 @@ describe( 'ButtonView', () => {
 			} );
 
 			it( '-pressed reacts to #isOn', () => {
+				view.isToggleable = true;
 				view.isOn = true;
 				expect( view.element.attributes[ 'aria-pressed' ].value ).to.equal( 'true' );
 
 				view.isOn = false;
-				expect( view.element.attributes[ 'aria-pressed' ] ).to.be.undefined;
+				expect( view.element.attributes[ 'aria-pressed' ].value ).to.equal( 'false' );
+			} );
+
+			it( '-pressed is not present for non–toggleable button', () => {
+				view.isOn = true;
+				expect( view.element.hasAttribute( 'aria-pressed' ) ).to.be.false;
+
+				view.isOn = false;
+				expect( view.element.hasAttribute( 'aria-pressed' ) ).to.be.false;
 			} );
 		} );
 

+ 4 - 0
packages/ckeditor5-ui/tests/button/switchbuttonview.js

@@ -24,6 +24,10 @@ describe( 'SwitchButtonView', () => {
 		it( 'sets CSS class', () => {
 			expect( view.element.classList.contains( 'ck-switchbutton' ) ).to.be.true;
 		} );
+
+		it( 'sets isToggleable flag to true', () => {
+			expect( view.isToggleable ).to.be.true;
+		} );
 	} );
 
 	describe( 'render', () => {

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

@@ -30,6 +30,14 @@ describe( 'SplitButtonView', () => {
 			expect( view.actionView.element.classList.contains( 'ck-splitbutton__action' ) ).to.be.true;
 		} );
 
+		it( 'adds isToggleable to view#actionView', () => {
+			expect( view.actionView.isToggleable ).to.be.false;
+
+			view.isToggleable = true;
+
+			expect( view.actionView.isToggleable ).to.be.true;
+		} );
+
 		it( 'creates view#arrowView', () => {
 			expect( view.arrowView ).to.be.instanceOf( ButtonView );
 			expect( view.arrowView.element.classList.contains( 'ck-splitbutton__arrow' ) ).to.be.true;
@@ -62,6 +70,14 @@ describe( 'SplitButtonView', () => {
 			expect( view.element.classList.contains( 'ck-splitbutton_open' ) ).to.be.false;
 		} );
 
+		it( 'binds arrowView aria-expanded attribute to #isOn', () => {
+			view.arrowView.isOn = true;
+			expect( view.arrowView.element.getAttribute( 'aria-expanded' ) ).to.equal( 'true' );
+
+			view.arrowView.isOn = false;
+			expect( view.arrowView.element.getAttribute( 'aria-expanded' ) ).to.equal( 'false' );
+		} );
+
 		describe( 'activates keyboard navigation for the toolbar', () => {
 			it( 'so "arrowright" on view#arrowView does nothing', () => {
 				const keyEvtData = {

+ 4 - 0
packages/ckeditor5-ui/tests/toolbar/block/blockbuttonview.js

@@ -22,6 +22,10 @@ describe( 'BlockButtonView', () => {
 		expect( view.element.classList.contains( 'ck-block-toolbar-button' ) ).to.be.true;
 	} );
 
+	it( 'should be initialized as toggleable button', () => {
+		expect( view.isToggleable ).to.be.true;
+	} );
+
 	describe( 'DOM binding', () => {
 		it( 'should react on `view#top` change', () => {
 			view.top = 0;