Skip to content

Commit

Permalink
issue/6 Distinction between readable and focusable for findForward
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverfoster authored Sep 16, 2021
2 parents d889e58 + 8ee4732 commit 5085758
Showing 1 changed file with 43 additions and 4 deletions.
47 changes: 43 additions & 4 deletions js/a11y.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class A11y extends Backbone.Controller {
_tabbableElementsExcludes: ':not(.a11y-ignore):not([data-a11y-force-focus])',
_focusableElements: 'a,button,input,select,textarea,[tabindex],label',
_readableElements: '[role=heading],[aria-label],[aria-labelledby],[alt]',
/**
* Prevent adapt from focusing forward onto these elements.
*/
_focusForwardElementsExcludes: ':not([aria-labelledby][role=dialog],[aria-labelledby][role=main],[aria-labelledby][role=region],[aria-labelledby][role=radiogroup],[aria-labelledby][role=group],[aria-labelledby][role=tablist],[aria-labelledby][role=list],[aria-labelledby][role=tree],[aria-labelledby][role=treegrid],[aria-labelledby][role=table],[aria-labelledby][role=grid][aria-labelledby],[role=menu],[aria-labelledby][role=rowgroup])',
/**
* Selector for elements which cause tab wrapping.
*/
Expand All @@ -59,6 +63,7 @@ class A11y extends Backbone.Controller {
}

initialize() {
this.isFocusable = this.isFocusable.bind(this);
this.isReadable = this.isReadable.bind(this);
this.isTabbable = this.isTabbable.bind(this);
this.$html = $('html');
Expand Down Expand Up @@ -287,6 +292,17 @@ class A11y extends Backbone.Controller {
return this._findFirstForward($element, this.isReadable);
}

/**
* Find the first focusable element after the specified element.
*
* @param {Object|string|Array} $element
* @returns {Object}
*/
findFirstFocusable($element) {
$element = $($element).first();
return this._findFirstForward($element, this.isFocusable);
}

/**
* Find all tabbable elements in the specified element.
*
Expand All @@ -307,6 +323,15 @@ class A11y extends Backbone.Controller {
return $($element).find('*').filter((index, element) => this.isReadable(element));
}

/**
* Find all focusable elements in the specified element.
*
* @param {Object|string|Array} $element
*/
findFocusable($element) {
return $($element).find('*').filter((index, element) => this.isFocusable(element));
}

/**
* Check if the element is natively or explicitly tabbable.
*
Expand All @@ -317,7 +342,7 @@ class A11y extends Backbone.Controller {
const config = this.config;
const value = $($element).is(config._options._tabbableElements).is(config._options._tabbableElementsExcludes);
if (!value) {
return undefined; // Allow _findForward to descend
return null; // Allow _findForward to descend
}
return value;
}
Expand Down Expand Up @@ -368,7 +393,21 @@ class A11y extends Backbone.Controller {
}
return true;
}
return undefined; // Allows _findForward to decend.
return null; // Allows _findForward to decend.
}

/**
* Check if the first item is readable by a screen reader.
*
* @param {Object|string|Array} $element
* @param {boolean} [checkParents=true] Check if parents are inaccessible.
* @returns {boolean}
*/
isFocusable($element, checkParents = true) {
const config = this.config;
$element = $($element).first();
if (!$element.is(config._options._focusForwardElementsExcludes)) return null;
return this.isReadable($element, checkParents);
}

/**
Expand Down Expand Up @@ -572,7 +611,7 @@ class A11y extends Backbone.Controller {
focusNext($element, options) {
options = new FocusOptions(options);
$element = $($element).first();
$element = this.findFirstReadable($element);
$element = this.findFirstFocusable($element);
this.focus($element, options);
return this;
}
Expand All @@ -592,7 +631,7 @@ class A11y extends Backbone.Controller {
this.focus($element, options);
return $element;
}
$element = this.findFirstReadable($element);
$element = this.findFirstFocusable($element);
this.focus($element, options);
return $element;
}
Expand Down

0 comments on commit 5085758

Please sign in to comment.