1
0
mirror of https://github.com/moodle/moodle.git synced 2025-04-23 09:23:09 +02:00

MDL-43863 Add Undo/Redo plugins to Atto

This commit is contained in:
Jerome Mouneyrac 2014-02-13 17:17:34 +08:00 committed by Damyon Wiese
parent f6bef145bd
commit 99061b7ad1
10 changed files with 561 additions and 11 deletions

@ -0,0 +1,27 @@
<?php
// 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/>.
/**
* Strings for component 'atto_undo', language 'en'.
*
* @package atto_undo
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Undo/Redo';
$string['redo'] = 'Redo';
$string['undo'] = 'Undo';

@ -0,0 +1,44 @@
<?php
// 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/>.
/**
* Atto text editor undo plugin lib.
*
* @package atto_undo
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Initialise the strings required for JS.
*
* @return void
*/
function atto_undo_strings_for_js() {
global $PAGE;
// In order to prevent extra strings to be imported, comment/uncomment the characters
// which are enabled in the JavaScript part of this plugin.
$PAGE->requires->strings_for_js(
array(
'redo',
'undo'
),
'atto_undo'
);
}

@ -0,0 +1,29 @@
<?php
// 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/>.
/**
* Atto text editor integration version file.
*
* @package atto_undo
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014012800; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2013110500; // Requires this Moodle version.
$plugin->component = 'atto_undo'; // Full name of the plugin (used for diagnostics).

@ -0,0 +1,146 @@
YUI.add('moodle-atto_undo-button', 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/>.
/**
* Atto text editor undo plugin.
*
* @package editor-undo
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
M.atto_undo = M.atto_undo || {
/**
* Property used to cache the result of testing the undo/redo browser support.
*
* @property browsersupportsundo
* @type {Boolean} or null
* @default null
*/
browsersupportsundo : null,
/**
* Handle a click on either button (passed via cmd)
*
* @method click_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
* @param {String} The button clicked (undo or redo)
*/
click_handler : function(e, elementid, cmd) {
e.preventDefault();
if (!M.editor_atto.is_active(elementid)) {
M.editor_atto.focus(elementid);
}
document.execCommand(cmd, false, null);
// Clean the YUI ids from the HTML.
M.editor_atto.text_updated(elementid);
},
/**
* Handle a click on undo
*
* @method undo_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
*/
undo_handler : function(e, elementid) {
M.atto_undo.click_handler(e, elementid, 'undo');
},
/**
* Handle a click on redo
*
* @method redo_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
*/
redo_handler : function(e, elementid) {
M.atto_undo.click_handler(e, elementid, 'redo');
},
/**
* Do a feature test to see if undo/redo is buggy in this browser.
*
* @method test_undo_support
* @return {Boolean} true if undo/redo is functional.
*/
test_undo_support : function() {
// Check now if other browser supports it.
// Save the focussed element.
var activeelement = document.activeElement;
// Creating a temp div to test if the browser support the undo execCommand.
var undosupport = false;
var foo = Y.Node.create('<div id="attoundotesting" contenteditable="true"' +
'style="position: fixed; top: 0px; height:0px">a</div>');
Y.one('body').prepend(foo);
foo.focus();
try {
document.execCommand('insertText', false, 'b');
if (foo.getHTML() === 'ba') {
document.execCommand('undo', false);
if (foo.getHTML() === 'a') {
document.execCommand('redo', false);
if (foo.getHTML() === 'ba') {
undosupport = true;
}
}
}
} catch (undosupportexception) {
// IE9 gives us an invalid parameter error on document.execCommand('insertText'...).
// The try/catch catches when the execCommands fail.
return false;
}
// Remove the tmp contenteditable and reset the focussed element.
Y.one('body').removeChild(foo);
activeelement.focus();
return undosupport;
},
/**
* Add the buttons to the toolbar
*
* @method init
* @param {object} params containing elementid and group
*/
init : function(params) {
// Retrieve undobrowsersupport global variable.
if (M.atto_undo.browsersupportsundo === null) {
M.atto_undo.browsersupportsundo = M.atto_undo.test_undo_support();
}
// Add the undo/redo buttons.
if (M.atto_undo.browsersupportsundo) {
// Undo button.
var iconurl = M.util.image_url('e/undo', 'core');
M.editor_atto.add_toolbar_button(params.elementid, 'undo', iconurl, params.group, M.atto_undo.undo_handler, 'undo', M.util.get_string('undo', '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'));
}
}
};
}, '@VERSION@', {"requires": ["node"]});

