MDL-71672 javascript: Fix the issue of focusOnShowSelector being ignored

When focusOnShowSelector is not present, as a fallback, focus the first
focusable element in YUI dialogues
Ref:
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/dialog_role
This commit is contained in:
Shamim Rezaie 2021-06-02 17:59:04 +10:00
parent 8453fe0ddb
commit 2092f152b2
4 changed files with 62 additions and 44 deletions

View File

@ -43,7 +43,12 @@ var DIALOGUE_NAME = 'Moodle dialogue',
MENUBAR_SELECTOR = '[role=menubar]',
DOT = '.',
HAS_ZINDEX = 'moodle-has-zindex',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]):not([disabled]):not([tabindex^="-"]),' +
'a[href]:not([disabled]):not([tabindex^="-"]),' +
'button:not([disabled]):not([tabindex^="-"]),' +
'textarea:not([disabled]):not([tabindex^="-"]),' +
'select:not([disabled]):not([tabindex^="-"]),' +
'[tabindex]:not([disabled]):not([tabindex^="-"])',
FORM_SELECTOR = 'form';
/**
@ -316,10 +321,6 @@ Y.extend(DIALOGUE, Y.Panel, {
Y.one(titlebar).setStyle('cursor', 'move');
}
}
require(['core/local/aria/focuslock'], function(FocusLockManager) {
// Trap focus to the current bounding box.
FocusLockManager.trapFocus(this.get('boundingBox').getDOMNode());
}.bind(this));
// Only do accessibility hiding for modals because the ARIA spec
// says that all ARIA dialogues should be modal.
@ -410,9 +411,12 @@ Y.extend(DIALOGUE, Y.Panel, {
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
},
_focus: function() {
this.focus();
},
show: function() {
var result = null,
header = this.headerNode,
content = this.bodyNode,
focusSelector = this.get('focusOnShowSelector'),
focusNode = null;
@ -429,16 +433,18 @@ Y.extend(DIALOGUE, Y.Panel, {
focusNode = this.get('boundingBox').one(focusSelector);
}
if (!focusNode) {
// Fall back to the header or the content if no focus node was found yet.
if (header && header !== '') {
focusNode = header;
} else if (content && content !== '') {
focusNode = content;
// Fall back to the first focusable element in the body of the dialogue if no focus node was found yet.
if (content && content !== '') {
focusNode = content.one(CAN_RECEIVE_FOCUS_SELECTOR);
}
}
if (focusNode) {
focusNode.focus();
}
require(['core/local/aria/focuslock'], function(FocusLockManager) {
// Trap focus to the current bounding box.
FocusLockManager.trapFocus(this.get('boundingBox').getDOMNode());
if (focusNode) {
focusNode.focus();
}
}.bind(this));
return result;
},

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,12 @@ var DIALOGUE_NAME = 'Moodle dialogue',
MENUBAR_SELECTOR = '[role=menubar]',
DOT = '.',
HAS_ZINDEX = 'moodle-has-zindex',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]):not([disabled]):not([tabindex^="-"]),' +
'a[href]:not([disabled]):not([tabindex^="-"]),' +
'button:not([disabled]):not([tabindex^="-"]),' +
'textarea:not([disabled]):not([tabindex^="-"]),' +
'select:not([disabled]):not([tabindex^="-"]),' +
'[tabindex]:not([disabled]):not([tabindex^="-"])',
FORM_SELECTOR = 'form';
/**
@ -316,10 +321,6 @@ Y.extend(DIALOGUE, Y.Panel, {
Y.one(titlebar).setStyle('cursor', 'move');
}
}
require(['core/local/aria/focuslock'], function(FocusLockManager) {
// Trap focus to the current bounding box.
FocusLockManager.trapFocus(this.get('boundingBox').getDOMNode());
}.bind(this));
// Only do accessibility hiding for modals because the ARIA spec
// says that all ARIA dialogues should be modal.
@ -410,9 +411,12 @@ Y.extend(DIALOGUE, Y.Panel, {
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
},
_focus: function() {
this.focus();
},
show: function() {
var result = null,
header = this.headerNode,
content = this.bodyNode,
focusSelector = this.get('focusOnShowSelector'),
focusNode = null;
@ -429,16 +433,18 @@ Y.extend(DIALOGUE, Y.Panel, {
focusNode = this.get('boundingBox').one(focusSelector);
}
if (!focusNode) {
// Fall back to the header or the content if no focus node was found yet.
if (header && header !== '') {
focusNode = header;
} else if (content && content !== '') {
focusNode = content;
// Fall back to the first focusable element in the body of the dialogue if no focus node was found yet.
if (content && content !== '') {
focusNode = content.one(CAN_RECEIVE_FOCUS_SELECTOR);
}
}
if (focusNode) {
focusNode.focus();
}
require(['core/local/aria/focuslock'], function(FocusLockManager) {
// Trap focus to the current bounding box.
FocusLockManager.trapFocus(this.get('boundingBox').getDOMNode());
if (focusNode) {
focusNode.focus();
}
}.bind(this));
return result;
},

View File

@ -13,7 +13,12 @@ var DIALOGUE_NAME = 'Moodle dialogue',
MENUBAR_SELECTOR = '[role=menubar]',
DOT = '.',
HAS_ZINDEX = 'moodle-has-zindex',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]):not([disabled]):not([tabindex^="-"]),' +
'a[href]:not([disabled]):not([tabindex^="-"]),' +
'button:not([disabled]):not([tabindex^="-"]),' +
'textarea:not([disabled]):not([tabindex^="-"]),' +
'select:not([disabled]):not([tabindex^="-"]),' +
'[tabindex]:not([disabled]):not([tabindex^="-"])',
FORM_SELECTOR = 'form';
/**
@ -286,10 +291,6 @@ Y.extend(DIALOGUE, Y.Panel, {
Y.one(titlebar).setStyle('cursor', 'move');
}
}
require(['core/local/aria/focuslock'], function(FocusLockManager) {
// Trap focus to the current bounding box.
FocusLockManager.trapFocus(this.get('boundingBox').getDOMNode());
}.bind(this));
// Only do accessibility hiding for modals because the ARIA spec
// says that all ARIA dialogues should be modal.
@ -380,9 +381,12 @@ Y.extend(DIALOGUE, Y.Panel, {
Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
},
_focus: function() {
this.focus();
},
show: function() {
var result = null,
header = this.headerNode,
content = this.bodyNode,
focusSelector = this.get('focusOnShowSelector'),
focusNode = null;
@ -399,16 +403,18 @@ Y.extend(DIALOGUE, Y.Panel, {
focusNode = this.get('boundingBox').one(focusSelector);
}
if (!focusNode) {
// Fall back to the header or the content if no focus node was found yet.
if (header && header !== '') {
focusNode = header;
} else if (content && content !== '') {
focusNode = content;
// Fall back to the first focusable element in the body of the dialogue if no focus node was found yet.
if (content && content !== '') {
focusNode = content.one(CAN_RECEIVE_FOCUS_SELECTOR);
}
}
if (focusNode) {
focusNode.focus();
}
require(['core/local/aria/focuslock'], function(FocusLockManager) {
// Trap focus to the current bounding box.
FocusLockManager.trapFocus(this.get('boundingBox').getDOMNode());
if (focusNode) {
focusNode.focus();
}
}.bind(this));
return result;
},