mirror of
https://github.com/moodle/moodle.git
synced 2025-02-20 08:05:49 +01:00
MDL-41870 atto: keyboard navigation for toolbar (arrows)
This commit is contained in:
parent
36973d707e
commit
6f9cf841c9
@ -159,19 +159,29 @@ M.editor_atto = M.editor_atto || {
|
||||
*/
|
||||
add_toolbar_menu : function(elementid, plugin, icon, groupname, entries) {
|
||||
var toolbar = Y.one('#' + elementid + '_toolbar'),
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group');
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group'),
|
||||
currentfocus,
|
||||
button;
|
||||
|
||||
if (!group) {
|
||||
group = Y.Node.create('<div class="atto_group ' + groupname + '_group"></div>');
|
||||
toolbar.append(group);
|
||||
}
|
||||
var button = Y.Node.create('<button class="atto_' + plugin + '_button atto_hasmenu" ' +
|
||||
button = Y.Node.create('<button class="atto_' + plugin + '_button atto_hasmenu" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'tabindex="-1" ' +
|
||||
'data-menu="' + plugin + '_' + elementid + '" >' +
|
||||
icon +
|
||||
'</button>');
|
||||
|
||||
group.append(button);
|
||||
|
||||
currentfocus = toolbar.getAttribute('aria-activedescendant');
|
||||
if (!currentfocus) {
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.setAttribute('aria-activedescendant', button.generateID());
|
||||
}
|
||||
|
||||
// Save the name of the plugin.
|
||||
M.editor_atto.widgets[plugin] = plugin;
|
||||
|
||||
@ -228,20 +238,30 @@ M.editor_atto = M.editor_atto || {
|
||||
*/
|
||||
add_toolbar_button : function(elementid, plugin, icon, groupname, handler) {
|
||||
var toolbar = Y.one('#' + elementid + '_toolbar'),
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group');
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group'),
|
||||
button,
|
||||
currentfocus;
|
||||
|
||||
if (!group) {
|
||||
group = Y.Node.create('<div class="atto_group ' + groupname +'_group"></div>');
|
||||
toolbar.append(group);
|
||||
}
|
||||
var button = Y.Node.create('<button class="atto_' + plugin + '_button" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'data-plugin="' + Y.Escape.html(plugin) + '" ' +
|
||||
'data-handler="' + Y.Escape.html(plugin) + '">' +
|
||||
icon +
|
||||
'</button>');
|
||||
button = Y.Node.create('<button class="atto_' + plugin + '_button" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'data-plugin="' + Y.Escape.html(plugin) + '" ' +
|
||||
'tabindex="-1" ' +
|
||||
'data-handler="' + Y.Escape.html(plugin) + '">' +
|
||||
icon +
|
||||
'</button>');
|
||||
|
||||
group.append(button);
|
||||
|
||||
currentfocus = toolbar.getAttribute('aria-activedescendant');
|
||||
if (!currentfocus) {
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.setAttribute('aria-activedescendant', button.generateID());
|
||||
}
|
||||
|
||||
// We only need to attach this once.
|
||||
if (!M.editor_atto.buttonhandlers[plugin]) {
|
||||
Y.one('body').delegate('click', M.editor_atto.buttonclicked_handler, '.atto_' + plugin + '_button');
|
||||
@ -294,7 +314,7 @@ M.editor_atto = M.editor_atto || {
|
||||
'spellcheck="true" ' +
|
||||
'class="editor_atto"/>');
|
||||
var cssfont = '';
|
||||
var toolbar = Y.Node.create('<div class="editor_atto_toolbar" id="' + params.elementid + '_toolbar"/>');
|
||||
var toolbar = Y.Node.create('<div class="editor_atto_toolbar" id="' + params.elementid + '_toolbar" role="toolbar"/>');
|
||||
|
||||
// Bleh - why are we sent a url and not the css to apply directly?
|
||||
var css = Y.io(params.content_css, { sync: true });
|
||||
@ -323,10 +343,61 @@ M.editor_atto = M.editor_atto || {
|
||||
textarea.set('value', atto.getHTML());
|
||||
});
|
||||
|
||||
// Listen for Arrow left and Arrow right keys.
|
||||
Y.one(Y.config.doc.body).delegate('key',
|
||||
this.keyboard_navigation,
|
||||
'down:37,39',
|
||||
'#' + params.elementid + '_toolbar',
|
||||
this,
|
||||
params.elementid);
|
||||
|
||||
// Save the file picker options for later.
|
||||
M.editor_atto.filepickeroptions[params.elementid] = params.filepickeroptions;
|
||||
},
|
||||
|
||||
/**
|
||||
* Implement arrow key navigation for the buttons in the toolbar.
|
||||
* @param Event e - the keyboard event.
|
||||
* @param string elementid - the id of the textarea we created this editor from.
|
||||
*/
|
||||
keyboard_navigation : function(e, elementid) {
|
||||
var buttons,
|
||||
current,
|
||||
currentid,
|
||||
currentindex;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
buttons = Y.all('#' + elementid + '_toolbar button');
|
||||
currentid = Y.one('#' + elementid + '_toolbar').getAttribute('aria-activedescendant');
|
||||
if (!currentid) {
|
||||
return;
|
||||
}
|
||||
current = Y.one('#' + currentid);
|
||||
current.setAttribute('tabindex', '-1');
|
||||
|
||||
currentindex = buttons.indexOf(current);
|
||||
|
||||
if (e.keyCode === 37) {
|
||||
// Left
|
||||
currentindex--;
|
||||
if (currentindex < 0) {
|
||||
currentindex = buttons.size()-1;
|
||||
}
|
||||
} else {
|
||||
// Right
|
||||
currentindex++;
|
||||
if (currentindex >= buttons.size()) {
|
||||
currentindex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
current = buttons.item(currentindex);
|
||||
current.setAttribute('tabindex', '0');
|
||||
current.focus();
|
||||
Y.one('#' + elementid + '_toolbar').setAttribute('aria-activedescendant', current.generateID());
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the filepicker.
|
||||
* @param string elementid for this editor instance.
|
||||
@ -432,4 +503,4 @@ M.editor_atto = M.editor_atto || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node", "io", "overlay", "escape", "moodle-core-notification"]});
|
||||
}, '@VERSION@', {"requires": ["node", "io", "overlay", "escape", "event-key", "moodle-core-notification"]});
|
||||
|
File diff suppressed because one or more lines are too long
@ -159,19 +159,29 @@ M.editor_atto = M.editor_atto || {
|
||||
*/
|
||||
add_toolbar_menu : function(elementid, plugin, icon, groupname, entries) {
|
||||
var toolbar = Y.one('#' + elementid + '_toolbar'),
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group');
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group'),
|
||||
currentfocus,
|
||||
button;
|
||||
|
||||
if (!group) {
|
||||
group = Y.Node.create('<div class="atto_group ' + groupname + '_group"></div>');
|
||||
toolbar.append(group);
|
||||
}
|
||||
var button = Y.Node.create('<button class="atto_' + plugin + '_button atto_hasmenu" ' +
|
||||
button = Y.Node.create('<button class="atto_' + plugin + '_button atto_hasmenu" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'tabindex="-1" ' +
|
||||
'data-menu="' + plugin + '_' + elementid + '" >' +
|
||||
icon +
|
||||
'</button>');
|
||||
|
||||
group.append(button);
|
||||
|
||||
currentfocus = toolbar.getAttribute('aria-activedescendant');
|
||||
if (!currentfocus) {
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.setAttribute('aria-activedescendant', button.generateID());
|
||||
}
|
||||
|
||||
// Save the name of the plugin.
|
||||
M.editor_atto.widgets[plugin] = plugin;
|
||||
|
||||
@ -228,20 +238,30 @@ M.editor_atto = M.editor_atto || {
|
||||
*/
|
||||
add_toolbar_button : function(elementid, plugin, icon, groupname, handler) {
|
||||
var toolbar = Y.one('#' + elementid + '_toolbar'),
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group');
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group'),
|
||||
button,
|
||||
currentfocus;
|
||||
|
||||
if (!group) {
|
||||
group = Y.Node.create('<div class="atto_group ' + groupname +'_group"></div>');
|
||||
toolbar.append(group);
|
||||
}
|
||||
var button = Y.Node.create('<button class="atto_' + plugin + '_button" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'data-plugin="' + Y.Escape.html(plugin) + '" ' +
|
||||
'data-handler="' + Y.Escape.html(plugin) + '">' +
|
||||
icon +
|
||||
'</button>');
|
||||
button = Y.Node.create('<button class="atto_' + plugin + '_button" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'data-plugin="' + Y.Escape.html(plugin) + '" ' +
|
||||
'tabindex="-1" ' +
|
||||
'data-handler="' + Y.Escape.html(plugin) + '">' +
|
||||
icon +
|
||||
'</button>');
|
||||
|
||||
group.append(button);
|
||||
|
||||
currentfocus = toolbar.getAttribute('aria-activedescendant');
|
||||
if (!currentfocus) {
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.setAttribute('aria-activedescendant', button.generateID());
|
||||
}
|
||||
|
||||
// We only need to attach this once.
|
||||
if (!M.editor_atto.buttonhandlers[plugin]) {
|
||||
Y.one('body').delegate('click', M.editor_atto.buttonclicked_handler, '.atto_' + plugin + '_button');
|
||||
@ -294,7 +314,7 @@ M.editor_atto = M.editor_atto || {
|
||||
'spellcheck="true" ' +
|
||||
'class="editor_atto"/>');
|
||||
var cssfont = '';
|
||||
var toolbar = Y.Node.create('<div class="editor_atto_toolbar" id="' + params.elementid + '_toolbar"/>');
|
||||
var toolbar = Y.Node.create('<div class="editor_atto_toolbar" id="' + params.elementid + '_toolbar" role="toolbar"/>');
|
||||
|
||||
// Bleh - why are we sent a url and not the css to apply directly?
|
||||
var css = Y.io(params.content_css, { sync: true });
|
||||
@ -323,10 +343,61 @@ M.editor_atto = M.editor_atto || {
|
||||
textarea.set('value', atto.getHTML());
|
||||
});
|
||||
|
||||
// Listen for Arrow left and Arrow right keys.
|
||||
Y.one(Y.config.doc.body).delegate('key',
|
||||
this.keyboard_navigation,
|
||||
'down:37,39',
|
||||
'#' + params.elementid + '_toolbar',
|
||||
this,
|
||||
params.elementid);
|
||||
|
||||
// Save the file picker options for later.
|
||||
M.editor_atto.filepickeroptions[params.elementid] = params.filepickeroptions;
|
||||
},
|
||||
|
||||
/**
|
||||
* Implement arrow key navigation for the buttons in the toolbar.
|
||||
* @param Event e - the keyboard event.
|
||||
* @param string elementid - the id of the textarea we created this editor from.
|
||||
*/
|
||||
keyboard_navigation : function(e, elementid) {
|
||||
var buttons,
|
||||
current,
|
||||
currentid,
|
||||
currentindex;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
buttons = Y.all('#' + elementid + '_toolbar button');
|
||||
currentid = Y.one('#' + elementid + '_toolbar').getAttribute('aria-activedescendant');
|
||||
if (!currentid) {
|
||||
return;
|
||||
}
|
||||
current = Y.one('#' + currentid);
|
||||
current.setAttribute('tabindex', '-1');
|
||||
|
||||
currentindex = buttons.indexOf(current);
|
||||
|
||||
if (e.keyCode === 37) {
|
||||
// Left
|
||||
currentindex--;
|
||||
if (currentindex < 0) {
|
||||
currentindex = buttons.size()-1;
|
||||
}
|
||||
} else {
|
||||
// Right
|
||||
currentindex++;
|
||||
if (currentindex >= buttons.size()) {
|
||||
currentindex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
current = buttons.item(currentindex);
|
||||
current.setAttribute('tabindex', '0');
|
||||
current.focus();
|
||||
Y.one('#' + elementid + '_toolbar').setAttribute('aria-activedescendant', current.generateID());
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the filepicker.
|
||||
* @param string elementid for this editor instance.
|
||||
@ -432,4 +503,4 @@ M.editor_atto = M.editor_atto || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node", "io", "overlay", "escape", "moodle-core-notification"]});
|
||||
}, '@VERSION@', {"requires": ["node", "io", "overlay", "escape", "event-key", "moodle-core-notification"]});
|
||||
|
91
lib/editor/atto/yui/src/editor/js/editor.js
vendored
91
lib/editor/atto/yui/src/editor/js/editor.js
vendored
@ -157,19 +157,29 @@ M.editor_atto = M.editor_atto || {
|
||||
*/
|
||||
add_toolbar_menu : function(elementid, plugin, icon, groupname, entries) {
|
||||
var toolbar = Y.one('#' + elementid + '_toolbar'),
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group');
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group'),
|
||||
currentfocus,
|
||||
button;
|
||||
|
||||
if (!group) {
|
||||
group = Y.Node.create('<div class="atto_group ' + groupname + '_group"></div>');
|
||||
toolbar.append(group);
|
||||
}
|
||||
var button = Y.Node.create('<button class="atto_' + plugin + '_button atto_hasmenu" ' +
|
||||
button = Y.Node.create('<button class="atto_' + plugin + '_button atto_hasmenu" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'tabindex="-1" ' +
|
||||
'data-menu="' + plugin + '_' + elementid + '" >' +
|
||||
icon +
|
||||
'</button>');
|
||||
|
||||
group.append(button);
|
||||
|
||||
currentfocus = toolbar.getAttribute('aria-activedescendant');
|
||||
if (!currentfocus) {
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.setAttribute('aria-activedescendant', button.generateID());
|
||||
}
|
||||
|
||||
// Save the name of the plugin.
|
||||
M.editor_atto.widgets[plugin] = plugin;
|
||||
|
||||
@ -226,20 +236,30 @@ M.editor_atto = M.editor_atto || {
|
||||
*/
|
||||
add_toolbar_button : function(elementid, plugin, icon, groupname, handler) {
|
||||
var toolbar = Y.one('#' + elementid + '_toolbar'),
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group');
|
||||
group = Y.one('#' + elementid + '_toolbar .atto_group.' + groupname + '_group'),
|
||||
button,
|
||||
currentfocus;
|
||||
|
||||
if (!group) {
|
||||
group = Y.Node.create('<div class="atto_group ' + groupname +'_group"></div>');
|
||||
toolbar.append(group);
|
||||
}
|
||||
var button = Y.Node.create('<button class="atto_' + plugin + '_button" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'data-plugin="' + Y.Escape.html(plugin) + '" ' +
|
||||
'data-handler="' + Y.Escape.html(plugin) + '">' +
|
||||
icon +
|
||||
'</button>');
|
||||
button = Y.Node.create('<button class="atto_' + plugin + '_button" ' +
|
||||
'data-editor="' + Y.Escape.html(elementid) + '" ' +
|
||||
'data-plugin="' + Y.Escape.html(plugin) + '" ' +
|
||||
'tabindex="-1" ' +
|
||||
'data-handler="' + Y.Escape.html(plugin) + '">' +
|
||||
icon +
|
||||
'</button>');
|
||||
|
||||
group.append(button);
|
||||
|
||||
currentfocus = toolbar.getAttribute('aria-activedescendant');
|
||||
if (!currentfocus) {
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.setAttribute('aria-activedescendant', button.generateID());
|
||||
}
|
||||
|
||||
// We only need to attach this once.
|
||||
if (!M.editor_atto.buttonhandlers[plugin]) {
|
||||
Y.one('body').delegate('click', M.editor_atto.buttonclicked_handler, '.atto_' + plugin + '_button');
|
||||
@ -292,7 +312,7 @@ M.editor_atto = M.editor_atto || {
|
||||
'spellcheck="true" ' +
|
||||
'class="editor_atto"/>');
|
||||
var cssfont = '';
|
||||
var toolbar = Y.Node.create('<div class="editor_atto_toolbar" id="' + params.elementid + '_toolbar"/>');
|
||||
var toolbar = Y.Node.create('<div class="editor_atto_toolbar" id="' + params.elementid + '_toolbar" role="toolbar"/>');
|
||||
|
||||
// Bleh - why are we sent a url and not the css to apply directly?
|
||||
var css = Y.io(params.content_css, { sync: true });
|
||||
@ -321,10 +341,61 @@ M.editor_atto = M.editor_atto || {
|
||||
textarea.set('value', atto.getHTML());
|
||||
});
|
||||
|
||||
// Listen for Arrow left and Arrow right keys.
|
||||
Y.one(Y.config.doc.body).delegate('key',
|
||||
this.keyboard_navigation,
|
||||
'down:37,39',
|
||||
'#' + params.elementid + '_toolbar',
|
||||
this,
|
||||
params.elementid);
|
||||
|
||||
// Save the file picker options for later.
|
||||
M.editor_atto.filepickeroptions[params.elementid] = params.filepickeroptions;
|
||||
},
|
||||
|
||||
/**
|
||||
* Implement arrow key navigation for the buttons in the toolbar.
|
||||
* @param Event e - the keyboard event.
|
||||
* @param string elementid - the id of the textarea we created this editor from.
|
||||
*/
|
||||
keyboard_navigation : function(e, elementid) {
|
||||
var buttons,
|
||||
current,
|
||||
currentid,
|
||||
currentindex;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
buttons = Y.all('#' + elementid + '_toolbar button');
|
||||
currentid = Y.one('#' + elementid + '_toolbar').getAttribute('aria-activedescendant');
|
||||
if (!currentid) {
|
||||
return;
|
||||
}
|
||||
current = Y.one('#' + currentid);
|
||||
current.setAttribute('tabindex', '-1');
|
||||
|
||||
currentindex = buttons.indexOf(current);
|
||||
|
||||
if (e.keyCode === 37) {
|
||||
// Left
|
||||
currentindex--;
|
||||
if (currentindex < 0) {
|
||||
currentindex = buttons.size()-1;
|
||||
}
|
||||
} else {
|
||||
// Right
|
||||
currentindex++;
|
||||
if (currentindex >= buttons.size()) {
|
||||
currentindex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
current = buttons.item(currentindex);
|
||||
current.setAttribute('tabindex', '0');
|
||||
current.focus();
|
||||
Y.one('#' + elementid + '_toolbar').setAttribute('aria-activedescendant', current.generateID());
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the filepicker.
|
||||
* @param string elementid for this editor instance.
|
||||
|
@ -5,6 +5,7 @@
|
||||
"io",
|
||||
"overlay",
|
||||
"escape",
|
||||
"event-key",
|
||||
"moodle-core-notification"
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user