Skip to content

Keyboard events and ARIA markup added to speed control - #2381

Merged
jmclaus merged 1 commit into
masterfrom
jmclaus/feature_video_speed_control_improved_a11y
Feb 10, 2014
Merged

Keyboard events and ARIA markup added to speed control#2381
jmclaus merged 1 commit into
masterfrom
jmclaus/feature_video_speed_control_improved_a11y

Conversation

@jmclaus

@jmclaus jmclaus commented Jan 30, 2014

Copy link
Copy Markdown

Addresses BLD-402.

@jmclaus

jmclaus commented Jan 31, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan DO NOT MERGE. Please review the new functionality of the speed menu button, I made it adhere to the following standards: http://www.w3.org/TR/wai-aria-practices/#menubutton. I will then fix the tests that are failing.

@jmclaus

jmclaus commented Feb 3, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan By the way, I did not add aria-haspopup="true" to the speed button on purpose, it doesn't work well with Voice Over. If added, it will also announce the position of the video and its total length. Will investigate why. For the moment, it is not an issue as the volume control doesn't have that ARIA markup either.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$(speedEntries.eq(1)) => speedEntries.eq(1)

@jmclaus

jmclaus commented Feb 3, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan Fixed tests. Will add a couple of missing cases (ENTER & ESC on speed entries) tomorrow.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@jmclaus Why is this function declared globally? Use the var keyword...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@valera-rozuvan Done. (Why is this function declared globally? Use the var keyword)

@polesye

polesye commented Feb 4, 2014

Copy link
Copy Markdown
Contributor

My thoughts: let's avoid navigation via TAB through the menu items.

When the container or its active descendant has focus, the user may navigate through the container by pressing additional keys, such as the arrow keys, to change the currently active descendant. Any additional press of the main navigation key (generally the TAB key) will move out of the container to the next widget. See w3.org

What do you think about following behaviors:

If focus is on the hint button:

  • Enter: Open or close hint popup. Select last focused hint item if opening
  • Space: Open or close hint popup. Select last focused hint item if opening
  • Esc: close hint popup
  • Tab: focus goes to the next hint button (Volume button)
  • Shift + Tab: focus goes to the previous hint button (Play/Pause button)

If focus is on a hint item:

  • Left arrow: Select previous hint item
  • Up arrow: Select previous hint item
  • Right arrow: Select next hint item
  • Down arrow: Select next hint item
  • Esc: close hint popup
  • Tab: focus goes to the next hint button (Volume button)
  • Shift + Tab: focus goes to the previous hint button (Play/Pause button)

@jmclaus

jmclaus commented Feb 4, 2014

Copy link
Copy Markdown
Author

@polesye I was modeling the TAB behavior on menu items after this:

http://adobe-accessibility.github.io/Accessible-Mega-Menu/

But I agree, it should rather adhere to the W3 standards. It's easy to change in the case of the speed control. And we should include this behavior in the upcoming plugin.

