mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-47133 editor_atto: Use strict validation of keyboard shortcuts
This commit is contained in:
parent
ca0e301c7b
commit
04b12fc1b3
9
lib/editor/atto/upgrade.txt
Normal file
9
lib/editor/atto/upgrade.txt
Normal file
@ -0,0 +1,9 @@
|
||||
This files describes API changes in the editor_atto code.
|
||||
|
||||
=== 2.9 ===
|
||||
|
||||
* When adding a shortcut to the button of a plugin, atto will add a layer of validation
|
||||
to ensure that only the required keys are pressed. However, if you are using a custom
|
||||
keyConfig object you must validate the shortcut yourself. This is particularly important
|
||||
for non-English keyboard users. For more information read the documentation of
|
||||
EditorPluginButtons::_addKeyboardListener() and MDL-47133.
|
@ -783,7 +783,11 @@ EditorPluginButtons.prototype = {
|
||||
* The keyConfig will take either an array of keyConfigurations, in
|
||||
* which case _addKeyboardListener is called multiple times; an object
|
||||
* containing an optional eventtype, optional container, and a set of
|
||||
* keyCodes, or just a string containing the keyCodes.
|
||||
* keyCodes, or just a string containing the keyCodes. When keyConfig is
|
||||
* not an object, it is wrapped around a function that ensures that
|
||||
* only the expected key modifiers were used. For instance, it checks
|
||||
* that space+ctrl is not triggered when the user presses ctrl+shift+space.
|
||||
* When using an object, the developer should check that manually.
|
||||
*
|
||||
* @method _addKeyboardListener
|
||||
* @param {function} callback
|
||||
@ -797,7 +801,9 @@ EditorPluginButtons.prototype = {
|
||||
_addKeyboardListener: function(callback, keyConfig, buttonName) {
|
||||
var eventtype = 'key',
|
||||
container = CSS.EDITORWRAPPER,
|
||||
keys;
|
||||
keys,
|
||||
handler,
|
||||
modifier;
|
||||
|
||||
if (Y.Lang.isArray(keyConfig)) {
|
||||
// If an Array was specified, call the add function for each element.
|
||||
@ -818,19 +824,27 @@ EditorPluginButtons.prototype = {
|
||||
|
||||
// Must be specified.
|
||||
keys = keyConfig.keyCodes;
|
||||
handler = callback;
|
||||
|
||||
} else {
|
||||
keys = this._getKeyEvent() + keyConfig + this._getDefaultMetaKey();
|
||||
modifier = this._getDefaultMetaKey()
|
||||
keys = this._getKeyEvent() + keyConfig + '+' + modifier;
|
||||
if (typeof this._primaryKeyboardShortcut[buttonName] === 'undefined') {
|
||||
this._primaryKeyboardShortcut[buttonName] = this._getDefaultMetaKeyDescription(keyConfig);
|
||||
}
|
||||
|
||||
// Wrap the callback into a handler to check if it uses the specified modifiers, not more.
|
||||
handler = Y.bind(function(modifiers, e) {
|
||||
if (this._eventUsesExactKeyModifiers(modifiers, e)) {
|
||||
callback.apply(this, [e]);
|
||||
}
|
||||
}, this, [modifier]);
|
||||
}
|
||||
|
||||
this._buttonHandlers.push(
|
||||
this.editor.delegate(
|
||||
eventtype,
|
||||
callback,
|
||||
handler,
|
||||
keys,
|
||||
container,
|
||||
this
|
||||
@ -841,6 +855,34 @@ EditorPluginButtons.prototype = {
|
||||
'debug', LOGNAME);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if a key event was strictly defined for the modifiers passed.
|
||||
*
|
||||
* @method _eventUsesExactKeyModifiers
|
||||
* @param {Array} modifiers List of key modifiers to check for (alt, ctrl, meta or shift).
|
||||
* @param {EventFacade} e The event facade.
|
||||
* @return {Boolean} True if the event was stricly using the modifiers specified.
|
||||
*/
|
||||
_eventUsesExactKeyModifiers: function(modifiers, e) {
|
||||
var exactMatch = true,
|
||||
hasKey;
|
||||
|
||||
if (e.type != 'key') {
|
||||
return false;
|
||||
}
|
||||
|
||||
hasKey = Y.Array.indexOf(modifiers, 'alt') > -1;
|
||||
exactMatch = exactMatch && ((e.altKey && hasKey) || (!e.altKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'ctrl') > -1;
|
||||
exactMatch = exactMatch && ((e.ctrlKey && hasKey) || (!e.ctrlKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'meta') > -1;
|
||||
exactMatch = exactMatch && ((e.metaKey && hasKey) || (!e.metaKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'shift') > -1;
|
||||
exactMatch = exactMatch && ((e.shiftKey && hasKey) || (!e.shiftKey && !hasKey));
|
||||
|
||||
return exactMatch;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if this plugin is enabled, based upon the state of it's buttons.
|
||||
*
|
||||
@ -978,9 +1020,9 @@ EditorPluginButtons.prototype = {
|
||||
*/
|
||||
_getDefaultMetaKey: function() {
|
||||
if (Y.UA.os === 'macintosh') {
|
||||
return '+meta';
|
||||
return 'meta';
|
||||
} else {
|
||||
return '+ctrl';
|
||||
return 'ctrl';
|
||||
}
|
||||
},
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -781,7 +781,11 @@ EditorPluginButtons.prototype = {
|
||||
* The keyConfig will take either an array of keyConfigurations, in
|
||||
* which case _addKeyboardListener is called multiple times; an object
|
||||
* containing an optional eventtype, optional container, and a set of
|
||||
* keyCodes, or just a string containing the keyCodes.
|
||||
* keyCodes, or just a string containing the keyCodes. When keyConfig is
|
||||
* not an object, it is wrapped around a function that ensures that
|
||||
* only the expected key modifiers were used. For instance, it checks
|
||||
* that space+ctrl is not triggered when the user presses ctrl+shift+space.
|
||||
* When using an object, the developer should check that manually.
|
||||
*
|
||||
* @method _addKeyboardListener
|
||||
* @param {function} callback
|
||||
@ -795,7 +799,9 @@ EditorPluginButtons.prototype = {
|
||||
_addKeyboardListener: function(callback, keyConfig, buttonName) {
|
||||
var eventtype = 'key',
|
||||
container = CSS.EDITORWRAPPER,
|
||||
keys;
|
||||
keys,
|
||||
handler,
|
||||
modifier;
|
||||
|
||||
if (Y.Lang.isArray(keyConfig)) {
|
||||
// If an Array was specified, call the add function for each element.
|
||||
@ -816,19 +822,27 @@ EditorPluginButtons.prototype = {
|
||||
|
||||
// Must be specified.
|
||||
keys = keyConfig.keyCodes;
|
||||
handler = callback;
|
||||
|
||||
} else {
|
||||
keys = this._getKeyEvent() + keyConfig + this._getDefaultMetaKey();
|
||||
modifier = this._getDefaultMetaKey()
|
||||
keys = this._getKeyEvent() + keyConfig + '+' + modifier;
|
||||
if (typeof this._primaryKeyboardShortcut[buttonName] === 'undefined') {
|
||||
this._primaryKeyboardShortcut[buttonName] = this._getDefaultMetaKeyDescription(keyConfig);
|
||||
}
|
||||
|
||||
// Wrap the callback into a handler to check if it uses the specified modifiers, not more.
|
||||
handler = Y.bind(function(modifiers, e) {
|
||||
if (this._eventUsesExactKeyModifiers(modifiers, e)) {
|
||||
callback.apply(this, [e]);
|
||||
}
|
||||
}, this, [modifier]);
|
||||
}
|
||||
|
||||
this._buttonHandlers.push(
|
||||
this.editor.delegate(
|
||||
eventtype,
|
||||
callback,
|
||||
handler,
|
||||
keys,
|
||||
container,
|
||||
this
|
||||
@ -837,6 +851,34 @@ EditorPluginButtons.prototype = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if a key event was strictly defined for the modifiers passed.
|
||||
*
|
||||
* @method _eventUsesExactKeyModifiers
|
||||
* @param {Array} modifiers List of key modifiers to check for (alt, ctrl, meta or shift).
|
||||
* @param {EventFacade} e The event facade.
|
||||
* @return {Boolean} True if the event was stricly using the modifiers specified.
|
||||
*/
|
||||
_eventUsesExactKeyModifiers: function(modifiers, e) {
|
||||
var exactMatch = true,
|
||||
hasKey;
|
||||
|
||||
if (e.type != 'key') {
|
||||
return false;
|
||||
}
|
||||
|
||||
hasKey = Y.Array.indexOf(modifiers, 'alt') > -1;
|
||||
exactMatch = exactMatch && ((e.altKey && hasKey) || (!e.altKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'ctrl') > -1;
|
||||
exactMatch = exactMatch && ((e.ctrlKey && hasKey) || (!e.ctrlKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'meta') > -1;
|
||||
exactMatch = exactMatch && ((e.metaKey && hasKey) || (!e.metaKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'shift') > -1;
|
||||
exactMatch = exactMatch && ((e.shiftKey && hasKey) || (!e.shiftKey && !hasKey));
|
||||
|
||||
return exactMatch;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if this plugin is enabled, based upon the state of it's buttons.
|
||||
*
|
||||
@ -974,9 +1016,9 @@ EditorPluginButtons.prototype = {
|
||||
*/
|
||||
_getDefaultMetaKey: function() {
|
||||
if (Y.UA.os === 'macintosh') {
|
||||
return '+meta';
|
||||
return 'meta';
|
||||
} else {
|
||||
return '+ctrl';
|
||||
return 'ctrl';
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -634,7 +634,11 @@ EditorPluginButtons.prototype = {
|
||||
* The keyConfig will take either an array of keyConfigurations, in
|
||||
* which case _addKeyboardListener is called multiple times; an object
|
||||
* containing an optional eventtype, optional container, and a set of
|
||||
* keyCodes, or just a string containing the keyCodes.
|
||||
* keyCodes, or just a string containing the keyCodes. When keyConfig is
|
||||
* not an object, it is wrapped around a function that ensures that
|
||||
* only the expected key modifiers were used. For instance, it checks
|
||||
* that space+ctrl is not triggered when the user presses ctrl+shift+space.
|
||||
* When using an object, the developer should check that manually.
|
||||
*
|
||||
* @method _addKeyboardListener
|
||||
* @param {function} callback
|
||||
@ -648,7 +652,9 @@ EditorPluginButtons.prototype = {
|
||||
_addKeyboardListener: function(callback, keyConfig, buttonName) {
|
||||
var eventtype = 'key',
|
||||
container = CSS.EDITORWRAPPER,
|
||||
keys;
|
||||
keys,
|
||||
handler,
|
||||
modifier;
|
||||
|
||||
if (Y.Lang.isArray(keyConfig)) {
|
||||
// If an Array was specified, call the add function for each element.
|
||||
@ -669,19 +675,27 @@ EditorPluginButtons.prototype = {
|
||||
|
||||
// Must be specified.
|
||||
keys = keyConfig.keyCodes;
|
||||
handler = callback;
|
||||
|
||||
} else {
|
||||
keys = this._getKeyEvent() + keyConfig + this._getDefaultMetaKey();
|
||||
modifier = this._getDefaultMetaKey()
|
||||
keys = this._getKeyEvent() + keyConfig + '+' + modifier;
|
||||
if (typeof this._primaryKeyboardShortcut[buttonName] === 'undefined') {
|
||||
this._primaryKeyboardShortcut[buttonName] = this._getDefaultMetaKeyDescription(keyConfig);
|
||||
}
|
||||
|
||||
// Wrap the callback into a handler to check if it uses the specified modifiers, not more.
|
||||
handler = Y.bind(function(modifiers, e) {
|
||||
if (this._eventUsesExactKeyModifiers(modifiers, e)) {
|
||||
callback.apply(this, [e]);
|
||||
}
|
||||
}, this, [modifier]);
|
||||
}
|
||||
|
||||
this._buttonHandlers.push(
|
||||
this.editor.delegate(
|
||||
eventtype,
|
||||
callback,
|
||||
handler,
|
||||
keys,
|
||||
container,
|
||||
this
|
||||
@ -692,6 +706,34 @@ EditorPluginButtons.prototype = {
|
||||
'debug', LOGNAME);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if a key event was strictly defined for the modifiers passed.
|
||||
*
|
||||
* @method _eventUsesExactKeyModifiers
|
||||
* @param {Array} modifiers List of key modifiers to check for (alt, ctrl, meta or shift).
|
||||
* @param {EventFacade} e The event facade.
|
||||
* @return {Boolean} True if the event was stricly using the modifiers specified.
|
||||
*/
|
||||
_eventUsesExactKeyModifiers: function(modifiers, e) {
|
||||
var exactMatch = true,
|
||||
hasKey;
|
||||
|
||||
if (e.type != 'key') {
|
||||
return false;
|
||||
}
|
||||
|
||||
hasKey = Y.Array.indexOf(modifiers, 'alt') > -1;
|
||||
exactMatch = exactMatch && ((e.altKey && hasKey) || (!e.altKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'ctrl') > -1;
|
||||
exactMatch = exactMatch && ((e.ctrlKey && hasKey) || (!e.ctrlKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'meta') > -1;
|
||||
exactMatch = exactMatch && ((e.metaKey && hasKey) || (!e.metaKey && !hasKey));
|
||||
hasKey = Y.Array.indexOf(modifiers, 'shift') > -1;
|
||||
exactMatch = exactMatch && ((e.shiftKey && hasKey) || (!e.shiftKey && !hasKey));
|
||||
|
||||
return exactMatch;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if this plugin is enabled, based upon the state of it's buttons.
|
||||
*
|
||||
@ -829,9 +871,9 @@ EditorPluginButtons.prototype = {
|
||||
*/
|
||||
_getDefaultMetaKey: function() {
|
||||
if (Y.UA.os === 'macintosh') {
|
||||
return '+meta';
|
||||
return 'meta';
|
||||
} else {
|
||||
return '+ctrl';
|
||||
return 'ctrl';
|
||||
}
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user