mirror of
https://github.com/moodle/moodle.git
synced 2025-03-15 05:00:06 +01:00
MDL-44760 editor_atto: Address issues with focus when closing menus
Safari fires it's events in a slightly different order for the focusoutside event which causes the focusAfterHide to be called *after* we change focus. As a result, we must keep track of the menus which are currently open and remove their focusAfterHide.
This commit is contained in:
parent
28c247a735
commit
c63f90539a
lib/editor/atto
plugins/table/yui
build/moodle-atto_table-button
src/button/js
yui
build
moodle-editor_atto-editor
moodle-editor_atto-plugin
src/editor/js
14
lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-debug.js
vendored
14
lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-debug.js
vendored
@ -626,15 +626,27 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
|||||||
|
|
||||||
this._hideInvalidEntries(boundingBox);
|
this._hideInvalidEntries(boundingBox);
|
||||||
|
|
||||||
|
// Clear the focusAfterHide for any other menus which may be open.
|
||||||
|
Y.Array.each(this.get('host').openMenus, function(menu) {
|
||||||
|
menu.set('focusAfterHide', null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure that we focus on the button in the toolbar when we tab back to the menu.
|
||||||
|
var creatorButton = this.buttons[this.name];
|
||||||
|
this.get('host')._setTabFocus(creatorButton);
|
||||||
|
|
||||||
// Show the context menu, and align to the current position.
|
// Show the context menu, and align to the current position.
|
||||||
this._contextMenu.show();
|
this._contextMenu.show();
|
||||||
this._contextMenu.align(this.buttons.table, [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
this._contextMenu.align(this.buttons.table, [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
||||||
this._contextMenu.set('focusAfterHide', this.buttons[this.name]);
|
this._contextMenu.set('focusAfterHide', creatorButton);
|
||||||
|
|
||||||
// If there are any anchors in the bounding box, focus on the first.
|
// If there are any anchors in the bounding box, focus on the first.
|
||||||
if (boundingBox.one('a')) {
|
if (boundingBox.one('a')) {
|
||||||
boundingBox.one('a').focus();
|
boundingBox.one('a').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this menu to the list of open menus.
|
||||||
|
this.get('host').openMenus = [this._contextMenu];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
4
lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-min.js
vendored
4
lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-min.js
vendored
File diff suppressed because one or more lines are too long
14
lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button.js
vendored
14
lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button.js
vendored
@ -626,15 +626,27 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
|||||||
|
|
||||||
this._hideInvalidEntries(boundingBox);
|
this._hideInvalidEntries(boundingBox);
|
||||||
|
|
||||||
|
// Clear the focusAfterHide for any other menus which may be open.
|
||||||
|
Y.Array.each(this.get('host').openMenus, function(menu) {
|
||||||
|
menu.set('focusAfterHide', null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure that we focus on the button in the toolbar when we tab back to the menu.
|
||||||
|
var creatorButton = this.buttons[this.name];
|
||||||
|
this.get('host')._setTabFocus(creatorButton);
|
||||||
|
|
||||||
// Show the context menu, and align to the current position.
|
// Show the context menu, and align to the current position.
|
||||||
this._contextMenu.show();
|
this._contextMenu.show();
|
||||||
this._contextMenu.align(this.buttons.table, [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
this._contextMenu.align(this.buttons.table, [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
||||||
this._contextMenu.set('focusAfterHide', this.buttons[this.name]);
|
this._contextMenu.set('focusAfterHide', creatorButton);
|
||||||
|
|
||||||
// If there are any anchors in the bounding box, focus on the first.
|
// If there are any anchors in the bounding box, focus on the first.
|
||||||
if (boundingBox.one('a')) {
|
if (boundingBox.one('a')) {
|
||||||
boundingBox.one('a').focus();
|
boundingBox.one('a').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this menu to the list of open menus.
|
||||||
|
this.get('host').openMenus = [this._contextMenu];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -624,15 +624,27 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
|||||||
|
|
||||||
this._hideInvalidEntries(boundingBox);
|
this._hideInvalidEntries(boundingBox);
|
||||||
|
|
||||||
|
// Clear the focusAfterHide for any other menus which may be open.
|
||||||
|
Y.Array.each(this.get('host').openMenus, function(menu) {
|
||||||
|
menu.set('focusAfterHide', null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure that we focus on the button in the toolbar when we tab back to the menu.
|
||||||
|
var creatorButton = this.buttons[this.name];
|
||||||
|
this.get('host')._setTabFocus(creatorButton);
|
||||||
|
|
||||||
// Show the context menu, and align to the current position.
|
// Show the context menu, and align to the current position.
|
||||||
this._contextMenu.show();
|
this._contextMenu.show();
|
||||||
this._contextMenu.align(this.buttons.table, [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
this._contextMenu.align(this.buttons.table, [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
||||||
this._contextMenu.set('focusAfterHide', this.buttons[this.name]);
|
this._contextMenu.set('focusAfterHide', creatorButton);
|
||||||
|
|
||||||
// If there are any anchors in the bounding box, focus on the first.
|
// If there are any anchors in the bounding box, focus on the first.
|
||||||
if (boundingBox.one('a')) {
|
if (boundingBox.one('a')) {
|
||||||
boundingBox.one('a').focus();
|
boundingBox.one('a').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this menu to the list of open menus.
|
||||||
|
this.get('host').openMenus = [this._contextMenu];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -652,6 +652,14 @@ EditorToolbar.prototype = {
|
|||||||
*/
|
*/
|
||||||
toolbar: null,
|
toolbar: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to any currently open menus in the toolbar.
|
||||||
|
*
|
||||||
|
* @property openMenus
|
||||||
|
* @type Array
|
||||||
|
*/
|
||||||
|
openMenus: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the toolbar on the editor.
|
* Setup the toolbar on the editor.
|
||||||
*
|
*
|
||||||
@ -660,6 +668,7 @@ EditorToolbar.prototype = {
|
|||||||
*/
|
*/
|
||||||
setupToolbar: function() {
|
setupToolbar: function() {
|
||||||
this.toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" role="toolbar" aria-live="off"/>');
|
this.toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" role="toolbar" aria-live="off"/>');
|
||||||
|
this.openMenus = [];
|
||||||
this._wrapper.appendChild(this.toolbar);
|
this._wrapper.appendChild(this.toolbar);
|
||||||
|
|
||||||
if (this.textareaLabel) {
|
if (this.textareaLabel) {
|
||||||
@ -732,6 +741,10 @@ EditorToolbarNav.prototype = {
|
|||||||
'down:37,39',
|
'down:37,39',
|
||||||
'.' + CSS.TOOLBAR,
|
'.' + CSS.TOOLBAR,
|
||||||
this);
|
this);
|
||||||
|
this._wrapper.delegate('focus',
|
||||||
|
function(e) {
|
||||||
|
this._setTabFocus(e.currentTarget);
|
||||||
|
}, '.' + CSS.TOOLBAR + ' button', this);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
File diff suppressed because one or more lines are too long
@ -649,6 +649,14 @@ EditorToolbar.prototype = {
|
|||||||
*/
|
*/
|
||||||
toolbar: null,
|
toolbar: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to any currently open menus in the toolbar.
|
||||||
|
*
|
||||||
|
* @property openMenus
|
||||||
|
* @type Array
|
||||||
|
*/
|
||||||
|
openMenus: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the toolbar on the editor.
|
* Setup the toolbar on the editor.
|
||||||
*
|
*
|
||||||
@ -657,6 +665,7 @@ EditorToolbar.prototype = {
|
|||||||
*/
|
*/
|
||||||
setupToolbar: function() {
|
setupToolbar: function() {
|
||||||
this.toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" role="toolbar" aria-live="off"/>');
|
this.toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" role="toolbar" aria-live="off"/>');
|
||||||
|
this.openMenus = [];
|
||||||
this._wrapper.appendChild(this.toolbar);
|
this._wrapper.appendChild(this.toolbar);
|
||||||
|
|
||||||
if (this.textareaLabel) {
|
if (this.textareaLabel) {
|
||||||
@ -729,6 +738,10 @@ EditorToolbarNav.prototype = {
|
|||||||
'down:37,39',
|
'down:37,39',
|
||||||
'.' + CSS.TOOLBAR,
|
'.' + CSS.TOOLBAR,
|
||||||
this);
|
this);
|
||||||
|
this._wrapper.delegate('focus',
|
||||||
|
function(e) {
|
||||||
|
this._setTabFocus(e.currentTarget);
|
||||||
|
}, '.' + CSS.TOOLBAR + ' button', this);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
@ -575,6 +575,11 @@ EditorPluginButtons.prototype = {
|
|||||||
this._chooseMenuItem, '.atto_menuentry a', this, config);
|
this._chooseMenuItem, '.atto_menuentry a', this, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the focusAfterHide for any other menus which may be open.
|
||||||
|
Y.Array.each(this.get('host').openMenus, function(menu) {
|
||||||
|
menu.set('focusAfterHide', null);
|
||||||
|
});
|
||||||
|
|
||||||
// Ensure that we focus on this button next time.
|
// Ensure that we focus on this button next time.
|
||||||
var creatorButton = this.buttons[config.buttonName];
|
var creatorButton = this.buttons[config.buttonName];
|
||||||
creatorButton.focus();
|
creatorButton.focus();
|
||||||
@ -585,15 +590,14 @@ EditorPluginButtons.prototype = {
|
|||||||
|
|
||||||
// Focus on the button by default after hiding this menu.
|
// Focus on the button by default after hiding this menu.
|
||||||
menuDialogue.set('focusAfterHide', creatorButton);
|
menuDialogue.set('focusAfterHide', creatorButton);
|
||||||
menuDialogue.on('focusAfterHide', function(e) {
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display the menu.
|
// Display the menu.
|
||||||
menuDialogue.show();
|
menuDialogue.show();
|
||||||
|
|
||||||
// Position it next to the button which opened it.
|
// Position it next to the button which opened it.
|
||||||
menuDialogue.align(this.buttons[config.buttonName], [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
menuDialogue.align(this.buttons[config.buttonName], [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
||||||
|
|
||||||
|
this.get('host').openMenus = [menuDialogue];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
File diff suppressed because one or more lines are too long
@ -573,6 +573,11 @@ EditorPluginButtons.prototype = {
|
|||||||
this._chooseMenuItem, '.atto_menuentry a', this, config);
|
this._chooseMenuItem, '.atto_menuentry a', this, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the focusAfterHide for any other menus which may be open.
|
||||||
|
Y.Array.each(this.get('host').openMenus, function(menu) {
|
||||||
|
menu.set('focusAfterHide', null);
|
||||||
|
});
|
||||||
|
|
||||||
// Ensure that we focus on this button next time.
|
// Ensure that we focus on this button next time.
|
||||||
var creatorButton = this.buttons[config.buttonName];
|
var creatorButton = this.buttons[config.buttonName];
|
||||||
creatorButton.focus();
|
creatorButton.focus();
|
||||||
@ -583,15 +588,14 @@ EditorPluginButtons.prototype = {
|
|||||||
|
|
||||||
// Focus on the button by default after hiding this menu.
|
// Focus on the button by default after hiding this menu.
|
||||||
menuDialogue.set('focusAfterHide', creatorButton);
|
menuDialogue.set('focusAfterHide', creatorButton);
|
||||||
menuDialogue.on('focusAfterHide', function(e) {
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display the menu.
|
// Display the menu.
|
||||||
menuDialogue.show();
|
menuDialogue.show();
|
||||||
|
|
||||||
// Position it next to the button which opened it.
|
// Position it next to the button which opened it.
|
||||||
menuDialogue.align(this.buttons[config.buttonName], [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
menuDialogue.align(this.buttons[config.buttonName], [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
||||||
|
|
||||||
|
this.get('host').openMenus = [menuDialogue];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -427,6 +427,11 @@ EditorPluginButtons.prototype = {
|
|||||||
this._chooseMenuItem, '.atto_menuentry a', this, config);
|
this._chooseMenuItem, '.atto_menuentry a', this, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the focusAfterHide for any other menus which may be open.
|
||||||
|
Y.Array.each(this.get('host').openMenus, function(menu) {
|
||||||
|
menu.set('focusAfterHide', null);
|
||||||
|
});
|
||||||
|
|
||||||
// Ensure that we focus on this button next time.
|
// Ensure that we focus on this button next time.
|
||||||
var creatorButton = this.buttons[config.buttonName];
|
var creatorButton = this.buttons[config.buttonName];
|
||||||
creatorButton.focus();
|
creatorButton.focus();
|
||||||
@ -437,15 +442,14 @@ EditorPluginButtons.prototype = {
|
|||||||
|
|
||||||
// Focus on the button by default after hiding this menu.
|
// Focus on the button by default after hiding this menu.
|
||||||
menuDialogue.set('focusAfterHide', creatorButton);
|
menuDialogue.set('focusAfterHide', creatorButton);
|
||||||
menuDialogue.on('focusAfterHide', function(e) {
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display the menu.
|
// Display the menu.
|
||||||
menuDialogue.show();
|
menuDialogue.show();
|
||||||
|
|
||||||
// Position it next to the button which opened it.
|
// Position it next to the button which opened it.
|
||||||
menuDialogue.align(this.buttons[config.buttonName], [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
menuDialogue.align(this.buttons[config.buttonName], [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.BL]);
|
||||||
|
|
||||||
|
this.get('host').openMenus = [menuDialogue];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,6 +56,10 @@ EditorToolbarNav.prototype = {
|
|||||||
'down:37,39',
|
'down:37,39',
|
||||||
'.' + CSS.TOOLBAR,
|
'.' + CSS.TOOLBAR,
|
||||||
this);
|
this);
|
||||||
|
this._wrapper.delegate('focus',
|
||||||
|
function(e) {
|
||||||
|
this._setTabFocus(e.currentTarget);
|
||||||
|
}, '.' + CSS.TOOLBAR + ' button', this);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
9
lib/editor/atto/yui/src/editor/js/toolbar.js
vendored
9
lib/editor/atto/yui/src/editor/js/toolbar.js
vendored
@ -41,6 +41,14 @@ EditorToolbar.prototype = {
|
|||||||
*/
|
*/
|
||||||
toolbar: null,
|
toolbar: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to any currently open menus in the toolbar.
|
||||||
|
*
|
||||||
|
* @property openMenus
|
||||||
|
* @type Array
|
||||||
|
*/
|
||||||
|
openMenus: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the toolbar on the editor.
|
* Setup the toolbar on the editor.
|
||||||
*
|
*
|
||||||
@ -49,6 +57,7 @@ EditorToolbar.prototype = {
|
|||||||
*/
|
*/
|
||||||
setupToolbar: function() {
|
setupToolbar: function() {
|
||||||
this.toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" role="toolbar" aria-live="off"/>');
|
this.toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" role="toolbar" aria-live="off"/>');
|
||||||
|
this.openMenus = [];
|
||||||
this._wrapper.appendChild(this.toolbar);
|
this._wrapper.appendChild(this.toolbar);
|
||||||
|
|
||||||
if (this.textareaLabel) {
|
if (this.textareaLabel) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user