I'm not sure of the behavior of:

  1. the UP and DOWN arrows, the focus should stay on menu control:
    (in http://www.w3.org/TR/wai-aria-practices/#menubutton)
    Space or Enter - With focus on the button pressing Space or Enter will toggle the display of the drop-down menu. Focus remains on the button.
  2. the LEFT and RIGHT arrows: I think they should rather behave as the SHIFT + TAB and TAB ie:
    LEFT arrow: focus goes to the previous hint button (Play/Pause button)
    RIGHT arrow: focus goes to the next hint button (Volume button)

This is also the standard behavior in native menus.

@polesye

polesye commented Feb 4, 2014

Copy link
Copy Markdown
Contributor

I think we need to implement [Menu Button(http://www.w3.org/TR/wai-aria-practices/#menubutton) behavior in this PR and no need to support LEFT/RIGHT arrows like in Menu.

I have updated behavior:
If focus is on the menu button:

  • Enter: Open or close menu. Select the first menu item if opening
  • Space: Open or close menu. Select the first menu item if opening
  • Up arrow: Open menu and move focus onto the first menu item.
  • Esc: Close menu
  • Tab: Move focus to the next menu button (Volume button)
  • Shift + Tab: Move focus to the previous menu button (Play/Pause button)

If focus is on a menu item:

  • Up arrow: Select previous menu item
  • Down arrow: Select next menu item
  • Esc: Close menu popup
  • Tab: Move focus to the next menu button (Volume button)
  • Shift + Tab: Move focus to the previous menu button (Play/Pause button)

@jmclaus

jmclaus commented Feb 4, 2014

Copy link
Copy Markdown
Author

@anton Agreed, lets not pack this PR with too many new features. I just noticed this (under 'Menu or Menu bar' not 'Menu button'):

If a menu bar item has focus and the menu is not open, then:
Enter, Space, and the up down arrow keys opens the menu and places focus on the first menu item in the opened menu or child menu bar.

So I agree on behavior of Space/Enter as it is not an isolated menu button but part of a menu bar.

I've added a few things. Here's the updated behavior:

If focus is on the menu button:

Enter/Space/Up arrow: Open menu and move focus onto the first menu item.
Esc: Close menu. Return focus to menu button.
Tab: Move focus to the next menu button (Volume button).
Shift + Tab: Move focus to the previous menu button (Play/Pause button).

If focus is on a menu item:

Up arrow: Select previous menu item.
Down arrow: Select next menu item.
Esc: Close menu popup. Return focus to menu button.
Enter: Select menu item value. Return focus to menu button.
Tab: Close menu. Move focus to the next menu button (Volume button).
Shift + Tab: Close menu. Move focus to the previous menu button (Play/Pause button).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

 speedEntries = speedControl.children('a')

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@polesye Done (speedEntries = speedControl.children('a')).

@jmclaus

jmclaus commented Feb 4, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan Addressed your comments, please continue review. Two specs were added, ENTER and ESCAPE behavior on menu items (I can't figure how to test the speed change on the ENTER keypress and left a TODO note. Any idea?). Also, using 'toBeFocused()' now makes the tests fail...

@jmclaus

jmclaus commented Feb 4, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan New behavior left to implement after our recent discussion:

  1. Pressing Space or Enter when Speed button has focus should open the menu and give focus to the last item in list (not the Speed button).
  2. Pressing TAB or SHIFT + TAB should give focus to Play/Pause button and Volume button respectively.

@jmclaus

jmclaus commented Feb 4, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan Implemented the following:

'Pressing Space or Enter when Speed button has focus should open the menu and give focus to the last item in list (not the Speed button).'

and changed the tests accordingly. Also reverted to not using 'toBeFocused()'.

@jmclaus

jmclaus commented Feb 5, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan Please continue review. I just implemented the following:

Pressing TAB or SHIFT + TAB should give focus to Play/Pause button and Volume button respectively.

and added related tests. In these, there are four things I cannot get to work (tests fail, therefore I omitted them):

  1. On ENTER, TAB, TAB+SHIFT, verify that menu closes.
  2. On ENTER, verify that speed has changed.

I welcome any suggestion.

@polesye

polesye commented Feb 6, 2014

Copy link
Copy Markdown
Contributor
  1. Open the menu with the keyboard when you mouse click away from the menu speed it should be closed.
  2. Open the menu with the keyboard -> focus in on last item -> mouse over speed menu -> mouse leave speed menu -> speed menu is closed and focus is lost. Probably, menu button should catch this focus on menu closing.
  3. Choose new speed in the menu via mouse -> menu is closed - > menu button catches focus. I think when we're working via mouse, menu button should not be outlined. What do you think?

@jmclaus

jmclaus commented Feb 6, 2014

Copy link
Copy Markdown
Author

@polesye

  1. I agree.
  2. I think that when the menu was opened with keyboard interaction, hovering the mouse on it then away from should do absolutely nothing. See http://adobe-accessibility.github.io/Accessible-Mega-Menu for example.
  3. I agree, it is BLD-804.

@polesye

polesye commented Feb 6, 2014

Copy link
Copy Markdown
Contributor

I think that when the menu was opened with keyboard interaction, hovering the mouse on it then away from should do absolutely nothing. See http://adobe-accessibility.github.io/Accessible-Mega-Menu for example.

Agree.

@polesye

polesye commented Feb 6, 2014

Copy link
Copy Markdown
Contributor

Anyway it looks great! I believe we'll add the same behavior for the captions in future.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe that we should not do that explicitly, it should works via native tab ordering.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@polesye If I remove the focus() call, things break. I'll leave it as is for the moment, let me wrap up the rest beforehand. Thanks.

@valera-rozuvan

Copy link
Copy Markdown
Contributor

@jmclaus Wow! How much work went into this PR! Crisp and clean. I like it = )

👍 @polesye Great job with the perfectionistic code review! You basically leave me no work = )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

To improve performance and memory usage:

var speedButtonAnchor = state.videoSpeedControl.el.children('a');

state.videoSpeedControl.videoSpeedsEl.on('keydown', 'a.speed_link', function (event) {
    event.preventDefault();
    event.stopImmediatePropagation();

    var el = state.videoSpeedControl.el,
        index = $(event.currentTarget).parent().index();

    switch (event.keyCode) {
        // Scroll up menu, wrapping at the top. Keep menu open.
        case KEY.UP:
            _previousSpeedLink(speedLinks, index).focus();
            break;
        // Scroll down  menu, wrapping at the bottom. Keep menu
        // open.
        case KEY.DOWN:
            _nextSpeedLink(speedLinks, index).focus();
            break;
        // Close menu.
        case KEY.TAB:
           el.removeClass('open');
        break;
        // Close menu, give focus to speed control and change
        // speed.
        case KEY.ENTER:
        case KEY.SPACE:
            el.removeClass('open');
            speedButtonAnchor.focus();
            state.videoSpeedControl.changeVideoSpeed(event);
            break;
        // Close menu and give focus to speed control.
        case KEY.ESCAPE:
            el.removeClass('open');
            speedButtonAnchor.focus();
            break;
    }
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@polesye Yes, delegated events, elegant. Done.

@jmclaus

jmclaus commented Feb 7, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan The following has been done:

  1. Open the menu with the keyboard when you mouse click away from the menu speed it should be closed.

  2. I think that when the menu was opened with keyboard interaction, hovering the mouse on it then away from should do absolutely nothing. See http://adobe-accessibility.github.io/Accessible-Mega-Menu for example.

And addressed all comments, except the one regarding TAB (or Tab + SHIFT) keypress on the speed entries. Did a lot of refactoring and got rid of the last anonymous eventHandler (key press on speed entries).

Left to do: correct the failing tests. And add a few more of them to test new functionality. It's starting to look good! Please review again when you have time. Thanks for all your help and comments!

@polesye

polesye commented Feb 7, 2014

Copy link
Copy Markdown
Contributor

👍 once all tests will be written.

@valera-rozuvan

Copy link
Copy Markdown
Contributor

👍

@jmclaus

jmclaus commented Feb 7, 2014

Copy link
Copy Markdown
Author

@valera-rozuvan @polesye OK, will let you know when they are done. Thanks.

@jmclaus

jmclaus commented Feb 10, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan I added the missing tests. Please review. What should we do with the 3 disabled tests? 2 of them are not relevant since the refactoring. Should I just remove them? And the other one, I cannot get it to function. Anton suggested that we open a new ticket for that issue. Should I do that and remove the test in video_speed_control_spec.js?

@polesye

polesye commented Feb 10, 2014

Copy link
Copy Markdown
Contributor

@jmclaus I spent some time to figure out why this test doesn't work and found the problem:
Use here

spyOn($.fn, 'focus').andCallThrough();

instead

spyOn($.fn, 'focus');

And test do not close the speed menu on mouseleave if... pass.

2 of them are not relevant since the refactoring.

Yes, remove them.

@jmclaus

jmclaus commented Feb 10, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan Removed 2 irrelevant tests. Fixed last test that wasn't working. Rebased and squashed commits. Good to merge? (when it passes Jenkins)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this handler really removed after this? I'm not sure, because of bind.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done.

@jmclaus

jmclaus commented Feb 10, 2014

Copy link
Copy Markdown
Author

@polesye You are right. Let me remove the bind, it is not necessary here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Description: Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. (See jquery is)

I think it can be rewritten so:

function _speedLinksFocused(state) {
    var speedLinks = state.videoSpeedControl.videoSpeedsEl
                                            .find('a.speed_link');

    return speedLinks.is(':focus');

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You right, done.

@polesye

polesye commented Feb 10, 2014

Copy link
Copy Markdown
Contributor

Good job! 👍 once Jenkins pass.

@jmclaus

jmclaus commented Feb 10, 2014

Copy link
Copy Markdown
Author

@polesye @valera-rozuvan Addressed latest comments. Rebased & squashed last commit. Checked new functionality -- all behaves correctly. All tests all pass locally.

@valera-rozuvan

Copy link
Copy Markdown
Contributor

@jmclaus "Test Result (no failures)" means you should restart the Jenkins tests manually. Go to https://jenkins.testeng.edx.org/ , log in, select "edx-all-tests-manual-pr", click on "Build with Parameters", enter the PR number. After the second pass, Jenkins usually reports OK.

@polesye

polesye commented Feb 10, 2014

Copy link
Copy Markdown
Contributor

@valera-rozuvan it doesn't help. I have the same issue in my PR.

@valera-rozuvan

Copy link
Copy Markdown
Contributor

@jmclaus 👍

@polesye

polesye commented Feb 10, 2014

Copy link
Copy Markdown
Contributor

👍

…ymous event handlers by named functions. Menu stays open on mouseleave when a speed entry has focus. In that case, the menu can be closed by clicking anywhere outside of it. [BLD-402, BLD-363]
jmclaus pushed a commit that referenced this pull request Feb 10, 2014
…_improved_a11y

Keyboard events and ARIA markup added to speed control
@jmclaus
jmclaus merged commit 72ea40d into master Feb 10, 2014
@jmclaus
jmclaus deleted the jmclaus/feature_video_speed_control_improved_a11y branch February 10, 2014 21:07
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