mirror of
https://github.com/moodle/moodle.git
synced 2025-04-25 10:26:17 +02:00
MDL-44040 editor: implemented shortcuts for bold, italic, underline and undo
This commit is contained in:
parent
f331980308
commit
bdfbdeeb64
@ -45,6 +45,7 @@ M.atto_bold = M.atto_bold || {
|
||||
|
||||
var iconurl = M.util.image_url('e/bold', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'bold', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'bold', keys: 66});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
@ -61,4 +62,4 @@ M.atto_bold = M.atto_bold || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -1 +1 @@
|
||||
YUI.add("moodle-atto_bold-button",function(e,t){var n={TAGS:"b,strong"};M.atto_bold=M.atto_bold||{init:function(e){var t=function(e,t){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand("bold",!1,null),M.editor_atto.text_updated(t)},r=M.util.image_url("e/bold","core");M.editor_atto.add_toolbar_button(e.elementid,"bold",r,e.group,t);var i=M.editor_atto.get_editable_node(e.elementid);i.on("atto:selectionchanged",function(e){M.editor_atto.selection_filter_matches(e.elementid,n.TAGS,e.selectedNodes)?M.editor_atto.add_widget_highlight(e.elementid,"bold"):M.editor_atto.remove_widget_highlight(e.elementid,"bold")})}}},"@VERSION@",{requires:["node"]});
|
||||
YUI.add("moodle-atto_bold-button",function(e,t){var n={TAGS:"b,strong"};M.atto_bold=M.atto_bold||{init:function(e){var t=function(e,t){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand("bold",!1,null),M.editor_atto.text_updated(t)},r=M.util.image_url("e/bold","core");M.editor_atto.add_toolbar_button(e.elementid,"bold",r,e.group,t),M.editor_atto.add_button_shortcut({action:"bold",keys:66});var i=M.editor_atto.get_editable_node(e.elementid);i.on("atto:selectionchanged",function(e){M.editor_atto.selection_filter_matches(e.elementid,n.TAGS,e.selectedNodes)?M.editor_atto.add_widget_highlight(e.elementid,"bold"):M.editor_atto.remove_widget_highlight(e.elementid,"bold")})}}},"@VERSION@",{requires:["node","moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -45,6 +45,7 @@ M.atto_bold = M.atto_bold || {
|
||||
|
||||
var iconurl = M.util.image_url('e/bold', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'bold', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'bold', keys: 66});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
@ -61,4 +62,4 @@ M.atto_bold = M.atto_bold || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -43,6 +43,7 @@ M.atto_bold = M.atto_bold || {
|
||||
|
||||
var iconurl = M.util.image_url('e/bold', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'bold', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'bold', keys: 66});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
|
@ -1,5 +1,8 @@
|
||||
{
|
||||
"moodle-atto_bold-button": {
|
||||
"requires": ["node"]
|
||||
"requires": [
|
||||
"node",
|
||||
"moodle-editor_atto-editor-shortcut"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ M.atto_italic = M.atto_italic || {
|
||||
|
||||
var iconurl = M.util.image_url('e/italic', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'italic', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'italic', keys: 73});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
@ -61,4 +62,4 @@ M.atto_italic = M.atto_italic || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -1 +1 @@
|
||||
YUI.add("moodle-atto_italic-button",function(e,t){var n={TAGS:"i"};M.atto_italic=M.atto_italic||{init:function(e){var t=function(e,t){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand("italic",!1,null),M.editor_atto.text_updated(t)},r=M.util.image_url("e/italic","core");M.editor_atto.add_toolbar_button(e.elementid,"italic",r,e.group,t);var i=M.editor_atto.get_editable_node(e.elementid);i.on("atto:selectionchanged",function(e){M.editor_atto.selection_filter_matches(e.elementid,n.TAGS,e.selectedNodes)?M.editor_atto.add_widget_highlight(e.elementid,"italic"):M.editor_atto.remove_widget_highlight(e.elementid,"italic")})}}},"@VERSION@",{requires:["node"]});
|
||||
YUI.add("moodle-atto_italic-button",function(e,t){var n={TAGS:"i"};M.atto_italic=M.atto_italic||{init:function(e){var t=function(e,t){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand("italic",!1,null),M.editor_atto.text_updated(t)},r=M.util.image_url("e/italic","core");M.editor_atto.add_toolbar_button(e.elementid,"italic",r,e.group,t),M.editor_atto.add_button_shortcut({action:"italic",keys:73});var i=M.editor_atto.get_editable_node(e.elementid);i.on("atto:selectionchanged",function(e){M.editor_atto.selection_filter_matches(e.elementid,n.TAGS,e.selectedNodes)?M.editor_atto.add_widget_highlight(e.elementid,"italic"):M.editor_atto.remove_widget_highlight(e.elementid,"italic")})}}},"@VERSION@",{requires:["node","moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -45,6 +45,7 @@ M.atto_italic = M.atto_italic || {
|
||||
|
||||
var iconurl = M.util.image_url('e/italic', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'italic', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'italic', keys: 73});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
@ -61,4 +62,4 @@ M.atto_italic = M.atto_italic || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -43,6 +43,7 @@ M.atto_italic = M.atto_italic || {
|
||||
|
||||
var iconurl = M.util.image_url('e/italic', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'italic', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'italic', keys: 73});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"moodle-atto_italic-button": {
|
||||
"requires": ["node"]
|
||||
"requires": ["node", "moodle-editor_atto-editor-shortcut"]
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ M.atto_underline = M.atto_underline || {
|
||||
|
||||
var iconurl = M.util.image_url('e/underline', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'underline', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'underline', keys: 85});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
@ -61,4 +62,4 @@ M.atto_underline = M.atto_underline || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -1 +1 @@
|
||||
YUI.add("moodle-atto_underline-button",function(e,t){var n={TAGS:"u"};M.atto_underline=M.atto_underline||{init:function(e){var t=function(e,t){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand("underline",!1,null),M.editor_atto.text_updated(t)},r=M.util.image_url("e/underline","core");M.editor_atto.add_toolbar_button(e.elementid,"underline",r,e.group,t);var i=M.editor_atto.get_editable_node(e.elementid);i.on("atto:selectionchanged",function(e){M.editor_atto.selection_filter_matches(e.elementid,n.TAGS,e.selectedNodes)?M.editor_atto.add_widget_highlight(e.elementid,"underline"):M.editor_atto.remove_widget_highlight(e.elementid,"underline")})}}},"@VERSION@",{requires:["node"]});
|
||||
YUI.add("moodle-atto_underline-button",function(e,t){var n={TAGS:"u"};M.atto_underline=M.atto_underline||{init:function(e){var t=function(e,t){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand("underline",!1,null),M.editor_atto.text_updated(t)},r=M.util.image_url("e/underline","core");M.editor_atto.add_toolbar_button(e.elementid,"underline",r,e.group,t),M.editor_atto.add_button_shortcut({action:"underline",keys:85});var i=M.editor_atto.get_editable_node(e.elementid);i.on("atto:selectionchanged",function(e){M.editor_atto.selection_filter_matches(e.elementid,n.TAGS,e.selectedNodes)?M.editor_atto.add_widget_highlight(e.elementid,"underline"):M.editor_atto.remove_widget_highlight(e.elementid,"underline")})}}},"@VERSION@",{requires:["node","moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -45,6 +45,7 @@ M.atto_underline = M.atto_underline || {
|
||||
|
||||
var iconurl = M.util.image_url('e/underline', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'underline', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'underline', keys: 85});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
@ -61,4 +62,4 @@ M.atto_underline = M.atto_underline || {
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -43,6 +43,7 @@ M.atto_underline = M.atto_underline || {
|
||||
|
||||
var iconurl = M.util.image_url('e/underline', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'underline', iconurl, params.group, click);
|
||||
M.editor_atto.add_button_shortcut({action: 'underline', keys: 85});
|
||||
|
||||
// Attach an event listner to watch for "changes" in the contenteditable.
|
||||
// This includes cursor changes, we check if the button should be active or not, based
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"moodle-atto_underline-button": {
|
||||
"requires": ["node"]
|
||||
"requires": ["node", "moodle-editor_atto-editor-shortcut"]
|
||||
}
|
||||
}
|
||||
|
@ -138,9 +138,10 @@ M.atto_undo = M.atto_undo || {
|
||||
// Redo button.
|
||||
iconurl = M.util.image_url('e/redo', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'undo', iconurl, params.group, M.atto_undo.redo_handler, 'redo', M.util.get_string('redo', 'atto_undo'));
|
||||
M.editor_atto.add_button_shortcut({action: 'redo', keys: 89});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -1 +1 @@
|
||||
YUI.add("moodle-atto_undo-button",function(e,t){M.atto_undo=M.atto_undo||{browsersupportsundo:null,click_handler:function(e,t,n){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand(n,!1,null),M.editor_atto.text_updated(t)},undo_handler:function(e,t){M.atto_undo.click_handler(e,t,"undo")},redo_handler:function(e,t){M.atto_undo.click_handler(e,t,"redo")},test_undo_support:function(){var t=document.activeElement,n=!1,r=e.Node.create('<div id="attoundotesting" contenteditable="true"style="position: fixed; top: 0px; height:0px">a</div>');e.one("body").prepend(r),r.focus();try{document.execCommand("insertText",!1,"b"),r.getHTML()==="ba"&&(document.execCommand("undo",!1),r.getHTML()==="a"&&(document.execCommand("redo",!1),r.getHTML()==="ba"&&(n=!0)))}catch(i){return!1}return e.one("body").removeChild(r),t.focus(),n},init:function(e){M.atto_undo.browsersupportsundo===null&&(M.atto_undo.browsersupportsundo=M.atto_undo.test_undo_support());if(M.atto_undo.browsersupportsundo){var t=M.util.image_url("e/undo","core");M.editor_atto.add_toolbar_button(e.elementid,"undo",t,e.group,M.atto_undo.undo_handler,"undo",M.util.get_string("undo","atto_undo")),t=M.util.image_url("e/redo","core"),M.editor_atto.add_toolbar_button(e.elementid,"undo",t,e.group,M.atto_undo.redo_handler,"redo",M.util.get_string("redo","atto_undo"))}}}},"@VERSION@",{requires:["node"]});
|
||||
YUI.add("moodle-atto_undo-button",function(e,t){M.atto_undo=M.atto_undo||{browsersupportsundo:null,click_handler:function(e,t,n){e.preventDefault(),M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand(n,!1,null),M.editor_atto.text_updated(t)},undo_handler:function(e,t){M.atto_undo.click_handler(e,t,"undo")},redo_handler:function(e,t){M.atto_undo.click_handler(e,t,"redo")},test_undo_support:function(){var t=document.activeElement,n=!1,r=e.Node.create('<div id="attoundotesting" contenteditable="true"style="position: fixed; top: 0px; height:0px">a</div>');e.one("body").prepend(r),r.focus();try{document.execCommand("insertText",!1,"b"),r.getHTML()==="ba"&&(document.execCommand("undo",!1),r.getHTML()==="a"&&(document.execCommand("redo",!1),r.getHTML()==="ba"&&(n=!0)))}catch(i){return!1}return e.one("body").removeChild(r),t.focus(),n},init:function(e){M.atto_undo.browsersupportsundo===null&&(M.atto_undo.browsersupportsundo=M.atto_undo.test_undo_support());if(M.atto_undo.browsersupportsundo){var t=M.util.image_url("e/undo","core");M.editor_atto.add_toolbar_button(e.elementid,"undo",t,e.group,M.atto_undo.undo_handler,"undo",M.util.get_string("undo","atto_undo")),t=M.util.image_url("e/redo","core"),M.editor_atto.add_toolbar_button(e.elementid,"undo",t,e.group,M.atto_undo.redo_handler,"redo",M.util.get_string("redo","atto_undo")),M.editor_atto.add_button_shortcut({action:"redo",keys:89})}}}},"@VERSION@",{requires:["node","moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -138,9 +138,10 @@ M.atto_undo = M.atto_undo || {
|
||||
// Redo button.
|
||||
iconurl = M.util.image_url('e/redo', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'undo', iconurl, params.group, M.atto_undo.redo_handler, 'redo', M.util.get_string('redo', 'atto_undo'));
|
||||
M.editor_atto.add_button_shortcut({action: 'redo', keys: 89});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node"]});
|
||||
}, '@VERSION@', {"requires": ["node", "moodle-editor_atto-editor-shortcut"]});
|
||||
|
@ -136,6 +136,7 @@ M.atto_undo = M.atto_undo || {
|
||||
// Redo button.
|
||||
iconurl = M.util.image_url('e/redo', 'core');
|
||||
M.editor_atto.add_toolbar_button(params.elementid, 'undo', iconurl, params.group, M.atto_undo.redo_handler, 'redo', M.util.get_string('redo', 'atto_undo'));
|
||||
M.editor_atto.add_button_shortcut({action: 'redo', keys: 89});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"moodle-atto_undo-button": {
|
||||
"requires": ["node"]
|
||||
"requires": ["node", "moodle-editor_atto-editor-shortcut"]
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,263 @@
|
||||
YUI.add('moodle-editor_atto-editor-shortcut', function (Y, NAME) {
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
var SHORTCUT,
|
||||
SHORTCUTNAME = 'AttoButtonShortcut',
|
||||
EVENTS = {
|
||||
press: 'press'
|
||||
},
|
||||
ATTRS = {
|
||||
action: 'action',
|
||||
eventtype: 'eventtype',
|
||||
keys: 'keys'
|
||||
},
|
||||
CSS = {
|
||||
editorid: 'data-editor',
|
||||
contenteditable: '.editor_atto_content'
|
||||
},
|
||||
NS = 'moodle-editor_atto-editor-shortcut';
|
||||
|
||||
/**
|
||||
* Atto editor shortcut class
|
||||
*
|
||||
* @namespace M.editor_atto
|
||||
* @class Shortcut
|
||||
* @constructor
|
||||
* @extends Base
|
||||
* @copyright 2014 Sam Hemelryk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
SHORTCUT = function() {
|
||||
SHORTCUT.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
SHORTCUT.prototype = {
|
||||
/**
|
||||
* Initialises a new shortcut.
|
||||
* @method initializer
|
||||
*/
|
||||
initializer: function() {
|
||||
/**
|
||||
* Shortcut Event: press.
|
||||
*
|
||||
* This event is fired when the user triggers the shortcut object by pressing the required keys.
|
||||
* The event has a default function {@see execActionDefault()} that calls the browser to execute the action used
|
||||
* when the shortcut is created.
|
||||
* If you wish to provide your own functionality you need to add a listener to the shortcut you create for this
|
||||
* event, and then when it is fired call e.preventDefault() on the event facade it provides.
|
||||
*
|
||||
* The event facade contains two custom properties:
|
||||
* * elementid: The ID of the editor that is being acted upon.
|
||||
* * origevent: The original event facade, should you need it for any reason (I hope not)
|
||||
*
|
||||
* @event press
|
||||
*/
|
||||
this.publish(EVENTS.press, {
|
||||
emitFacade: true,
|
||||
defaultFn: this.execActionDefault
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Gets called when the user has triggered this shortcut.
|
||||
* @method trigger
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
trigger: function(e) {
|
||||
e.preventDefault();
|
||||
var elementid = e.target.getAttribute(CSS.editorid);
|
||||
this.fire(EVENTS.press, {
|
||||
elementid: elementid,
|
||||
origevent: e
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Binds this shortcut to the editors being shown on the page.
|
||||
* @method bind
|
||||
* @chainable
|
||||
* @param {Node} node
|
||||
* @param {String} container CSS to select the container element to bind to. Usually the contenteditable element.
|
||||
* @return {SHORTCUT}
|
||||
*/
|
||||
bind: function(node, container) {
|
||||
var eventtype = this.get(ATTRS.eventtype),
|
||||
keys = this.get(ATTRS.keys);
|
||||
Y.one('body').delegate(
|
||||
eventtype, // Event.
|
||||
this.trigger, // Callback.
|
||||
keys, // Keys.
|
||||
container, // Delegated container.
|
||||
this // Context.
|
||||
);
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* The default action performed when this shortcut (or any) is triggered.
|
||||
*
|
||||
* This can be cancelled by attaching your own event listener to the press event published
|
||||
* by this shortcut and then calling e.preventDefault() on the EventFacade it triggers.
|
||||
*
|
||||
* @method execActionDefault
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
execActionDefault: function(e) {
|
||||
var elementid = e.elementid;
|
||||
if (!M.editor_atto.is_active(elementid)) {
|
||||
M.editor_atto.focus(elementid);
|
||||
}
|
||||
document.execCommand(this.get(ATTRS.action), false, null);
|
||||
// Clean the YUI ids from the HTML.
|
||||
M.editor_atto.text_updated(elementid);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the default meta key to use with a shortcut.
|
||||
* @method getDefaultMeta
|
||||
* @returns {string}
|
||||
*/
|
||||
getDefaultMeta: function() {
|
||||
return (Y.UA.os === 'macintosh') ? '+meta' : '+ctrl';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the key event to use for this shortcut.
|
||||
* @returns {string}
|
||||
*/
|
||||
getKeyEvent: function() {
|
||||
return 'down:';
|
||||
}
|
||||
};
|
||||
Y.extend(SHORTCUT, Y.Base, SHORTCUT.prototype, {
|
||||
NAME: SHORTCUTNAME,
|
||||
ATTRS: {
|
||||
/**
|
||||
* The action this shortcut is performing.
|
||||
* If using the default functionality this should be the browser command to execute.
|
||||
* @attribute action
|
||||
* @type String
|
||||
* @writeOnce
|
||||
*/
|
||||
action: {
|
||||
writeOnce: 'init',
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The key code(s) used to trigger the shortcut, should be something like `85` for u (underline).
|
||||
*
|
||||
* For a single char all you need to do is set the keys property to the char you want to map to a shortcut.
|
||||
* If you need to do something more advanced (special combinations etc) you can specify a complete key set and
|
||||
* then set the simplekeys property to false.
|
||||
*
|
||||
* Please note that if you do provide an complete char set the browser defaults can only be overridden on the key down
|
||||
* event. A keypress is unfortunately good enough.
|
||||
*
|
||||
* @attribute keys
|
||||
* @default false
|
||||
* @type String|Bool
|
||||
* @writeOnce
|
||||
*/
|
||||
keys: {
|
||||
writeOnce: 'init',
|
||||
value: false,
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val) || Y.Lang.isNumber(val) || Y.Lang.isBoolean(val);
|
||||
},
|
||||
getter: function(val) {
|
||||
if (this.get('simplekeys')) {
|
||||
return this.getKeyEvent() + val + this.getDefaultMeta();
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The event type to trigger on.
|
||||
* I can't imagine any good reason to override this, if you find one please let me know.
|
||||
* @attribute eventtype
|
||||
* @type String
|
||||
* @writeOnce
|
||||
* @default key
|
||||
*/
|
||||
eventtype: {
|
||||
writeOnce: 'init',
|
||||
value: 'key',
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* When set to true a simple key combination is being used and we'll have to append the correct type and control for it.
|
||||
*
|
||||
* Set this too off if you want to define the complete key combination for the shortcut yourself (advanced).
|
||||
*/
|
||||
simplekeys: {
|
||||
value: true,
|
||||
validator: function(val) {
|
||||
return Y.Lang.isBoolean(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
M.editor_atto = M.editor_atto || {};
|
||||
Y.mix(M.editor_atto, {
|
||||
/**
|
||||
* An associative collection of shortcut objects that have been bound to the editors on the page.
|
||||
* @protected
|
||||
* @namespace M.editor_atto
|
||||
* @property shortcutdelegations
|
||||
* @type Object
|
||||
*/
|
||||
shortcutdelegations: {},
|
||||
|
||||
/**
|
||||
* Adds a button shortcut given a configuration object containing properties for it.
|
||||
*
|
||||
* The config object must contain at least action and keys.
|
||||
* For more details see {@link SHORTCUT()}
|
||||
*
|
||||
* @static
|
||||
* @namespace M.editor_atto
|
||||
* @method add_button_shortcut
|
||||
* @param {Object} config A configuration object containing at least action and keys.
|
||||
* @return SHORTCUT
|
||||
*/
|
||||
add_button_shortcut: function(config) {
|
||||
var shortcut = new SHORTCUT(config);
|
||||
return this.register_button_shortcut(shortcut);
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a shortcut object and binds it to the editors being displayed on the current page.
|
||||
*
|
||||
* @static
|
||||
* @namespace M.editor_atto
|
||||
* @method register_button_shortcut
|
||||
* @param {SHORTCUT} shortcut The shortcut object to add.
|
||||
* @return SHORTCUT
|
||||
*/
|
||||
register_button_shortcut: function(shortcut) {
|
||||
var action = shortcut.get(ATTRS.action),
|
||||
keys = shortcut.get(ATTRS.keys);
|
||||
if (!M.editor_atto.shortcutdelegations[action] && keys) {
|
||||
Y.log('Atto shortcut registered: ' + keys + ' now triggers ' + action, 'debug', NS);
|
||||
M.editor_atto.shortcutdelegations[action] = shortcut.bind(Y.one('body'), CSS.contenteditable);
|
||||
}
|
||||
return M.editor_atto.shortcutdelegations[action];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node", "event", "event-custom", "moodle-editor_atto-editor"]});
|
@ -0,0 +1 @@
|
||||
YUI.add("moodle-editor_atto-editor-shortcut",function(e,t){var n,r="AttoButtonShortcut",i={press:"press"},s={action:"action",eventtype:"eventtype",keys:"keys"},o={editorid:"data-editor",contenteditable:".editor_atto_content"},u="moodle-editor_atto-editor-shortcut";n=function(){n.superclass.constructor.apply(this,arguments)},n.prototype={initializer:function(){this.publish(i.press,{emitFacade:!0,defaultFn:this.execActionDefault})},trigger:function(e){e.preventDefault();var t=e.target.getAttribute(o.editorid);this.fire(i.press,{elementid:t,origevent:e})},bind:function(t,n){var r=this.get(s.eventtype),i=this.get(s.keys);return e.one("body").delegate(r,this.trigger,i,n,this),this},execActionDefault:function(e){var t=e.elementid;M.editor_atto.is_active(t)||M.editor_atto.focus(t),document.execCommand(this.get(s.action),!1,null),M.editor_atto.text_updated(t)},getDefaultMeta:function(){return e.UA.os==="macintosh"?"+meta":"+ctrl"},getKeyEvent:function(){return"down:"}},e.extend(n,e.Base,n.prototype,{NAME:r,ATTRS:{action:{writeOnce:"init",validator:function(t){return e.Lang.isString(t)}},keys:{writeOnce:"init",value:!1,validator:function(t){return e.Lang.isString(t)||e.Lang.isNumber(t)||e.Lang.isBoolean(t)},getter:function(e){if(this.get("simplekeys"))return this.getKeyEvent()+e+this.getDefaultMeta()}},eventtype:{writeOnce:"init",value:"key",validator:function(t){return e.Lang.isString(t)}},simplekeys:{value:!0,validator:function(t){return e.Lang.isBoolean(t)}}}}),M.editor_atto=M.editor_atto||{},e.mix(M.editor_atto,{shortcutdelegations:{},add_button_shortcut:function(e){var t=new n(e);return this.register_button_shortcut(t)},register_button_shortcut:function(t){var n=t.get(s.action),r=t.get(s.keys);return!M.editor_atto.shortcutdelegations[n]&&r&&(M.editor_atto.shortcutdelegations[n]=t.bind(e.one("body"),o.contenteditable)),M.editor_atto.shortcutdelegations[n]}})},"@VERSION@",{requires:["node","event","event-custom","moodle-editor_atto-editor"]});
|
262
lib/editor/atto/yui/build/moodle-editor_atto-editor-shortcut/moodle-editor_atto-editor-shortcut.js
vendored
Normal file
262
lib/editor/atto/yui/build/moodle-editor_atto-editor-shortcut/moodle-editor_atto-editor-shortcut.js
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
YUI.add('moodle-editor_atto-editor-shortcut', function (Y, NAME) {
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
var SHORTCUT,
|
||||
SHORTCUTNAME = 'AttoButtonShortcut',
|
||||
EVENTS = {
|
||||
press: 'press'
|
||||
},
|
||||
ATTRS = {
|
||||
action: 'action',
|
||||
eventtype: 'eventtype',
|
||||
keys: 'keys'
|
||||
},
|
||||
CSS = {
|
||||
editorid: 'data-editor',
|
||||
contenteditable: '.editor_atto_content'
|
||||
},
|
||||
NS = 'moodle-editor_atto-editor-shortcut';
|
||||
|
||||
/**
|
||||
* Atto editor shortcut class
|
||||
*
|
||||
* @namespace M.editor_atto
|
||||
* @class Shortcut
|
||||
* @constructor
|
||||
* @extends Base
|
||||
* @copyright 2014 Sam Hemelryk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
SHORTCUT = function() {
|
||||
SHORTCUT.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
SHORTCUT.prototype = {
|
||||
/**
|
||||
* Initialises a new shortcut.
|
||||
* @method initializer
|
||||
*/
|
||||
initializer: function() {
|
||||
/**
|
||||
* Shortcut Event: press.
|
||||
*
|
||||
* This event is fired when the user triggers the shortcut object by pressing the required keys.
|
||||
* The event has a default function {@see execActionDefault()} that calls the browser to execute the action used
|
||||
* when the shortcut is created.
|
||||
* If you wish to provide your own functionality you need to add a listener to the shortcut you create for this
|
||||
* event, and then when it is fired call e.preventDefault() on the event facade it provides.
|
||||
*
|
||||
* The event facade contains two custom properties:
|
||||
* * elementid: The ID of the editor that is being acted upon.
|
||||
* * origevent: The original event facade, should you need it for any reason (I hope not)
|
||||
*
|
||||
* @event press
|
||||
*/
|
||||
this.publish(EVENTS.press, {
|
||||
emitFacade: true,
|
||||
defaultFn: this.execActionDefault
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Gets called when the user has triggered this shortcut.
|
||||
* @method trigger
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
trigger: function(e) {
|
||||
e.preventDefault();
|
||||
var elementid = e.target.getAttribute(CSS.editorid);
|
||||
this.fire(EVENTS.press, {
|
||||
elementid: elementid,
|
||||
origevent: e
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Binds this shortcut to the editors being shown on the page.
|
||||
* @method bind
|
||||
* @chainable
|
||||
* @param {Node} node
|
||||
* @param {String} container CSS to select the container element to bind to. Usually the contenteditable element.
|
||||
* @return {SHORTCUT}
|
||||
*/
|
||||
bind: function(node, container) {
|
||||
var eventtype = this.get(ATTRS.eventtype),
|
||||
keys = this.get(ATTRS.keys);
|
||||
Y.one('body').delegate(
|
||||
eventtype, // Event.
|
||||
this.trigger, // Callback.
|
||||
keys, // Keys.
|
||||
container, // Delegated container.
|
||||
this // Context.
|
||||
);
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* The default action performed when this shortcut (or any) is triggered.
|
||||
*
|
||||
* This can be cancelled by attaching your own event listener to the press event published
|
||||
* by this shortcut and then calling e.preventDefault() on the EventFacade it triggers.
|
||||
*
|
||||
* @method execActionDefault
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
execActionDefault: function(e) {
|
||||
var elementid = e.elementid;
|
||||
if (!M.editor_atto.is_active(elementid)) {
|
||||
M.editor_atto.focus(elementid);
|
||||
}
|
||||
document.execCommand(this.get(ATTRS.action), false, null);
|
||||
// Clean the YUI ids from the HTML.
|
||||
M.editor_atto.text_updated(elementid);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the default meta key to use with a shortcut.
|
||||
* @method getDefaultMeta
|
||||
* @returns {string}
|
||||
*/
|
||||
getDefaultMeta: function() {
|
||||
return (Y.UA.os === 'macintosh') ? '+meta' : '+ctrl';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the key event to use for this shortcut.
|
||||
* @returns {string}
|
||||
*/
|
||||
getKeyEvent: function() {
|
||||
return 'down:';
|
||||
}
|
||||
};
|
||||
Y.extend(SHORTCUT, Y.Base, SHORTCUT.prototype, {
|
||||
NAME: SHORTCUTNAME,
|
||||
ATTRS: {
|
||||
/**
|
||||
* The action this shortcut is performing.
|
||||
* If using the default functionality this should be the browser command to execute.
|
||||
* @attribute action
|
||||
* @type String
|
||||
* @writeOnce
|
||||
*/
|
||||
action: {
|
||||
writeOnce: 'init',
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The key code(s) used to trigger the shortcut, should be something like `85` for u (underline).
|
||||
*
|
||||
* For a single char all you need to do is set the keys property to the char you want to map to a shortcut.
|
||||
* If you need to do something more advanced (special combinations etc) you can specify a complete key set and
|
||||
* then set the simplekeys property to false.
|
||||
*
|
||||
* Please note that if you do provide an complete char set the browser defaults can only be overridden on the key down
|
||||
* event. A keypress is unfortunately good enough.
|
||||
*
|
||||
* @attribute keys
|
||||
* @default false
|
||||
* @type String|Bool
|
||||
* @writeOnce
|
||||
*/
|
||||
keys: {
|
||||
writeOnce: 'init',
|
||||
value: false,
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val) || Y.Lang.isNumber(val) || Y.Lang.isBoolean(val);
|
||||
},
|
||||
getter: function(val) {
|
||||
if (this.get('simplekeys')) {
|
||||
return this.getKeyEvent() + val + this.getDefaultMeta();
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The event type to trigger on.
|
||||
* I can't imagine any good reason to override this, if you find one please let me know.
|
||||
* @attribute eventtype
|
||||
* @type String
|
||||
* @writeOnce
|
||||
* @default key
|
||||
*/
|
||||
eventtype: {
|
||||
writeOnce: 'init',
|
||||
value: 'key',
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* When set to true a simple key combination is being used and we'll have to append the correct type and control for it.
|
||||
*
|
||||
* Set this too off if you want to define the complete key combination for the shortcut yourself (advanced).
|
||||
*/
|
||||
simplekeys: {
|
||||
value: true,
|
||||
validator: function(val) {
|
||||
return Y.Lang.isBoolean(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
M.editor_atto = M.editor_atto || {};
|
||||
Y.mix(M.editor_atto, {
|
||||
/**
|
||||
* An associative collection of shortcut objects that have been bound to the editors on the page.
|
||||
* @protected
|
||||
* @namespace M.editor_atto
|
||||
* @property shortcutdelegations
|
||||
* @type Object
|
||||
*/
|
||||
shortcutdelegations: {},
|
||||
|
||||
/**
|
||||
* Adds a button shortcut given a configuration object containing properties for it.
|
||||
*
|
||||
* The config object must contain at least action and keys.
|
||||
* For more details see {@link SHORTCUT()}
|
||||
*
|
||||
* @static
|
||||
* @namespace M.editor_atto
|
||||
* @method add_button_shortcut
|
||||
* @param {Object} config A configuration object containing at least action and keys.
|
||||
* @return SHORTCUT
|
||||
*/
|
||||
add_button_shortcut: function(config) {
|
||||
var shortcut = new SHORTCUT(config);
|
||||
return this.register_button_shortcut(shortcut);
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a shortcut object and binds it to the editors being displayed on the current page.
|
||||
*
|
||||
* @static
|
||||
* @namespace M.editor_atto
|
||||
* @method register_button_shortcut
|
||||
* @param {SHORTCUT} shortcut The shortcut object to add.
|
||||
* @return SHORTCUT
|
||||
*/
|
||||
register_button_shortcut: function(shortcut) {
|
||||
var action = shortcut.get(ATTRS.action),
|
||||
keys = shortcut.get(ATTRS.keys);
|
||||
if (!M.editor_atto.shortcutdelegations[action] && keys) {
|
||||
M.editor_atto.shortcutdelegations[action] = shortcut.bind(Y.one('body'), CSS.contenteditable);
|
||||
}
|
||||
return M.editor_atto.shortcutdelegations[action];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '@VERSION@', {"requires": ["node", "event", "event-custom", "moodle-editor_atto-editor"]});
|
@ -572,7 +572,8 @@ M.editor_atto = M.editor_atto || {
|
||||
'role="textbox" ' +
|
||||
'spellcheck="true" ' +
|
||||
'aria-live="off" ' +
|
||||
'class="' + CSS.CONTENT + '" />');
|
||||
'class="' + CSS.CONTENT + '" '+
|
||||
'data-editor="' + params.elementid + '" />');
|
||||
|
||||
var toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" id="' + params.elementid + '_toolbar" role="toolbar" aria-live="off"/>');
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -572,7 +572,8 @@ M.editor_atto = M.editor_atto || {
|
||||
'role="textbox" ' +
|
||||
'spellcheck="true" ' +
|
||||
'aria-live="off" ' +
|
||||
'class="' + CSS.CONTENT + '" />');
|
||||
'class="' + CSS.CONTENT + '" '+
|
||||
'data-editor="' + params.elementid + '" />');
|
||||
|
||||
var toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" id="' + params.elementid + '_toolbar" role="toolbar" aria-live="off"/>');
|
||||
|
||||
|
@ -7,6 +7,11 @@
|
||||
"controlmenu.js",
|
||||
"clean.js"
|
||||
]
|
||||
},
|
||||
"moodle-editor_atto-editor-shortcut": {
|
||||
"jsfiles": [
|
||||
"shortcut.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
lib/editor/atto/yui/src/editor/js/editor.js
vendored
3
lib/editor/atto/yui/src/editor/js/editor.js
vendored
@ -570,7 +570,8 @@ M.editor_atto = M.editor_atto || {
|
||||
'role="textbox" ' +
|
||||
'spellcheck="true" ' +
|
||||
'aria-live="off" ' +
|
||||
'class="' + CSS.CONTENT + '" />');
|
||||
'class="' + CSS.CONTENT + '" '+
|
||||
'data-editor="' + params.elementid + '" />');
|
||||
|
||||
var toolbar = Y.Node.create('<div class="' + CSS.TOOLBAR + '" id="' + params.elementid + '_toolbar" role="toolbar" aria-live="off"/>');
|
||||
|
||||
|
258
lib/editor/atto/yui/src/editor/js/shortcut.js
vendored
Normal file
258
lib/editor/atto/yui/src/editor/js/shortcut.js
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
var SHORTCUT,
|
||||
SHORTCUTNAME = 'AttoButtonShortcut',
|
||||
EVENTS = {
|
||||
press: 'press'
|
||||
},
|
||||
ATTRS = {
|
||||
action: 'action',
|
||||
eventtype: 'eventtype',
|
||||
keys: 'keys'
|
||||
},
|
||||
CSS = {
|
||||
editorid: 'data-editor',
|
||||
contenteditable: '.editor_atto_content'
|
||||
},
|
||||
NS = 'moodle-editor_atto-editor-shortcut';
|
||||
|
||||
/**
|
||||
* Atto editor shortcut class
|
||||
*
|
||||
* @namespace M.editor_atto
|
||||
* @class Shortcut
|
||||
* @constructor
|
||||
* @extends Base
|
||||
* @copyright 2014 Sam Hemelryk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
SHORTCUT = function() {
|
||||
SHORTCUT.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
SHORTCUT.prototype = {
|
||||
/**
|
||||
* Initialises a new shortcut.
|
||||
* @method initializer
|
||||
*/
|
||||
initializer: function() {
|
||||
/**
|
||||
* Shortcut Event: press.
|
||||
*
|
||||
* This event is fired when the user triggers the shortcut object by pressing the required keys.
|
||||
* The event has a default function {@see execActionDefault()} that calls the browser to execute the action used
|
||||
* when the shortcut is created.
|
||||
* If you wish to provide your own functionality you need to add a listener to the shortcut you create for this
|
||||
* event, and then when it is fired call e.preventDefault() on the event facade it provides.
|
||||
*
|
||||
* The event facade contains two custom properties:
|
||||
* * elementid: The ID of the editor that is being acted upon.
|
||||
* * origevent: The original event facade, should you need it for any reason (I hope not)
|
||||
*
|
||||
* @event press
|
||||
*/
|
||||
this.publish(EVENTS.press, {
|
||||
emitFacade: true,
|
||||
defaultFn: this.execActionDefault
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Gets called when the user has triggered this shortcut.
|
||||
* @method trigger
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
trigger: function(e) {
|
||||
e.preventDefault();
|
||||
var elementid = e.target.getAttribute(CSS.editorid);
|
||||
this.fire(EVENTS.press, {
|
||||
elementid: elementid,
|
||||
origevent: e
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Binds this shortcut to the editors being shown on the page.
|
||||
* @method bind
|
||||
* @chainable
|
||||
* @param {Node} node
|
||||
* @param {String} container CSS to select the container element to bind to. Usually the contenteditable element.
|
||||
* @return {SHORTCUT}
|
||||
*/
|
||||
bind: function(node, container) {
|
||||
var eventtype = this.get(ATTRS.eventtype),
|
||||
keys = this.get(ATTRS.keys);
|
||||
Y.one('body').delegate(
|
||||
eventtype, // Event.
|
||||
this.trigger, // Callback.
|
||||
keys, // Keys.
|
||||
container, // Delegated container.
|
||||
this // Context.
|
||||
);
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* The default action performed when this shortcut (or any) is triggered.
|
||||
*
|
||||
* This can be cancelled by attaching your own event listener to the press event published
|
||||
* by this shortcut and then calling e.preventDefault() on the EventFacade it triggers.
|
||||
*
|
||||
* @method execActionDefault
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
execActionDefault: function(e) {
|
||||
var elementid = e.elementid;
|
||||
if (!M.editor_atto.is_active(elementid)) {
|
||||
M.editor_atto.focus(elementid);
|
||||
}
|
||||
document.execCommand(this.get(ATTRS.action), false, null);
|
||||
// Clean the YUI ids from the HTML.
|
||||
M.editor_atto.text_updated(elementid);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the default meta key to use with a shortcut.
|
||||
* @method getDefaultMeta
|
||||
* @returns {string}
|
||||
*/
|
||||
getDefaultMeta: function() {
|
||||
return (Y.UA.os === 'macintosh') ? '+meta' : '+ctrl';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the key event to use for this shortcut.
|
||||
* @returns {string}
|
||||
*/
|
||||
getKeyEvent: function() {
|
||||
return 'down:';
|
||||
}
|
||||
};
|
||||
Y.extend(SHORTCUT, Y.Base, SHORTCUT.prototype, {
|
||||
NAME: SHORTCUTNAME,
|
||||
ATTRS: {
|
||||
/**
|
||||
* The action this shortcut is performing.
|
||||
* If using the default functionality this should be the browser command to execute.
|
||||
* @attribute action
|
||||
* @type String
|
||||
* @writeOnce
|
||||
*/
|
||||
action: {
|
||||
writeOnce: 'init',
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The key code(s) used to trigger the shortcut, should be something like `85` for u (underline).
|
||||
*
|
||||
* For a single char all you need to do is set the keys property to the char you want to map to a shortcut.
|
||||
* If you need to do something more advanced (special combinations etc) you can specify a complete key set and
|
||||
* then set the simplekeys property to false.
|
||||
*
|
||||
* Please note that if you do provide an complete char set the browser defaults can only be overridden on the key down
|
||||
* event. A keypress is unfortunately good enough.
|
||||
*
|
||||
* @attribute keys
|
||||
* @default false
|
||||
* @type String|Bool
|
||||
* @writeOnce
|
||||
*/
|
||||
keys: {
|
||||
writeOnce: 'init',
|
||||
value: false,
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val) || Y.Lang.isNumber(val) || Y.Lang.isBoolean(val);
|
||||
},
|
||||
getter: function(val) {
|
||||
if (this.get('simplekeys')) {
|
||||
return this.getKeyEvent() + val + this.getDefaultMeta();
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The event type to trigger on.
|
||||
* I can't imagine any good reason to override this, if you find one please let me know.
|
||||
* @attribute eventtype
|
||||
* @type String
|
||||
* @writeOnce
|
||||
* @default key
|
||||
*/
|
||||
eventtype: {
|
||||
writeOnce: 'init',
|
||||
value: 'key',
|
||||
validator: function(val) {
|
||||
return Y.Lang.isString(val);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* When set to true a simple key combination is being used and we'll have to append the correct type and control for it.
|
||||
*
|
||||
* Set this too off if you want to define the complete key combination for the shortcut yourself (advanced).
|
||||
*/
|
||||
simplekeys: {
|
||||
value: true,
|
||||
validator: function(val) {
|
||||
return Y.Lang.isBoolean(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
M.editor_atto = M.editor_atto || {};
|
||||
Y.mix(M.editor_atto, {
|
||||
/**
|
||||
* An associative collection of shortcut objects that have been bound to the editors on the page.
|
||||
* @protected
|
||||
* @namespace M.editor_atto
|
||||
* @property shortcutdelegations
|
||||
* @type Object
|
||||
*/
|
||||
shortcutdelegations: {},
|
||||
|
||||
/**
|
||||
* Adds a button shortcut given a configuration object containing properties for it.
|
||||
*
|
||||
* The config object must contain at least action and keys.
|
||||
* For more details see {@link SHORTCUT()}
|
||||
*
|
||||
* @static
|
||||
* @namespace M.editor_atto
|
||||
* @method add_button_shortcut
|
||||
* @param {Object} config A configuration object containing at least action and keys.
|
||||
* @return SHORTCUT
|
||||
*/
|
||||
add_button_shortcut: function(config) {
|
||||
var shortcut = new SHORTCUT(config);
|
||||
return this.register_button_shortcut(shortcut);
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a shortcut object and binds it to the editors being displayed on the current page.
|
||||
*
|
||||
* @static
|
||||
* @namespace M.editor_atto
|
||||
* @method register_button_shortcut
|
||||
* @param {SHORTCUT} shortcut The shortcut object to add.
|
||||
* @return SHORTCUT
|
||||
*/
|
||||
register_button_shortcut: function(shortcut) {
|
||||
var action = shortcut.get(ATTRS.action),
|
||||
keys = shortcut.get(ATTRS.keys);
|
||||
if (!M.editor_atto.shortcutdelegations[action] && keys) {
|
||||
Y.log('Atto shortcut registered: ' + keys + ' now triggers ' + action, 'debug', NS);
|
||||
M.editor_atto.shortcutdelegations[action] = shortcut.bind(Y.one('body'), CSS.contenteditable);
|
||||
}
|
||||
return M.editor_atto.shortcutdelegations[action];
|
||||
}
|
||||
});
|
@ -11,5 +11,13 @@
|
||||
"yui-throttle",
|
||||
"moodle-core-notification"
|
||||
]
|
||||
},
|
||||
"moodle-editor_atto-editor-shortcut": {
|
||||
"requires": [
|
||||
"node",
|
||||
"event",
|
||||
"event-custom",
|
||||
"moodle-editor_atto-editor"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user