这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@kloots
Copy link
Contributor

@kloots kloots commented Jun 6, 2017

This PR addresses issue #7 and ensures the focus-ring class is applied to contenteditable elements. Additionally, it removes the dom-matches polyfill dependency and updates the demo with more use cases.

…ven if no ARIA role attribute is applied. Remove dependency on the dom-matches polyfill. Update the demo with more use cases.
@jonathantneal jonathantneal mentioned this pull request Jun 6, 2017
Copy link
Contributor

@jonathantneal jonathantneal left a comment

Choose a reason for hiding this comment

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

I’ve left you a note about some small optimizations which I believe will keep the code better focused.

The toLowerCase() methods are unnecessary, and errantly suggest to some developers that the code may be working with non-standard elements (which are the only times tagName returns lowercase).

function focusTriggersKeyboardModality(el) {
return matches(el, keyboardModalityWhitelist) && matches(el, ':not([readonly])');
var type = el.type;
var tagName = el.tagName.toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

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

You’re only testing tagName against 'input' and 'textarea'. Therefore, you could safely omit .toLowerCase() and test for 'INPUT' and 'TEXTAREA' instead.

if (matches(document.activeElement, ':focus'))
addFocusRingClass(document.activeElement);
var activeElement = document.activeElement;
if (activeElement.tagName.toLowerCase() == 'body')
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly here, there is no browser that will return the tagName of 'BODY' in lowercase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jonathantneal are you sure? I recall IE returning the declared case if in quirks mode. If you're 100% sure I'm happy to remove the use of toLowerCase()

Copy link
Contributor

Choose a reason for hiding this comment

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

I am sure.

<body></body><script>document.write(document.body.tagName)</script>

Screenshot of Internet Explorer 8 displaying the tagName of body in uppercase

In older IE, there would be an issue with new “unknown” elements (back then, HTML5 elements) returning lowercase. It’s unneeded here, because you’re testing for some of the oldest elements known to web. :)

var tagName = el.tagName.toLowerCase();
var tagName = el.tagName;

if (tagName == 'input' && inputTypesWhitelist[type] && !el.readonly)
Copy link
Contributor

Choose a reason for hiding this comment

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

Be sure to test these changes. I’m not sure 'input' will work because it should now be uppercase?

Copy link
Contributor Author

@kloots kloots Jun 6, 2017

Choose a reason for hiding this comment

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

Fixed

if (tagName == 'textarea' && !el.readonly)
return true;

if (el.contentEditable)
Copy link
Contributor

Choose a reason for hiding this comment

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

The possible values of contentEditable are 'inherit', 'true', or 'false'.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@kloots
Copy link
Contributor Author

kloots commented Jun 7, 2017

@alice, any thoughts on this PR?

Copy link
Member

@alice alice left a comment

Choose a reason for hiding this comment

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

Generally in favour, but one concern per my comment.

if (activeElement.tagName == 'BODY')
return;

hadKeyboardEvent = true;
Copy link
Member

Choose a reason for hiding this comment

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

Why was this moved below the check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because the more I thought about it, we don't want to set that to true if focus hasn't moved to a focusable control. This way we can use hadKeyboardEvent to determine if a focus moved to a focusable element as a result of keyboard navigation.

Copy link
Member

Choose a reason for hiding this comment

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

hasKeyboardEvent is not intended for that use, though. I think this could cause a bug if a keyboard event triggered a focus move (for example, activating a button which caused a piece of modal UI to appear). Please revert this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I'm not 100% following you regarding the bug that could result from this change. Mind explaining in great detail?

Copy link
Member

Choose a reason for hiding this comment

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

Ah - I had it backwards. However, since the keyboard event precedes the focus event, this is checking where focus is coming from, rather than going to, isn't it?

Copy link
Contributor Author

@kloots kloots Jun 14, 2017

Choose a reason for hiding this comment

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

No worries at all. To answer your question: it's the other way around. The fact the keyboard event precedes the focus event actually works to our advantage here because we know the event sequence is: keydown then focus, and therefore the focus handler can key off of hadKeyboardEvent to know focus happened as a result of keyboard, and then add the focus-ring class.

Copy link
Member

Choose a reason for hiding this comment

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

Right: so at the point where this fires, activeElement is the element which is about to lose focus, isn't it? So why not set hadKeyboardEvent based on that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yes! Now I see what you're saying. Will change.

@alice
Copy link
Member

alice commented Jun 14, 2017

👍

@alice alice merged commit 66a7ce1 into WICG:master Jun 14, 2017
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