MDL-71669 atto_table: Set appropriate ARIA roles for table button

The table button can become a menu button when the cursor's position
in the editor is within a table. So we'd need to update the button with
ARIA attributes appropriate for a menu button.
This is best done when the button's highlight gets toggled, so we're
adding an event listener for when this happens and add/remove the ARIA
attributes accordingly.
This commit is contained in:
Jun Pataleta
2021-06-23 13:10:16 +08:00
parent 2874db9bd5
commit 335e628e27
4 changed files with 147 additions and 15 deletions
@@ -293,11 +293,20 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_menuOptions: null,
initializer: function() {
this.addButton({
var button = this.addButton({
icon: 'e/table',
callback: this._displayTableEditor,
tags: 'table'
});
// Listen for toggled highlighting.
require(['editor_atto/events'], function(attoEvents) {
var domButton = button.getDOMNode();
domButton.addEventListener(attoEvents.eventTypes.attoButtonHighlightToggled, function(e) {
this._setAriaAttributes(e.detail.buttonName, e.detail.highlight);
}.bind(this));
}.bind(this));
// Disable mozilla table controls.
if (Y.UA.gecko) {
document.execCommand("enableInlineTableEditing", false, false);
@@ -305,6 +314,30 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
},
/**
* Sets the appropriate ARIA attributes for the table button when it switches roles between a button and a menu button.
*
* @param {String} buttonName The button name.
* @param {Boolean} highlight True when the button was highlighted. False, otherwise.
* @private
*/
_setAriaAttributes: function(buttonName, highlight) {
var menuButton = this.buttons[buttonName];
if (menuButton) {
if (highlight) {
// This button becomes a menu button. Add appropriate ARIA attributes.
var id = menuButton.getAttribute('id');
menuButton.setAttribute('aria-haspopup', true);
menuButton.setAttribute('aria-controls', id + '_menu');
menuButton.setAttribute('aria-expanded', true);
} else {
menuButton.removeAttribute('aria-haspopup');
menuButton.removeAttribute('aria-controls');
menuButton.removeAttribute('aria-expanded');
}
}
},
/**
* Display the table tool.
*
@@ -343,10 +376,19 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
*/
_displayTableEditor: function(e) {
var cell = this._getSuitableTableCell();
var menuButton = e.currentTarget.ancestor('button', true);
if (cell) {
var id = menuButton.getAttribute('id');
// Indicate that the menu is expanded.
menuButton.setAttribute('aria-expanded', true);
// Add the cell to the EventFacade to save duplication in when showing the menu.
e.tableCell = cell;
return this._showTableMenu(e);
return this._showTableMenu(e, id);
} else {
// Dialog mode. Remove aria-expanded attribute.
menuButton.removeAttribute('aria-expanded');
}
return this._displayDialogue(e);
},
@@ -815,9 +857,10 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
*
* @method _showTableMenu
* @param {EventFacade} e
* @param {String} buttonId The ID of the menu button associated with this menu.
* @private
*/
_showTableMenu: function(e) {
_showTableMenu: function(e, buttonId) {
e.preventDefault();
var boundingBox;
@@ -873,7 +916,8 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
];
this._contextMenu = new Y.M.editor_atto.Menu({
items: this._menuOptions
items: this._menuOptions,
buttonId: buttonId
});
// Add event handlers for table control menus.
File diff suppressed because one or more lines are too long
@@ -293,11 +293,20 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_menuOptions: null,
initializer: function() {
this.addButton({
var button = this.addButton({
icon: 'e/table',
callback: this._displayTableEditor,
tags: 'table'
});
// Listen for toggled highlighting.
require(['editor_atto/events'], function(attoEvents) {
var domButton = button.getDOMNode();
domButton.addEventListener(attoEvents.eventTypes.attoButtonHighlightToggled, function(e) {
this._setAriaAttributes(e.detail.buttonName, e.detail.highlight);
}.bind(this));
}.bind(this));
// Disable mozilla table controls.
if (Y.UA.gecko) {
document.execCommand("enableInlineTableEditing", false, false);
@@ -305,6 +314,30 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
},
/**
* Sets the appropriate ARIA attributes for the table button when it switches roles between a button and a menu button.
*
* @param {String} buttonName The button name.
* @param {Boolean} highlight True when the button was highlighted. False, otherwise.
* @private
*/
_setAriaAttributes: function(buttonName, highlight) {
var menuButton = this.buttons[buttonName];
if (menuButton) {
if (highlight) {
// This button becomes a menu button. Add appropriate ARIA attributes.
var id = menuButton.getAttribute('id');
menuButton.setAttribute('aria-haspopup', true);
menuButton.setAttribute('aria-controls', id + '_menu');
menuButton.setAttribute('aria-expanded', true);
} else {
menuButton.removeAttribute('aria-haspopup');
menuButton.removeAttribute('aria-controls');
menuButton.removeAttribute('aria-expanded');
}
}
},
/**
* Display the table tool.
*
@@ -343,10 +376,19 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
*/
_displayTableEditor: function(e) {
var cell = this._getSuitableTableCell();
var menuButton = e.currentTarget.ancestor('button', true);
if (cell) {
var id = menuButton.getAttribute('id');
// Indicate that the menu is expanded.
menuButton.setAttribute('aria-expanded', true);
// Add the cell to the EventFacade to save duplication in when showing the menu.
e.tableCell = cell;
return this._showTableMenu(e);
return this._showTableMenu(e, id);
} else {
// Dialog mode. Remove aria-expanded attribute.
menuButton.removeAttribute('aria-expanded');
}
return this._displayDialogue(e);
},
@@ -815,9 +857,10 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
*
* @method _showTableMenu
* @param {EventFacade} e
* @param {String} buttonId The ID of the menu button associated with this menu.
* @private
*/
_showTableMenu: function(e) {
_showTableMenu: function(e, buttonId) {
e.preventDefault();
var boundingBox;
@@ -873,7 +916,8 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
];
this._contextMenu = new Y.M.editor_atto.Menu({
items: this._menuOptions
items: this._menuOptions,
buttonId: buttonId
});
// Add event handlers for table control menus.
+48 -4
View File
@@ -291,11 +291,20 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_menuOptions: null,
initializer: function() {
this.addButton({
var button = this.addButton({
icon: 'e/table',
callback: this._displayTableEditor,
tags: 'table'
});
// Listen for toggled highlighting.
require(['editor_atto/events'], function(attoEvents) {
var domButton = button.getDOMNode();
domButton.addEventListener(attoEvents.eventTypes.attoButtonHighlightToggled, function(e) {
this._setAriaAttributes(e.detail.buttonName, e.detail.highlight);
}.bind(this));
}.bind(this));
// Disable mozilla table controls.
if (Y.UA.gecko) {
document.execCommand("enableInlineTableEditing", false, false);
@@ -303,6 +312,30 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
},
/**
* Sets the appropriate ARIA attributes for the table button when it switches roles between a button and a menu button.
*
* @param {String} buttonName The button name.
* @param {Boolean} highlight True when the button was highlighted. False, otherwise.
* @private
*/
_setAriaAttributes: function(buttonName, highlight) {
var menuButton = this.buttons[buttonName];
if (menuButton) {
if (highlight) {
// This button becomes a menu button. Add appropriate ARIA attributes.
var id = menuButton.getAttribute('id');
menuButton.setAttribute('aria-haspopup', true);
menuButton.setAttribute('aria-controls', id + '_menu');
menuButton.setAttribute('aria-expanded', true);
} else {
menuButton.removeAttribute('aria-haspopup');
menuButton.removeAttribute('aria-controls');
menuButton.removeAttribute('aria-expanded');
}
}
},
/**
* Display the table tool.
*
@@ -341,10 +374,19 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
*/
_displayTableEditor: function(e) {
var cell = this._getSuitableTableCell();
var menuButton = e.currentTarget.ancestor('button', true);
if (cell) {
var id = menuButton.getAttribute('id');
// Indicate that the menu is expanded.
menuButton.setAttribute('aria-expanded', true);
// Add the cell to the EventFacade to save duplication in when showing the menu.
e.tableCell = cell;
return this._showTableMenu(e);
return this._showTableMenu(e, id);
} else {
// Dialog mode. Remove aria-expanded attribute.
menuButton.removeAttribute('aria-expanded');
}
return this._displayDialogue(e);
},
@@ -813,9 +855,10 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
*
* @method _showTableMenu
* @param {EventFacade} e
* @param {String} buttonId The ID of the menu button associated with this menu.
* @private
*/
_showTableMenu: function(e) {
_showTableMenu: function(e, buttonId) {
e.preventDefault();
var boundingBox;
@@ -871,7 +914,8 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
];
this._contextMenu = new Y.M.editor_atto.Menu({
items: this._menuOptions
items: this._menuOptions,
buttonId: buttonId
});
// Add event handlers for table control menus.