Page MenuHomePhabricator

Find a solution for handling duplicate access keys and access keys of hidden elements (watchlist, login, contributions, search, edit)
Open, MediumPublicBUG REPORT

Description

In Vector 2022, given menu items can appear in multiple locations we have a problem with access keys. When links share a similar access key, there is no guidance in the WHATWG about how this behave. This means in Chrome and Firefox the experience is different. In Firefox, as flagged in T311281 the button is focused rather than navigated to. This issue also impacts other products including Special:Translate tool (https://github.com/webcompat/web-bugs/issues/116510).

This was intentionally raised as a problem in September 2022 (T318305) and deemed to be a browser bug and an upstream bug was filed: https://bugzilla.mozilla.org/show_bug.cgi?id=1797214 but it doesn't look like a fix will be forthcoming.

Multiple access keys also cause problems in certain browsers when elements are hidden as described in T321428.

Possible solutions

Wait on the spec for guidance

Any change we make here will likely need to be revisited on https://bugzilla.mozilla.org/show_bug.cgi?id=1797214 so it might be worth waiting.

De-duplicate access keys in core / Vector 2022 / gadget

To workaround this inconsistency, one option is to de-duplicate access keys in the page. This can be done either via a gadget or as part of the core software:

var isVisible = ( node ) => node.offsetParent === null;
const activeKey = {};

function updateAccessKeys() {
    accessKeyNodes.forEach( ( node ) => {
        const key = node.dataset.accessKey;
        if ( !isVisible( node ) ) {
            // do we need to remove?
            if ( activeKey[ key ] === node ) {
                activeKey[ key ] = null;
                node.removeAttribute( 'accesskey' );
            }
        } else if ( !activeKey[ key ] ) {
            // do we need to add ?
            activeKey[ key ] = node;
            node.setAttribute( 'accesskey', key );
        }
    } );
}

const accessKeyNodes = Array.from(document.querySelectorAll( '[accesskey]') );
accessKeyNodes.forEach((node) => {
    const key = node.getAttribute( 'accesskey' );
    node.dataset.accessKey = key;
    if ( isVisible( node) && !activeKey[ key ] ) {
        activeKey[key] = node;
    } else {
        node.removeAttribute( 'accesskey' );
    }
} );

const belowDesktopMedia = window.matchMedia( '(max-width: 999px)' );
belowDesktopMedia.onchange = () => {
    updateAccessKeys();
};

`

Since the feature is most often used by logged in users, solution might be restricted to logged in users.

decouple menu items from access keys

Update Vector to only add one access key to one item. (This won't fix the problem of when menu items are hidden)

Other?

Ideas welcome!

Event Timeline

Jdlrobson triaged this task as Medium priority.May 9 2023, 4:58 PM
Jdlrobson moved this task from Incoming to Current Fiscal Year on the Web-Team-Backlog board.

Quite recently, the edit buttons were also duplicated to the toolbox (and hidden), meaning there are now two elements with accesskey="e" in the DOM. This is probably the accesskey I use the most, and this recent addition moves this bug (for me) from "a minor inconvenience" to "kind of a PITA". Could something be done about it? E.g. adding the solution Jdlrobson put in the task description (preferrably to the skin proper and not as a gadget, since that would mean adding it as a gadget to basically all wikis, with all the maintenance overhead that comes with that).

Jdlrobson renamed this task from Find a solution for handling duplicate access keys and access keys of hidden elements (watchlist, login, contributions, search) to Find a solution for handling duplicate access keys and access keys of hidden elements (watchlist, login, contributions, search, edit).Sep 21 2023, 4:02 PM
Jdlrobson added a subscriber: Samwilson.

There's a user script that @Ruthven set up with the above code:

mw.loader.load( 'https://nap.wikisource.org/w/index.php?title=Utente:Ruthven/De-duplicateAccessKeys.js&action=raw&ctype=text/javascript' );

I don't undertand the first line in the "De-duplicate access keys" Javascript code:

var isVisible = ( node ) => node.offsetParent === null;

Don't you think it should be:

var isVisible = ( node ) => node.offsetParent != null;

The first version deactivates most shortcuts.

The solution is to not get two accesskeys onto the page in the first place. It is a WCAG violation: https://www.w3.org/TR/2014/NOTE-WCAG20-TECHS-20140311/F17

It is not good when a user script does that, but in that case, at least we can sort of yell at their maintainers. For a default skin to do this it is, really, a sin. It should be handled first and foremost with a change in HTML, not with a change by JavaScript.

It is not good when a user script does that, but in that case, at least we can sort of yell at their maintainers. For a default skin to do this it is, really, a sin. It should be handled first and foremost with a change in HTML, not with a change by JavaScript.

We can certainly make sure the accesskeys are only printed once, but this means access keys will stop working on Chrome/Firefox when the browser is resized. In case you missed the upstream issue here the specification is unclear on the behaviour here and your note seems to be in direct conflict with how this actually works in practice: https://bugzilla.mozilla.org/show_bug.cgi?id=1797214

In lieu of a fix in the browser, I still think a JavaScript solution is required here to make this behave how our users expect it to behave.

HTML spec and WCAG spec are two separate things. We were discussing the case of the duplicated accesskeys with @sgrabarczuk in Russian Discord server (in English) and the thing is, many of those duplicated ones are just duplicated items in various menus (Edit button also present in Actions menu, etc.). If this is to try to get the elements resized correctly, then yes, probably some JS to move accesskeys around to the element that is not display: none is needed. But the HTML on the page also should not be giving duplicated edit accesskeys etc. by default, because having them duplicated is like having IDs duplicated: wrong for accessibility (and understandability for those who use the accesskeys).