' +
@@ -111,7 +118,19 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
*/
_content: null,
+ /**
+ * A reference to the tab focus set on each group.
+ *
+ * The keys are the IDs of the group, the value is the Node on which the focus is set.
+ *
+ * @property _groupFocus
+ * @type Object
+ * @private
+ */
+ _groupFocus: null,
+
initializer: function() {
+ this._groupFocus = {};
if (this.get('texfilteractive')) {
// Add the button to the toolbar.
this.addButton({
@@ -152,7 +171,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
var content = this._getDialogueContent();
dialogue.set('bodyContent', content);
- var library = content.one(SELECTORS.LIBRARY_GROUP_PREFIX);
+ var library = content.one(SELECTORS.LIBRARY);
var tabview = new Y.TabView({
srcNode: library
@@ -321,6 +340,17 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
CSS: CSS
}));
+ // Sets the default focus.
+ this._content.all(SELECTORS.LIBRARY_GROUP).each(function(group) {
+ // The first button gets the focus.
+ this._setGroupTabFocus(group, group.one('button'));
+ // Sometimes the filter adds an anchor in the button, no tabindex on that.
+ group.all('button a').setAttribute('tabindex', '-1');
+ }, this);
+
+ // Keyboard navigation in groups.
+ this._content.delegate('key', this._groupNavigation, 'down:37,39', SELECTORS.LIBRARY_BUTTON, this);
+
this._content.one(SELECTORS.SUBMIT).on('click', this._setEquation, this);
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._updatePreview, this);
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._updatePreview, this);
@@ -330,6 +360,61 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
return this._content;
},
+ /**
+ * Callback handling the keyboard navigation in the groups of the library.
+ *
+ * @param {EventFacade} e The event.
+ * @method _groupNavigation
+ * @private
+ */
+ _groupNavigation: function(e) {
+ e.preventDefault();
+
+ var current = e.currentTarget,
+ parent = current.get('parentNode'), // This must be the
containing all the buttons of the group.
+ buttons = parent.all('button'),
+ direction = e.keyCode !== 37 ? 1 : -1,
+ index = buttons.indexOf(current),
+ nextButton;
+
+ if (index < 0) {
+ Y.log('Unable to find the current button in the list of buttons', 'debug', LOGNAME);
+ index = 0;
+ }
+
+ index += direction;
+ if (index < 0) {
+ index = buttons.size() - 1;
+ } else if (index >= buttons.size()) {
+ index = 0;
+ }
+ nextButton = buttons.item(index);
+
+ this._setGroupTabFocus(parent, nextButton);
+ nextButton.focus();
+ },
+
+ /**
+ * Sets tab focus for the group.
+ *
+ * @method _setGroupTabFocus
+ * @param {Node} button The node that focus should now be set to.
+ * @private
+ */
+ _setGroupTabFocus: function(parent, button) {
+ var parentId = parent.generateID();
+
+ // Unset the previous entry.
+ if (typeof this._groupFocus[parentId] !== 'undefined') {
+ this._groupFocus[parentId].setAttribute('tabindex', '-1');
+ }
+
+ // Set on the new entry.
+ this._groupFocus[parentId] = button;
+ button.setAttribute('tabindex', 0);
+ parent.setAttribute('aria-activedescendant', button.generateID());
+ },
+
/**
* Reponse to button presses in the TeX library panels.
*
@@ -343,6 +428,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
e.preventDefault();
+ // Set the group focus on the button.
+ this._setGroupTabFocus(e.currentTarget.get('parentNode'), e.currentTarget);
+
input = e.currentTarget.ancestor('.atto_form').one('textarea');
value = input.get('value');
diff --git a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js
index c043250ead3..a15a84eb374 100644
--- a/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js
+++ b/lib/editor/atto/plugins/equation/yui/build/moodle-atto_equation-button/moodle-atto_equation-button-min.js
@@ -1 +1,2 @@
-YUI.add("moodle-atto_equation-button",function(e,t){var n="atto_equation",r={EQUATION_TEXT:"atto_equation_equation",EQUATION_PREVIEW:"atto_equation_preview",SUBMIT:"atto_equation_submit",LIBRARY:"atto_equation_library",LIBRARY_GROUP_PREFIX:"atto_equation_library"},i={LIBRARY_GROUP_PREFIX:"."+r.LIBRARY_GROUP_PREFIX,EQUATION_TEXT:"."+r.EQUATION_TEXT,EQUATION_PREVIEW:"."+r.EQUATION_PREVIEW,SUBMIT:"."+r.SUBMIT,LIBRARY_BUTTON:"."+r.LIBRARY+" button"},s={FORM:'',LIBRARY:'
' +
@@ -111,7 +118,19 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
*/
_content: null,
+ /**
+ * A reference to the tab focus set on each group.
+ *
+ * The keys are the IDs of the group, the value is the Node on which the focus is set.
+ *
+ * @property _groupFocus
+ * @type Object
+ * @private
+ */
+ _groupFocus: null,
+
initializer: function() {
+ this._groupFocus = {};
if (this.get('texfilteractive')) {
// Add the button to the toolbar.
this.addButton({
@@ -152,7 +171,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
var content = this._getDialogueContent();
dialogue.set('bodyContent', content);
- var library = content.one(SELECTORS.LIBRARY_GROUP_PREFIX);
+ var library = content.one(SELECTORS.LIBRARY);
var tabview = new Y.TabView({
srcNode: library
@@ -321,6 +340,17 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
CSS: CSS
}));
+ // Sets the default focus.
+ this._content.all(SELECTORS.LIBRARY_GROUP).each(function(group) {
+ // The first button gets the focus.
+ this._setGroupTabFocus(group, group.one('button'));
+ // Sometimes the filter adds an anchor in the button, no tabindex on that.
+ group.all('button a').setAttribute('tabindex', '-1');
+ }, this);
+
+ // Keyboard navigation in groups.
+ this._content.delegate('key', this._groupNavigation, 'down:37,39', SELECTORS.LIBRARY_BUTTON, this);
+
this._content.one(SELECTORS.SUBMIT).on('click', this._setEquation, this);
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._updatePreview, this);
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._updatePreview, this);
@@ -330,6 +360,60 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
return this._content;
},
+ /**
+ * Callback handling the keyboard navigation in the groups of the library.
+ *
+ * @param {EventFacade} e The event.
+ * @method _groupNavigation
+ * @private
+ */
+ _groupNavigation: function(e) {
+ e.preventDefault();
+
+ var current = e.currentTarget,
+ parent = current.get('parentNode'), // This must be the
containing all the buttons of the group.
+ buttons = parent.all('button'),
+ direction = e.keyCode !== 37 ? 1 : -1,
+ index = buttons.indexOf(current),
+ nextButton;
+
+ if (index < 0) {
+ index = 0;
+ }
+
+ index += direction;
+ if (index < 0) {
+ index = buttons.size() - 1;
+ } else if (index >= buttons.size()) {
+ index = 0;
+ }
+ nextButton = buttons.item(index);
+
+ this._setGroupTabFocus(parent, nextButton);
+ nextButton.focus();
+ },
+
+ /**
+ * Sets tab focus for the group.
+ *
+ * @method _setGroupTabFocus
+ * @param {Node} button The node that focus should now be set to.
+ * @private
+ */
+ _setGroupTabFocus: function(parent, button) {
+ var parentId = parent.generateID();
+
+ // Unset the previous entry.
+ if (typeof this._groupFocus[parentId] !== 'undefined') {
+ this._groupFocus[parentId].setAttribute('tabindex', '-1');
+ }
+
+ // Set on the new entry.
+ this._groupFocus[parentId] = button;
+ button.setAttribute('tabindex', 0);
+ parent.setAttribute('aria-activedescendant', button.generateID());
+ },
+
/**
* Reponse to button presses in the TeX library panels.
*
@@ -343,6 +427,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
e.preventDefault();
+ // Set the group focus on the button.
+ this._setGroupTabFocus(e.currentTarget.get('parentNode'), e.currentTarget);
+
input = e.currentTarget.ancestor('.atto_form').one('textarea');
value = input.get('value');
diff --git a/lib/editor/atto/plugins/equation/yui/src/button/js/button.js b/lib/editor/atto/plugins/equation/yui/src/button/js/button.js
index a5af93df7ef..e84acfc54ab 100644
--- a/lib/editor/atto/plugins/equation/yui/src/button/js/button.js
+++ b/lib/editor/atto/plugins/equation/yui/src/button/js/button.js
@@ -32,15 +32,18 @@
*/
var COMPONENTNAME = 'atto_equation',
+ LOGNAME = 'atto_equation',
CSS = {
EQUATION_TEXT: 'atto_equation_equation',
EQUATION_PREVIEW: 'atto_equation_preview',
SUBMIT: 'atto_equation_submit',
LIBRARY: 'atto_equation_library',
- LIBRARY_GROUP_PREFIX: 'atto_equation_library'
+ LIBRARY_GROUPS: 'atto_equation_groups',
+ LIBRARY_GROUP_PREFIX: 'atto_equation_group'
},
SELECTORS = {
- LIBRARY_GROUP_PREFIX: '.' + CSS.LIBRARY_GROUP_PREFIX,
+ LIBRARY: '.' + CSS.LIBRARY,
+ LIBRARY_GROUP: '.' + CSS.LIBRARY_GROUPS + ' > div > div',
EQUATION_TEXT: '.' + CSS.EQUATION_TEXT,
EQUATION_PREVIEW: '.' + CSS.EQUATION_PREVIEW,
SUBMIT: '.' + CSS.SUBMIT,
@@ -63,15 +66,19 @@ var COMPONENTNAME = 'atto_equation',
'
' +
@@ -109,7 +116,19 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
*/
_content: null,
+ /**
+ * A reference to the tab focus set on each group.
+ *
+ * The keys are the IDs of the group, the value is the Node on which the focus is set.
+ *
+ * @property _groupFocus
+ * @type Object
+ * @private
+ */
+ _groupFocus: null,
+
initializer: function() {
+ this._groupFocus = {};
if (this.get('texfilteractive')) {
// Add the button to the toolbar.
this.addButton({
@@ -150,7 +169,7 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
var content = this._getDialogueContent();
dialogue.set('bodyContent', content);
- var library = content.one(SELECTORS.LIBRARY_GROUP_PREFIX);
+ var library = content.one(SELECTORS.LIBRARY);
var tabview = new Y.TabView({
srcNode: library
@@ -319,6 +338,17 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
CSS: CSS
}));
+ // Sets the default focus.
+ this._content.all(SELECTORS.LIBRARY_GROUP).each(function(group) {
+ // The first button gets the focus.
+ this._setGroupTabFocus(group, group.one('button'));
+ // Sometimes the filter adds an anchor in the button, no tabindex on that.
+ group.all('button a').setAttribute('tabindex', '-1');
+ }, this);
+
+ // Keyboard navigation in groups.
+ this._content.delegate('key', this._groupNavigation, 'down:37,39', SELECTORS.LIBRARY_BUTTON, this);
+
this._content.one(SELECTORS.SUBMIT).on('click', this._setEquation, this);
this._content.one(SELECTORS.EQUATION_TEXT).on('valuechange', this._updatePreview, this);
this._content.one(SELECTORS.EQUATION_TEXT).on('mouseup', this._updatePreview, this);
@@ -328,6 +358,61 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
return this._content;
},
+ /**
+ * Callback handling the keyboard navigation in the groups of the library.
+ *
+ * @param {EventFacade} e The event.
+ * @method _groupNavigation
+ * @private
+ */
+ _groupNavigation: function(e) {
+ e.preventDefault();
+
+ var current = e.currentTarget,
+ parent = current.get('parentNode'), // This must be the
containing all the buttons of the group.
+ buttons = parent.all('button'),
+ direction = e.keyCode !== 37 ? 1 : -1,
+ index = buttons.indexOf(current),
+ nextButton;
+
+ if (index < 0) {
+ Y.log('Unable to find the current button in the list of buttons', 'debug', LOGNAME);
+ index = 0;
+ }
+
+ index += direction;
+ if (index < 0) {
+ index = buttons.size() - 1;
+ } else if (index >= buttons.size()) {
+ index = 0;
+ }
+ nextButton = buttons.item(index);
+
+ this._setGroupTabFocus(parent, nextButton);
+ nextButton.focus();
+ },
+
+ /**
+ * Sets tab focus for the group.
+ *
+ * @method _setGroupTabFocus
+ * @param {Node} button The node that focus should now be set to.
+ * @private
+ */
+ _setGroupTabFocus: function(parent, button) {
+ var parentId = parent.generateID();
+
+ // Unset the previous entry.
+ if (typeof this._groupFocus[parentId] !== 'undefined') {
+ this._groupFocus[parentId].setAttribute('tabindex', '-1');
+ }
+
+ // Set on the new entry.
+ this._groupFocus[parentId] = button;
+ button.setAttribute('tabindex', 0);
+ parent.setAttribute('aria-activedescendant', button.generateID());
+ },
+
/**
* Reponse to button presses in the TeX library panels.
*
@@ -341,6 +426,9 @@ Y.namespace('M.atto_equation').Button = Y.Base.create('button', Y.M.editor_atto.
e.preventDefault();
+ // Set the group focus on the button.
+ this._setGroupTabFocus(e.currentTarget.get('parentNode'), e.currentTarget);
+
input = e.currentTarget.ancestor('.atto_form').one('textarea');
value = input.get('value');