Skip to content

Commit

Permalink
MDL-43863 Add Undo/Redo plugins to Atto
Browse files Browse the repository at this point in the history
  • Loading branch information
mouneyrac authored and Damyon Wiese committed Mar 26, 2014
1 parent f6bef14 commit 99061b7
Show file tree
Hide file tree
Showing 10 changed files with 561 additions and 11 deletions.
27 changes: 27 additions & 0 deletions lib/editor/atto/plugins/undo/lang/en/atto_undo.php
Original file line number Diff line number Diff line change
@@ -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';
44 changes: 44 additions & 0 deletions lib/editor/atto/plugins/undo/lib.php
Original file line number Diff line number Diff line change
@@ -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'
);
}
29 changes: 29 additions & 0 deletions lib/editor/atto/plugins/undo/version.php
Original file line number Diff line number Diff line change
@@ -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).
Original file line number Diff line number Diff line change
@@ -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"]});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -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"]});
Loading

0 comments on commit 99061b7

Please sign in to comment.