@ -0,0 +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"]});

@ -0,0 +1,146 @@
YUI.add('moodle-atto_undo-button', 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/>.
/**
* Atto text editor undo plugin.
*
* @package editor-undo
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
M.atto_undo = M.atto_undo || {
/**
* Property used to cache the result of testing the undo/redo browser support.
*
* @property browsersupportsundo
* @type {Boolean} or null
* @default null
*/
browsersupportsundo : null,
/**
* Handle a click on either button (passed via cmd)
*
* @method click_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
* @param {String} The button clicked (undo or redo)
*/
click_handler : function(e, elementid, cmd) {
e.preventDefault();
if (!M.editor_atto.is_active(elementid)) {
M.editor_atto.focus(elementid);
}
document.execCommand(cmd, false, null);
// Clean the YUI ids from the HTML.
M.editor_atto.text_updated(elementid);
},
/**
* Handle a click on undo
*
* @method undo_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
*/
undo_handler : function(e, elementid) {
M.atto_undo.click_handler(e, elementid, 'undo');
},
/**
* Handle a click on redo
*
* @method redo_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
*/
redo_handler : function(e, elementid) {
M.atto_undo.click_handler(e, elementid, 'redo');
},
/**
* Do a feature test to see if undo/redo is buggy in this browser.
*
* @method test_undo_support
* @return {Boolean} true if undo/redo is functional.
*/
test_undo_support : function() {
// Check now if other browser supports it.
// Save the focussed element.
var activeelement = document.activeElement;
// Creating a temp div to test if the browser support the undo execCommand.
var undosupport = false;
var foo = Y.Node.create('<div id="attoundotesting" contenteditable="true"' +
'style="position: fixed; top: 0px; height:0px">a</div>');
Y.one('body').prepend(foo);
foo.focus();
try {
document.execCommand('insertText', false, 'b');
if (foo.getHTML() === 'ba') {
document.execCommand('undo', false);
if (foo.getHTML() === 'a') {
document.execCommand('redo', false);
if (foo.getHTML() === 'ba') {
undosupport = true;
}
}
}
} catch (undosupportexception) {
// IE9 gives us an invalid parameter error on document.execCommand('insertText'...).
// The try/catch catches when the execCommands fail.
return false;
}
// Remove the tmp contenteditable and reset the focussed element.
Y.one('body').removeChild(foo);
activeelement.focus();
return undosupport;
},
/**
* Add the buttons to the toolbar
*
* @method init
* @param {object} params containing elementid and group
*/
init : function(params) {
// Retrieve undobrowsersupport global variable.
if (M.atto_undo.browsersupportsundo === null) {
M.atto_undo.browsersupportsundo = M.atto_undo.test_undo_support();
}
// Add the undo/redo buttons.
if (M.atto_undo.browsersupportsundo) {
// Undo button.
var iconurl = M.util.image_url('e/undo', 'core');
M.editor_atto.add_toolbar_button(params.elementid, 'undo', iconurl, params.group, M.atto_undo.undo_handler, 'undo', M.util.get_string('undo', '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'));
}
}
};
}, '@VERSION@', {"requires": ["node"]});

@ -0,0 +1,10 @@
{
"name": "moodle-atto_undo-button",
"builds": {
"moodle-atto_undo-button": {
"jsfiles": [
"button.js"
]
}
}
}

