[Editor] Fix the accessibility of the dropdown in the color picker

This commit is contained in:
Calixte Denizet 2025-06-19 18:39:37 +02:00
parent 5653458b51
commit 1f2e9e5c0f
2 changed files with 22 additions and 12 deletions

View File

@ -78,7 +78,7 @@ class ColorPicker {
this.#uiManager = editor?._uiManager || uiManager; this.#uiManager = editor?._uiManager || uiManager;
this.#eventBus = this.#uiManager._eventBus; this.#eventBus = this.#uiManager._eventBus;
this.#defaultColor = this.#defaultColor =
editor?.color || editor?.color?.toUpperCase() ||
this.#uiManager?.highlightColors.values().next().value || this.#uiManager?.highlightColors.values().next().value ||
"#FFFF98"; "#FFFF98";
@ -96,13 +96,16 @@ class ColorPicker {
button.className = "colorPicker"; button.className = "colorPicker";
button.tabIndex = "0"; button.tabIndex = "0";
button.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-button"); button.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-button");
button.setAttribute("aria-haspopup", true); button.ariaHasPopup = "true";
if (this.#editor) {
button.ariaControls = `${this.#editor.id}_colorpicker_dropdown`;
}
const signal = this.#uiManager._signal; const signal = this.#uiManager._signal;
button.addEventListener("click", this.#openDropdown.bind(this), { signal }); button.addEventListener("click", this.#openDropdown.bind(this), { signal });
button.addEventListener("keydown", this.#keyDown.bind(this), { signal }); button.addEventListener("keydown", this.#keyDown.bind(this), { signal });
const swatch = (this.#buttonSwatch = document.createElement("span")); const swatch = (this.#buttonSwatch = document.createElement("span"));
swatch.className = "swatch"; swatch.className = "swatch";
swatch.setAttribute("aria-hidden", true); swatch.ariaHidden = "true";
swatch.style.backgroundColor = this.#defaultColor; swatch.style.backgroundColor = this.#defaultColor;
button.append(swatch); button.append(swatch);
return button; return button;
@ -110,8 +113,8 @@ class ColorPicker {
renderMainDropdown() { renderMainDropdown() {
const dropdown = (this.#dropdown = this.#getDropdownRoot()); const dropdown = (this.#dropdown = this.#getDropdownRoot());
dropdown.setAttribute("aria-orientation", "horizontal"); dropdown.ariaOrientation = "horizontal";
dropdown.setAttribute("aria-labelledby", "highlightColorPickerLabel"); dropdown.ariaLabelledBy = "highlightColorPickerLabel";
return dropdown; return dropdown;
} }
@ -122,9 +125,12 @@ class ColorPicker {
div.addEventListener("contextmenu", noContextMenu, { signal }); div.addEventListener("contextmenu", noContextMenu, { signal });
div.className = "dropdown"; div.className = "dropdown";
div.role = "listbox"; div.role = "listbox";
div.setAttribute("aria-multiselectable", false); div.ariaMultiSelectable = "false";
div.setAttribute("aria-orientation", "vertical"); div.ariaOrientation = "vertical";
div.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-dropdown"); div.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-dropdown");
if (this.#editor) {
div.id = `${this.#editor.id}_colorpicker_dropdown`;
}
for (const [name, color] of this.#uiManager.highlightColors) { for (const [name, color] of this.#uiManager.highlightColors) {
const button = document.createElement("button"); const button = document.createElement("button");
button.tabIndex = "0"; button.tabIndex = "0";
@ -136,7 +142,7 @@ class ColorPicker {
button.append(swatch); button.append(swatch);
swatch.className = "swatch"; swatch.className = "swatch";
swatch.style.backgroundColor = color; swatch.style.backgroundColor = color;
button.setAttribute("aria-selected", color === this.#defaultColor); button.ariaSelected = color === this.#defaultColor;
button.addEventListener("click", this.#colorSelect.bind(this, color), { button.addEventListener("click", this.#colorSelect.bind(this, color), {
signal, signal,
}); });
@ -231,6 +237,7 @@ class ColorPicker {
signal: this.#uiManager.combinedSignal(this.#openDropdownAC), signal: this.#uiManager.combinedSignal(this.#openDropdownAC),
}); });
} }
this.#button.ariaExpanded = "true";
if (this.#dropdown) { if (this.#dropdown) {
this.#dropdown.classList.remove("hidden"); this.#dropdown.classList.remove("hidden");
return; return;
@ -248,6 +255,7 @@ class ColorPicker {
hideDropdown() { hideDropdown() {
this.#dropdown?.classList.add("hidden"); this.#dropdown?.classList.add("hidden");
this.#button.ariaExpanded = "false";
this.#openDropdownAC?.abort(); this.#openDropdownAC?.abort();
this.#openDropdownAC = null; this.#openDropdownAC = null;
} }
@ -283,7 +291,7 @@ class ColorPicker {
const i = this.#uiManager.highlightColors.values(); const i = this.#uiManager.highlightColors.values();
for (const child of this.#dropdown.children) { for (const child of this.#dropdown.children) {
child.setAttribute("aria-selected", i.next().value === color); child.ariaSelected = i.next().value === color.toUpperCase();
} }
} }

View File

@ -957,9 +957,11 @@ class AnnotationEditorUIManager {
"highlightColors", "highlightColors",
this.#highlightColors this.#highlightColors
? new Map( ? new Map(
this.#highlightColors this.#highlightColors.split(",").map(pair => {
.split(",") pair = pair.split("=").map(x => x.trim());
.map(pair => pair.split("=").map(x => x.trim())) pair[1] = pair[1].toUpperCase();
return pair;
})
) )
: null : null
); );