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

Add keyboard support and accessibility polyfill for IE11 & Edge #5

Merged
merged 13 commits into from
Sep 27, 2017

Conversation

muan
Copy link
Collaborator

@muan muan commented Sep 1, 2017

👋🏻 This follows the definitions in https://www.w3.org/TR/html-aam-1.0/#summary-and-details-elements:

The summary element should be focusable by default.

Pressing the spacebar or enter key when the summary element has focus will show the details element content if the content is hidden. If the details element content is showing and the summary element has focus, pressing the spacebar or enter key will hide the details element content.

In accessibility APIs that do not have such a fine grained role, the summary element should be mapped to a button role.

When the details element content is shown, on the summary element (ROLE_SYSTEM_PUSHBUTTON), set STATE_SYSTEM_EXPANDED. The hidden and shown states of the details element content is reflected by the absence or presence of the open attribute.

And adds

  1. Toggling aria-expanded on <summary>
  2. tabindex and role to <summary>
  3. enter and space trigger for <summary>
  4. Test for <summary> being focusable

It'd be nice to test addAttributesForSummary when details isn't supported. Is checking for navigator.userAgent in test.coffee the only way?

I also tried adding a test for enter/space trigger, but the keydown event simulation doesn't seem to trigger the default action when I tested in Chrome 🤔.

cc @josh @dgraham @keithamus

@keithamus
Copy link

This all looks excellent and matches with the linked spec 👌 💯

else
document.addEventListener "DOMNodeInserted", (event) ->
if event.target.tagName is "SUMMARY"
addAttributesForSummary event.target
Copy link
Owner

Choose a reason for hiding this comment

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

Ideally, we'd only create a single MutationObserver (or DOMNodeInserted listener). Think this could be combined with the one in polyfillToggleEvent?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

polyfillToggleEvent only get called when support.element and not support.toggleEvent while polyfillFocusAndARIA only get called when not support.element, so only one MutationObserver will ever get created. Do you think it's worth combining them still? The conditions make it a bit awkward when I tried. 🤔

addAttributesForSummary event.target

addAttributesForSummary = (summary) ->
details = findClosestElementWithTagName(summary, "DETAILS")
Copy link
Owner

@javan javan Sep 20, 2017

Choose a reason for hiding this comment

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

This closest trip up the DOM could be avoided if the details element was (optionally) passed too. You already have a reference to it in the mutation observer callback.

@@ -56,11 +56,37 @@ polyfillProperties = ->
removeAttribute.call(this, name)

polyfillToggle = ->
onTogglingClick (element) ->
onTogglingTrigger (element) ->
summary = element.querySelector "summary"
Copy link
Owner

Choose a reason for hiding this comment

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

I prefer using parens for function calls in CoffeeScript even though they're optional. Mind updating to follow that style throughout?

event.metaKey or
event.shiftKey or
event.target.isContentEditable
)
Copy link
Owner

Choose a reason for hiding this comment

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

Since this is so similar to clickEventIsSignificant, maybe there should be a single eventIsSignificant function with the common parts. And the event handlers can check the unique parts, e.g.:

addEventListener "keydown", (event) ->
  if eventIsSignificant(event)
    if event.keyCode in [13, 32]
      ...

@javan
Copy link
Owner

javan commented Sep 20, 2017

Thank you! And sorry for the delay in reviewing. These are welcomed improvements.

I also tried adding a test for enter/space trigger, but the keydown event simulation doesn't seem to trigger the default action when I tested in Chrome

What did you try? Dispatching an event with the right properties (like keyCode) seems like it'd work.

@javan
Copy link
Owner

javan commented Sep 20, 2017

Do you think it's appropriate for a polyfill to manage aria-expanded, tabindex, and role? Those attributes won't be present in browsers with native <details> support.

details = findClosestElementWithTagName(summary, "DETAILS")
summary.setAttribute "tabindex", "0"
summary.setAttribute "aria-expanded", details.hasAttribute("open")
summary.setAttribute "role", "button"
Copy link
Owner

Choose a reason for hiding this comment

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

Should probably avoid overwriting these attributes if they're present initially:

summary.setAttribute("tabindex", "0") unless summary.hasAttribute("tabindex")
...

@muan
Copy link
Collaborator Author

muan commented Sep 27, 2017

What did you try? Dispatching an event with the right properties (like keyCode) seems like it'd work.

Something like this: http://jsbin.com/yatubamege/1/edit?js,console,output If it works, details should be opened on load. In debugging I found this:

[1] Starting with Chrome 53, untrusted events do not invoke the default action.
https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted#Browser_compatibility

I think this might be the cause. I tested in Safari & Firefox, the events don't work either, but I couldn't find any reference other than this one for Chrome.


Do you think it's appropriate for a polyfill to manage aria-expanded, tabindex, and role? Those attributes won't be present in browsers with native <details> support.

I think it is. The attributes aren't present, but the characteristics they simulate are there, and these attributes were designed to add support for these characteristics.


Thanks for the review ⭐ I made all the other changes.

@javan javan merged commit a21de8b into javan:master Sep 27, 2017
@javan
Copy link
Owner

javan commented Sep 27, 2017

Thank you! I just released v2.0.0 with these changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants