Problem/Motivation
When a link is used to open an ajax dialog when the dialog is closed the jQuery dialog that core uses will return the focus to the item that had focus before the dialog was opened.
This does not work for contextual links. When a contextual link is used to open an ajax dialog when the dialog is closed(not a form save & page reload) the contextual link will not be visible and focus will not be returned.
This was discovered in #2784569: Settings Tray Accessibility: Improve tabbing for the off-canvas dialog but it affects all core dialogs.
Proposed resolution
When a dialog is closed that was opened from a contextual link the contextual lin button for the context
Remaining tasks
Figure out desired behaviourDetermine if this general Drupal dialog problem or specific to off-canvas dialog.- Implement fix
User interface changes
Contextual button will be focused after the dialog is closed.
API changes
None
Data model changes
none
Original Summary
from #2784569: Settings Tray Accessibility: Improve tabbing comment 9 point 7 of @Wim Leers review
However, when I close the Settings Tray dialog, my previous location is lost/forgotten — I'm back at the root of the page, and have to tab back all the way to where I was before I triggered the "Quick Edit" contextual link.
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | 2915762-23.patch | 4.82 KB | ranjith_kumar_k_u |
| #13 | 2915762-13.patch | 4.89 KB | tedbow |
| #13 | interdiff-12-13.txt | 1.78 KB | tedbow |
| #12 | 2915762-12.patch | 4.98 KB | tedbow |
| #12 | interdiff-8-12.txt | 4.44 KB | tedbow |
Comments
Comment #2
mgiffordComment #3
mgiffordremoving "a11y" tag since we aren't using it.
Comment #4
tedbowI have confirmed this is a problem with contextual links and dialogs even without Settings Tray enabled. We use to not support ajax/dialog links in contextual links so it won't have been a problem.
To test
You can also confirm that the focus work for the off-canvas dialog when not using context links by enabling
off_canvas_testand then doing steps first 6 step on the page /off-canvas-test-linksI tried to use the
dialog:beforecreateevent to capture the currently focused link but at that point the focus is already on the dialog I think.I am not sure what desired behavior would be here.
Comment #5
tedbowOk here is a fix. It will need work.
I talked to @andrewmacpherson and we agreed that focus should go to the contextual button that opened the contextual links list with the dialog link. This patch does that.
@andrewmacpherson also pointed out that we need to consider what should happen when a form is saved in the dialog and then reloads the current page. I think that should a new issue.
Need to figure out how to test this.
Comment #6
tedbowIf the dialog is being triggered for an element this element will be lost when opening the dialog if we don't save it in
dialogOptionsWe have to save the triggering element because
settingsis not available indialog:aftercloseevent.This patch adds test coverage to prove the trigger button is the active element when the dialog is closed.
Comment #7
tedbowIn #6 I was going to add test coverage for all dialog types but I realized it is difficult to test the off-canvas dialog unless you extend
\Drupal\Tests\system\FunctionalJavascript\OffCanvasTestBaseSo created #2927926: Create OffCanvas testing trait to allow other modules to test using off-canvas dialog
Comment #8
tedbowUpdated the comment which was I copied originally.
Also provided TEST_ONLY patch to prove the button does not get focus without this fix.
Comment #10
tim.plunkettI can't speak to the JS changes, but the test looks good.
Comment #11
GrandmaGlassesRopeManIs there any value in checking to see that
ajax.elementis actually of a type we expect?Probably need some docs describing what this is for. Also perhaps move it closer to where it's actually used?
Multiline comment format.
Comment #12
tedbow@drpal thanks for the review!
ajax.element instanceof ElementI looked into using
ajax.element instanceof HTMLElementbut from what I can tell Element is supported in many more browsers than HTMLElementdialog:beforecreatewhether it is contextual link. Because there no point saving the element if the link that opened the dialog is not a contextual link.As result of this it make more sense to just save the trigger button which will be given focus. So I changed the var name to
dialogLinkContextualButton. Added a comment and moved it closer to where it is used.Comment #13
tedbowchatted with @drpal and here is just small change to the
ifstatement when checking for the contextual button.Comment #14
GrandmaGlassesRopeMan@tedbow - Yes, looks good.
So just a general question about this. Previously in
dialog.ajax.es6.jswe perform some extensive checks before addingajax.elementtodrupalTriggerElement, does it make sense to move these checks to the changes in thedialog:beforecreatefunction?Comment #23
ranjith_kumar_k_u commentedRe-rolled #13 for 9.4
Comment #24
larowlanWe can achieve this without jQuery
dialogLinkContextualButton = settings.drupalTriggerElement.closest(['data-contextual-id'].querySelector('button')No need for the if anymore
no need for jQuery here, focus works on a HTMLElement in Vanilla JS
Comment #27
mgiffordAdding SC 2.1.1