From 4157ad13472f59f3471a9aec75def9d375cf72d0 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Thu, 14 Mar 2024 07:28:32 +0100 Subject: [PATCH 1/7] Add the visual label to the beginning of the programmatic aria label in heading dropdown --- packages/ckeditor5-heading/src/headingui.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/ckeditor5-heading/src/headingui.ts b/packages/ckeditor5-heading/src/headingui.ts index a2aef2d3d6e..1d138d59be4 100644 --- a/packages/ckeditor5-heading/src/headingui.ts +++ b/packages/ckeditor5-heading/src/headingui.ts @@ -15,7 +15,7 @@ import { type ButtonExecuteEvent, type ListDropdownItemDefinition } from 'ckeditor5/src/ui.js'; -import { Collection } from 'ckeditor5/src/utils.js'; +import { Collection, type ObservableChangeEvent } from 'ckeditor5/src/utils.js'; import type { ParagraphCommand } from 'ckeditor5/src/paragraph.js'; import { getLocalizedOptions } from './utils.js'; @@ -124,6 +124,21 @@ export default class HeadingUI extends Plugin { return titles[ whichModel ]; } ); + dropdownView.buttonView.bind( 'ariaLabel' ).to( headingCommand, 'value', paragraphCommand, 'value', ( value, para ) => { + const whichModel = value || para && 'paragraph'; + + if ( typeof whichModel === 'boolean' ) { + return accessibleLabel; + } + + // If none of the commands is active, display default title. + if ( !titles[ whichModel ] ) { + return accessibleLabel; + } + + return `${ titles[ whichModel ] }, ${ accessibleLabel }`; + } ); + // Execute command when an item from the dropdown is selected. this.listenTo( dropdownView, 'execute', evt => { const { commandName, commandValue } = evt.source as any; From f83fa75985cf629ef4a723f117bfb52ae3987af1 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Thu, 14 Mar 2024 07:47:38 +0100 Subject: [PATCH 2/7] Adjust test --- packages/ckeditor5-heading/tests/headingui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ckeditor5-heading/tests/headingui.js b/packages/ckeditor5-heading/tests/headingui.js index 9f5a22a41f2..3177d730315 100644 --- a/packages/ckeditor5-heading/tests/headingui.js +++ b/packages/ckeditor5-heading/tests/headingui.js @@ -74,7 +74,7 @@ describe( 'HeadingUI', () => { expect( dropdown.buttonView.isOn ).to.be.false; expect( dropdown.buttonView.label ).to.equal( 'Paragraph' ); expect( dropdown.buttonView.tooltip ).to.equal( 'Heading' ); - expect( dropdown.buttonView.ariaLabel ).to.equal( 'Heading' ); + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Paragraph, Heading' ); expect( dropdown.buttonView.ariaLabelledBy ).to.be.undefined; } ); From 14ab254f4e2f700d8721d9da9fa41e5a88dec870 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Wed, 20 Mar 2024 07:48:17 +0100 Subject: [PATCH 3/7] Reduce condition --- packages/ckeditor5-heading/src/headingui.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ckeditor5-heading/src/headingui.ts b/packages/ckeditor5-heading/src/headingui.ts index 1d138d59be4..d5d2d54b6da 100644 --- a/packages/ckeditor5-heading/src/headingui.ts +++ b/packages/ckeditor5-heading/src/headingui.ts @@ -109,8 +109,8 @@ export default class HeadingUI extends Plugin { return areEnabled.some( isEnabled => isEnabled ); } ); - dropdownView.buttonView.bind( 'label' ).to( headingCommand, 'value', paragraphCommand, 'value', ( value, para ) => { - const whichModel = value || para && 'paragraph'; + dropdownView.buttonView.bind( 'label' ).to( headingCommand, 'value', paragraphCommand, 'value', ( heading, paragraph ) => { + const whichModel = paragraph ? 'paragraph' : heading; if ( typeof whichModel === 'boolean' ) { return defaultTitle; @@ -124,8 +124,8 @@ export default class HeadingUI extends Plugin { return titles[ whichModel ]; } ); - dropdownView.buttonView.bind( 'ariaLabel' ).to( headingCommand, 'value', paragraphCommand, 'value', ( value, para ) => { - const whichModel = value || para && 'paragraph'; + dropdownView.buttonView.bind( 'ariaLabel' ).to( headingCommand, 'value', paragraphCommand, 'value', ( heading, paragraph ) => { + const whichModel = paragraph ? 'paragraph' : heading; if ( typeof whichModel === 'boolean' ) { return accessibleLabel; From 39205ba239d7f346ad960484ca30f0dd3291ae30 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Wed, 20 Mar 2024 07:52:40 +0100 Subject: [PATCH 4/7] Add more tests --- packages/ckeditor5-heading/tests/headingui.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/ckeditor5-heading/tests/headingui.js b/packages/ckeditor5-heading/tests/headingui.js index 3177d730315..5df52f3900c 100644 --- a/packages/ckeditor5-heading/tests/headingui.js +++ b/packages/ckeditor5-heading/tests/headingui.js @@ -156,6 +156,34 @@ describe( 'HeadingUI', () => { paragraphCommand.value = true; expect( dropdown.buttonView.label ).to.equal( 'Paragraph' ); } ); + + it( 'label when heading and paragraph commands active', () => { + command.value = 'heading2'; + paragraphCommand.value = true; + + expect( dropdown.buttonView.label ).to.equal( 'Paragraph' ); + } ); + + it( 'ariaLabel', () => { + command.value = false; + paragraphCommand.value = false; + + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Heading' ); + + command.value = 'heading2'; + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Heading 2, Heading' ); + command.value = false; + + paragraphCommand.value = true; + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Paragraph, Heading' ); + } ); + + it( 'ariaLabel when heading and paragraph commands active', () => { + command.value = 'heading2'; + paragraphCommand.value = true; + + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Paragraph, Heading' ); + } ); } ); describe( 'localization', () => { From 5f994b1319c2a4bf09de61f984047a59cfbab582 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Wed, 20 Mar 2024 08:01:53 +0100 Subject: [PATCH 5/7] Set proper `aria-label` attribute in language dropdown --- .../ckeditor5-language/src/textpartlanguageui.ts | 10 ++++++++++ .../ckeditor5-language/tests/textpartlanguageui.js | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/ckeditor5-language/src/textpartlanguageui.ts b/packages/ckeditor5-language/src/textpartlanguageui.ts index 8e8073daa06..535dd69b620 100644 --- a/packages/ckeditor5-language/src/textpartlanguageui.ts +++ b/packages/ckeditor5-language/src/textpartlanguageui.ts @@ -106,6 +106,16 @@ export default class TextPartLanguageUI extends Plugin { return ( value && titles[ value ] ) || defaultTitle; } ); + dropdownView.buttonView.bind( 'ariaLabel' ).to( languageCommand, 'value', value => { + const selectedLanguageTitle = value && titles[ value ]; + + if ( !selectedLanguageTitle ) { + return accessibleLabel; + } + + return `${ accessibleLabel }, ${ selectedLanguageTitle }`; + } ); + // Execute command when an item from the dropdown is selected. this.listenTo( dropdownView, 'execute', evt => { languageCommand.execute( { diff --git a/packages/ckeditor5-language/tests/textpartlanguageui.js b/packages/ckeditor5-language/tests/textpartlanguageui.js index 024971051c3..165389ed616 100644 --- a/packages/ckeditor5-language/tests/textpartlanguageui.js +++ b/packages/ckeditor5-language/tests/textpartlanguageui.js @@ -151,6 +151,18 @@ describe( 'TextPartLanguageUI', () => { expect( dropdown.buttonView.label ).to.equal( 'Arabic' ); } ); + it( 'ariaLabel', () => { + command.value = false; + + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Language' ); + + command.value = 'fr:ltr'; + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Language, French' ); + + command.value = 'ar:rtl'; + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Language, Arabic' ); + } ); + it( 'reflects the #value of the command', () => { // Trigger lazy init. dropdown.isOpen = true; From a7bed63794ee9f83d19ad0e3c2f34319c2b70b7b Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Wed, 20 Mar 2024 08:07:30 +0100 Subject: [PATCH 6/7] Fix import --- packages/ckeditor5-heading/src/headingui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ckeditor5-heading/src/headingui.ts b/packages/ckeditor5-heading/src/headingui.ts index d5d2d54b6da..e34e77a883e 100644 --- a/packages/ckeditor5-heading/src/headingui.ts +++ b/packages/ckeditor5-heading/src/headingui.ts @@ -15,7 +15,7 @@ import { type ButtonExecuteEvent, type ListDropdownItemDefinition } from 'ckeditor5/src/ui.js'; -import { Collection, type ObservableChangeEvent } from 'ckeditor5/src/utils.js'; +import { Collection } from 'ckeditor5/src/utils.js'; import type { ParagraphCommand } from 'ckeditor5/src/paragraph.js'; import { getLocalizedOptions } from './utils.js'; From ecb43e41e8d13591ff1633147032b164aabed6a0 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Wed, 20 Mar 2024 12:10:08 +0100 Subject: [PATCH 7/7] Fix incorrect language button `ariaLabel` --- packages/ckeditor5-language/src/textpartlanguageui.ts | 2 +- packages/ckeditor5-language/tests/textpartlanguageui.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ckeditor5-language/src/textpartlanguageui.ts b/packages/ckeditor5-language/src/textpartlanguageui.ts index 535dd69b620..5f2314576c5 100644 --- a/packages/ckeditor5-language/src/textpartlanguageui.ts +++ b/packages/ckeditor5-language/src/textpartlanguageui.ts @@ -113,7 +113,7 @@ export default class TextPartLanguageUI extends Plugin { return accessibleLabel; } - return `${ accessibleLabel }, ${ selectedLanguageTitle }`; + return `${ selectedLanguageTitle }, ${ accessibleLabel }`; } ); // Execute command when an item from the dropdown is selected. diff --git a/packages/ckeditor5-language/tests/textpartlanguageui.js b/packages/ckeditor5-language/tests/textpartlanguageui.js index 165389ed616..d7e0e6daba0 100644 --- a/packages/ckeditor5-language/tests/textpartlanguageui.js +++ b/packages/ckeditor5-language/tests/textpartlanguageui.js @@ -157,10 +157,10 @@ describe( 'TextPartLanguageUI', () => { expect( dropdown.buttonView.ariaLabel ).to.equal( 'Language' ); command.value = 'fr:ltr'; - expect( dropdown.buttonView.ariaLabel ).to.equal( 'Language, French' ); + expect( dropdown.buttonView.ariaLabel ).to.equal( 'French, Language' ); command.value = 'ar:rtl'; - expect( dropdown.buttonView.ariaLabel ).to.equal( 'Language, Arabic' ); + expect( dropdown.buttonView.ariaLabel ).to.equal( 'Arabic, Language' ); } ); it( 'reflects the #value of the command', () => {