@ -0,0 +1,141 @@
// 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/>.
/**
* Atto text editor undo plugin.
*
* @package editor-undo
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
M.atto_undo = M.atto_undo || {
/**
* Property used to cache the result of testing the undo/redo browser support.
*
* @property browsersupportsundo
* @type {Boolean} or null
* @default null
*/
browsersupportsundo : null,
/**
* Handle a click on either button (passed via cmd)
*
* @method click_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
* @param {String} The button clicked (undo or redo)
*/
click_handler : function(e, elementid, cmd) {
e.preventDefault();
if (!M.editor_atto.is_active(elementid)) {
M.editor_atto.focus(elementid);
}
document.execCommand(cmd, false, null);
// Clean the YUI ids from the HTML.
M.editor_atto.text_updated(elementid);
},
/**
* Handle a click on undo
*
* @method undo_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
*/
undo_handler : function(e, elementid) {
M.atto_undo.click_handler(e, elementid, 'undo');
},
/**
* Handle a click on redo
*
* @method redo_handler
* @param {Y.Event} The click event
* @param {String} The id for the editor
*/
redo_handler : function(e, elementid) {
M.atto_undo.click_handler(e, elementid, 'redo');
},
/**
* Do a feature test to see if undo/redo is buggy in this browser.
*
* @method test_undo_support
* @return {Boolean} true if undo/redo is functional.
*/
test_undo_support : function() {
// Check now if other browser supports it.
// Save the focussed element.
var activeelement = document.activeElement;
// Creating a temp div to test if the browser support the undo execCommand.
var undosupport = false;
var foo = Y.Node.create('<div id="attoundotesting" contenteditable="true"' +
'style="position: fixed; top: 0px; height:0px">a</div>');
Y.one('body').prepend(foo);
foo.focus();
try {
document.execCommand('insertText', false, 'b');
if (foo.getHTML() === 'ba') {
document.execCommand('undo', false);
if (foo.getHTML() === 'a') {
document.execCommand('redo', false);
if (foo.getHTML() === 'ba') {
undosupport = true;
}
}
}
} catch (undosupportexception) {
// IE9 gives us an invalid parameter error on document.execCommand('insertText'...).
// The try/catch catches when the execCommands fail.
return false;
}
// Remove the tmp contenteditable and reset the focussed element.
Y.one('body').removeChild(foo);
activeelement.focus();
return undosupport;
},
/**
* Add the buttons to the toolbar
*
* @method init
* @param {object} params containing elementid and group
*/
init : function(params) {
// Retrieve undobrowsersupport global variable.
if (M.atto_undo.browsersupportsundo === null) {
M.atto_undo.browsersupportsundo = M.atto_undo.test_undo_support();
}
// Add the undo/redo buttons.
if (M.atto_undo.browsersupportsundo) {
// Undo button.
var iconurl = M.util.image_url('e/undo', 'core');
M.editor_atto.add_toolbar_button(params.elementid, 'undo', iconurl, params.group, M.atto_undo.undo_handler, 'undo', M.util.get_string('undo', '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'));
}
}
};

@ -0,0 +1,5 @@
{
"moodle-atto_undo-button": {
"requires": ["node"]
}
}

23
lib/editor/atto/settings.php Normal file → Executable file

@ -30,17 +30,18 @@ $settings = new admin_settingpage('editorsettingsatto', new lang_string('setting
if ($ADMIN->fulltree) {
$name = new lang_string('toolbarconfig', 'editor_atto');
$desc = new lang_string('toolbarconfig_desc', 'editor_atto');
$default = 'collapse = collapse' . "\n" .
'style1 = title, bold, italic' . "\n" .
'list = unorderedlist, orderedlist' . "\n" .
'links = link, unlink' . "\n" .
'files = image, media, managefiles' . "\n" .
'style2 = underline, strike, subscript, superscript' . "\n" .
'align = align' . "\n" .
'indent = indent, outdent' . "\n" .
'insert = equation, charmap, table, clear' . "\n" .
'accessibility = accessibilitychecker, accessibilityhelper' . "\n" .
'other = html';
$default = 'collapse = collapse
style1 = title, bold, italic
list = unorderedlist, orderedlist
links = link, unlink
files = image, media, managefiles
style2 = underline, strike, subscript, superscript
align = align
indent = indent, outdent
insert = equation, charmap, table, clear
undo = undo
accessibility = accessibilitychecker, accessibilityhelper
other = html';
$setting = new admin_setting_configtextarea('editor_atto/toolbar',
$name,
$desc,