Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desktop: Accessibility: Add a new shortcut to set focus to editor toolbar #11764

Merged
merged 12 commits into from
Feb 7, 2025

Conversation

pedr
Copy link
Collaborator

@pedr pedr commented Feb 1, 2025

Related to #10795

Summary

When using the RTE only with the keyboard the tab was skipping the toolbar items. TinyMCE has a shortcut for it (Alt+F10) but it is not accessible on all systems.

On this PR I'm adding a new command that should fix that by setting the focus to the first item of the toolbar on the RTE or the Markdown editor, if that is the active one.

Potential problem:
While the feature it is working, it seems like sometimes the element of the toolbar with focus is not set properly. I would guess that has to do with how React re-renders the elements. To emulate the faulty behaviour:

  1. Select Markdown/RTE editor
  2. Set focus to the note body
  3. Select the other editor
  4. Set focus to the note body
  5. Use the shortcut
  6. Focus is on the toolbar but, sometimes, the element is not highlighted

WCAG

Guideline 2.1 Make all functionality available from a keyboard

Testing

Testing Markdown edtior

  1. On Markdown editor
  2. Put focus on the note body
  3. Press Alt+F6
  4. See focus being set to toolbar

Testing Rich text editor

  1. On Rich text editor
  2. Put focus on the note body
  3. Press Alt+F6
  4. See focus being set to toolbar

@pedr pedr added desktop All desktop platforms accessibility Related to accessibility labels Feb 1, 2025
}

const boldOnMarkdown = dependencies.editorContainerDomElement.querySelector(
'.button.toolbar-button[title=\'Bold\']',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this!

Does this selector work in non-English locales? (When the title isn't "bold").

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion, you are right! I tried to avoid using deep selectors because I thought they could break more easily, but I didn't think about the language impact.

I updated the selector, it would be nice to hear what do you think about it.

Comment on lines 26 to 28
const boldOnMarkdown = dependencies.editorContainerDomElement.querySelector(
'#CodeMirrorToolbar div.group:nth-of-type(2) button.button.toolbar-button:nth-of-type(1)',
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the Markdown toolbar is a custom component, here's one way this might be made simpler:

  • From the toolbar code: Add an -autofocus class (or similar) to the button that should be autofocused (probably near this line).
  • In focusToolbar.ts: Select the button to be focused with .button.-autofocus.

Alternatively, the button that should be autofocused might already be the only button that doesn't have tabindex=-1 (the Markdown toolbar should follow the toolbar pattern).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • It seems like that Bold is only tabindex=0 when Forward and Backwards are disabled
  • I'm going to try to do something like this with a class directly where we want the focus to be, I guess that would work better and be less refactor-prone.

Thanks for the suggestions!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Instead of using another class I opted for using the [tabindex="0"]
  • I also use a :not(.disabled) so we skip the backwards and forwards button if they are disabled

Comment on lines 17 to 19
const boldOnRTE = dependencies.editorContainerDomElement.querySelector(
'.tox-toolbar-overlord div.tox-toolbar__group:nth-of-type(1) button:nth-of-type(1)',
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible simplification: This may still work if querySelector doesn't uniquely resolve to an element. For example,

Suggested change
const boldOnRTE = dependencies.editorContainerDomElement.querySelector(
'.tox-toolbar-overlord div.tox-toolbar__group:nth-of-type(1) button:nth-of-type(1)',
);
const boldOnRTE = dependencies.editorContainerDomElement.querySelector(
'.tox-toolbar__group button',
);

@pedr
Copy link
Collaborator Author

pedr commented Feb 3, 2025

I tested using { focusVisible: true } to fix the problem where the element was focused but we had no visual effect, but that didn't make any difference.
It seems like it has never been supported on Chrome, I guess that also means that we don't have support on Electron, right?
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#focusvisible

@personalizedrefrigerator
Copy link
Collaborator

It seems like it has never been supported on Chrome, I guess that also means that we don't have support on Electron, right?

That would mean it's not supported in Electron. Thank you for checking!

Copy link
Owner

@laurent22 laurent22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pedr, there's a also a focusElement command - please add yours to it for consistency.

@@ -814,6 +815,11 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
editor.addShortcut('Meta+Shift+7', '', () => editor.execCommand('InsertOrderedList'));
editor.addShortcut('Meta+Shift+8', '', () => editor.execCommand('InsertUnorderedList'));
editor.addShortcut('Meta+Shift+9', '', () => editor.execCommand('InsertJoplinChecklist'));
editor.addShortcut(
KeymapService.instance().getAccelerator('focusToolbar'),
'Focus toolbar',
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of the "Focus toolbar" string here? Can it be omitted like in the other addShortcut calls? (especially since it's not translated)

setShowRevisions,
isInFocusedDocument: () => {
return containerRef.current?.ownerDocument?.hasFocus();
},
editorContainerDomElement: containerRef.current,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

editorContainerDomElement => editorContainerElement

@@ -112,6 +113,7 @@ const defaultKeymapItems = {
{ accelerator: 'Ctrl+Alt+3', command: 'switchProfile3' },
{ accelerator: 'Ctrl+Alt+N', command: 'openNoteInNewWindow' },
{ accelerator: 'Ctrl+M', command: 'toggleTabMovesFocus' },
{ accelerator: 'Alt+F6', command: 'focusToolbar' },
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please put this shortcut below all the other focusXxx shortcuts?

Also what was the reason for choosing a completely different keyboard shortcut for this? All the other ones are "Ctrl+Shift+Something"

@@ -0,0 +1,36 @@
import { CommandRuntime, CommandDeclaration } from '@joplin/lib/services/CommandService';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whenever implementing a change, please check how other similar things are named. For example, all focus shortcuts are named "focusElement...". So yours should also be called "focusElementToolbar" for consistency. Could you please update the name?

@pedr
Copy link
Collaborator Author

pedr commented Feb 7, 2025

I finally update this PR. I end up changing a lot because I realized that there is no reason why I should be calling the command from the editor specifically (Before I would call from NoteEditor and TinyMCE).

I end up adding the command to the useWindowCommandHandler.

@laurent22 laurent22 merged commit 1230e1b into laurent22:dev Feb 7, 2025
7 checks passed
@pedr pedr deleted the change-focus-on-toolbar-shorcut branch February 7, 2025 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility Related to accessibility desktop All desktop platforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants