Merge branch 'MDL-44084-master' of git://github.com/damyon/moodle

This commit is contained in:
Marina Glancy
2014-03-26 10:02:06 +08:00
533 changed files with 43780 additions and 187 deletions
@@ -45,7 +45,7 @@ Feature: Publish rubrics as templates
@javascript
Scenario: Create a rubric template and reuse it as a teacher, with Javascript enabled
Then the field "Description" matches value "<p>Assignment 1 description</p>"
Then the field "Description" matches value "Assignment 1 description"
And I should see "Criterion 1"
And I press "Cancel"
+3 -59
View File
@@ -577,70 +577,14 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
/**
* Ensures that all the page's editors are loaded.
*
* This method is expensive as it waits for .mceEditor CSS
* so use with caution and only where there will be editors.
*
* @deprecated since Moodle 2.7 MDL-44084 - please do not use this function any more.
* @throws ElementNotFoundException
* @throws ExpectationException
* @return void
*/
protected function ensure_editors_are_loaded() {
if (!$this->running_javascript()) {
return;
}
// If there are no editors we don't need to wait.
try {
$this->find('css', '.mceEditor', false, false, self::REDUCED_TIMEOUT);
} catch (ElementNotFoundException $e) {
return;
}
// Exception if it timesout and the element is not appearing.
$msg = 'The editors are not completely loaded';
$exception = new ExpectationException($msg, $this->getSession());
// Here we know that there are .mceEditor editors in the page and we will
// probably need to interact with them, if we use tinyMCE JS var before
// it exists it will throw an exception and we want to catch it until all
// the page's editors are ready to interact with them.
$this->spin(
function($context) {
// It may return 0 if tinyMCE is loaded but not the instances, so we just loop again.
$neditors = $context->getSession()->evaluateScript('return tinyMCE.editors.length;');
if ($neditors == 0) {
return false;
}
// It may be there but not ready.
$iframeready = $context->getSession()->evaluateScript('
var readyeditors = new Array;
for (editorid in tinyMCE.editors) {
if (tinyMCE.editors[editorid].getDoc().readyState === "complete") {
readyeditors[editorid] = editorid;
}
}
if (tinyMCE.editors.length === readyeditors.length) {
return "complete";
}
return "";
');
// Now we know that the editors are there.
if ($iframeready) {
return true;
}
// Loop again if it is not ready.
return false;
},
false,
self::EXTENDED_TIMEOUT,
$exception,
true
);
debugging('Function behat_base::ensure_editors_are_loaded() is deprecated. It is no longer required.');
return;
}
}
+14 -110
View File
@@ -48,118 +48,22 @@ class behat_form_editor extends behat_form_textarea {
*/
public function set_value($value) {
$lastexception = null;
// We want the editor to be ready, otherwise the value can not
// be set and an exception is thrown.
for ($i = 0; $i < behat_base::EXTENDED_TIMEOUT; $i++) {
try {
// Get tinyMCE editor id if it exists.
if ($editorid = $this->get_editor_id()) {
// Set the value to the iframe and save it to the textarea.
$value = str_replace('"', '\"', $value);
$this->session->executeScript('
tinyMCE.get("'.$editorid.'").setContent("' . $value . '");
tinyMCE.get("'.$editorid.'").save();
');
} else {
// Set the value to a textarea otherwise.
parent::set_value($value);
}
return;
} catch (Exception $e) {
// Catching any kind of exception and ignoring it until times out.
$lastexception = $e;
// Waiting 0.1 seconds.
usleep(100000);
}
$editorid = $this->field->getAttribute('id');
if ($this->running_javascript()) {
$value = addslashes($value);
$js = '
var editor = M.editor_atto.get_editable_node("'.$editorid.'");
if (editor) {
editor.setHTML("' . $value . '").focus();
} else {
editor = Y.one(document.getElementById("'.$editorid.'"));
editor.set("value", "' . $value . '");
}';
$result = $this->session->executeScript($js);
} else {
parent::set_value($value);
}
// If it is not available we throw the last exception.
throw $lastexception;
}
/**
* Returns the field value.
*
* @return string
*/
public function get_value() {
// Can be be a string value or an exception depending whether the editor loads or not.
$lastoutcome = '';
// We want the editor to be ready to return the correct value, sometimes the
// page loads too fast and the returned value may be '' if the editor didn't
// have enough time to load completely despite having a different value.
for ($i = 0; $i < behat_base::EXTENDED_TIMEOUT; $i++) {
try {
// Get tinyMCE editor id if it exists.
if ($editorid = $this->get_editor_id()) {
// Save the current iframe value in case default value has been edited.
$this->session->executeScript('tinyMCE.get("'.$editorid.'").save();');
}
$lastoutcome = $this->field->getValue();
// We only want to wait until it times out if the value is empty.
if ($lastoutcome != '') {
return $lastoutcome;
}
} catch (Exception $e) {
// Catching any kind of exception and ignoring it until times out.
$lastoutcome = $e;
// Waiting 0.1 seconds.
usleep(100000);
}
}
// If it is not available we throw the last exception.
if (is_a($lastoutcome, 'Exception')) {
throw $lastoutcome;
}
// Return the value if there are no exceptions it will be '' at this point
return $lastoutcome;
}
/**
* Returns the tinyMCE editor id or false if it is not available.
*
* The editor availability depends on the driver running the tests; Goutte
* can not execute Javascript, also some Moodle settings disables the HTML
* editor.
*
* @return mixed The id of the editor of false if it is not available
*/
protected function get_editor_id() {
// Non-JS drivers throws exceptions when running JS.
try {
$available = $this->session->evaluateScript('return (typeof tinyMCE != "undefined")');
// Also checking that it exists a tinyMCE editor for the requested field.
$editorid = $this->field->getAttribute('id');
$available = $this->session->evaluateScript('return (typeof tinyMCE.get("'.$editorid.'") != "undefined")');
} catch (Exception $e) {
return false;
}
// No available if JS drivers returned false.
if ($available == false) {
return false;
}
return $editorid;
}
}
+2 -1
View File
@@ -63,7 +63,8 @@ class behat_form_text extends behat_form_field {
* @return bool The provided value matches the field value?
*/
public function matches($expectedvalue) {
return $this->text_matches($expectedvalue);
// A text editor may silently wrap the content in p tags (or not). Neither is an error.
return $this->text_matches($expectedvalue) || $this->text_matches('<p>' . $expectedvalue . '</p>');
}
}
+10 -1
View File
@@ -930,6 +930,15 @@ class core_plugin_manager {
$standard_plugins = array(
'atto' => array(
'accessibilitychecker', 'accessibilityhelper', 'align',
'backcolor', 'bold', 'charmap', 'clear', 'collapse', 'emoticon',
'equation', 'fontcolor', 'html', 'image', 'indent', 'italic',
'link', 'managefiles', 'media', 'noautolink', 'orderedlist',
'rtl', 'strike', 'subscript', 'superscript', 'table', 'title',
'underline', 'undo', 'unlink', 'unorderedlist'
),
'assignment' => array(
'offline', 'online', 'upload', 'uploadsingle'
),
@@ -992,7 +1001,7 @@ class core_plugin_manager {
),
'editor' => array(
'textarea', 'tinymce'
'atto', 'textarea', 'tinymce'
),
'enrol' => array(
+1 -1
View File
@@ -40,7 +40,7 @@ class editor extends base {
global $CFG;
if (empty($CFG->texteditors)) {
return array('tinymce'=>'tinymce', 'textarea'=>'textarea');
return array('atto'=>'atto', 'tinymce'=>'tinymce', 'textarea'=>'textarea');
}
$enabled = array();
+1 -1
View File
@@ -129,7 +129,7 @@ function xmldb_main_install() {
'sessiontimeout' => 7200, // must be present during roles installation
'stringfilters' => '', // These two are managed in a strange way by the filters
'filterall' => 0, // setting page, so have to be initialised here.
'texteditors' => 'tinymce,textarea',
'texteditors' => 'atto,tinymce,textarea',
);
foreach($defaults as $key => $value) {
set_config($key, $value);
+234
View File
@@ -0,0 +1,234 @@
<?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 admin setting stuff.
*
* @package editor_atto
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Special class for Atto plugins administration.
*
* @package editor_atto
* @copyright 2014 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class atto_subplugins_settings extends admin_setting {
/**
* Constructor.
*/
public function __construct() {
$this->nosave = true;
parent::__construct('attosubplugins', get_string('subplugintype_atto_plural', 'editor_atto'), '', '');
}
/**
* Returns current value of this setting.
* Always returns true, does nothing.
*
* @return true
*/
public function get_setting() {
return true;
}
/**
* Returns default setting if exists.
* Always returns true, does nothing.
*
* @return true
*/
public function get_defaultsetting() {
return true;
}
/**
* Store new setting.
* Always returns '', does not write anything.
*
* @param string $data string or array, must not be NULL.
* @return string Always returns ''.
*/
public function write_setting($data) {
// Do not write any setting.
return '';
}
/**
* Checks if $query is one of the available subplugins.
*
* @param string $query The string to search for.
* @return bool Returns true if found, false if not.
*/
public function is_related($query) {
if (parent::is_related($query)) {
return true;
}
$subplugins = core_component::get_plugin_list('atto');
foreach ($subplugins as $name => $dir) {
if (stripos($name, $query) !== false) {
return true;
}
$namestr = get_string('pluginname', 'atto_' . $name);
if (strpos(core_text::strtolower($namestr), core_text::strtolower($query)) !== false) {
return true;
}
}
return false;
}
/**
* Builds the XHTML to display the control.
*
* @param mixed $data Unused.
* @param string $query
* @return string highlight.
*/
public function output_html($data, $query = '') {
global $CFG, $OUTPUT, $PAGE;
require_once($CFG->libdir . "/editorlib.php");
require_once(__DIR__ . '/lib.php');
$pluginmanager = core_plugin_manager::instance();
// Display strings.
$strtoolbarconfig = get_string('toolbarconfig', 'editor_atto');
$strname = get_string('name');
$strsettings = get_string('settings');
$struninstall = get_string('uninstallplugin', 'core_admin');
$strversion = get_string('version');
$subplugins = core_component::get_plugin_list('atto');
$return = $OUTPUT->heading(get_string('subplugintype_atto_plural', 'editor_atto'), 3, 'main', true);
$return .= $OUTPUT->box_start('generalbox attosubplugins');
$table = new html_table();
$table->head = array($strname, $strversion, $strtoolbarconfig, $strsettings, $struninstall);
$table->align = array('left', 'left', 'center', 'center', 'center', 'center');
$table->data = array();
$table->attributes['class'] = 'admintable generaltable';
$corepluginicons = array(
'accessibilitychecker' => $OUTPUT->pix_url('e/visual_blocks', 'core'),
'accessibilityhelper' => $OUTPUT->pix_url('e/visual_aid'),
'align' => array(
$OUTPUT->pix_url('e/align_left', 'core'),
$OUTPUT->pix_url('e/align_center', 'core'), $OUTPUT->pix_url('e/align_right', 'core')
),
'backcolor' => $OUTPUT->pix_url('e/text_highlight', 'core'),
'bold' => $OUTPUT->pix_url('e/bold', 'core'),
'charmap' => $OUTPUT->pix_url('e/special_character', 'core'),
'clear' => $OUTPUT->pix_url('e/clear_formatting', 'core'),
'emoticon' => $OUTPUT->pix_url('e/emoticons', 'core'),
'equation' => $OUTPUT->pix_url('e/math', 'core'),
'fontcolor' => $OUTPUT->pix_url('e/text_color', 'core'),
'html' => $OUTPUT->pix_url('e/source_code', 'core'),
'image' => $OUTPUT->pix_url('e/insert_edit_image', 'core'),
'indent' => array(
$OUTPUT->pix_url('e/increase_indent', 'core'),
$OUTPUT->pix_url('e/decrease_indent', 'core'),
),
'italic' => $OUTPUT->pix_url('e/italic', 'core'),
'link' => $OUTPUT->pix_url('e/insert_edit_link', 'core'),
'managefiles' => $OUTPUT->pix_url('e/manage_files', 'core'),
'media' => $OUTPUT->pix_url('e/insert_edit_video', 'core'),
'orderedlist' => $OUTPUT->pix_url('e/numbered_list', 'core'),
'rtl' => array($OUTPUT->pix_url('e/left_to_right', 'core'),
$OUTPUT->pix_url('e/right_to_left', 'core')),
'strike' => $OUTPUT->pix_url('e/strikethrough', 'core'),
'subscript' => $OUTPUT->pix_url('e/subscript', 'core'),
'superscript' => $OUTPUT->pix_url('e/superscript', 'core'),
'table' => $OUTPUT->pix_url('e/table', 'core'),
'title' => $OUTPUT->pix_url('e/styleprops', 'core'),
'underline' => $OUTPUT->pix_url('e/underline', 'core'),
'undo' => array($OUTPUT->pix_url('e/undo', 'core'), $OUTPUT->pix_url('e/redo', 'core')),
'unlink' => $OUTPUT->pix_url('e/remove_link', 'core'),
'unorderedlist' => $OUTPUT->pix_url('e/bullet_list', 'core')
);
// Iterate through subplugins.
foreach ($subplugins as $name => $dir) {
$namestr = get_string('pluginname', 'atto_' . $name);
$version = get_config('atto_' . $name, 'version');
if ($version === false) {
$version = '';
}
$plugininfo = $pluginmanager->get_plugin_info('atto_' . $name);
$toolbarconfig = $name;
$displayname = $namestr;
// Check if there is a pix folder in the atto plugin.
if ($PAGE->theme->resolve_image_location('icon', 'atto_' . $name, false)) {
$icon = $OUTPUT->pix_icon('icon', '', 'atto_' . $name, array('class' => 'icon pluginicon'));
} else {
// Attempt to find out the icons for core atto plugins.
if (array_key_exists($name, $corepluginicons)) {
// It's a core plugin.
$icons = array();
if (!is_array($corepluginicons[$name])) {
$icons[] = $corepluginicons[$name];
} else {
$icons = $corepluginicons[$name];
}
$icon = '';
foreach ($icons as $anicon) {
$icon .= html_writer::empty_tag('img', array('src' => $anicon,
"class" => "pluginicon", "alt" => $displayname));
}
} else {
// No icon found.
$icon = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'icon pluginicon noicon'));
}
}
$displayname = $icon . ' ' . $displayname;
// Add settings link.
if (!$version) {
$settings = '';
} else if ($url = $plugininfo->get_settings_url()) {
$settings = html_writer::link($url, $strsettings);
} else {
$settings = '';
}
// Add uninstall info.
$uninstall = '';
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('atto_' . $name, 'manage')) {
$uninstall = html_writer::link($uninstallurl, $struninstall);
}
// Add a row to the table.
$row = new html_table_row(array($displayname, $version, $toolbarconfig, $settings, $uninstall));
$table->data[] = $row;
}
$return .= html_writer::table($table);
$return .= html_writer::tag('p', get_string('tablenosave', 'admin'));
$return .= $OUTPUT->box_end();
return highlight($query, $return);
}
}
@@ -0,0 +1,86 @@
<?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/>.
/**
* Subplugin info class.
*
* @package editor_atto
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace editor_atto\plugininfo;
use core\plugininfo\base;
defined('MOODLE_INTERNAL') || die();
class atto extends base {
/**
* Yes you can uninstall these plugins if you want.
* @return \moodle_url
*/
public function is_uninstall_allowed() {
return true;
}
/**
* Return URL used for management of plugins of this type.
* @return \moodle_url
*/
public static function get_manage_url() {
return new \moodle_url('/admin/settings.php', array('section'=>'editorsettingsatto'));
}
/**
* Include the settings.php file from sub plugins if they provide it.
* This is a copy of very similar implementations from various other subplugin areas.
*
* @return \moodle_url
*/
public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
$ADMIN = $adminroot; // May be used in settings.php.
$plugininfo = $this; // Also can be used inside settings.php.
if (!$this->is_installed_and_upgraded()) {
return;
}
if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) {
return;
}
$section = $this->get_settings_section_name();
$settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
include($this->full_path('settings.php')); // This may also set $settings to null.
if ($settings) {
$ADMIN->add($parentnodename, $settings);
}
}
/**
* Get the settings section name.
* It's used to get the setting links in the Atto sub-plugins table.
*
* @return null|string the settings section name.
*/
public function get_settings_section_name() {
return 'atto' . $this->name . 'settings';
}
}
+27
View File
@@ -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/>.
/**
* Yui Editor
*
* @package editor_atto
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$subplugins = array('atto' => 'lib/editor/atto/plugins');
+30
View File
@@ -0,0 +1,30 @@
<?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 'editor_atto', language 'en'.
*
* @package editor_atto
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Atto HTML editor';
$string['subplugintype_atto'] = 'Atto plugin';
$string['subplugintype_atto_plural'] = 'Atto plugins';
$string['settings'] = 'Atto toolbar settings';
$string['toolbarconfig'] = 'Toolbar config';
$string['toolbarconfig_desc'] = 'The list of plugins and the order they are displayed can be configured here. The configuration consists of groups (one per line) followed by the ordered list of plugins for that group. The group is separated from the plugins with an equals sign and the plugins are separated with commas. The group must be one of the following: style, paragraph, links, insert, other.';
+160
View File
@@ -0,0 +1,160 @@
<?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/>.
/**
* YUI text editor integration.
*
* @package editor_atto
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* This is the texteditor implementation.
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class atto_texteditor extends texteditor {
/**
* Is the current browser supported by this editor?
*
* Of course!
* @return bool
*/
public function supported_by_browser() {
return true;
}
/**
* Returns array of supported text formats.
* @return array
*/
public function get_supported_formats() {
// FORMAT_MOODLE is not supported here, sorry.
return array(FORMAT_HTML => FORMAT_HTML);
}
/**
* Returns text format preferred by this editor.
* @return int
*/
public function get_preferred_format() {
return FORMAT_HTML;
}
/**
* Does this editor support picking from repositories?
* @return bool
*/
public function supports_repositories() {
return true;
}
/**
* Use this editor for given element.
*
* @param string $elementid
* @param array $options
* @param null $fpoptions
*/
public function use_editor($elementid, array $options=null, $fpoptions=null) {
global $PAGE;
$configstr = get_config('editor_atto', 'toolbar');
$grouplines = explode("\n", $configstr);
$groups = array();
foreach ($grouplines as $groupline) {
$line = explode('=', $groupline);
if (count($line) > 1) {
$group = trim(array_shift($line));
$plugins = array_map('trim', explode(',', array_shift($line)));
$groups[$group] = $plugins;
}
}
$modules = array('moodle-editor_atto-editor');
$options['context'] = empty($options['context']) ? context_system::instance() : $options['context'];
$jsplugins = array();
foreach ($groups as $group => $plugins) {
$groupplugins = array();
foreach ($plugins as $plugin) {
// Do not die on missing plugin.
if (!core_component::get_component_directory('atto_' . $plugin)) {
debugging('Missing atto plugin ' . $plugin, DEBUG_DEVELOPER);
continue;
}
$jsplugin = array();
$jsplugin['name'] = $plugin;
$jsplugin['params'] = array();
$modules[] = 'moodle-atto_' . $plugin . '-button';
component_callback('atto_' . $plugin, 'strings_for_js');
$extra = component_callback('atto_' . $plugin, 'params_for_js', array($elementid, $options, $fpoptions));
if ($extra) {
$jsplugin = array_merge($jsplugin, $extra);
}
// We always need the plugin name.
$PAGE->requires->string_for_js('pluginname', 'atto_' . $plugin);
$groupplugins[] = $jsplugin;
}
$jsplugins[] = array('group'=>$group, 'plugins'=>$groupplugins);
}
$PAGE->requires->yui_module($modules,
'Y.M.editor_atto.Editor.init',
array($this->get_init_params($elementid, $options, $fpoptions, $jsplugins)));
}
/**
* Create a params array to init the editor.
*
* @param string $elementid
* @param array $options
* @param array $fpoptions
*/
protected function get_init_params($elementid, array $options = null, array $fpoptions = null, $plugins = null) {
global $PAGE;
$directionality = get_string('thisdirection', 'langconfig');
$strtime = get_string('strftimetime');
$strdate = get_string('strftimedaydate');
$lang = current_language();
$contentcss = $PAGE->theme->editor_css_url()->out(false);
$params = array(
'elementid' => $elementid,
'content_css' => $contentcss,
'language' => $lang,
'directionality' => $directionality,
'filepickeroptions' => array(),
'plugins' => $plugins
);
if ($fpoptions) {
$params['filepickeroptions'] = $fpoptions;
}
return $params;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

+91
View File
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="New document 1">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="155.41976"
inkscape:cy="37.330502"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1004"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid2993"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="4px"
spacingy="4px" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-924.36218)">
<rect
style="fill:#000000;fill-opacity:1;stroke:none"
id="rect2991"
width="96"
height="96"
x="16"
y="16"
transform="translate(0,924.36218)"
ry="16" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:FreeSans;-inkscape-font-specification:FreeSans"
x="20"
y="1008.3622"
id="text2985"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan2987"
x="20"
y="1008.3622"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:FreeSans;-inkscape-font-specification:FreeSans"><tspan
style="font-size:40px"
id="tspan3763">10</tspan><tspan
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;baseline-shift:super;fill:#ffffff;fill-opacity:1;font-family:FreeSans;-inkscape-font-specification:FreeSans"
id="tspan2989">-18</tspan></tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -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/>.
/**
* Strings for component 'atto_accessibilitychecker', language 'en'.
*
* @package atto_accessibilitychecker
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Accessibility checker';
$string['nowarnings'] = 'Congratulations, no accessibility problems found!';
$string['report'] = 'Accessibility report:';
$string['imagesmissingalt'] = 'Images require alternative text. To fix this warning, add an alt attribute to your img tags. An empty alt attribute may be used, but only when the image is purely decorative and carries no information.';
$string['needsmorecontrast'] = 'The colors of the foreground and background text do not have enough contrast. To fix this warning, change either foreground or background color of the text so that it is easier to read.';
@@ -0,0 +1,40 @@
<?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_accessibilitychecker
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Initialise this plugin
* @param string $elementid
*/
function atto_accessibilitychecker_strings_for_js() {
global $PAGE;
$PAGE->requires->strings_for_js(array('nowarnings',
'report',
'imagesmissingalt',
'needsmorecontrast'),
'atto_accessibilitychecker');
}
@@ -0,0 +1,4 @@
.accessibilitywarnings img {
max-width: 32px;
max-height: 32px;
}
@@ -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_accessibilitychecker
* @copyright 2014 Damyon Wiese <[email protected]>
* @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_accessibilitychecker'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,266 @@
YUI.add('moodle-atto_accessibilitychecker-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/>.
/*
* @package atto_accessibilitychecker
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_accessibilitychecker-button
*/
/**
* Accessibility Checking tool for the Atto editor.
*
* @namespace M.atto_accessibilitychecker
* @class Button
* @extends M.editor_atto.EditorPlugin
*/
var COMPONENT = 'atto_accessibilitychecker';
Y.namespace('M.atto_accessibilitychecker').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* The warnings which are displayed.
*
* @property _displayedWarnings
* @type Object
* @private
*/
_displayedWarnings: {},
initializer: function() {
this.addButton({
icon: 'e/accessibility_checker',
callback: this._displayDialogue
});
},
/**
* Display the Accessibility Checker tool.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENT),
width: '800px',
focusAfterHide: true
});
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var content = Y.Node.create('<div style="word-wrap: break-word;"></div>');
content.append(this._getWarnings());
// Add ability to select problem areas in the editor.
content.delegate('click', function(e) {
e.preventDefault();
var host = this.get('host'),
index = e.target.getAttribute("data-index"),
node = this._displayedWarnings[index],
dialogue = this.getDialogue();
if (node) {
// Clear the dialogue's focusAfterHide to ensure we focus
// on the selection.
dialogue.set('focusAfterHide', null);
// Hide the dialogue.
dialogue.hide();
// Then set the selection.
host.setSelection(host.getSelectionFromNode(node));
} else {
// Hide the dialogue.
dialogue.hide();
}
}, 'a', this);
return content;
},
/**
* Find all problems with the content editable region.
*
* @method _getWarnings
* @return {Node} A complete list of all warnings and problems.
* @private
*/
_getWarnings: function() {
var problemNodes,
list = Y.Node.create('<div></div>');
// Images with no alt text or dodgy alt text.
problemNodes = [];
this.editor.all('img').each(function (img) {
alt = img.getAttribute('alt');
if (typeof alt === 'undefined' || alt === '') {
if (img.getAttribute('role') !== 'presentation') {
problemNodes.push(img);
}
}
}, this);
this._addWarnings(list, M.util.get_string('imagesmissingalt', COMPONENT), problemNodes, true);
problemNodes = [];
this.editor.all('*').each(function (node) {
var foreground,
background,
ratio,
lum1,
lum2;
// Check for non-empty text.
if (Y.Lang.trim(node.get('text')) !== '') {
foreground = node.getComputedStyle('color');
background = node.getComputedStyle('backgroundColor');
lum1 = this._getLuminanceFromCssColor(foreground);
lum2 = this._getLuminanceFromCssColor(background);
// Algorithm from "http://www.w3.org/TR/WCAG20-GENERAL/G18.html".
if (lum1 > lum2) {
ratio = (lum1 + 0.05) / (lum2 + 0.05);
} else {
ratio = (lum2 + 0.05) / (lum1 + 0.05);
}
if (ratio <= 4.5) {
Y.log('Contrast ratio is too low: ' + ratio +
' Colour 1: ' + foreground +
' Colour 2: ' + background +
' Luminance 1: ' + lum1 +
' Luminance 2: ' + lum2);
// We only want the highest node with dodgy contrast reported.
var i = 0, found = false;
for (i = 0; i < problemNodes.length; i++) {
if (node.ancestors('*').indexOf(problemNodes[i]) !== -1) {
// Do not add node - it already has a parent in the list.
found = true;
break;
} else if (problemNodes[i].ancestors('*').indexOf(node) !== -1) {
// Replace the existing node with this one because it is higher up the DOM.
problemNodes[i] = node;
found = true;
break;
}
}
if (!found) {
problemNodes.push(node);
}
}
}
}, this);
this._addWarnings(list, M.util.get_string('needsmorecontrast', COMPONENT), problemNodes, false);
if (!list.hasChildNodes()) {
list.append('<p>' + M.util.get_string('nowarnings', COMPONENT) + '</p>');
}
// Append the list of current styles.
return list;
},
/**
* Generate the HTML that lists the found warnings.
*
* @method _addWarnings
* @param {Node} A Node to append the html to.
* @param {String} description Description of this failure.
* @param {array} nodes An array of failing nodes.
* @param {boolean} imagewarnings true if the warnings are related to images, false if text.
*/
_addWarnings: function(list, description, nodes, imagewarnings) {
var warning, fails, i, key, src, textfield;
if (nodes.length > 0) {
warning = Y.Node.create('<p>' + description + '</p>');
fails = Y.Node.create('<ol class="accessibilitywarnings"></ol>');
i = 0;
for (i = 0; i < nodes.length; i++) {
if (imagewarnings) {
key = 'image_'+i;
src = nodes[i].getAttribute('src');
fails.append(Y.Node.create('<li><a data-index="'+key+'" href="#"><img data-index="'+key+'" src="' + src + '" /> '+src+'</a></li>'));
} else {
key = 'text_' + i;
textfield = ('innerText' in nodes[i])? 'innerText' : 'textContent';
fails.append(Y.Node.create('<li><a href="#" data-index="'+key+'">' + nodes[i].get(textfield) + '</a></li>'));
}
this._displayedWarnings[key] = nodes[i];
}
warning.append(fails);
list.append(warning);
}
},
/**
* Convert a CSS color to a luminance value.
*
* @method _getLuminanceFromCssColor
* @param {String} colortext The Hex value for the colour
* @return {Number} The luminance value.
* @private
*/
_getLuminanceFromCssColor: function(colortext) {
var color;
if (colortext === 'transparent') {
colortext = '#ffffff';
}
color = Y.Color.toArray(Y.Color.toRGB(colortext));
// Algorithm from "http://www.w3.org/TR/WCAG20-GENERAL/G18.html".
var part1 = function(a) {
a = parseInt(a, 10) / 255.0;
if (a <= 0.03928) {
a = a/12.92;
} else {
a = Math.pow(((a + 0.055)/1.055), 2.4);
}
return a;
};
var r1 = part1(color[0]),
g1 = part1(color[1]),
b1 = part1(color[2]);
return 0.2126 * r1 + 0.7152 * g1 + 0.0722 * b1;
}
});
}, '@VERSION@', {"requires": ["color-base", "moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_accessibilitychecker-button",function(e,t){var n="atto_accessibilitychecker";e.namespace("M.atto_accessibilitychecker").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_displayedWarnings:{},initializer:function(){this.addButton({icon:"e/accessibility_checker",callback:this._displayDialogue})},_displayDialogue:function(){var e=this.getDialogue({headerContent:M.util.get_string("pluginname",n),width:"800px",focusAfterHide:!0});e.set("bodyContent",this._getDialogueContent()).show()},_getDialogueContent:function(){var t=e.Node.create('<div style="word-wrap: break-word;"></div>');return t.append(this._getWarnings()),t.delegate("click",function(e){e.preventDefault();var t=this.get("host"),n=e.target.getAttribute("data-index"),r=this._displayedWarnings[n],i=this.getDialogue();r?(i.set("focusAfterHide",null),i.hide(),t.setSelection(t.getSelectionFromNode(r))):i.hide()},"a",this),t},_getWarnings:function(){var t,r=e.Node.create("<div></div>");return t=[],this.editor.all("img").each(function(e){alt=e.getAttribute("alt"),(typeof alt=="undefined"||alt==="")&&e.getAttribute("role")!=="presentation"&&t.push(e)},this),this._addWarnings(r,M.util.get_string("imagesmissingalt",n),t,!0),t=[],this.editor.all("*").each(function(n){var r,i,s,o,u;if(e.Lang.trim(n.get("text"))!==""){r=n.getComputedStyle("color"),i=n.getComputedStyle("backgroundColor"),o=this._getLuminanceFromCssColor(r),u=this._getLuminanceFromCssColor(i),o>u?s=(o+.05)/(u+.05):s=(u+.05)/(o+.05);if(s<=4.5){var a=0,f=!1;for(a=0;a<t.length;a++){if(n.ancestors("*").indexOf(t[a])!==-1){f=!0;break}if(t[a].ancestors("*").indexOf(n)!==-1){t[a]=n,f=!0;break}}f||t.push(n)}}},this),this._addWarnings(r,M.util.get_string("needsmorecontrast",n),t,!1),r.hasChildNodes()||r.append("<p>"+M.util.get_string("nowarnings",n)+"</p>"),r},_addWarnings:function(t,n,r,i){var s,o,u,a,f,l;if(r.length>0){s=e.Node.create("<p>"+n+"</p>"),o=e.Node.create('<ol class="accessibilitywarnings"></ol>'),u=0;for(u=0;u<r.length;u++)i?(a="image_"+u,f=r[u].getAttribute("src"),o.append(e.Node.create('<li><a data-index="'+a+'" href="#"><img data-index="'+a+'" src="'+f+'" /> '+f+"</a></li>"))):(a="text_"+u,l="innerText"in r[u]?"innerText":"textContent",o.append(e.Node.create('<li><a href="#" data-index="'+a+'">'+r[u].get(l)+"</a></li>"))),this._displayedWarnings[a]=r[u];s.append(o),t.append(s)}},_getLuminanceFromCssColor:function(t){var n;t==="transparent"&&(t="#ffffff"),n=e.Color.toArray(e.Color.toRGB(t));var r=function(e){return e=parseInt(e,10)/255,e<=.03928?e/=12.92:e=Math.pow((e+.055)/1.055,2.4),e},i=r(n[0]),s=r(n[1]),o=r(n[2]);return.2126*i+.7152*s+.0722*o}})},"@VERSION@",{requires:["color-base","moodle-editor_atto-plugin"]});
@@ -0,0 +1,261 @@
YUI.add('moodle-atto_accessibilitychecker-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/>.
/*
* @package atto_accessibilitychecker
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_accessibilitychecker-button
*/
/**
* Accessibility Checking tool for the Atto editor.
*
* @namespace M.atto_accessibilitychecker
* @class Button
* @extends M.editor_atto.EditorPlugin
*/
var COMPONENT = 'atto_accessibilitychecker';
Y.namespace('M.atto_accessibilitychecker').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* The warnings which are displayed.
*
* @property _displayedWarnings
* @type Object
* @private
*/
_displayedWarnings: {},
initializer: function() {
this.addButton({
icon: 'e/accessibility_checker',
callback: this._displayDialogue
});
},
/**
* Display the Accessibility Checker tool.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENT),
width: '800px',
focusAfterHide: true
});
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var content = Y.Node.create('<div style="word-wrap: break-word;"></div>');
content.append(this._getWarnings());
// Add ability to select problem areas in the editor.
content.delegate('click', function(e) {
e.preventDefault();
var host = this.get('host'),
index = e.target.getAttribute("data-index"),
node = this._displayedWarnings[index],
dialogue = this.getDialogue();
if (node) {
// Clear the dialogue's focusAfterHide to ensure we focus
// on the selection.
dialogue.set('focusAfterHide', null);
// Hide the dialogue.
dialogue.hide();
// Then set the selection.
host.setSelection(host.getSelectionFromNode(node));
} else {
// Hide the dialogue.
dialogue.hide();
}
}, 'a', this);
return content;
},
/**
* Find all problems with the content editable region.
*
* @method _getWarnings
* @return {Node} A complete list of all warnings and problems.
* @private
*/
_getWarnings: function() {
var problemNodes,
list = Y.Node.create('<div></div>');
// Images with no alt text or dodgy alt text.
problemNodes = [];
this.editor.all('img').each(function (img) {
alt = img.getAttribute('alt');
if (typeof alt === 'undefined' || alt === '') {
if (img.getAttribute('role') !== 'presentation') {
problemNodes.push(img);
}
}
}, this);
this._addWarnings(list, M.util.get_string('imagesmissingalt', COMPONENT), problemNodes, true);
problemNodes = [];
this.editor.all('*').each(function (node) {
var foreground,
background,
ratio,
lum1,
lum2;
// Check for non-empty text.
if (Y.Lang.trim(node.get('text')) !== '') {
foreground = node.getComputedStyle('color');
background = node.getComputedStyle('backgroundColor');
lum1 = this._getLuminanceFromCssColor(foreground);
lum2 = this._getLuminanceFromCssColor(background);
// Algorithm from "http://www.w3.org/TR/WCAG20-GENERAL/G18.html".
if (lum1 > lum2) {
ratio = (lum1 + 0.05) / (lum2 + 0.05);
} else {
ratio = (lum2 + 0.05) / (lum1 + 0.05);
}
if (ratio <= 4.5) {
// We only want the highest node with dodgy contrast reported.
var i = 0, found = false;
for (i = 0; i < problemNodes.length; i++) {
if (node.ancestors('*').indexOf(problemNodes[i]) !== -1) {
// Do not add node - it already has a parent in the list.
found = true;
break;
} else if (problemNodes[i].ancestors('*').indexOf(node) !== -1) {
// Replace the existing node with this one because it is higher up the DOM.
problemNodes[i] = node;
found = true;
break;
}
}
if (!found) {
problemNodes.push(node);
}
}
}
}, this);
this._addWarnings(list, M.util.get_string('needsmorecontrast', COMPONENT), problemNodes, false);
if (!list.hasChildNodes()) {
list.append('<p>' + M.util.get_string('nowarnings', COMPONENT) + '</p>');
}
// Append the list of current styles.
return list;
},
/**
* Generate the HTML that lists the found warnings.
*
* @method _addWarnings
* @param {Node} A Node to append the html to.
* @param {String} description Description of this failure.
* @param {array} nodes An array of failing nodes.
* @param {boolean} imagewarnings true if the warnings are related to images, false if text.
*/
_addWarnings: function(list, description, nodes, imagewarnings) {
var warning, fails, i, key, src, textfield;
if (nodes.length > 0) {
warning = Y.Node.create('<p>' + description + '</p>');
fails = Y.Node.create('<ol class="accessibilitywarnings"></ol>');
i = 0;
for (i = 0; i < nodes.length; i++) {
if (imagewarnings) {
key = 'image_'+i;
src = nodes[i].getAttribute('src');
fails.append(Y.Node.create('<li><a data-index="'+key+'" href="#"><img data-index="'+key+'" src="' + src + '" /> '+src+'</a></li>'));
} else {
key = 'text_' + i;
textfield = ('innerText' in nodes[i])? 'innerText' : 'textContent';
fails.append(Y.Node.create('<li><a href="#" data-index="'+key+'">' + nodes[i].get(textfield) + '</a></li>'));
}
this._displayedWarnings[key] = nodes[i];
}
warning.append(fails);
list.append(warning);
}
},
/**
* Convert a CSS color to a luminance value.
*
* @method _getLuminanceFromCssColor
* @param {String} colortext The Hex value for the colour
* @return {Number} The luminance value.
* @private
*/
_getLuminanceFromCssColor: function(colortext) {
var color;
if (colortext === 'transparent') {
colortext = '#ffffff';
}
color = Y.Color.toArray(Y.Color.toRGB(colortext));
// Algorithm from "http://www.w3.org/TR/WCAG20-GENERAL/G18.html".
var part1 = function(a) {
a = parseInt(a, 10) / 255.0;
if (a <= 0.03928) {
a = a/12.92;
} else {
a = Math.pow(((a + 0.055)/1.055), 2.4);
}
return a;
};
var r1 = part1(color[0]),
g1 = part1(color[1]),
b1 = part1(color[2]);
return 0.2126 * r1 + 0.7152 * g1 + 0.0722 * b1;
}
});
}, '@VERSION@', {"requires": ["color-base", "moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_accessibilitychecker-button",
"builds": {
"moodle-atto_accessibilitychecker-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,261 @@
// 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/>.
/*
* @package atto_accessibilitychecker
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_accessibilitychecker-button
*/
/**
* Accessibility Checking tool for the Atto editor.
*
* @namespace M.atto_accessibilitychecker
* @class Button
* @extends M.editor_atto.EditorPlugin
*/
var COMPONENT = 'atto_accessibilitychecker';
Y.namespace('M.atto_accessibilitychecker').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* The warnings which are displayed.
*
* @property _displayedWarnings
* @type Object
* @private
*/
_displayedWarnings: {},
initializer: function() {
this.addButton({
icon: 'e/accessibility_checker',
callback: this._displayDialogue
});
},
/**
* Display the Accessibility Checker tool.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENT),
width: '800px',
focusAfterHide: true
});
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var content = Y.Node.create('<div style="word-wrap: break-word;"></div>');
content.append(this._getWarnings());
// Add ability to select problem areas in the editor.
content.delegate('click', function(e) {
e.preventDefault();
var host = this.get('host'),
index = e.target.getAttribute("data-index"),
node = this._displayedWarnings[index],
dialogue = this.getDialogue();
if (node) {
// Clear the dialogue's focusAfterHide to ensure we focus
// on the selection.
dialogue.set('focusAfterHide', null);
// Hide the dialogue.
dialogue.hide();
// Then set the selection.
host.setSelection(host.getSelectionFromNode(node));
} else {
// Hide the dialogue.
dialogue.hide();
}
}, 'a', this);
return content;
},
/**
* Find all problems with the content editable region.
*
* @method _getWarnings
* @return {Node} A complete list of all warnings and problems.
* @private
*/
_getWarnings: function() {
var problemNodes,
list = Y.Node.create('<div></div>');
// Images with no alt text or dodgy alt text.
problemNodes = [];
this.editor.all('img').each(function (img) {
alt = img.getAttribute('alt');
if (typeof alt === 'undefined' || alt === '') {
if (img.getAttribute('role') !== 'presentation') {
problemNodes.push(img);
}
}
}, this);
this._addWarnings(list, M.util.get_string('imagesmissingalt', COMPONENT), problemNodes, true);
problemNodes = [];
this.editor.all('*').each(function (node) {
var foreground,
background,
ratio,
lum1,
lum2;
// Check for non-empty text.
if (Y.Lang.trim(node.get('text')) !== '') {
foreground = node.getComputedStyle('color');
background = node.getComputedStyle('backgroundColor');
lum1 = this._getLuminanceFromCssColor(foreground);
lum2 = this._getLuminanceFromCssColor(background);
// Algorithm from "http://www.w3.org/TR/WCAG20-GENERAL/G18.html".
if (lum1 > lum2) {
ratio = (lum1 + 0.05) / (lum2 + 0.05);
} else {
ratio = (lum2 + 0.05) / (lum1 + 0.05);
}
if (ratio <= 4.5) {
Y.log('Contrast ratio is too low: ' + ratio +
' Colour 1: ' + foreground +
' Colour 2: ' + background +
' Luminance 1: ' + lum1 +
' Luminance 2: ' + lum2);
// We only want the highest node with dodgy contrast reported.
var i = 0, found = false;
for (i = 0; i < problemNodes.length; i++) {
if (node.ancestors('*').indexOf(problemNodes[i]) !== -1) {
// Do not add node - it already has a parent in the list.
found = true;
break;
} else if (problemNodes[i].ancestors('*').indexOf(node) !== -1) {
// Replace the existing node with this one because it is higher up the DOM.
problemNodes[i] = node;
found = true;
break;
}
}
if (!found) {
problemNodes.push(node);
}
}
}
}, this);
this._addWarnings(list, M.util.get_string('needsmorecontrast', COMPONENT), problemNodes, false);
if (!list.hasChildNodes()) {
list.append('<p>' + M.util.get_string('nowarnings', COMPONENT) + '</p>');
}
// Append the list of current styles.
return list;
},
/**
* Generate the HTML that lists the found warnings.
*
* @method _addWarnings
* @param {Node} A Node to append the html to.
* @param {String} description Description of this failure.
* @param {array} nodes An array of failing nodes.
* @param {boolean} imagewarnings true if the warnings are related to images, false if text.
*/
_addWarnings: function(list, description, nodes, imagewarnings) {
var warning, fails, i, key, src, textfield;
if (nodes.length > 0) {
warning = Y.Node.create('<p>' + description + '</p>');
fails = Y.Node.create('<ol class="accessibilitywarnings"></ol>');
i = 0;
for (i = 0; i < nodes.length; i++) {
if (imagewarnings) {
key = 'image_'+i;
src = nodes[i].getAttribute('src');
fails.append(Y.Node.create('<li><a data-index="'+key+'" href="#"><img data-index="'+key+'" src="' + src + '" /> '+src+'</a></li>'));
} else {
key = 'text_' + i;
textfield = ('innerText' in nodes[i])? 'innerText' : 'textContent';
fails.append(Y.Node.create('<li><a href="#" data-index="'+key+'">' + nodes[i].get(textfield) + '</a></li>'));
}
this._displayedWarnings[key] = nodes[i];
}
warning.append(fails);
list.append(warning);
}
},
/**
* Convert a CSS color to a luminance value.
*
* @method _getLuminanceFromCssColor
* @param {String} colortext The Hex value for the colour
* @return {Number} The luminance value.
* @private
*/
_getLuminanceFromCssColor: function(colortext) {
var color;
if (colortext === 'transparent') {
colortext = '#ffffff';
}
color = Y.Color.toArray(Y.Color.toRGB(colortext));
// Algorithm from "http://www.w3.org/TR/WCAG20-GENERAL/G18.html".
var part1 = function(a) {
a = parseInt(a, 10) / 255.0;
if (a <= 0.03928) {
a = a/12.92;
} else {
a = Math.pow(((a + 0.055)/1.055), 2.4);
}
return a;
};
var r1 = part1(color[0]),
g1 = part1(color[1]),
b1 = part1(color[2]);
return 0.2126 * r1 + 0.7152 * g1 + 0.0722 * b1;
}
});
@@ -0,0 +1,8 @@
{
"moodle-atto_accessibilitychecker-button": {
"requires": [
"color-base",
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,33 @@
<?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_accessibilityhelper', language 'en'.
*
* @package atto_accessibilityhelper
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Screenreader helper';
$string['liststyles'] = 'Styles for current selection:';
$string['nostyles'] = 'No styles';
$string['listlinks'] = 'Links in text editor:';
$string['nolinks'] = 'No links';
$string['selectlink'] = 'Select link';
$string['listimages'] = 'Images in text editor:';
$string['noimages'] = 'No images';
$string['selectimage'] = 'Select image';
@@ -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 integration version file.
*
* @package atto_accessibilityhelper
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Initialise this plugin
* @param string $elementid
*/
function atto_accessibilityhelper_strings_for_js() {
global $PAGE;
$PAGE->requires->strings_for_js(array('liststyles',
'nostyles',
'listlinks',
'nolinks',
'selectlink',
'listimages',
'noimages',
'selectimage'),
'atto_accessibilityhelper');
}
@@ -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_accessibilityhelper
* @copyright 2014 Damyon Wiese <[email protected]>
* @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_accessibilityhelper'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,311 @@
YUI.add('moodle-atto_accessibilityhelper-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/>.
/*
* @package atto_accessibilityhelper
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_accessibilityhelper-button
*/
/**
* Atto text editor accessibilityhelper plugin.
*
* This plugin adds some functions to do things that screen readers do not do well.
* Specifically, listing the active styles for the selected text,
* listing the images in the page, listing the links in the page.
*
*
* @namespace M.atto_accessibilityhelper
* @class Button
* @extends M.editor_atto.EditorPlugin
*/
var COMPONENT = 'atto_accessibilityhelper',
TEMPLATE = '' +
// The list of styles.
'<div><p id="{{elementid}}_{{CSS.STYLESLABEL}}">' +
'{{get_string "liststyles" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.STYLESLABEL}}" />' +
'</p></div>' +
'<span class="listStyles"></span>' +
'<p id="{{elementid}}_{{CSS.LINKSLABEL}}">' +
'{{get_string "listlinks" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.LINKSLABEL}}"/>' +
'</p>' +
'<span class="listLinks"></span>' +
'<p id="{{elementid}}_{{CSS.IMAGESLABEL}}">' +
'{{get_string "listimages" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.IMAGESLABEL}}"/>' +
'</p>' +
'<span class="listImages"></span>',
CSS = {
STYLESLABEL: COMPONENT + '_styleslabel',
LINKSLABEL: COMPONENT + '_linkslabel',
IMAGESLABEL: COMPONENT + '_imageslabel'
};
Y.namespace('M.atto_accessibilityhelper').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* The warnings which are displayed.
*
* @property _displayedWarnings
* @type Object
* @private
*/
_displayedWarnings: {},
initializer: function() {
this.addButton({
icon: 'e/screenreader_helper',
callback: this._displayDialogue
});
},
/**
* Display the Accessibility Helper tool.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENT),
width: '800px',
focusAfterHide: true
});
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool, attaching any required
* events.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(TEMPLATE),
content = Y.Node.create(template({
CSS: CSS,
component: COMPONENT
}));
// Add the data.
content.one('.listStyles')
.empty()
.appendChild(this._listStyles());
content.one('.listLinks')
.empty()
.appendChild(this._listLinks());
content.one('.listImages')
.empty()
.appendChild(this._listImages());
// Add ability to select problem areas in the editor.
content.delegate('click', function(e) {
e.preventDefault();
var host = this.get('host'),
index = e.target.getAttribute("data-index"),
node = this._displayedWarnings[index],
dialogue = this.getDialogue();
if (node) {
// Clear the dialogue's focusAfterHide to ensure we focus
// on the selection.
dialogue.set('focusAfterHide', null);
host.setSelection(host.getSelectionFromNode(node));
}
// Hide the dialogue.
dialogue.hide();
}, 'a', this);
return content;
},
/**
* List the styles present for the selection.
*
* @method _listStyles
* @return {String} The list of styles in use.
* @private
*/
_listStyles: function() {
// Clear the status node.
var list = [],
host = this.get('host'),
current = host.getSelectionParentNode(),
tagname;
if (current) {
current = Y.one(current);
}
while (current && (current !== this.editor)) {
tagname = current.get('tagName');
if (typeof tagname !== 'undefined') {
list.push(Y.Escape.html(tagname));
}
current = current.ancestor();
}
if (list.length === 0) {
list.push(M.util.get_string('nostyles', COMPONENT));
}
list.reverse();
// Append the list of current styles.
return list.join(', ');
},
/**
* List the links for the current editor
*
* @method _listLinks
* @return {string}
* @private
*/
_listLinks: function() {
var list = Y.Node.create('<ol />'),
listitem,
selectlink;
this.editor.all('a').each(function(link) {
selectlink = Y.Node.create('<a href="#" title="' +
M.util.get_string('selectlink', COMPONENT) + '">' +
Y.Escape.html(link.get('text')) +
'</a>');
selectlink.setData('sourcelink', link);
selectlink.on('click', this._linkSelected, this);
listitem = Y.Node.create('<li></li>');
listitem.appendChild(selectlink);
list.appendChild(listitem);
}, this);
if (!list.hasChildNodes()) {
list.append('<li>' + M.util.get_string('nolinks', COMPONENT) + '</li>');
}
// Append the list of current styles.
return list;
},
/**
* List the images used in the editor.
*
* @method _listImages
* @return {Node} A Node containing all of the images present in the editor.
* @private
*/
_listImages: function() {
var list = Y.Node.create('<ol/>'),
listitem,
selectimage;
this.editor.all('img').each(function(image) {
// Get the alt or title or img url of the image.
var imgalt = image.getAttribute('alt');
if (imgalt === '') {
imgalt = image.getAttribute('title');
if (imgalt === '') {
imgalt = image.getAttribute('src');
}
}
selectimage = Y.Node.create('<a href="#" title="' +
M.util.get_string('selectimage', COMPONENT) + '">' +
Y.Escape.html(imgalt) +
'</a>');
selectimage.setData('sourceimage', image);
selectimage.on('click', this._imageSelected, this);
listitem = Y.Node.create('<li></li>');
listitem.append(selectimage);
list.append(listitem);
}, this);
if (!list.hasChildNodes()) {
list.append('<li>' + M.util.get_string('noimages', COMPONENT) + '</li>');
}
// Append the list of current styles.
return list;
},
/**
* Event handler for selecting an image.
*
* @method _imageSelected
* @param {EventFacade} e
* @private
*/
_imageSelected: function(e) {
e.preventDefault();
this.getDialogue({
focusAfterNode: null
}).hide();
var host = this.get('host'),
target = e.target.getData('sourceimage');
this.editor.focus();
host.setSelection(host.getSelectionFromNode(target));
},
/**
* Event handler for selecting a link.
*
* @method _linkSelected
* @param {EventFacade} e
* @private
*/
_linkSelected: function(e) {
e.preventDefault();
this.getDialogue({
focusAfterNode: null
}).hide();
var host = this.get('host'),
target = e.target.getData('sourcelink');
this.editor.focus();
host.setSelection(host.getSelectionFromNode(target));
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_accessibilityhelper-button",function(e,t){var n="atto_accessibilityhelper",r='<div><p id="{{elementid}}_{{CSS.STYLESLABEL}}">{{get_string "liststyles" component}}<br/><span aria-labelledby="{{elementid}}_{{CSS.STYLESLABEL}}" /></p></div><span class="listStyles"></span><p id="{{elementid}}_{{CSS.LINKSLABEL}}">{{get_string "listlinks" component}}<br/><span aria-labelledby="{{elementid}}_{{CSS.LINKSLABEL}}"/></p><span class="listLinks"></span><p id="{{elementid}}_{{CSS.IMAGESLABEL}}">{{get_string "listimages" component}}<br/><span aria-labelledby="{{elementid}}_{{CSS.IMAGESLABEL}}"/></p><span class="listImages"></span>',i={STYLESLABEL:n+"_styleslabel",LINKSLABEL:n+"_linkslabel",IMAGESLABEL:n+"_imageslabel"};e.namespace("M.atto_accessibilityhelper").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_displayedWarnings:{},initializer:function(){this.addButton({icon:"e/screenreader_helper",callback:this._displayDialogue})},_displayDialogue:function(){var e=this.getDialogue({headerContent:M.util.get_string("pluginname",n),width:"800px",focusAfterHide:!0});e.set("bodyContent",this._getDialogueContent()).show()},_getDialogueContent:function(){var t=e.Handlebars.compile(r),s=e.Node.create(t({CSS:i,component:n}));return s.one(".listStyles").empty().appendChild(this._listStyles()),s.one(".listLinks").empty().appendChild(this._listLinks()),s.one(".listImages").empty().appendChild(this._listImages()),s.delegate("click",function(e){e.preventDefault();var t=this.get("host"),n=e.target.getAttribute("data-index"),r=this._displayedWarnings[n],i=this.getDialogue();r&&(i.set("focusAfterHide",null),t.setSelection(t.getSelectionFromNode(r))),i.hide()},"a",this),s},_listStyles:function(){var t=[],r=this.get("host"),i=r.getSelectionParentNode(),s;i&&(i=e.one(i));while(i&&i!==this.editor)s=i.get("tagName"),typeof s!="undefined"&&t.push(e.Escape.html(s)),i=i.ancestor();return t.length===0&&t.push(M.util.get_string("nostyles",n)),t.reverse(),t.join(", ")},_listLinks:function(){var t=e.Node.create("<ol />"),r,i;return this.editor.all("a").each(function(s){i=e.Node.create('<a href="#" title="'+M.util.get_string("selectlink",n)+'">'+e.Escape.html(s.get("text"))+"</a>"),i.setData("sourcelink",s),i.on("click",this._linkSelected,this),r=e.Node.create("<li></li>"),r.appendChild(i),t.appendChild(r)},this),t.hasChildNodes()||t.append("<li>"+M.util.get_string("nolinks",n)+"</li>"),t},_listImages:function(){var t=e.Node.create("<ol/>"),r,i;return this.editor.all("img").each(function(s){var o=s.getAttribute("alt");o===""&&(o=s.getAttribute("title"),o===""&&(o=s.getAttribute("src"))),i=e.Node.create('<a href="#" title="'+M.util.get_string("selectimage",n)+'">'+e.Escape.html(o)+"</a>"),i.setData("sourceimage",s),i.on("click",this._imageSelected,this),r=e.Node.create("<li></li>"),r.append(i),t.append(r)},this),t.hasChildNodes()||t.append("<li>"+M.util.get_string("noimages",n)+"</li>"),t},_imageSelected:function(e){e.preventDefault(),this.getDialogue({focusAfterNode:null}).hide();var t=this.get("host"),n=e.target.getData("sourceimage");this.editor.focus(),t.setSelection(t.getSelectionFromNode(n))},_linkSelected:function(e){e.preventDefault(),this.getDialogue({focusAfterNode:null}).hide();var t=this.get("host"),n=e.target.getData("sourcelink");this.editor.focus(),t.setSelection(t.getSelectionFromNode(n))}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
@@ -0,0 +1,311 @@
YUI.add('moodle-atto_accessibilityhelper-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/>.
/*
* @package atto_accessibilityhelper
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_accessibilityhelper-button
*/
/**
* Atto text editor accessibilityhelper plugin.
*
* This plugin adds some functions to do things that screen readers do not do well.
* Specifically, listing the active styles for the selected text,
* listing the images in the page, listing the links in the page.
*
*
* @namespace M.atto_accessibilityhelper
* @class Button
* @extends M.editor_atto.EditorPlugin
*/
var COMPONENT = 'atto_accessibilityhelper',
TEMPLATE = '' +
// The list of styles.
'<div><p id="{{elementid}}_{{CSS.STYLESLABEL}}">' +
'{{get_string "liststyles" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.STYLESLABEL}}" />' +
'</p></div>' +
'<span class="listStyles"></span>' +
'<p id="{{elementid}}_{{CSS.LINKSLABEL}}">' +
'{{get_string "listlinks" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.LINKSLABEL}}"/>' +
'</p>' +
'<span class="listLinks"></span>' +
'<p id="{{elementid}}_{{CSS.IMAGESLABEL}}">' +
'{{get_string "listimages" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.IMAGESLABEL}}"/>' +
'</p>' +
'<span class="listImages"></span>',
CSS = {
STYLESLABEL: COMPONENT + '_styleslabel',
LINKSLABEL: COMPONENT + '_linkslabel',
IMAGESLABEL: COMPONENT + '_imageslabel'
};
Y.namespace('M.atto_accessibilityhelper').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* The warnings which are displayed.
*
* @property _displayedWarnings
* @type Object
* @private
*/
_displayedWarnings: {},
initializer: function() {
this.addButton({
icon: 'e/screenreader_helper',
callback: this._displayDialogue
});
},
/**
* Display the Accessibility Helper tool.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENT),
width: '800px',
focusAfterHide: true
});
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool, attaching any required
* events.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(TEMPLATE),
content = Y.Node.create(template({
CSS: CSS,
component: COMPONENT
}));
// Add the data.
content.one('.listStyles')
.empty()
.appendChild(this._listStyles());
content.one('.listLinks')
.empty()
.appendChild(this._listLinks());
content.one('.listImages')
.empty()
.appendChild(this._listImages());
// Add ability to select problem areas in the editor.
content.delegate('click', function(e) {
e.preventDefault();
var host = this.get('host'),
index = e.target.getAttribute("data-index"),
node = this._displayedWarnings[index],
dialogue = this.getDialogue();
if (node) {
// Clear the dialogue's focusAfterHide to ensure we focus
// on the selection.
dialogue.set('focusAfterHide', null);
host.setSelection(host.getSelectionFromNode(node));
}
// Hide the dialogue.
dialogue.hide();
}, 'a', this);
return content;
},
/**
* List the styles present for the selection.
*
* @method _listStyles
* @return {String} The list of styles in use.
* @private
*/
_listStyles: function() {
// Clear the status node.
var list = [],
host = this.get('host'),
current = host.getSelectionParentNode(),
tagname;
if (current) {
current = Y.one(current);
}
while (current && (current !== this.editor)) {
tagname = current.get('tagName');
if (typeof tagname !== 'undefined') {
list.push(Y.Escape.html(tagname));
}
current = current.ancestor();
}
if (list.length === 0) {
list.push(M.util.get_string('nostyles', COMPONENT));
}
list.reverse();
// Append the list of current styles.
return list.join(', ');
},
/**
* List the links for the current editor
*
* @method _listLinks
* @return {string}
* @private
*/
_listLinks: function() {
var list = Y.Node.create('<ol />'),
listitem,
selectlink;
this.editor.all('a').each(function(link) {
selectlink = Y.Node.create('<a href="#" title="' +
M.util.get_string('selectlink', COMPONENT) + '">' +
Y.Escape.html(link.get('text')) +
'</a>');
selectlink.setData('sourcelink', link);
selectlink.on('click', this._linkSelected, this);
listitem = Y.Node.create('<li></li>');
listitem.appendChild(selectlink);
list.appendChild(listitem);
}, this);
if (!list.hasChildNodes()) {
list.append('<li>' + M.util.get_string('nolinks', COMPONENT) + '</li>');
}
// Append the list of current styles.
return list;
},
/**
* List the images used in the editor.
*
* @method _listImages
* @return {Node} A Node containing all of the images present in the editor.
* @private
*/
_listImages: function() {
var list = Y.Node.create('<ol/>'),
listitem,
selectimage;
this.editor.all('img').each(function(image) {
// Get the alt or title or img url of the image.
var imgalt = image.getAttribute('alt');
if (imgalt === '') {
imgalt = image.getAttribute('title');
if (imgalt === '') {
imgalt = image.getAttribute('src');
}
}
selectimage = Y.Node.create('<a href="#" title="' +
M.util.get_string('selectimage', COMPONENT) + '">' +
Y.Escape.html(imgalt) +
'</a>');
selectimage.setData('sourceimage', image);
selectimage.on('click', this._imageSelected, this);
listitem = Y.Node.create('<li></li>');
listitem.append(selectimage);
list.append(listitem);
}, this);
if (!list.hasChildNodes()) {
list.append('<li>' + M.util.get_string('noimages', COMPONENT) + '</li>');
}
// Append the list of current styles.
return list;
},
/**
* Event handler for selecting an image.
*
* @method _imageSelected
* @param {EventFacade} e
* @private
*/
_imageSelected: function(e) {
e.preventDefault();
this.getDialogue({
focusAfterNode: null
}).hide();
var host = this.get('host'),
target = e.target.getData('sourceimage');
this.editor.focus();
host.setSelection(host.getSelectionFromNode(target));
},
/**
* Event handler for selecting a link.
*
* @method _linkSelected
* @param {EventFacade} e
* @private
*/
_linkSelected: function(e) {
e.preventDefault();
this.getDialogue({
focusAfterNode: null
}).hide();
var host = this.get('host'),
target = e.target.getData('sourcelink');
this.editor.focus();
host.setSelection(host.getSelectionFromNode(target));
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_accessibilityhelper-button",
"builds": {
"moodle-atto_accessibilityhelper-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,306 @@
// 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/>.
/*
* @package atto_accessibilityhelper
* @copyright 2014 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_accessibilityhelper-button
*/
/**
* Atto text editor accessibilityhelper plugin.
*
* This plugin adds some functions to do things that screen readers do not do well.
* Specifically, listing the active styles for the selected text,
* listing the images in the page, listing the links in the page.
*
*
* @namespace M.atto_accessibilityhelper
* @class Button
* @extends M.editor_atto.EditorPlugin
*/
var COMPONENT = 'atto_accessibilityhelper',
TEMPLATE = '' +
// The list of styles.
'<div><p id="{{elementid}}_{{CSS.STYLESLABEL}}">' +
'{{get_string "liststyles" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.STYLESLABEL}}" />' +
'</p></div>' +
'<span class="listStyles"></span>' +
'<p id="{{elementid}}_{{CSS.LINKSLABEL}}">' +
'{{get_string "listlinks" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.LINKSLABEL}}"/>' +
'</p>' +
'<span class="listLinks"></span>' +
'<p id="{{elementid}}_{{CSS.IMAGESLABEL}}">' +
'{{get_string "listimages" component}}<br/>' +
'<span aria-labelledby="{{elementid}}_{{CSS.IMAGESLABEL}}"/>' +
'</p>' +
'<span class="listImages"></span>',
CSS = {
STYLESLABEL: COMPONENT + '_styleslabel',
LINKSLABEL: COMPONENT + '_linkslabel',
IMAGESLABEL: COMPONENT + '_imageslabel'
};
Y.namespace('M.atto_accessibilityhelper').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* The warnings which are displayed.
*
* @property _displayedWarnings
* @type Object
* @private
*/
_displayedWarnings: {},
initializer: function() {
this.addButton({
icon: 'e/screenreader_helper',
callback: this._displayDialogue
});
},
/**
* Display the Accessibility Helper tool.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
var dialogue = this.getDialogue({
headerContent: M.util.get_string('pluginname', COMPONENT),
width: '800px',
focusAfterHide: true
});
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool, attaching any required
* events.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(TEMPLATE),
content = Y.Node.create(template({
CSS: CSS,
component: COMPONENT
}));
// Add the data.
content.one('.listStyles')
.empty()
.appendChild(this._listStyles());
content.one('.listLinks')
.empty()
.appendChild(this._listLinks());
content.one('.listImages')
.empty()
.appendChild(this._listImages());
// Add ability to select problem areas in the editor.
content.delegate('click', function(e) {
e.preventDefault();
var host = this.get('host'),
index = e.target.getAttribute("data-index"),
node = this._displayedWarnings[index],
dialogue = this.getDialogue();
if (node) {
// Clear the dialogue's focusAfterHide to ensure we focus
// on the selection.
dialogue.set('focusAfterHide', null);
host.setSelection(host.getSelectionFromNode(node));
}
// Hide the dialogue.
dialogue.hide();
}, 'a', this);
return content;
},
/**
* List the styles present for the selection.
*
* @method _listStyles
* @return {String} The list of styles in use.
* @private
*/
_listStyles: function() {
// Clear the status node.
var list = [],
host = this.get('host'),
current = host.getSelectionParentNode(),
tagname;
if (current) {
current = Y.one(current);
}
while (current && (current !== this.editor)) {
tagname = current.get('tagName');
if (typeof tagname !== 'undefined') {
list.push(Y.Escape.html(tagname));
}
current = current.ancestor();
}
if (list.length === 0) {
list.push(M.util.get_string('nostyles', COMPONENT));
}
list.reverse();
// Append the list of current styles.
return list.join(', ');
},
/**
* List the links for the current editor
*
* @method _listLinks
* @return {string}
* @private
*/
_listLinks: function() {
var list = Y.Node.create('<ol />'),
listitem,
selectlink;
this.editor.all('a').each(function(link) {
selectlink = Y.Node.create('<a href="#" title="' +
M.util.get_string('selectlink', COMPONENT) + '">' +
Y.Escape.html(link.get('text')) +
'</a>');
selectlink.setData('sourcelink', link);
selectlink.on('click', this._linkSelected, this);
listitem = Y.Node.create('<li></li>');
listitem.appendChild(selectlink);
list.appendChild(listitem);
}, this);
if (!list.hasChildNodes()) {
list.append('<li>' + M.util.get_string('nolinks', COMPONENT) + '</li>');
}
// Append the list of current styles.
return list;
},
/**
* List the images used in the editor.
*
* @method _listImages
* @return {Node} A Node containing all of the images present in the editor.
* @private
*/
_listImages: function() {
var list = Y.Node.create('<ol/>'),
listitem,
selectimage;
this.editor.all('img').each(function(image) {
// Get the alt or title or img url of the image.
var imgalt = image.getAttribute('alt');
if (imgalt === '') {
imgalt = image.getAttribute('title');
if (imgalt === '') {
imgalt = image.getAttribute('src');
}
}
selectimage = Y.Node.create('<a href="#" title="' +
M.util.get_string('selectimage', COMPONENT) + '">' +
Y.Escape.html(imgalt) +
'</a>');
selectimage.setData('sourceimage', image);
selectimage.on('click', this._imageSelected, this);
listitem = Y.Node.create('<li></li>');
listitem.append(selectimage);
list.append(listitem);
}, this);
if (!list.hasChildNodes()) {
list.append('<li>' + M.util.get_string('noimages', COMPONENT) + '</li>');
}
// Append the list of current styles.
return list;
},
/**
* Event handler for selecting an image.
*
* @method _imageSelected
* @param {EventFacade} e
* @private
*/
_imageSelected: function(e) {
e.preventDefault();
this.getDialogue({
focusAfterNode: null
}).hide();
var host = this.get('host'),
target = e.target.getData('sourceimage');
this.editor.focus();
host.setSelection(host.getSelectionFromNode(target));
},
/**
* Event handler for selecting a link.
*
* @method _linkSelected
* @param {EventFacade} e
* @private
*/
_linkSelected: function(e) {
e.preventDefault();
this.getDialogue({
focusAfterNode: null
}).hide();
var host = this.get('host'),
target = e.target.getData('sourcelink');
this.editor.focus();
host.setSelection(host.getSelectionFromNode(target));
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_accessibilityhelper-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,28 @@
<?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_align', language 'en'.
*
* @package atto_align
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['center'] = 'Center';
$string['leftalign'] = 'Left align';
$string['pluginname'] = 'Text align';
$string['rightalign'] = 'Right align';
+35
View File
@@ -0,0 +1,35 @@
<?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 align plugin lib.
*
* @package atto_align
* @copyright 2014 Frédéric Massart
* @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_align_strings_for_js() {
global $PAGE;
$PAGE->requires->strings_for_js(array('center', 'leftalign', 'rightalign'), 'atto_align');
}
+29
View File
@@ -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 align plugin version file.
*
* @package atto_align
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014021300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2013110500; // Requires this Moodle version.
$plugin->component = 'atto_align'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,97 @@
YUI.add('moodle-atto_align-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/>.
/*
* @package atto_align
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_align-button
*/
/**
* Atto text editor align plugin.
*
* @namespace M.atto_align
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_align').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var alignment;
alignment = 'justifyLeft';
this.addButton({
icon: 'e/align_left',
title: 'leftalign',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
alignment = 'justifyCenter';
this.addButton({
icon: 'e/align_center',
title: 'center',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
alignment = 'justifyRight';
this.addButton({
icon: 'e/align_right',
title: 'rightalign',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
},
/**
* Change the alignment to the specified justification.
*
* @method _changeStyle
* @param {EventFacade} e
* @param {string} justification The execCommand for the new justification.
* @private
*/
_changeStyle: function(e, justification) {
var host = this.get('host');
// We temporarily re-enable CSS styling to try to have the most consistency.
// Though, IE, as always, is stubborn and will do its own thing...
host.enableCssStyling();
document.execCommand(justification, false, null);
// Re-disable the CSS styling after making the change.
host.disableCssStyling();
// Mark the text as having been updated.
this.markUpdated();
this.editor.focus();
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_align-button",function(e,t){e.namespace("M.atto_align").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){var e;e="justifyLeft",this.addButton({icon:"e/align_left",title:"leftalign",buttonName:e,callback:this._changeStyle,callbackArgs:e}),e="justifyCenter",this.addButton({icon:"e/align_center",title:"center",buttonName:e,callback:this._changeStyle,callbackArgs:e}),e="justifyRight",this.addButton({icon:"e/align_right",title:"rightalign",buttonName:e,callback:this._changeStyle,callbackArgs:e})},_changeStyle:function(e,t){var n=this.get("host");n.enableCssStyling(),document.execCommand(t,!1,null),n.disableCssStyling(),this.markUpdated(),this.editor.focus()}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
@@ -0,0 +1,97 @@
YUI.add('moodle-atto_align-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/>.
/*
* @package atto_align
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_align-button
*/
/**
* Atto text editor align plugin.
*
* @namespace M.atto_align
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_align').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var alignment;
alignment = 'justifyLeft';
this.addButton({
icon: 'e/align_left',
title: 'leftalign',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
alignment = 'justifyCenter';
this.addButton({
icon: 'e/align_center',
title: 'center',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
alignment = 'justifyRight';
this.addButton({
icon: 'e/align_right',
title: 'rightalign',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
},
/**
* Change the alignment to the specified justification.
*
* @method _changeStyle
* @param {EventFacade} e
* @param {string} justification The execCommand for the new justification.
* @private
*/
_changeStyle: function(e, justification) {
var host = this.get('host');
// We temporarily re-enable CSS styling to try to have the most consistency.
// Though, IE, as always, is stubborn and will do its own thing...
host.enableCssStyling();
document.execCommand(justification, false, null);
// Re-disable the CSS styling after making the change.
host.disableCssStyling();
// Mark the text as having been updated.
this.markUpdated();
this.editor.focus();
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_align-button",
"builds": {
"moodle-atto_align-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,92 @@
// 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/>.
/*
* @package atto_align
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_align-button
*/
/**
* Atto text editor align plugin.
*
* @namespace M.atto_align
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_align').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var alignment;
alignment = 'justifyLeft';
this.addButton({
icon: 'e/align_left',
title: 'leftalign',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
alignment = 'justifyCenter';
this.addButton({
icon: 'e/align_center',
title: 'center',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
alignment = 'justifyRight';
this.addButton({
icon: 'e/align_right',
title: 'rightalign',
buttonName: alignment,
callback: this._changeStyle,
callbackArgs: alignment
});
},
/**
* Change the alignment to the specified justification.
*
* @method _changeStyle
* @param {EventFacade} e
* @param {string} justification The execCommand for the new justification.
* @private
*/
_changeStyle: function(e, justification) {
var host = this.get('host');
// We temporarily re-enable CSS styling to try to have the most consistency.
// Though, IE, as always, is stubborn and will do its own thing...
host.enableCssStyling();
document.execCommand(justification, false, null);
// Re-disable the CSS styling after making the change.
host.disableCssStyling();
// Mark the text as having been updated.
this.markUpdated();
this.editor.focus();
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_align-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,25 @@
<?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_backcolor', language 'en'.
*
* @package atto_backcolor
* @copyright 2014 Rossiani Wijaya <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Background color';
@@ -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_backcolor
* @copyright 2014 Rossiani Wijaya <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014020600; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2013110500; // Requires this Moodle version.
$plugin->component = 'atto_backcolor'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,143 @@
YUI.add('moodle-atto_backcolor-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/>.
/*
* @package atto_backcolor
* @copyright 2014 Rossiani Wijaya <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_backcolor-button
*/
/**
* Atto text editor backcolor plugin.
*
* @namespace M.atto_backcolor
* @class button
* @extends M.editor_atto.EditorPlugin
*/
var doc = document,
BackColor = 'BackColor',
colors = [
{
name: 'white',
color: '#FFFFFF'
}, {
name: 'red',
color: '#EF4540'
}, {
name: 'yellow',
color: '#FFCF35'
}, {
name: 'green',
color: '#98CA3E'
}, {
name: 'blue',
color: '#7D9FD3'
}, {
name: 'black',
color: '#333333'
}
];
Y.namespace('M.atto_backcolor').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var items = [];
Y.Array.each(colors, function(color) {
items.push({
text: '<div style="width: 20px; height: 20px; border: 1px solid #CCC; background-color: ' +
color.color +
'"></div>',
callbackArgs: color.color
});
});
this.addToolbarMenu({
icon: 'e/text_highlight',
overlayWidth: '4',
globalItemConfig: {
callback: this._changeStyle
},
items: items
});
},
/**
* Change the background color to the specified color.
*
* @method _changeStyle
* @param {EventFacade} e
* @param {string} color The new background color
* @private
*/
_changeStyle: function(e, color) {
if (window.getSelection) {
// Test for IE9 and non-IE browsers.
try {
if (!doc.execCommand(BackColor, false, color)) {
this._fallbackChangeStyle(color);
}
} catch (ex) {
this._fallbackChangeStyle(color);
}
} else if (doc.selection && doc.selection.createRange) {
// Test for IE8 or less.
range = doc.selection.createRange();
range.execCommand(BackColor, false, color);
}
// Mark as updated
this.markUpdated();
},
/**
* Change the background color.
*
* This function is an alternative use for IE browsers.
*
* @method _fallbackChangeStyle
* @param {string} color The color for the background.
* @chainable
* @private
*/
_fallbackChangeStyle: function (color) {
var selection = window.getSelection(),
range;
if (selection.rangeCount && selection.getRangeAt) {
range = selection.getRangeAt(0);
}
doc.designMode = "on";
if (range) {
selection.removeAllRanges();
selection.addRange(range);
}
if (!doc.execCommand("HiliteColor", false, color)) {
doc.execCommand(BackColor, false, color);
}
doc.designMode = "off";
return this;
}
});
}, '@VERSION@');
@@ -0,0 +1 @@
YUI.add("moodle-atto_backcolor-button",function(e,t){var n=document,r="BackColor",i=[{name:"white",color:"#FFFFFF"},{name:"red",color:"#EF4540"},{name:"yellow",color:"#FFCF35"},{name:"green",color:"#98CA3E"},{name:"blue",color:"#7D9FD3"},{name:"black",color:"#333333"}];e.namespace("M.atto_backcolor").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){var t=[];e.Array.each(i,function(e){t.push({text:'<div style="width: 20px; height: 20px; border: 1px solid #CCC; background-color: '+e.color+'"></div>',callbackArgs:e.color})}),this.addToolbarMenu({icon:"e/text_highlight",overlayWidth:"4",globalItemConfig:{callback:this._changeStyle},items:t})},_changeStyle:function(e,t){if(window.getSelection)try{n.execCommand(r,!1,t)||this._fallbackChangeStyle(t)}catch(i){this._fallbackChangeStyle(t)}else n.selection&&n.selection.createRange&&(range=n.selection.createRange(),range.execCommand(r,!1,t));this.markUpdated()},_fallbackChangeStyle:function(e){var t=window.getSelection(),i;return t.rangeCount&&t.getRangeAt&&(i=t.getRangeAt(0)),n.designMode="on",i&&(t.removeAllRanges(),t.addRange(i)),n.execCommand("HiliteColor",!1,e)||n.execCommand(r,!1,e),n.designMode="off",this}})},"@VERSION@");
@@ -0,0 +1,143 @@
YUI.add('moodle-atto_backcolor-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/>.
/*
* @package atto_backcolor
* @copyright 2014 Rossiani Wijaya <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_backcolor-button
*/
/**
* Atto text editor backcolor plugin.
*
* @namespace M.atto_backcolor
* @class button
* @extends M.editor_atto.EditorPlugin
*/
var doc = document,
BackColor = 'BackColor',
colors = [
{
name: 'white',
color: '#FFFFFF'
}, {
name: 'red',
color: '#EF4540'
}, {
name: 'yellow',
color: '#FFCF35'
}, {
name: 'green',
color: '#98CA3E'
}, {
name: 'blue',
color: '#7D9FD3'
}, {
name: 'black',
color: '#333333'
}
];
Y.namespace('M.atto_backcolor').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var items = [];
Y.Array.each(colors, function(color) {
items.push({
text: '<div style="width: 20px; height: 20px; border: 1px solid #CCC; background-color: ' +
color.color +
'"></div>',
callbackArgs: color.color
});
});
this.addToolbarMenu({
icon: 'e/text_highlight',
overlayWidth: '4',
globalItemConfig: {
callback: this._changeStyle
},
items: items
});
},
/**
* Change the background color to the specified color.
*
* @method _changeStyle
* @param {EventFacade} e
* @param {string} color The new background color
* @private
*/
_changeStyle: function(e, color) {
if (window.getSelection) {
// Test for IE9 and non-IE browsers.
try {
if (!doc.execCommand(BackColor, false, color)) {
this._fallbackChangeStyle(color);
}
} catch (ex) {
this._fallbackChangeStyle(color);
}
} else if (doc.selection && doc.selection.createRange) {
// Test for IE8 or less.
range = doc.selection.createRange();
range.execCommand(BackColor, false, color);
}
// Mark as updated
this.markUpdated();
},
/**
* Change the background color.
*
* This function is an alternative use for IE browsers.
*
* @method _fallbackChangeStyle
* @param {string} color The color for the background.
* @chainable
* @private
*/
_fallbackChangeStyle: function (color) {
var selection = window.getSelection(),
range;
if (selection.rangeCount && selection.getRangeAt) {
range = selection.getRangeAt(0);
}
doc.designMode = "on";
if (range) {
selection.removeAllRanges();
selection.addRange(range);
}
if (!doc.execCommand("HiliteColor", false, color)) {
doc.execCommand(BackColor, false, color);
}
doc.designMode = "off";
return this;
}
});
}, '@VERSION@');
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_backcolor-button",
"builds": {
"moodle-atto_backcolor-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,138 @@
// 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/>.
/*
* @package atto_backcolor
* @copyright 2014 Rossiani Wijaya <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_backcolor-button
*/
/**
* Atto text editor backcolor plugin.
*
* @namespace M.atto_backcolor
* @class button
* @extends M.editor_atto.EditorPlugin
*/
var doc = document,
BackColor = 'BackColor',
colors = [
{
name: 'white',
color: '#FFFFFF'
}, {
name: 'red',
color: '#EF4540'
}, {
name: 'yellow',
color: '#FFCF35'
}, {
name: 'green',
color: '#98CA3E'
}, {
name: 'blue',
color: '#7D9FD3'
}, {
name: 'black',
color: '#333333'
}
];
Y.namespace('M.atto_backcolor').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var items = [];
Y.Array.each(colors, function(color) {
items.push({
text: '<div style="width: 20px; height: 20px; border: 1px solid #CCC; background-color: ' +
color.color +
'"></div>',
callbackArgs: color.color
});
});
this.addToolbarMenu({
icon: 'e/text_highlight',
overlayWidth: '4',
globalItemConfig: {
callback: this._changeStyle
},
items: items
});
},
/**
* Change the background color to the specified color.
*
* @method _changeStyle
* @param {EventFacade} e
* @param {string} color The new background color
* @private
*/
_changeStyle: function(e, color) {
if (window.getSelection) {
// Test for IE9 and non-IE browsers.
try {
if (!doc.execCommand(BackColor, false, color)) {
this._fallbackChangeStyle(color);
}
} catch (ex) {
this._fallbackChangeStyle(color);
}
} else if (doc.selection && doc.selection.createRange) {
// Test for IE8 or less.
range = doc.selection.createRange();
range.execCommand(BackColor, false, color);
}
// Mark as updated
this.markUpdated();
},
/**
* Change the background color.
*
* This function is an alternative use for IE browsers.
*
* @method _fallbackChangeStyle
* @param {string} color The color for the background.
* @chainable
* @private
*/
_fallbackChangeStyle: function (color) {
var selection = window.getSelection(),
range;
if (selection.rangeCount && selection.getRangeAt) {
range = selection.getRangeAt(0);
}
doc.designMode = "on";
if (range) {
selection.removeAllRanges();
selection.addRange(range);
}
if (!doc.execCommand("HiliteColor", false, color)) {
doc.execCommand(BackColor, false, color);
}
doc.designMode = "off";
return this;
}
});
@@ -0,0 +1,5 @@
{
"moodle-atto_backcolor-button": {
"requires": ["node"]
}
}
@@ -0,0 +1,25 @@
<?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_bold', language 'en'.
*
* @package atto_bold
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Bold';
+29
View File
@@ -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_bold
* @copyright 2013 Damyon Wiese <[email protected]>
* @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_bold'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,51 @@
YUI.add('moodle-atto_bold-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/>.
/*
* @package atto_bold
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_bold-button
*/
/**
* Atto text editor bold plugin.
*
* @namespace M.atto_bold
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_bold').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
this.addBasicButton({
exec: 'bold',
// Key code for the keyboard shortcut which triggers this button:
keys: '66',
// Watch the following tags and add/remove highlighting as appropriate:
tags: 'b, strong'
});
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_bold-button",function(e,t){e.namespace("M.atto_bold").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){this.addBasicButton({exec:"bold",keys:"66",tags:"b, strong"})}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
@@ -0,0 +1,51 @@
YUI.add('moodle-atto_bold-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/>.
/*
* @package atto_bold
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_bold-button
*/
/**
* Atto text editor bold plugin.
*
* @namespace M.atto_bold
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_bold').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
this.addBasicButton({
exec: 'bold',
// Key code for the keyboard shortcut which triggers this button:
keys: '66',
// Watch the following tags and add/remove highlighting as appropriate:
tags: 'b, strong'
});
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_bold-button",
"builds": {
"moodle-atto_bold-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,46 @@
// 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/>.
/*
* @package atto_bold
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_bold-button
*/
/**
* Atto text editor bold plugin.
*
* @namespace M.atto_bold
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_bold').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
this.addBasicButton({
exec: 'bold',
// Key code for the keyboard shortcut which triggers this button:
keys: '66',
// Watch the following tags and add/remove highlighting as appropriate:
tags: 'b, strong'
});
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_bold-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,281 @@
<?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_charmap', language 'en'.
*
* @package atto_charmap
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['insertcharacter'] = 'Insert character';
$string['pluginname'] = 'Insert character';
// The following are not ordered on purpose, they are kept
// in the order in which they appear in the user interface.
$string['nobreakspace'] = 'no-break space';
$string['ampersand'] = 'ampersand';
$string['quotationmark'] = 'quotation mark';
$string['centsign'] = 'cent sign';
$string['eurosign'] = 'euro sign';
$string['poundsign'] = 'pound sign';
$string['yensign'] = 'yen sign';
$string['copyrightsign'] = 'copyright sign';
$string['registeredsign'] = 'registered sign';
$string['trademarksign'] = 'trade mark sign';
$string['permillesign'] = 'per mille sign';
$string['microsign'] = 'micro sign';
$string['middledot'] = 'middle dot';
$string['bullet'] = 'bullet';
$string['threedotleader'] = 'three dot leader';
$string['minutesfeet'] = 'minutes / feet';
$string['secondsinches'] = 'seconds / inches';
$string['sectionsign'] = 'section sign';
$string['paragraphsign'] = 'paragraph sign';
$string['sharpsesszed'] = 'sharp s / ess-zed';
$string['singleleftpointinganglequotationmark'] = 'single left-pointing angle quotation mark';
$string['singlerightpointinganglequotationmark'] = 'single right-pointing angle quotation mark';
$string['leftpointingguillemet'] = 'left pointing guillemet';
$string['rightpointingguillemet'] = 'right pointing guillemet';
$string['leftsinglequotationmark'] = 'left single quotation mark';
$string['rightsinglequotationmark'] = 'right single quotation mark';
$string['leftdoublequotationmark'] = 'left double quotation mark';
$string['rightdoublequotationmark'] = 'right double quotation mark';
$string['singlelow9quotationmark'] = 'single low-9 quotation mark';
$string['doublelow9quotationmark'] = 'double low-9 quotation mark';
$string['lessthansign'] = 'less-than sign';
$string['greaterthansign'] = 'greater-than sign';
$string['lessthanorequalto'] = 'less-than or equal to';
$string['greaterthanorequalto'] = 'greater-than or equal to';
$string['endash'] = 'en dash';
$string['emdash'] = 'em dash';
$string['macron'] = 'macron';
$string['overline'] = 'overline';
$string['currencysign'] = 'currency sign';
$string['brokenbar'] = 'broken bar';
$string['diaeresis'] = 'diaeresis';
$string['invertedexclamationmark'] = 'inverted exclamation mark';
$string['turnedquestionmark'] = 'turned question mark';
$string['circumflexaccent'] = 'circumflex accent';
$string['smalltilde'] = 'small tilde';
$string['degreesign'] = 'degree sign';
$string['minussign'] = 'minus sign';
$string['plusminussign'] = 'plus-minus sign';
$string['divisionsign'] = 'division sign';
$string['fractionslash'] = 'fraction slash';
$string['multiplicationsign'] = 'multiplication sign';
$string['superscriptone'] = 'superscript one';
$string['superscripttwo'] = 'superscript two';
$string['superscriptthree'] = 'superscript three';
$string['fractiononequarter'] = 'fraction one quarter';
$string['fractiononehalf'] = 'fraction one half';
$string['fractionthreequarters'] = 'fraction three quarters';
$string['functionflorin'] = 'function / florin';
$string['integral'] = 'integral';
$string['narysumation'] = 'n-ary sumation';
$string['infinity'] = 'infinity';
$string['squareroot'] = 'square root';
$string['similarto'] = 'similar to';
$string['approximatelyequalto'] = 'approximately equal to';
$string['almostequalto'] = 'almost equal to';
$string['notequalto'] = 'not equal to';
$string['identicalto'] = 'identical to';
$string['elementof'] = 'element of';
$string['notanelementof'] = 'not an element of';
$string['containsasmember'] = 'contains as member';
$string['naryproduct'] = 'n-ary product';
$string['logicaland'] = 'logical and';
$string['logicalor'] = 'logical or';
$string['notsign'] = 'not sign';
$string['intersection'] = 'intersection';
$string['union'] = 'union';
$string['partialdifferential'] = 'partial differential';
$string['forall'] = 'for all';
$string['thereexists'] = 'there exists';
$string['diameter'] = 'diameter';
$string['backwarddifference'] = 'backward difference';
$string['asteriskoperator'] = 'asterisk operator';
$string['proportionalto'] = 'proportional to';
$string['angle'] = 'angle';
$string['acuteaccent'] = 'acute accent';
$string['cedilla'] = 'cedilla';
$string['feminineordinalindicator'] = 'feminine ordinal indicator';
$string['masculineordinalindicator'] = 'masculine ordinal indicator';
$string['dagger'] = 'dagger';
$string['doubledagger'] = 'double dagger';
$string['agrave_caps'] = 'A - grave';
$string['aacute_caps'] = 'A - acute';
$string['acircumflex_caps'] = 'A - circumflex';
$string['atilde_caps'] = 'A - tilde';
$string['adiaeresis_caps'] = 'A - diaeresis';
$string['aringabove_caps'] = 'A - ring above';
$string['ligatureae_caps'] = 'ligature AE';
$string['ccedilla_caps'] = 'C - cedilla';
$string['egrave_caps'] = 'E - grave';
$string['eacute_caps'] = 'E - acute';
$string['ecircumflex_caps'] = 'E - circumflex';
$string['ediaeresis_caps'] = 'E - diaeresis';
$string['igrave_caps'] = 'I - grave';
$string['iacute_caps'] = 'I - acute';
$string['icircumflex_caps'] = 'I - circumflex';
$string['idiaeresis_caps'] = 'I - diaeresis';
$string['eth_caps'] = 'ETH';
$string['ntilde_caps'] = 'N - tilde';
$string['ograve_caps'] = 'O - grave';
$string['oacute_caps'] = 'O - acute';
$string['ocircumflex_caps'] = 'O - circumflex';
$string['otilde_caps'] = 'O - tilde';
$string['odiaeresis_caps'] = 'O - diaeresis';
$string['oslash_caps'] = 'O - slash';
$string['ligatureoe_caps'] = 'ligature OE';
$string['scaron_caps'] = 'S - caron';
$string['ugrave_caps'] = 'U - grave';
$string['uacute_caps'] = 'U - acute';
$string['ucircumflex_caps'] = 'U - circumflex';
$string['udiaeresis_caps'] = 'U - diaeresis';
$string['yacute_caps'] = 'Y - acute';
$string['ydiaeresis_caps'] = 'Y - diaeresis';
$string['thorn_caps'] = 'THORN';
$string['agrave'] = 'a - grave';
$string['aacute'] = 'a - acute';
$string['acircumflex'] = 'a - circumflex';
$string['atilde'] = 'a - tilde';
$string['adiaeresis'] = 'a - diaeresis';
$string['aringabove'] = 'a - ring above';
$string['ligatureae'] = 'ligature ae';
$string['ccedilla'] = 'c - cedilla';
$string['egrave'] = 'e - grave';
$string['eacute'] = 'e - acute';
$string['ecircumflex'] = 'e - circumflex';
$string['ediaeresis'] = 'e - diaeresis';
$string['igrave'] = 'i - grave';
$string['iacute'] = 'i - acute';
$string['icircumflex'] = 'i - circumflex';
$string['idiaeresis'] = 'i - diaeresis';
$string['eth'] = 'eth';
$string['ntilde'] = 'n - tilde';
$string['ograve'] = 'o - grave';
$string['oacute'] = 'o - acute';
$string['ocircumflex'] = 'o - circumflex';
$string['otilde'] = 'o - tilde';
$string['odiaeresis'] = 'o - diaeresis';
$string['oslash'] = 'o slash';
$string['ligatureoe'] = 'ligature oe';
$string['scaron'] = 's - caron';
$string['ugrave'] = 'u - grave';
$string['uacute'] = 'u - acute';
$string['ucircumflex'] = 'u - circumflex';
$string['udiaeresis'] = 'u - diaeresis';
$string['yacute'] = 'y - acute';
$string['thorn'] = 'thorn';
$string['ydiaeresis'] = 'y - diaeresis';
$string['alpha_caps'] = 'Alpha';
$string['beta_caps'] = 'Beta';
$string['gamma_caps'] = 'Gamma';
$string['delta_caps'] = 'Delta';
$string['epsilon_caps'] = 'Epsilon';
$string['zeta_caps'] = 'Zeta';
$string['eta_caps'] = 'Eta';
$string['theta_caps'] = 'Theta';
$string['iota_caps'] = 'Iota';
$string['kappa_caps'] = 'Kappa';
$string['lambda_caps'] = 'Lambda';
$string['mu_caps'] = 'Mu';
$string['nu_caps'] = 'Nu';
$string['xi_caps'] = 'Xi';
$string['omicron_caps'] = 'Omicron';
$string['pi_caps'] = 'Pi';
$string['rho_caps'] = 'Rho';
$string['sigma_caps'] = 'Sigma';
$string['tau_caps'] = 'Tau';
$string['upsilon_caps'] = 'Upsilon';
$string['phi_caps'] = 'Phi';
$string['chi_caps'] = 'Chi';
$string['psi_caps'] = 'Psi';
$string['omega_caps'] = 'Omega';
$string['alpha'] = 'alpha';
$string['beta'] = 'beta';
$string['gamma'] = 'gamma';
$string['delta'] = 'delta';
$string['epsilon'] = 'epsilon';
$string['zeta'] = 'zeta';
$string['eta'] = 'eta';
$string['theta'] = 'theta';
$string['iota'] = 'iota';
$string['kappa'] = 'kappa';
$string['lambda'] = 'lambda';
$string['mu'] = 'mu';
$string['nu'] = 'nu';
$string['xi'] = 'xi';
$string['omicron'] = 'omicron';
$string['pi'] = 'pi';
$string['rho'] = 'rho';
$string['finalsigma'] = 'final sigma';
$string['sigma'] = 'sigma';
$string['tau'] = 'tau';
$string['upsilon'] = 'upsilon';
$string['phi'] = 'phi';
$string['chi'] = 'chi';
$string['psi'] = 'psi';
$string['omega'] = 'omega';
$string['alefsymbol'] = 'alef symbol';
$string['pisymbol'] = 'pi symbol';
$string['realpartsymbol'] = 'real part symbol';
$string['thetasymbol'] = 'theta symbol';
$string['upsilonhooksymbol'] = 'upsilon - hook symbol';
$string['weierstrassp'] = 'Weierstrass p';
$string['imaginarypart'] = 'imaginary part';
$string['leftwardsarrow'] = 'leftwards arrow';
$string['upwardsarrow'] = 'upwards arrow';
$string['rightwardsarrow'] = 'rightwards arrow';
$string['downwardsarrow'] = 'downwards arrow';
$string['leftrightarrow'] = 'left right arrow';
$string['carriagereturn'] = 'carriage return';
$string['leftwardsdoublearrow'] = 'leftwards double arrow';
$string['upwardsdoublearrow'] = 'upwards double arrow';
$string['rightwardsdoublearrow'] = 'rightwards double arrow';
$string['downwardsdoublearrow'] = 'downwards double arrow';
$string['leftrightdoublearrow'] = 'left right double arrow';
$string['therefore'] = 'therefore';
$string['subsetof'] = 'subset of';
$string['supersetof'] = 'superset of';
$string['notasubsetof'] = 'not a subset of';
$string['subsetoforequalto'] = 'subset of or equal to';
$string['supersetoforequalto'] = 'superset of or equal to';
$string['circledplus'] = 'circled plus';
$string['circledtimes'] = 'circled times';
$string['perpendicular'] = 'perpendicular';
$string['dotoperator'] = 'dot operator';
$string['leftceiling'] = 'left ceiling';
$string['rightceiling'] = 'right ceiling';
$string['leftfloor'] = 'left floor';
$string['rightfloor'] = 'right floor';
$string['leftpointinganglebracket'] = 'left-pointing angle bracket';
$string['rightpointinganglebracket'] = 'right-pointing angle bracket';
$string['lozenge'] = 'lozenge';
$string['blackspadesuit'] = 'black spade suit';
$string['blackclubsuit'] = 'black club suit';
$string['blackheartsuit'] = 'black heart suit';
$string['blackdiamondsuit'] = 'black diamond suit';
$string['enspace'] = 'en space';
$string['emspace'] = 'em space';
$string['thinspace'] = 'thin space';
$string['zerowidthnonjoiner'] = 'zero width non-joiner';
$string['zerowidthjoiner'] = 'zero width joiner';
$string['lefttorightmark'] = 'left-to-right mark';
$string['righttoleftmark'] = 'right-to-left mark';
$string['softhyphen'] = 'soft hyphen';
+295
View File
@@ -0,0 +1,295 @@
<?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 charmap plugin lib.
*
* @package atto_charmap
* @copyright 2014 Frédéric Massart
* @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_charmap_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(
'insertcharacter',
'nobreakspace',
'ampersand',
'quotationmark',
'centsign',
'eurosign',
'poundsign',
'yensign',
'copyrightsign',
'registeredsign',
'trademarksign',
'permillesign',
'microsign',
'middledot',
'bullet',
'threedotleader',
'minutesfeet',
'secondsinches',
'sectionsign',
'paragraphsign',
'sharpsesszed',
'singleleftpointinganglequotationmark',
'singlerightpointinganglequotationmark',
'leftpointingguillemet',
'rightpointingguillemet',
'leftsinglequotationmark',
'rightsinglequotationmark',
'leftdoublequotationmark',
'rightdoublequotationmark',
'singlelow9quotationmark',
'doublelow9quotationmark',
'lessthansign',
'greaterthansign',
'lessthanorequalto',
'greaterthanorequalto',
'endash',
'emdash',
'macron',
'overline',
'currencysign',
'brokenbar',
'diaeresis',
'invertedexclamationmark',
'turnedquestionmark',
'circumflexaccent',
'smalltilde',
'degreesign',
'minussign',
'plusminussign',
'divisionsign',
'fractionslash',
'multiplicationsign',
'superscriptone',
'superscripttwo',
'superscriptthree',
'fractiononequarter',
'fractiononehalf',
'fractionthreequarters',
'functionflorin',
'integral',
'narysumation',
'infinity',
'squareroot',
// 'similarto',
// 'approximatelyequalto',
'almostequalto',
'notequalto',
'identicalto',
// 'elementof',
// 'notanelementof',
// 'containsasmember',
'naryproduct',
// 'logicaland',
// 'logicalor',
'notsign',
'intersection',
// 'union',
'partialdifferential',
// 'forall',
// 'thereexists',
// 'diameter',
// 'backwarddifference',
// 'asteriskoperator',
// 'proportionalto',
// 'angle',
'acuteaccent',
'cedilla',
'feminineordinalindicator',
'masculineordinalindicator',
'dagger',
'doubledagger',
'agrave_caps',
'aacute_caps',
'acircumflex_caps',
'atilde_caps',
'adiaeresis_caps',
'aringabove_caps',
'ligatureae_caps',
'ccedilla_caps',
'egrave_caps',
'eacute_caps',
'ecircumflex_caps',
'ediaeresis_caps',
'igrave_caps',
'iacute_caps',
'icircumflex_caps',
'idiaeresis_caps',
'eth_caps',
'ntilde_caps',
'ograve_caps',
'oacute_caps',
'ocircumflex_caps',
'otilde_caps',
'odiaeresis_caps',
'oslash_caps',
'ligatureoe_caps',
'scaron_caps',
'ugrave_caps',
'uacute_caps',
'ucircumflex_caps',
'udiaeresis_caps',
'yacute_caps',
'ydiaeresis_caps',
'thorn_caps',
'agrave',
'aacute',
'acircumflex',
'atilde',
'adiaeresis',
'aringabove',
'ligatureae',
'ccedilla',
'egrave',
'eacute',
'ecircumflex',
'ediaeresis',
'igrave',
'iacute',
'icircumflex',
'idiaeresis',
'eth',
'ntilde',
'ograve',
'oacute',
'ocircumflex',
'otilde',
'odiaeresis',
'oslash',
'ligatureoe',
'scaron',
'ugrave',
'uacute',
'ucircumflex',
'udiaeresis',
'yacute',
'thorn',
'ydiaeresis',
'alpha_caps',
'beta_caps',
'gamma_caps',
'delta_caps',
'epsilon_caps',
'zeta_caps',
'eta_caps',
'theta_caps',
'iota_caps',
'kappa_caps',
'lambda_caps',
'mu_caps',
'nu_caps',
'xi_caps',
'omicron_caps',
'pi_caps',
'rho_caps',
'sigma_caps',
'tau_caps',
'upsilon_caps',
'phi_caps',
'chi_caps',
'psi_caps',
'omega_caps',
'alpha',
'beta',
'gamma',
'delta',
'epsilon',
'zeta',
'eta',
'theta',
'iota',
'kappa',
'lambda',
'mu',
'nu',
'xi',
'omicron',
'pi',
'rho',
'finalsigma',
'sigma',
'tau',
'upsilon',
'phi',
'chi',
'psi',
'omega',
// 'alefsymbol',
// 'pisymbol',
// 'realpartsymbol',
// 'thetasymbol',
// 'upsilonhooksymbol',
// 'weierstrassp',
// 'imaginarypart',
'leftwardsarrow',
'upwardsarrow',
'rightwardsarrow',
'downwardsarrow',
'leftrightarrow',
// 'carriagereturn',
// 'leftwardsdoublearrow',
// 'upwardsdoublearrow',
// 'rightwardsdoublearrow',
// 'downwardsdoublearrow',
// 'leftrightdoublearrow',
// 'therefore',
// 'subsetof',
// 'supersetof',
// 'notasubsetof',
// 'subsetoforequalto',
// 'supersetoforequalto',
// 'circledplus',
// 'circledtimes',
// 'perpendicular',
// 'dotoperator',
// 'leftceiling',
// 'rightceiling',
// 'leftfloor',
// 'rightfloor',
// 'leftpointinganglebracket',
// 'rightpointinganglebracket',
'lozenge',
'blackspadesuit',
'blackclubsuit',
'blackheartsuit',
'blackdiamondsuit',
// 'enspace',
// 'emspace',
// 'thinspace',
// 'zerowidthnonjoiner',
// 'zerowidthjoiner',
// 'lefttorightmark',
// 'righttoleftmark',
// 'softhyphen',
),
'atto_charmap'
);
}
@@ -0,0 +1,4 @@
.atto_charmap_selector button {
width: 2em;
padding: 0 3px;
}
@@ -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 charmap plugin version file.
*
* @package atto_charmap
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014013000; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2013110500; // Requires this Moodle version.
$plugin->component = 'atto_charmap'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,417 @@
YUI.add('moodle-atto_charmap-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/>.
/*
* @package atto_charmap
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Atto text editor character map plugin
*
* @module moodle-atto_charmap-button
*/
var COMPONENTNAME = 'atto_charmap',
CSS = {
BUTTON: 'atto_charmap_character',
CHARMAP: 'atto_charmap_selector'
},
/*
* Map of special characters, kindly borrowed from TinyMCE.
*
* Each entries contains in order:
* - {String} HTML code
* - {String} HTML numerical code
* - {Boolean} Whether or not to include it in the list
* - {String} The language string key
*
* @property CHARMAP
* @type {Array}
*/
CHARMAP = [
['&nbsp;', '&#160;', true, 'nobreakspace'],
['&amp;', '&#38;', true, 'ampersand'],
['&quot;', '&#34;', true, 'quotationmark'],
// Finance.
['&cent;', '&#162;', true, 'centsign'],
['&euro;', '&#8364;', true, 'eurosign'],
['&pound;', '&#163;', true, 'poundsign'],
['&yen;', '&#165;', true, 'yensign'],
// Signs.
['&copy;', '&#169;', true, 'copyrightsign'],
['&reg;', '&#174;', true, 'registeredsign'],
['&trade;', '&#8482;', true, 'trademarksign'],
['&permil;', '&#8240;', true, 'permillesign'],
['&micro;', '&#181;', true, 'microsign'],
['&middot;', '&#183;', true, 'middledot'],
['&bull;', '&#8226;', true, 'bullet'],
['&hellip;', '&#8230;', true, 'threedotleader'],
['&prime;', '&#8242;', true, 'minutesfeet'],
['&Prime;', '&#8243;', true, 'secondsinches'],
['&sect;', '&#167;', true, 'sectionsign'],
['&para;', '&#182;', true, 'paragraphsign'],
['&szlig;', '&#223;', true, 'sharpsesszed'],
// Quotations.
['&lsaquo;', '&#8249;', true, 'singleleftpointinganglequotationmark'],
['&rsaquo;', '&#8250;', true, 'singlerightpointinganglequotationmark'],
['&laquo;', '&#171;', true, 'leftpointingguillemet'],
['&raquo;', '&#187;', true, 'rightpointingguillemet'],
['&lsquo;', '&#8216;', true, 'leftsinglequotationmark'],
['&rsquo;', '&#8217;', true, 'rightsinglequotationmark'],
['&ldquo;', '&#8220;', true, 'leftdoublequotationmark'],
['&rdquo;', '&#8221;', true, 'rightdoublequotationmark'],
['&sbquo;', '&#8218;', true, 'singlelow9quotationmark'],
['&bdquo;', '&#8222;', true, 'doublelow9quotationmark'],
['&lt;', '&#60;', true, 'lessthansign'],
['&gt;', '&#62;', true, 'greaterthansign'],
['&le;', '&#8804;', true, 'lessthanorequalto'],
['&ge;', '&#8805;', true, 'greaterthanorequalto'],
['&ndash;', '&#8211;', true, 'endash'],
['&mdash;', '&#8212;', true, 'emdash'],
['&macr;', '&#175;', true, 'macron'],
['&oline;', '&#8254;', true, 'overline'],
['&curren;', '&#164;', true, 'currencysign'],
['&brvbar;', '&#166;', true, 'brokenbar'],
['&uml;', '&#168;', true, 'diaeresis'],
['&iexcl;', '&#161;', true, 'invertedexclamationmark'],
['&iquest;', '&#191;', true, 'turnedquestionmark'],
['&circ;', '&#710;', true, 'circumflexaccent'],
['&tilde;', '&#732;', true, 'smalltilde'],
['&deg;', '&#176;', true, 'degreesign'],
['&minus;', '&#8722;', true, 'minussign'],
['&plusmn;', '&#177;', true, 'plusminussign'],
['&divide;', '&#247;', true, 'divisionsign'],
['&frasl;', '&#8260;', true, 'fractionslash'],
['&times;', '&#215;', true, 'multiplicationsign'],
['&sup1;', '&#185;', true, 'superscriptone'],
['&sup2;', '&#178;', true, 'superscripttwo'],
['&sup3;', '&#179;', true, 'superscriptthree'],
['&frac14;', '&#188;', true, 'fractiononequarter'],
['&frac12;', '&#189;', true, 'fractiononehalf'],
['&frac34;', '&#190;', true, 'fractionthreequarters'],
// Math / logical.
['&fnof;', '&#402;', true, 'functionflorin'],
['&int;', '&#8747;', true, 'integral'],
['&sum;', '&#8721;', true, 'narysumation'],
['&infin;', '&#8734;', true, 'infinity'],
['&radic;', '&#8730;', true, 'squareroot'],
['&sim;', '&#8764;', false,'similarto'],
['&cong;', '&#8773;', false,'approximatelyequalto'],
['&asymp;', '&#8776;', true, 'almostequalto'],
['&ne;', '&#8800;', true, 'notequalto'],
['&equiv;', '&#8801;', true, 'identicalto'],
['&isin;', '&#8712;', false,'elementof'],
['&notin;', '&#8713;', false,'notanelementof'],
['&ni;', '&#8715;', false,'containsasmember'],
['&prod;', '&#8719;', true, 'naryproduct'],
['&and;', '&#8743;', false,'logicaland'],
['&or;', '&#8744;', false,'logicalor'],
['&not;', '&#172;', true, 'notsign'],
['&cap;', '&#8745;', true, 'intersection'],
['&cup;', '&#8746;', false,'union'],
['&part;', '&#8706;', true, 'partialdifferential'],
['&forall;', '&#8704;', false,'forall'],
['&exist;', '&#8707;', false,'thereexists'],
['&empty;', '&#8709;', false,'diameter'],
['&nabla;', '&#8711;', false,'backwarddifference'],
['&lowast;', '&#8727;', false,'asteriskoperator'],
['&prop;', '&#8733;', false,'proportionalto'],
['&ang;', '&#8736;', false,'angle'],
// Undefined.
['&acute;', '&#180;', true, 'acuteaccent'],
['&cedil;', '&#184;', true, 'cedilla'],
['&ordf;', '&#170;', true, 'feminineordinalindicator'],
['&ordm;', '&#186;', true, 'masculineordinalindicator'],
['&dagger;', '&#8224;', true, 'dagger'],
['&Dagger;', '&#8225;', true, 'doubledagger'],
// Alphabetical special chars.
['&Agrave;', '&#192;', true, 'agrave_caps'],
['&Aacute;', '&#193;', true, 'aacute_caps'],
['&Acirc;', '&#194;', true, 'acircumflex_caps'],
['&Atilde;', '&#195;', true, 'atilde_caps'],
['&Auml;', '&#196;', true, 'adiaeresis_caps'],
['&Aring;', '&#197;', true, 'aringabove_caps'],
['&AElig;', '&#198;', true, 'ligatureae_caps'],
['&Ccedil;', '&#199;', true, 'ccedilla_caps'],
['&Egrave;', '&#200;', true, 'egrave_caps'],
['&Eacute;', '&#201;', true, 'eacute_caps'],
['&Ecirc;', '&#202;', true, 'ecircumflex_caps'],
['&Euml;', '&#203;', true, 'ediaeresis_caps'],
['&Igrave;', '&#204;', true, 'igrave_caps'],
['&Iacute;', '&#205;', true, 'iacute_caps'],
['&Icirc;', '&#206;', true, 'icircumflex_caps'],
['&Iuml;', '&#207;', true, 'idiaeresis_caps'],
['&ETH;', '&#208;', true, 'eth_caps'],
['&Ntilde;', '&#209;', true, 'ntilde_caps'],
['&Ograve;', '&#210;', true, 'ograve_caps'],
['&Oacute;', '&#211;', true, 'oacute_caps'],
['&Ocirc;', '&#212;', true, 'ocircumflex_caps'],
['&Otilde;', '&#213;', true, 'otilde_caps'],
['&Ouml;', '&#214;', true, 'odiaeresis_caps'],
['&Oslash;', '&#216;', true, 'oslash_caps'],
['&OElig;', '&#338;', true, 'ligatureoe_caps'],
['&Scaron;', '&#352;', true, 'scaron_caps'],
['&Ugrave;', '&#217;', true, 'ugrave_caps'],
['&Uacute;', '&#218;', true, 'uacute_caps'],
['&Ucirc;', '&#219;', true, 'ucircumflex_caps'],
['&Uuml;', '&#220;', true, 'udiaeresis_caps'],
['&Yacute;', '&#221;', true, 'yacute_caps'],
['&Yuml;', '&#376;', true, 'ydiaeresis_caps'],
['&THORN;', '&#222;', true, 'thorn_caps'],
['&agrave;', '&#224;', true, 'agrave'],
['&aacute;', '&#225;', true, 'aacute'],
['&acirc;', '&#226;', true, 'acircumflex'],
['&atilde;', '&#227;', true, 'atilde'],
['&auml;', '&#228;', true, 'adiaeresis'],
['&aring;', '&#229;', true, 'aringabove'],
['&aelig;', '&#230;', true, 'ligatureae'],
['&ccedil;', '&#231;', true, 'ccedilla'],
['&egrave;', '&#232;', true, 'egrave'],
['&eacute;', '&#233;', true, 'eacute'],
['&ecirc;', '&#234;', true, 'ecircumflex'],
['&euml;', '&#235;', true, 'ediaeresis'],
['&igrave;', '&#236;', true, 'igrave'],
['&iacute;', '&#237;', true, 'iacute'],
['&icirc;', '&#238;', true, 'icircumflex'],
['&iuml;', '&#239;', true, 'idiaeresis'],
['&eth;', '&#240;', true, 'eth'],
['&ntilde;', '&#241;', true, 'ntilde'],
['&ograve;', '&#242;', true, 'ograve'],
['&oacute;', '&#243;', true, 'oacute'],
['&ocirc;', '&#244;', true, 'ocircumflex'],
['&otilde;', '&#245;', true, 'otilde'],
['&ouml;', '&#246;', true, 'odiaeresis'],
['&oslash;', '&#248;', true, 'oslash'],
['&oelig;', '&#339;', true, 'ligatureoe'],
['&scaron;', '&#353;', true, 'scaron'],
['&ugrave;', '&#249;', true, 'ugrave'],
['&uacute;', '&#250;', true, 'uacute'],
['&ucirc;', '&#251;', true, 'ucircumflex'],
['&uuml;', '&#252;', true, 'udiaeresis'],
['&yacute;', '&#253;', true, 'yacute'],
['&thorn;', '&#254;', true, 'thorn'],
['&yuml;', '&#255;', true, 'ydiaeresis'],
['&Alpha;', '&#913;', true, 'alpha_caps'],
['&Beta;', '&#914;', true, 'beta_caps'],
['&Gamma;', '&#915;', true, 'gamma_caps'],
['&Delta;', '&#916;', true, 'delta_caps'],
['&Epsilon;', '&#917;', true, 'epsilon_caps'],
['&Zeta;', '&#918;', true, 'zeta_caps'],
['&Eta;', '&#919;', true, 'eta_caps'],
['&Theta;', '&#920;', true, 'theta_caps'],
['&Iota;', '&#921;', true, 'iota_caps'],
['&Kappa;', '&#922;', true, 'kappa_caps'],
['&Lambda;', '&#923;', true, 'lambda_caps'],
['&Mu;', '&#924;', true, 'mu_caps'],
['&Nu;', '&#925;', true, 'nu_caps'],
['&Xi;', '&#926;', true, 'xi_caps'],
['&Omicron;', '&#927;', true, 'omicron_caps'],
['&Pi;', '&#928;', true, 'pi_caps'],
['&Rho;', '&#929;', true, 'rho_caps'],
['&Sigma;', '&#931;', true, 'sigma_caps'],
['&Tau;', '&#932;', true, 'tau_caps'],
['&Upsilon;', '&#933;', true, 'upsilon_caps'],
['&Phi;', '&#934;', true, 'phi_caps'],
['&Chi;', '&#935;', true, 'chi_caps'],
['&Psi;', '&#936;', true, 'psi_caps'],
['&Omega;', '&#937;', true, 'omega_caps'],
['&alpha;', '&#945;', true, 'alpha'],
['&beta;', '&#946;', true, 'beta'],
['&gamma;', '&#947;', true, 'gamma'],
['&delta;', '&#948;', true, 'delta'],
['&epsilon;', '&#949;', true, 'epsilon'],
['&zeta;', '&#950;', true, 'zeta'],
['&eta;', '&#951;', true, 'eta'],
['&theta;', '&#952;', true, 'theta'],
['&iota;', '&#953;', true, 'iota'],
['&kappa;', '&#954;', true, 'kappa'],
['&lambda;', '&#955;', true, 'lambda'],
['&mu;', '&#956;', true, 'mu'],
['&nu;', '&#957;', true, 'nu'],
['&xi;', '&#958;', true, 'xi'],
['&omicron;', '&#959;', true, 'omicron'],
['&pi;', '&#960;', true, 'pi'],
['&rho;', '&#961;', true, 'rho'],
['&sigmaf;', '&#962;', true, 'finalsigma'],
['&sigma;', '&#963;', true, 'sigma'],
['&tau;', '&#964;', true, 'tau'],
['&upsilon;', '&#965;', true, 'upsilon'],
['&phi;', '&#966;', true, 'phi'],
['&chi;', '&#967;', true, 'chi'],
['&psi;', '&#968;', true, 'psi'],
['&omega;', '&#969;', true, 'omega'],
// Symbols.
['&alefsym;', '&#8501;', false,'alefsymbol'],
['&piv;', '&#982;', false,'pisymbol'],
['&real;', '&#8476;', false,'realpartsymbol'],
['&thetasym;','&#977;', false,'thetasymbol'],
['&upsih;', '&#978;', false,'upsilonhooksymbol'],
['&weierp;', '&#8472;', false,'weierstrassp'],
['&image;', '&#8465;', false,'imaginarypart'],
// Arrows.
['&larr;', '&#8592;', true, 'leftwardsarrow'],
['&uarr;', '&#8593;', true, 'upwardsarrow'],
['&rarr;', '&#8594;', true, 'rightwardsarrow'],
['&darr;', '&#8595;', true, 'downwardsarrow'],
['&harr;', '&#8596;', true, 'leftrightarrow'],
['&crarr;', '&#8629;', false,'carriagereturn'],
['&lArr;', '&#8656;', false,'leftwardsdoublearrow'],
['&uArr;', '&#8657;', false,'upwardsdoublearrow'],
['&rArr;', '&#8658;', false,'rightwardsdoublearrow'],
['&dArr;', '&#8659;', false,'downwardsdoublearrow'],
['&hArr;', '&#8660;', false,'leftrightdoublearrow'],
['&there4;', '&#8756;', false,'therefore'],
['&sub;', '&#8834;', false,'subsetof'],
['&sup;', '&#8835;', false,'supersetof'],
['&nsub;', '&#8836;', false,'notasubsetof'],
['&sube;', '&#8838;', false,'subsetoforequalto'],
['&supe;', '&#8839;', false,'supersetoforequalto'],
['&oplus;', '&#8853;', false,'circledplus'],
['&otimes;', '&#8855;', false,'circledtimes'],
['&perp;', '&#8869;', false,'perpendicular'],
['&sdot;', '&#8901;', false,'dotoperator'],
['&lceil;', '&#8968;', false,'leftceiling'],
['&rceil;', '&#8969;', false,'rightceiling'],
['&lfloor;', '&#8970;', false,'leftfloor'],
['&rfloor;', '&#8971;', false,'rightfloor'],
['&lang;', '&#9001;', false,'leftpointinganglebracket'],
['&rang;', '&#9002;', false,'rightpointinganglebracket'],
['&loz;', '&#9674;', true, 'lozenge'],
['&spades;', '&#9824;', true, 'blackspadesuit'],
['&clubs;', '&#9827;', true, 'blackclubsuit'],
['&hearts;', '&#9829;', true, 'blackheartsuit'],
['&diams;', '&#9830;', true, 'blackdiamondsuit'],
['&ensp;', '&#8194;', false,'enspace'],
['&emsp;', '&#8195;', false,'emspace'],
['&thinsp;', '&#8201;', false,'thinspace'],
['&zwnj;', '&#8204;', false,'zerowidthnonjoiner'],
['&zwj;', '&#8205;', false,'zerowidthjoiner'],
['&lrm;', '&#8206;', false,'lefttorightmark'],
['&rlm;', '&#8207;', false,'righttoleftmark'],
['&shy;', '&#173;', false,'softhyphen']
];
/**
* Atto text editor charmap plugin.
*
* @namespace M.atto_charmap
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_charmap').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* A reference to the current selection at the time that the dialogue
* was opened.
*
* @property _currentSelection
* @type Range
* @private
*/
_currentSelection: null,
initializer: function() {
this.addButton({
icon: 'e/special_character',
callback: this._displayDialogue
});
},
/**
* Display the Character Map selector.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
// Store the current selection.
this._currentSelection = this.get('host').getSelection();
if (this._currentSelection === false) {
return;
}
var dialogue = this.getDialogue({
headerContent: M.util.get_string('insertcharacter', COMPONENTNAME),
focusAfterHide: true
}, true);
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(
'<div class="{{CSS.CHARMAP}}">' +
'{{#each CHARMAP}}' +
'{{#if this.[2]}}' +
'<button class="{{../../CSS.BUTTON}}" ' +
'aria-label="{{get_string this.[3] ../../component}}" ' +
'title="{{get_string this.[3] ../../component}}" ' +
'data-character="{{this.[0]}}" ' +
'>{{{this.[0]}}}</button>' +
'{{/if}}' +
'{{/each}}' +
'</div>'
);
var content = Y.Node.create(template({
component: COMPONENTNAME,
CSS: CSS,
CHARMAP: CHARMAP
}));
content.delegate('click', this._insertChar, '.' + CSS.BUTTON, this);
return content;
},
/**
* Insert the picked character into the editor.
*
* @method _insertChar
* @param {EventFacade} e
* @private
*/
_insertChar: function(e) {
var character = e.target.getData('character');
// Hide the dialogue.
this.getDialogue({
focusAfterHide: null
}).hide();
var host = this.get('host');
// Focus on the last point.
host.setSelection(this._currentSelection);
// And add the character.
host.insertContentAtFocusPoint(character);
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
File diff suppressed because one or more lines are too long
@@ -0,0 +1,417 @@
YUI.add('moodle-atto_charmap-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/>.
/*
* @package atto_charmap
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Atto text editor character map plugin
*
* @module moodle-atto_charmap-button
*/
var COMPONENTNAME = 'atto_charmap',
CSS = {
BUTTON: 'atto_charmap_character',
CHARMAP: 'atto_charmap_selector'
},
/*
* Map of special characters, kindly borrowed from TinyMCE.
*
* Each entries contains in order:
* - {String} HTML code
* - {String} HTML numerical code
* - {Boolean} Whether or not to include it in the list
* - {String} The language string key
*
* @property CHARMAP
* @type {Array}
*/
CHARMAP = [
['&nbsp;', '&#160;', true, 'nobreakspace'],
['&amp;', '&#38;', true, 'ampersand'],
['&quot;', '&#34;', true, 'quotationmark'],
// Finance.
['&cent;', '&#162;', true, 'centsign'],
['&euro;', '&#8364;', true, 'eurosign'],
['&pound;', '&#163;', true, 'poundsign'],
['&yen;', '&#165;', true, 'yensign'],
// Signs.
['&copy;', '&#169;', true, 'copyrightsign'],
['&reg;', '&#174;', true, 'registeredsign'],
['&trade;', '&#8482;', true, 'trademarksign'],
['&permil;', '&#8240;', true, 'permillesign'],
['&micro;', '&#181;', true, 'microsign'],
['&middot;', '&#183;', true, 'middledot'],
['&bull;', '&#8226;', true, 'bullet'],
['&hellip;', '&#8230;', true, 'threedotleader'],
['&prime;', '&#8242;', true, 'minutesfeet'],
['&Prime;', '&#8243;', true, 'secondsinches'],
['&sect;', '&#167;', true, 'sectionsign'],
['&para;', '&#182;', true, 'paragraphsign'],
['&szlig;', '&#223;', true, 'sharpsesszed'],
// Quotations.
['&lsaquo;', '&#8249;', true, 'singleleftpointinganglequotationmark'],
['&rsaquo;', '&#8250;', true, 'singlerightpointinganglequotationmark'],
['&laquo;', '&#171;', true, 'leftpointingguillemet'],
['&raquo;', '&#187;', true, 'rightpointingguillemet'],
['&lsquo;', '&#8216;', true, 'leftsinglequotationmark'],
['&rsquo;', '&#8217;', true, 'rightsinglequotationmark'],
['&ldquo;', '&#8220;', true, 'leftdoublequotationmark'],
['&rdquo;', '&#8221;', true, 'rightdoublequotationmark'],
['&sbquo;', '&#8218;', true, 'singlelow9quotationmark'],
['&bdquo;', '&#8222;', true, 'doublelow9quotationmark'],
['&lt;', '&#60;', true, 'lessthansign'],
['&gt;', '&#62;', true, 'greaterthansign'],
['&le;', '&#8804;', true, 'lessthanorequalto'],
['&ge;', '&#8805;', true, 'greaterthanorequalto'],
['&ndash;', '&#8211;', true, 'endash'],
['&mdash;', '&#8212;', true, 'emdash'],
['&macr;', '&#175;', true, 'macron'],
['&oline;', '&#8254;', true, 'overline'],
['&curren;', '&#164;', true, 'currencysign'],
['&brvbar;', '&#166;', true, 'brokenbar'],
['&uml;', '&#168;', true, 'diaeresis'],
['&iexcl;', '&#161;', true, 'invertedexclamationmark'],
['&iquest;', '&#191;', true, 'turnedquestionmark'],
['&circ;', '&#710;', true, 'circumflexaccent'],
['&tilde;', '&#732;', true, 'smalltilde'],
['&deg;', '&#176;', true, 'degreesign'],
['&minus;', '&#8722;', true, 'minussign'],
['&plusmn;', '&#177;', true, 'plusminussign'],
['&divide;', '&#247;', true, 'divisionsign'],
['&frasl;', '&#8260;', true, 'fractionslash'],
['&times;', '&#215;', true, 'multiplicationsign'],
['&sup1;', '&#185;', true, 'superscriptone'],
['&sup2;', '&#178;', true, 'superscripttwo'],
['&sup3;', '&#179;', true, 'superscriptthree'],
['&frac14;', '&#188;', true, 'fractiononequarter'],
['&frac12;', '&#189;', true, 'fractiononehalf'],
['&frac34;', '&#190;', true, 'fractionthreequarters'],
// Math / logical.
['&fnof;', '&#402;', true, 'functionflorin'],
['&int;', '&#8747;', true, 'integral'],
['&sum;', '&#8721;', true, 'narysumation'],
['&infin;', '&#8734;', true, 'infinity'],
['&radic;', '&#8730;', true, 'squareroot'],
['&sim;', '&#8764;', false,'similarto'],
['&cong;', '&#8773;', false,'approximatelyequalto'],
['&asymp;', '&#8776;', true, 'almostequalto'],
['&ne;', '&#8800;', true, 'notequalto'],
['&equiv;', '&#8801;', true, 'identicalto'],
['&isin;', '&#8712;', false,'elementof'],
['&notin;', '&#8713;', false,'notanelementof'],
['&ni;', '&#8715;', false,'containsasmember'],
['&prod;', '&#8719;', true, 'naryproduct'],
['&and;', '&#8743;', false,'logicaland'],
['&or;', '&#8744;', false,'logicalor'],
['&not;', '&#172;', true, 'notsign'],
['&cap;', '&#8745;', true, 'intersection'],
['&cup;', '&#8746;', false,'union'],
['&part;', '&#8706;', true, 'partialdifferential'],
['&forall;', '&#8704;', false,'forall'],
['&exist;', '&#8707;', false,'thereexists'],
['&empty;', '&#8709;', false,'diameter'],
['&nabla;', '&#8711;', false,'backwarddifference'],
['&lowast;', '&#8727;', false,'asteriskoperator'],
['&prop;', '&#8733;', false,'proportionalto'],
['&ang;', '&#8736;', false,'angle'],
// Undefined.
['&acute;', '&#180;', true, 'acuteaccent'],
['&cedil;', '&#184;', true, 'cedilla'],
['&ordf;', '&#170;', true, 'feminineordinalindicator'],
['&ordm;', '&#186;', true, 'masculineordinalindicator'],
['&dagger;', '&#8224;', true, 'dagger'],
['&Dagger;', '&#8225;', true, 'doubledagger'],
// Alphabetical special chars.
['&Agrave;', '&#192;', true, 'agrave_caps'],
['&Aacute;', '&#193;', true, 'aacute_caps'],
['&Acirc;', '&#194;', true, 'acircumflex_caps'],
['&Atilde;', '&#195;', true, 'atilde_caps'],
['&Auml;', '&#196;', true, 'adiaeresis_caps'],
['&Aring;', '&#197;', true, 'aringabove_caps'],
['&AElig;', '&#198;', true, 'ligatureae_caps'],
['&Ccedil;', '&#199;', true, 'ccedilla_caps'],
['&Egrave;', '&#200;', true, 'egrave_caps'],
['&Eacute;', '&#201;', true, 'eacute_caps'],
['&Ecirc;', '&#202;', true, 'ecircumflex_caps'],
['&Euml;', '&#203;', true, 'ediaeresis_caps'],
['&Igrave;', '&#204;', true, 'igrave_caps'],
['&Iacute;', '&#205;', true, 'iacute_caps'],
['&Icirc;', '&#206;', true, 'icircumflex_caps'],
['&Iuml;', '&#207;', true, 'idiaeresis_caps'],
['&ETH;', '&#208;', true, 'eth_caps'],
['&Ntilde;', '&#209;', true, 'ntilde_caps'],
['&Ograve;', '&#210;', true, 'ograve_caps'],
['&Oacute;', '&#211;', true, 'oacute_caps'],
['&Ocirc;', '&#212;', true, 'ocircumflex_caps'],
['&Otilde;', '&#213;', true, 'otilde_caps'],
['&Ouml;', '&#214;', true, 'odiaeresis_caps'],
['&Oslash;', '&#216;', true, 'oslash_caps'],
['&OElig;', '&#338;', true, 'ligatureoe_caps'],
['&Scaron;', '&#352;', true, 'scaron_caps'],
['&Ugrave;', '&#217;', true, 'ugrave_caps'],
['&Uacute;', '&#218;', true, 'uacute_caps'],
['&Ucirc;', '&#219;', true, 'ucircumflex_caps'],
['&Uuml;', '&#220;', true, 'udiaeresis_caps'],
['&Yacute;', '&#221;', true, 'yacute_caps'],
['&Yuml;', '&#376;', true, 'ydiaeresis_caps'],
['&THORN;', '&#222;', true, 'thorn_caps'],
['&agrave;', '&#224;', true, 'agrave'],
['&aacute;', '&#225;', true, 'aacute'],
['&acirc;', '&#226;', true, 'acircumflex'],
['&atilde;', '&#227;', true, 'atilde'],
['&auml;', '&#228;', true, 'adiaeresis'],
['&aring;', '&#229;', true, 'aringabove'],
['&aelig;', '&#230;', true, 'ligatureae'],
['&ccedil;', '&#231;', true, 'ccedilla'],
['&egrave;', '&#232;', true, 'egrave'],
['&eacute;', '&#233;', true, 'eacute'],
['&ecirc;', '&#234;', true, 'ecircumflex'],
['&euml;', '&#235;', true, 'ediaeresis'],
['&igrave;', '&#236;', true, 'igrave'],
['&iacute;', '&#237;', true, 'iacute'],
['&icirc;', '&#238;', true, 'icircumflex'],
['&iuml;', '&#239;', true, 'idiaeresis'],
['&eth;', '&#240;', true, 'eth'],
['&ntilde;', '&#241;', true, 'ntilde'],
['&ograve;', '&#242;', true, 'ograve'],
['&oacute;', '&#243;', true, 'oacute'],
['&ocirc;', '&#244;', true, 'ocircumflex'],
['&otilde;', '&#245;', true, 'otilde'],
['&ouml;', '&#246;', true, 'odiaeresis'],
['&oslash;', '&#248;', true, 'oslash'],
['&oelig;', '&#339;', true, 'ligatureoe'],
['&scaron;', '&#353;', true, 'scaron'],
['&ugrave;', '&#249;', true, 'ugrave'],
['&uacute;', '&#250;', true, 'uacute'],
['&ucirc;', '&#251;', true, 'ucircumflex'],
['&uuml;', '&#252;', true, 'udiaeresis'],
['&yacute;', '&#253;', true, 'yacute'],
['&thorn;', '&#254;', true, 'thorn'],
['&yuml;', '&#255;', true, 'ydiaeresis'],
['&Alpha;', '&#913;', true, 'alpha_caps'],
['&Beta;', '&#914;', true, 'beta_caps'],
['&Gamma;', '&#915;', true, 'gamma_caps'],
['&Delta;', '&#916;', true, 'delta_caps'],
['&Epsilon;', '&#917;', true, 'epsilon_caps'],
['&Zeta;', '&#918;', true, 'zeta_caps'],
['&Eta;', '&#919;', true, 'eta_caps'],
['&Theta;', '&#920;', true, 'theta_caps'],
['&Iota;', '&#921;', true, 'iota_caps'],
['&Kappa;', '&#922;', true, 'kappa_caps'],
['&Lambda;', '&#923;', true, 'lambda_caps'],
['&Mu;', '&#924;', true, 'mu_caps'],
['&Nu;', '&#925;', true, 'nu_caps'],
['&Xi;', '&#926;', true, 'xi_caps'],
['&Omicron;', '&#927;', true, 'omicron_caps'],
['&Pi;', '&#928;', true, 'pi_caps'],
['&Rho;', '&#929;', true, 'rho_caps'],
['&Sigma;', '&#931;', true, 'sigma_caps'],
['&Tau;', '&#932;', true, 'tau_caps'],
['&Upsilon;', '&#933;', true, 'upsilon_caps'],
['&Phi;', '&#934;', true, 'phi_caps'],
['&Chi;', '&#935;', true, 'chi_caps'],
['&Psi;', '&#936;', true, 'psi_caps'],
['&Omega;', '&#937;', true, 'omega_caps'],
['&alpha;', '&#945;', true, 'alpha'],
['&beta;', '&#946;', true, 'beta'],
['&gamma;', '&#947;', true, 'gamma'],
['&delta;', '&#948;', true, 'delta'],
['&epsilon;', '&#949;', true, 'epsilon'],
['&zeta;', '&#950;', true, 'zeta'],
['&eta;', '&#951;', true, 'eta'],
['&theta;', '&#952;', true, 'theta'],
['&iota;', '&#953;', true, 'iota'],
['&kappa;', '&#954;', true, 'kappa'],
['&lambda;', '&#955;', true, 'lambda'],
['&mu;', '&#956;', true, 'mu'],
['&nu;', '&#957;', true, 'nu'],
['&xi;', '&#958;', true, 'xi'],
['&omicron;', '&#959;', true, 'omicron'],
['&pi;', '&#960;', true, 'pi'],
['&rho;', '&#961;', true, 'rho'],
['&sigmaf;', '&#962;', true, 'finalsigma'],
['&sigma;', '&#963;', true, 'sigma'],
['&tau;', '&#964;', true, 'tau'],
['&upsilon;', '&#965;', true, 'upsilon'],
['&phi;', '&#966;', true, 'phi'],
['&chi;', '&#967;', true, 'chi'],
['&psi;', '&#968;', true, 'psi'],
['&omega;', '&#969;', true, 'omega'],
// Symbols.
['&alefsym;', '&#8501;', false,'alefsymbol'],
['&piv;', '&#982;', false,'pisymbol'],
['&real;', '&#8476;', false,'realpartsymbol'],
['&thetasym;','&#977;', false,'thetasymbol'],
['&upsih;', '&#978;', false,'upsilonhooksymbol'],
['&weierp;', '&#8472;', false,'weierstrassp'],
['&image;', '&#8465;', false,'imaginarypart'],
// Arrows.
['&larr;', '&#8592;', true, 'leftwardsarrow'],
['&uarr;', '&#8593;', true, 'upwardsarrow'],
['&rarr;', '&#8594;', true, 'rightwardsarrow'],
['&darr;', '&#8595;', true, 'downwardsarrow'],
['&harr;', '&#8596;', true, 'leftrightarrow'],
['&crarr;', '&#8629;', false,'carriagereturn'],
['&lArr;', '&#8656;', false,'leftwardsdoublearrow'],
['&uArr;', '&#8657;', false,'upwardsdoublearrow'],
['&rArr;', '&#8658;', false,'rightwardsdoublearrow'],
['&dArr;', '&#8659;', false,'downwardsdoublearrow'],
['&hArr;', '&#8660;', false,'leftrightdoublearrow'],
['&there4;', '&#8756;', false,'therefore'],
['&sub;', '&#8834;', false,'subsetof'],
['&sup;', '&#8835;', false,'supersetof'],
['&nsub;', '&#8836;', false,'notasubsetof'],
['&sube;', '&#8838;', false,'subsetoforequalto'],
['&supe;', '&#8839;', false,'supersetoforequalto'],
['&oplus;', '&#8853;', false,'circledplus'],
['&otimes;', '&#8855;', false,'circledtimes'],
['&perp;', '&#8869;', false,'perpendicular'],
['&sdot;', '&#8901;', false,'dotoperator'],
['&lceil;', '&#8968;', false,'leftceiling'],
['&rceil;', '&#8969;', false,'rightceiling'],
['&lfloor;', '&#8970;', false,'leftfloor'],
['&rfloor;', '&#8971;', false,'rightfloor'],
['&lang;', '&#9001;', false,'leftpointinganglebracket'],
['&rang;', '&#9002;', false,'rightpointinganglebracket'],
['&loz;', '&#9674;', true, 'lozenge'],
['&spades;', '&#9824;', true, 'blackspadesuit'],
['&clubs;', '&#9827;', true, 'blackclubsuit'],
['&hearts;', '&#9829;', true, 'blackheartsuit'],
['&diams;', '&#9830;', true, 'blackdiamondsuit'],
['&ensp;', '&#8194;', false,'enspace'],
['&emsp;', '&#8195;', false,'emspace'],
['&thinsp;', '&#8201;', false,'thinspace'],
['&zwnj;', '&#8204;', false,'zerowidthnonjoiner'],
['&zwj;', '&#8205;', false,'zerowidthjoiner'],
['&lrm;', '&#8206;', false,'lefttorightmark'],
['&rlm;', '&#8207;', false,'righttoleftmark'],
['&shy;', '&#173;', false,'softhyphen']
];
/**
* Atto text editor charmap plugin.
*
* @namespace M.atto_charmap
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_charmap').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* A reference to the current selection at the time that the dialogue
* was opened.
*
* @property _currentSelection
* @type Range
* @private
*/
_currentSelection: null,
initializer: function() {
this.addButton({
icon: 'e/special_character',
callback: this._displayDialogue
});
},
/**
* Display the Character Map selector.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
// Store the current selection.
this._currentSelection = this.get('host').getSelection();
if (this._currentSelection === false) {
return;
}
var dialogue = this.getDialogue({
headerContent: M.util.get_string('insertcharacter', COMPONENTNAME),
focusAfterHide: true
}, true);
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(
'<div class="{{CSS.CHARMAP}}">' +
'{{#each CHARMAP}}' +
'{{#if this.[2]}}' +
'<button class="{{../../CSS.BUTTON}}" ' +
'aria-label="{{get_string this.[3] ../../component}}" ' +
'title="{{get_string this.[3] ../../component}}" ' +
'data-character="{{this.[0]}}" ' +
'>{{{this.[0]}}}</button>' +
'{{/if}}' +
'{{/each}}' +
'</div>'
);
var content = Y.Node.create(template({
component: COMPONENTNAME,
CSS: CSS,
CHARMAP: CHARMAP
}));
content.delegate('click', this._insertChar, '.' + CSS.BUTTON, this);
return content;
},
/**
* Insert the picked character into the editor.
*
* @method _insertChar
* @param {EventFacade} e
* @private
*/
_insertChar: function(e) {
var character = e.target.getData('character');
// Hide the dialogue.
this.getDialogue({
focusAfterHide: null
}).hide();
var host = this.get('host');
// Focus on the last point.
host.setSelection(this._currentSelection);
// And add the character.
host.insertContentAtFocusPoint(character);
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_charmap-button",
"builds": {
"moodle-atto_charmap-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,412 @@
// 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/>.
/*
* @package atto_charmap
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Atto text editor character map plugin
*
* @module moodle-atto_charmap-button
*/
var COMPONENTNAME = 'atto_charmap',
CSS = {
BUTTON: 'atto_charmap_character',
CHARMAP: 'atto_charmap_selector'
},
/*
* Map of special characters, kindly borrowed from TinyMCE.
*
* Each entries contains in order:
* - {String} HTML code
* - {String} HTML numerical code
* - {Boolean} Whether or not to include it in the list
* - {String} The language string key
*
* @property CHARMAP
* @type {Array}
*/
CHARMAP = [
['&nbsp;', '&#160;', true, 'nobreakspace'],
['&amp;', '&#38;', true, 'ampersand'],
['&quot;', '&#34;', true, 'quotationmark'],
// Finance.
['&cent;', '&#162;', true, 'centsign'],
['&euro;', '&#8364;', true, 'eurosign'],
['&pound;', '&#163;', true, 'poundsign'],
['&yen;', '&#165;', true, 'yensign'],
// Signs.
['&copy;', '&#169;', true, 'copyrightsign'],
['&reg;', '&#174;', true, 'registeredsign'],
['&trade;', '&#8482;', true, 'trademarksign'],
['&permil;', '&#8240;', true, 'permillesign'],
['&micro;', '&#181;', true, 'microsign'],
['&middot;', '&#183;', true, 'middledot'],
['&bull;', '&#8226;', true, 'bullet'],
['&hellip;', '&#8230;', true, 'threedotleader'],
['&prime;', '&#8242;', true, 'minutesfeet'],
['&Prime;', '&#8243;', true, 'secondsinches'],
['&sect;', '&#167;', true, 'sectionsign'],
['&para;', '&#182;', true, 'paragraphsign'],
['&szlig;', '&#223;', true, 'sharpsesszed'],
// Quotations.
['&lsaquo;', '&#8249;', true, 'singleleftpointinganglequotationmark'],
['&rsaquo;', '&#8250;', true, 'singlerightpointinganglequotationmark'],
['&laquo;', '&#171;', true, 'leftpointingguillemet'],
['&raquo;', '&#187;', true, 'rightpointingguillemet'],
['&lsquo;', '&#8216;', true, 'leftsinglequotationmark'],
['&rsquo;', '&#8217;', true, 'rightsinglequotationmark'],
['&ldquo;', '&#8220;', true, 'leftdoublequotationmark'],
['&rdquo;', '&#8221;', true, 'rightdoublequotationmark'],
['&sbquo;', '&#8218;', true, 'singlelow9quotationmark'],
['&bdquo;', '&#8222;', true, 'doublelow9quotationmark'],
['&lt;', '&#60;', true, 'lessthansign'],
['&gt;', '&#62;', true, 'greaterthansign'],
['&le;', '&#8804;', true, 'lessthanorequalto'],
['&ge;', '&#8805;', true, 'greaterthanorequalto'],
['&ndash;', '&#8211;', true, 'endash'],
['&mdash;', '&#8212;', true, 'emdash'],
['&macr;', '&#175;', true, 'macron'],
['&oline;', '&#8254;', true, 'overline'],
['&curren;', '&#164;', true, 'currencysign'],
['&brvbar;', '&#166;', true, 'brokenbar'],
['&uml;', '&#168;', true, 'diaeresis'],
['&iexcl;', '&#161;', true, 'invertedexclamationmark'],
['&iquest;', '&#191;', true, 'turnedquestionmark'],
['&circ;', '&#710;', true, 'circumflexaccent'],
['&tilde;', '&#732;', true, 'smalltilde'],
['&deg;', '&#176;', true, 'degreesign'],
['&minus;', '&#8722;', true, 'minussign'],
['&plusmn;', '&#177;', true, 'plusminussign'],
['&divide;', '&#247;', true, 'divisionsign'],
['&frasl;', '&#8260;', true, 'fractionslash'],
['&times;', '&#215;', true, 'multiplicationsign'],
['&sup1;', '&#185;', true, 'superscriptone'],
['&sup2;', '&#178;', true, 'superscripttwo'],
['&sup3;', '&#179;', true, 'superscriptthree'],
['&frac14;', '&#188;', true, 'fractiononequarter'],
['&frac12;', '&#189;', true, 'fractiononehalf'],
['&frac34;', '&#190;', true, 'fractionthreequarters'],
// Math / logical.
['&fnof;', '&#402;', true, 'functionflorin'],
['&int;', '&#8747;', true, 'integral'],
['&sum;', '&#8721;', true, 'narysumation'],
['&infin;', '&#8734;', true, 'infinity'],
['&radic;', '&#8730;', true, 'squareroot'],
['&sim;', '&#8764;', false,'similarto'],
['&cong;', '&#8773;', false,'approximatelyequalto'],
['&asymp;', '&#8776;', true, 'almostequalto'],
['&ne;', '&#8800;', true, 'notequalto'],
['&equiv;', '&#8801;', true, 'identicalto'],
['&isin;', '&#8712;', false,'elementof'],
['&notin;', '&#8713;', false,'notanelementof'],
['&ni;', '&#8715;', false,'containsasmember'],
['&prod;', '&#8719;', true, 'naryproduct'],
['&and;', '&#8743;', false,'logicaland'],
['&or;', '&#8744;', false,'logicalor'],
['&not;', '&#172;', true, 'notsign'],
['&cap;', '&#8745;', true, 'intersection'],
['&cup;', '&#8746;', false,'union'],
['&part;', '&#8706;', true, 'partialdifferential'],
['&forall;', '&#8704;', false,'forall'],
['&exist;', '&#8707;', false,'thereexists'],
['&empty;', '&#8709;', false,'diameter'],
['&nabla;', '&#8711;', false,'backwarddifference'],
['&lowast;', '&#8727;', false,'asteriskoperator'],
['&prop;', '&#8733;', false,'proportionalto'],
['&ang;', '&#8736;', false,'angle'],
// Undefined.
['&acute;', '&#180;', true, 'acuteaccent'],
['&cedil;', '&#184;', true, 'cedilla'],
['&ordf;', '&#170;', true, 'feminineordinalindicator'],
['&ordm;', '&#186;', true, 'masculineordinalindicator'],
['&dagger;', '&#8224;', true, 'dagger'],
['&Dagger;', '&#8225;', true, 'doubledagger'],
// Alphabetical special chars.
['&Agrave;', '&#192;', true, 'agrave_caps'],
['&Aacute;', '&#193;', true, 'aacute_caps'],
['&Acirc;', '&#194;', true, 'acircumflex_caps'],
['&Atilde;', '&#195;', true, 'atilde_caps'],
['&Auml;', '&#196;', true, 'adiaeresis_caps'],
['&Aring;', '&#197;', true, 'aringabove_caps'],
['&AElig;', '&#198;', true, 'ligatureae_caps'],
['&Ccedil;', '&#199;', true, 'ccedilla_caps'],
['&Egrave;', '&#200;', true, 'egrave_caps'],
['&Eacute;', '&#201;', true, 'eacute_caps'],
['&Ecirc;', '&#202;', true, 'ecircumflex_caps'],
['&Euml;', '&#203;', true, 'ediaeresis_caps'],
['&Igrave;', '&#204;', true, 'igrave_caps'],
['&Iacute;', '&#205;', true, 'iacute_caps'],
['&Icirc;', '&#206;', true, 'icircumflex_caps'],
['&Iuml;', '&#207;', true, 'idiaeresis_caps'],
['&ETH;', '&#208;', true, 'eth_caps'],
['&Ntilde;', '&#209;', true, 'ntilde_caps'],
['&Ograve;', '&#210;', true, 'ograve_caps'],
['&Oacute;', '&#211;', true, 'oacute_caps'],
['&Ocirc;', '&#212;', true, 'ocircumflex_caps'],
['&Otilde;', '&#213;', true, 'otilde_caps'],
['&Ouml;', '&#214;', true, 'odiaeresis_caps'],
['&Oslash;', '&#216;', true, 'oslash_caps'],
['&OElig;', '&#338;', true, 'ligatureoe_caps'],
['&Scaron;', '&#352;', true, 'scaron_caps'],
['&Ugrave;', '&#217;', true, 'ugrave_caps'],
['&Uacute;', '&#218;', true, 'uacute_caps'],
['&Ucirc;', '&#219;', true, 'ucircumflex_caps'],
['&Uuml;', '&#220;', true, 'udiaeresis_caps'],
['&Yacute;', '&#221;', true, 'yacute_caps'],
['&Yuml;', '&#376;', true, 'ydiaeresis_caps'],
['&THORN;', '&#222;', true, 'thorn_caps'],
['&agrave;', '&#224;', true, 'agrave'],
['&aacute;', '&#225;', true, 'aacute'],
['&acirc;', '&#226;', true, 'acircumflex'],
['&atilde;', '&#227;', true, 'atilde'],
['&auml;', '&#228;', true, 'adiaeresis'],
['&aring;', '&#229;', true, 'aringabove'],
['&aelig;', '&#230;', true, 'ligatureae'],
['&ccedil;', '&#231;', true, 'ccedilla'],
['&egrave;', '&#232;', true, 'egrave'],
['&eacute;', '&#233;', true, 'eacute'],
['&ecirc;', '&#234;', true, 'ecircumflex'],
['&euml;', '&#235;', true, 'ediaeresis'],
['&igrave;', '&#236;', true, 'igrave'],
['&iacute;', '&#237;', true, 'iacute'],
['&icirc;', '&#238;', true, 'icircumflex'],
['&iuml;', '&#239;', true, 'idiaeresis'],
['&eth;', '&#240;', true, 'eth'],
['&ntilde;', '&#241;', true, 'ntilde'],
['&ograve;', '&#242;', true, 'ograve'],
['&oacute;', '&#243;', true, 'oacute'],
['&ocirc;', '&#244;', true, 'ocircumflex'],
['&otilde;', '&#245;', true, 'otilde'],
['&ouml;', '&#246;', true, 'odiaeresis'],
['&oslash;', '&#248;', true, 'oslash'],
['&oelig;', '&#339;', true, 'ligatureoe'],
['&scaron;', '&#353;', true, 'scaron'],
['&ugrave;', '&#249;', true, 'ugrave'],
['&uacute;', '&#250;', true, 'uacute'],
['&ucirc;', '&#251;', true, 'ucircumflex'],
['&uuml;', '&#252;', true, 'udiaeresis'],
['&yacute;', '&#253;', true, 'yacute'],
['&thorn;', '&#254;', true, 'thorn'],
['&yuml;', '&#255;', true, 'ydiaeresis'],
['&Alpha;', '&#913;', true, 'alpha_caps'],
['&Beta;', '&#914;', true, 'beta_caps'],
['&Gamma;', '&#915;', true, 'gamma_caps'],
['&Delta;', '&#916;', true, 'delta_caps'],
['&Epsilon;', '&#917;', true, 'epsilon_caps'],
['&Zeta;', '&#918;', true, 'zeta_caps'],
['&Eta;', '&#919;', true, 'eta_caps'],
['&Theta;', '&#920;', true, 'theta_caps'],
['&Iota;', '&#921;', true, 'iota_caps'],
['&Kappa;', '&#922;', true, 'kappa_caps'],
['&Lambda;', '&#923;', true, 'lambda_caps'],
['&Mu;', '&#924;', true, 'mu_caps'],
['&Nu;', '&#925;', true, 'nu_caps'],
['&Xi;', '&#926;', true, 'xi_caps'],
['&Omicron;', '&#927;', true, 'omicron_caps'],
['&Pi;', '&#928;', true, 'pi_caps'],
['&Rho;', '&#929;', true, 'rho_caps'],
['&Sigma;', '&#931;', true, 'sigma_caps'],
['&Tau;', '&#932;', true, 'tau_caps'],
['&Upsilon;', '&#933;', true, 'upsilon_caps'],
['&Phi;', '&#934;', true, 'phi_caps'],
['&Chi;', '&#935;', true, 'chi_caps'],
['&Psi;', '&#936;', true, 'psi_caps'],
['&Omega;', '&#937;', true, 'omega_caps'],
['&alpha;', '&#945;', true, 'alpha'],
['&beta;', '&#946;', true, 'beta'],
['&gamma;', '&#947;', true, 'gamma'],
['&delta;', '&#948;', true, 'delta'],
['&epsilon;', '&#949;', true, 'epsilon'],
['&zeta;', '&#950;', true, 'zeta'],
['&eta;', '&#951;', true, 'eta'],
['&theta;', '&#952;', true, 'theta'],
['&iota;', '&#953;', true, 'iota'],
['&kappa;', '&#954;', true, 'kappa'],
['&lambda;', '&#955;', true, 'lambda'],
['&mu;', '&#956;', true, 'mu'],
['&nu;', '&#957;', true, 'nu'],
['&xi;', '&#958;', true, 'xi'],
['&omicron;', '&#959;', true, 'omicron'],
['&pi;', '&#960;', true, 'pi'],
['&rho;', '&#961;', true, 'rho'],
['&sigmaf;', '&#962;', true, 'finalsigma'],
['&sigma;', '&#963;', true, 'sigma'],
['&tau;', '&#964;', true, 'tau'],
['&upsilon;', '&#965;', true, 'upsilon'],
['&phi;', '&#966;', true, 'phi'],
['&chi;', '&#967;', true, 'chi'],
['&psi;', '&#968;', true, 'psi'],
['&omega;', '&#969;', true, 'omega'],
// Symbols.
['&alefsym;', '&#8501;', false,'alefsymbol'],
['&piv;', '&#982;', false,'pisymbol'],
['&real;', '&#8476;', false,'realpartsymbol'],
['&thetasym;','&#977;', false,'thetasymbol'],
['&upsih;', '&#978;', false,'upsilonhooksymbol'],
['&weierp;', '&#8472;', false,'weierstrassp'],
['&image;', '&#8465;', false,'imaginarypart'],
// Arrows.
['&larr;', '&#8592;', true, 'leftwardsarrow'],
['&uarr;', '&#8593;', true, 'upwardsarrow'],
['&rarr;', '&#8594;', true, 'rightwardsarrow'],
['&darr;', '&#8595;', true, 'downwardsarrow'],
['&harr;', '&#8596;', true, 'leftrightarrow'],
['&crarr;', '&#8629;', false,'carriagereturn'],
['&lArr;', '&#8656;', false,'leftwardsdoublearrow'],
['&uArr;', '&#8657;', false,'upwardsdoublearrow'],
['&rArr;', '&#8658;', false,'rightwardsdoublearrow'],
['&dArr;', '&#8659;', false,'downwardsdoublearrow'],
['&hArr;', '&#8660;', false,'leftrightdoublearrow'],
['&there4;', '&#8756;', false,'therefore'],
['&sub;', '&#8834;', false,'subsetof'],
['&sup;', '&#8835;', false,'supersetof'],
['&nsub;', '&#8836;', false,'notasubsetof'],
['&sube;', '&#8838;', false,'subsetoforequalto'],
['&supe;', '&#8839;', false,'supersetoforequalto'],
['&oplus;', '&#8853;', false,'circledplus'],
['&otimes;', '&#8855;', false,'circledtimes'],
['&perp;', '&#8869;', false,'perpendicular'],
['&sdot;', '&#8901;', false,'dotoperator'],
['&lceil;', '&#8968;', false,'leftceiling'],
['&rceil;', '&#8969;', false,'rightceiling'],
['&lfloor;', '&#8970;', false,'leftfloor'],
['&rfloor;', '&#8971;', false,'rightfloor'],
['&lang;', '&#9001;', false,'leftpointinganglebracket'],
['&rang;', '&#9002;', false,'rightpointinganglebracket'],
['&loz;', '&#9674;', true, 'lozenge'],
['&spades;', '&#9824;', true, 'blackspadesuit'],
['&clubs;', '&#9827;', true, 'blackclubsuit'],
['&hearts;', '&#9829;', true, 'blackheartsuit'],
['&diams;', '&#9830;', true, 'blackdiamondsuit'],
['&ensp;', '&#8194;', false,'enspace'],
['&emsp;', '&#8195;', false,'emspace'],
['&thinsp;', '&#8201;', false,'thinspace'],
['&zwnj;', '&#8204;', false,'zerowidthnonjoiner'],
['&zwj;', '&#8205;', false,'zerowidthjoiner'],
['&lrm;', '&#8206;', false,'lefttorightmark'],
['&rlm;', '&#8207;', false,'righttoleftmark'],
['&shy;', '&#173;', false,'softhyphen']
];
/**
* Atto text editor charmap plugin.
*
* @namespace M.atto_charmap
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_charmap').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* A reference to the current selection at the time that the dialogue
* was opened.
*
* @property _currentSelection
* @type Range
* @private
*/
_currentSelection: null,
initializer: function() {
this.addButton({
icon: 'e/special_character',
callback: this._displayDialogue
});
},
/**
* Display the Character Map selector.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
// Store the current selection.
this._currentSelection = this.get('host').getSelection();
if (this._currentSelection === false) {
return;
}
var dialogue = this.getDialogue({
headerContent: M.util.get_string('insertcharacter', COMPONENTNAME),
focusAfterHide: true
}, true);
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Return the dialogue content for the tool.
*
* @method _getDialogueContent
* @private
* @return {Node} The content to place in the dialogue.
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(
'<div class="{{CSS.CHARMAP}}">' +
'{{#each CHARMAP}}' +
'{{#if this.[2]}}' +
'<button class="{{../../CSS.BUTTON}}" ' +
'aria-label="{{get_string this.[3] ../../component}}" ' +
'title="{{get_string this.[3] ../../component}}" ' +
'data-character="{{this.[0]}}" ' +
'>{{{this.[0]}}}</button>' +
'{{/if}}' +
'{{/each}}' +
'</div>'
);
var content = Y.Node.create(template({
component: COMPONENTNAME,
CSS: CSS,
CHARMAP: CHARMAP
}));
content.delegate('click', this._insertChar, '.' + CSS.BUTTON, this);
return content;
},
/**
* Insert the picked character into the editor.
*
* @method _insertChar
* @param {EventFacade} e
* @private
*/
_insertChar: function(e) {
var character = e.target.getData('character');
// Hide the dialogue.
this.getDialogue({
focusAfterHide: null
}).hide();
var host = this.get('host');
// Focus on the last point.
host.setSelection(this._currentSelection);
// And add the character.
host.insertContentAtFocusPoint(character);
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_charmap-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,25 @@
<?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_clear', language 'en'.
*
* @package atto_clear
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Clear formatting';
+29
View File
@@ -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_clear
* @copyright 2013 Damyon Wiese <[email protected]>
* @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_clear'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,46 @@
YUI.add('moodle-atto_clear-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/>.
/*
* @package atto_clear
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_clear-button
*/
/**
* Atto text editor clear plugin.
*
* @namespace M.atto_clear
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_clear').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
this.addBasicButton({
exec: 'removeFormat',
icon: 'e/clear_formatting'
});
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_clear-button",function(e,t){e.namespace("M.atto_clear").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){this.addBasicButton({exec:"removeFormat",icon:"e/clear_formatting"})}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
@@ -0,0 +1,46 @@
YUI.add('moodle-atto_clear-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/>.
/*
* @package atto_clear
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_clear-button
*/
/**
* Atto text editor clear plugin.
*
* @namespace M.atto_clear
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_clear').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
this.addBasicButton({
exec: 'removeFormat',
icon: 'e/clear_formatting'
});
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_clear-button",
"builds": {
"moodle-atto_clear-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,41 @@
// 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/>.
/*
* @package atto_clear
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_clear-button
*/
/**
* Atto text editor clear plugin.
*
* @namespace M.atto_clear
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_clear').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
this.addBasicButton({
exec: 'removeFormat',
icon: 'e/clear_formatting'
});
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_clear-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,30 @@
<?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_collapse', language 'en'.
*
* @package atto_collapse
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Show/hide advanced buttons';
$string['showmore'] = 'Show more buttons';
$string['showfewer'] = 'Show fewer buttons';
$string['settings'] = 'Collapse toolbar settings';
$string['showgroups'] = 'Show (n) groups when collapsed.';
$string['showgroups_desc'] = 'When the toolbar is collapsed (it is by default) only this many groups will be displayed at once.';
+44
View File
@@ -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 integration version file.
*
* @package atto_collapse
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Initialise the js strings required for this module.
*/
function atto_collapse_strings_for_js() {
global $PAGE;
$PAGE->requires->strings_for_js(array('showmore', 'showfewer'), 'atto_collapse');
}
/**
* Set params for this plugin
* @param string $elementid
*/
function atto_collapse_params_for_js($elementid, $options, $fpoptions) {
// Pass the number of visible groups as a param.
$params = array('showgroups' => get_config('atto_collapse', 'showgroups'));
return $params;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
width="16"
height="16"
sodipodi:docname="icon.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview4"
showgrid="true"
inkscape:zoom="14.75"
inkscape:cx="8"
inkscape:cy="8"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid3033"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<g
id="g3027"
transform="translate(-9.9661016,-5.4237289)">
<path
style="fill:#ffffff"
d="m 10.966102,16.923729 0,-3.5 7,0 7,0 0,3.5 0,3.5 -7,0 -7,0 0,-3.5 z m 5,1.5 c 0,-0.55 -0.9,-1 -2,-1 -1.1,0 -2,0.45 -2,1 0,0.55 0.9,1 2,1 1.1,0 2,-0.45 2,-1 z m 3,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 5,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m -10,-3 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 3,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 3,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 4,0 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z m -10.25,-3.732205 c 2.3375,-0.210535 6.1625,-0.210535 8.5,0 2.3375,0.210535 0.425,0.382791 -4.25,0.382791 -4.675,0 -6.5875,-0.172256 -4.25,-0.382791 z m -2.75,-3.2677951 c 0,-1.8095238 0.666666,-2 7,-2 6.333333,0 7,0.1904762 7,2 0,1.8095241 -0.666667,2.0000001 -7,2.0000001 -6.333334,0 -7,-0.190476 -7,-2.0000001 z m 3,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 3,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 3,0 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 4,0 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z"
id="path3031"
inkscape:connector-curvature="0" />
<path
style="fill:#999999"
d="m 9.9661016,16.923729 0,-4.5 8.0000004,0 8,0 0,4.5 0,4.5 -8,0 -8.0000004,0 0,-4.5 z m 15.0000004,0 0,-3.5 -7,0 -7,0 0,3.5 0,3.5 7,0 7,0 0,-3.5 z m -13,1.5 c 0,-0.55 0.9,-1 2,-1 1.1,0 2,0.45 2,1 0,0.55 -0.9,1 -2,1 -1.1,0 -2,-0.45 -2,-1 z m 5,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 5,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m -10,-3 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 3,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 3,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 3,0 c 0,-0.55 0.675,-1 1.5,-1 0.825,0 1.5,0.45 1.5,1 0,0.55 -0.675,1 -1.5,1 -0.825,0 -1.5,-0.45 -1.5,-1 z M 9.9661016,8.4237289 l 0,-3 8.0000004,0 8,0 0,3 0,3.0000001 -8,0 -8.0000004,0 0,-3.0000001 z m 15.0000004,0 c 0,-1.8095238 -0.666667,-2 -7,-2 -6.333334,0 -7,0.1904762 -7,2 0,1.8095241 0.666666,2.0000001 7,2.0000001 6.333333,0 7,-0.190476 7,-2.0000001 z m -13,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 3,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 3,0 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 3,0 c 0,-0.55 0.675,-1 1.5,-1 0.825,0 1.5,0.45 1.5,1 0,0.55 -0.675,1 -1.5,1 -0.825,0 -1.5,-0.45 -1.5,-1 z"
id="path3029"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

@@ -0,0 +1,43 @@
<?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/>.
/**
* Settings that allow configuration of the list of tex examples in the equation editor.
*
* @package atto_collapse
* @copyright 2013 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$ADMIN->add('editoratto', new admin_category('atto_collapse', new lang_string('pluginname', 'atto_collapse')));
$settings = new admin_settingpage('atto_collapse_settings', new lang_string('settings', 'atto_collapse'));
if ($ADMIN->fulltree) {
// Number of groups to show when collapsed.
$name = new lang_string('showgroups', 'atto_collapse');
$desc = new lang_string('showgroups_desc', 'atto_collapse');
$default = 5;
$options = array_combine(range(1, 20), range(1, 20));
$setting = new admin_setting_configselect('atto_collapse/showgroups',
$name,
$desc,
$default,
$options);
$settings->add($setting);
}
@@ -0,0 +1,5 @@
@media (max-width: 768px) {
.toolbarbreak {
display: none;
}
}
@@ -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_collapse
* @copyright 2013 Damyon Wiese <[email protected]>
* @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_collapse'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,115 @@
YUI.add('moodle-atto_collapse-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/>.
/*
* @package atto_collapse
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_collapse-button
*/
/**
* Atto text editor collapse plugin.
*
* @namespace M.atto_collapse
* @class button
* @extends M.editor_atto.EditorPlugin
*/
var PLUGINNAME = 'atto_collapse',
ATTRSHOWGROUPS = 'showgroups',
COLLAPSE = 'collapse',
COLLAPSED = 'collapsed',
GROUPS = '.atto_group';
Y.namespace('M.atto_collapse').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var button = this.addButton({
icon: M.util.image_url('icon', PLUGINNAME),
callback: this._toggle
});
// Perform a toggle after all plugins have been loaded for the first time.
this.get('host').on('pluginsloaded', function(e, button) {
this._setVisibility(button);
// Set the toolbar to break after the initial those displayed by default.
var firstGroup = this.toolbar.all(GROUPS).item(this.get(ATTRSHOWGROUPS));
firstGroup.insert('<div class="toolbarbreak"></div>', 'before');
}, this, button);
},
/**
* Toggle the visibility of the extra groups in the toolbar.
*
* @method _toggle
* @param {EventFacade} e
* @private
*/
_toggle: function(e) {
e.preventDefault();
var button = this.buttons[COLLAPSE];
if (button.getData(COLLAPSED)) {
this._setVisibility(button, true);
} else {
this._setVisibility(button);
}
},
/**
* Set the visibility of the toolbar groups.
*
* @method _setVisibility
* @param {Node} button The collapse button
* @param {Booelan} visibility Whether the groups should be made visible
* @private
*/
_setVisibility: function(button, visibility) {
var groups = this.toolbar.all(GROUPS).slice(this.get(ATTRSHOWGROUPS));
if (visibility) {
button.set('title', M.util.get_string('showfewer', PLUGINNAME));
groups.show();
button.setData(COLLAPSED, false);
} else {
button.set('title', M.util.get_string('showmore', PLUGINNAME));
groups.hide();
button.setData(COLLAPSED, true);
}
}
}, {
ATTRS: {
/**
* How many groups to show when collapsed.
*
* @attribute showgroups
* @type Number
* @default 3
*/
showgroups: {
value: 3
}
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_collapse-button",function(e,t){var n="atto_collapse",r="showgroups",i="collapse",s="collapsed",o=".atto_group";e.namespace("M.atto_collapse").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){var e=this.addButton({icon:M.util.image_url("icon",n),callback:this._toggle});this.get("host").on("pluginsloaded",function(e,t){this._setVisibility(t);var n=this.toolbar.all(o).item(this.get(r));n.insert('<div class="toolbarbreak"></div>',"before")},this,e)},_toggle:function(e){e.preventDefault();var t=this.buttons[i];t.getData(s)?this._setVisibility(t,!0):this._setVisibility(t)},_setVisibility:function(e,t){var i=this.toolbar.all(o).slice(this.get(r));t?(e.set("title",M.util.get_string("showfewer",n)),i.show(),e.setData(s,!1)):(e.set("title",M.util.get_string("showmore",n)),i.hide(),e.setData(s,!0))}},{ATTRS:{showgroups:{value:3}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
@@ -0,0 +1,115 @@
YUI.add('moodle-atto_collapse-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/>.
/*
* @package atto_collapse
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_collapse-button
*/
/**
* Atto text editor collapse plugin.
*
* @namespace M.atto_collapse
* @class button
* @extends M.editor_atto.EditorPlugin
*/
var PLUGINNAME = 'atto_collapse',
ATTRSHOWGROUPS = 'showgroups',
COLLAPSE = 'collapse',
COLLAPSED = 'collapsed',
GROUPS = '.atto_group';
Y.namespace('M.atto_collapse').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var button = this.addButton({
icon: M.util.image_url('icon', PLUGINNAME),
callback: this._toggle
});
// Perform a toggle after all plugins have been loaded for the first time.
this.get('host').on('pluginsloaded', function(e, button) {
this._setVisibility(button);
// Set the toolbar to break after the initial those displayed by default.
var firstGroup = this.toolbar.all(GROUPS).item(this.get(ATTRSHOWGROUPS));
firstGroup.insert('<div class="toolbarbreak"></div>', 'before');
}, this, button);
},
/**
* Toggle the visibility of the extra groups in the toolbar.
*
* @method _toggle
* @param {EventFacade} e
* @private
*/
_toggle: function(e) {
e.preventDefault();
var button = this.buttons[COLLAPSE];
if (button.getData(COLLAPSED)) {
this._setVisibility(button, true);
} else {
this._setVisibility(button);
}
},
/**
* Set the visibility of the toolbar groups.
*
* @method _setVisibility
* @param {Node} button The collapse button
* @param {Booelan} visibility Whether the groups should be made visible
* @private
*/
_setVisibility: function(button, visibility) {
var groups = this.toolbar.all(GROUPS).slice(this.get(ATTRSHOWGROUPS));
if (visibility) {
button.set('title', M.util.get_string('showfewer', PLUGINNAME));
groups.show();
button.setData(COLLAPSED, false);
} else {
button.set('title', M.util.get_string('showmore', PLUGINNAME));
groups.hide();
button.setData(COLLAPSED, true);
}
}
}, {
ATTRS: {
/**
* How many groups to show when collapsed.
*
* @attribute showgroups
* @type Number
* @default 3
*/
showgroups: {
value: 3
}
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_collapse-button",
"builds": {
"moodle-atto_collapse-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,110 @@
// 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/>.
/*
* @package atto_collapse
* @copyright 2013 Damyon Wiese <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_collapse-button
*/
/**
* Atto text editor collapse plugin.
*
* @namespace M.atto_collapse
* @class button
* @extends M.editor_atto.EditorPlugin
*/
var PLUGINNAME = 'atto_collapse',
ATTRSHOWGROUPS = 'showgroups',
COLLAPSE = 'collapse',
COLLAPSED = 'collapsed',
GROUPS = '.atto_group';
Y.namespace('M.atto_collapse').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
initializer: function() {
var button = this.addButton({
icon: M.util.image_url('icon', PLUGINNAME),
callback: this._toggle
});
// Perform a toggle after all plugins have been loaded for the first time.
this.get('host').on('pluginsloaded', function(e, button) {
this._setVisibility(button);
// Set the toolbar to break after the initial those displayed by default.
var firstGroup = this.toolbar.all(GROUPS).item(this.get(ATTRSHOWGROUPS));
firstGroup.insert('<div class="toolbarbreak"></div>', 'before');
}, this, button);
},
/**
* Toggle the visibility of the extra groups in the toolbar.
*
* @method _toggle
* @param {EventFacade} e
* @private
*/
_toggle: function(e) {
e.preventDefault();
var button = this.buttons[COLLAPSE];
if (button.getData(COLLAPSED)) {
this._setVisibility(button, true);
} else {
this._setVisibility(button);
}
},
/**
* Set the visibility of the toolbar groups.
*
* @method _setVisibility
* @param {Node} button The collapse button
* @param {Booelan} visibility Whether the groups should be made visible
* @private
*/
_setVisibility: function(button, visibility) {
var groups = this.toolbar.all(GROUPS).slice(this.get(ATTRSHOWGROUPS));
if (visibility) {
button.set('title', M.util.get_string('showfewer', PLUGINNAME));
groups.show();
button.setData(COLLAPSED, false);
} else {
button.set('title', M.util.get_string('showmore', PLUGINNAME));
groups.hide();
button.setData(COLLAPSED, true);
}
}
}, {
ATTRS: {
/**
* How many groups to show when collapsed.
*
* @attribute showgroups
* @type Number
* @default 3
*/
showgroups: {
value: 3
}
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_collapse-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
@@ -0,0 +1,26 @@
<?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_emoticon', language 'en'.
*
* @package atto_emoticon
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['insertemoticon'] = 'Insert emoticon';
$string['pluginname'] = 'Emoticon';
+54
View File
@@ -0,0 +1,54 @@
<?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 emoticon plugin lib.
*
* @package atto_emoticon
* @copyright 2014 Frédéric Massart
* @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_emoticon_strings_for_js() {
global $PAGE;
$PAGE->requires->strings_for_js(array('insertemoticon'), 'atto_emoticon');
// Load the strings required by the emotes.
$manager = get_emoticon_manager();
foreach ($manager->get_emoticons() as $emote) {
$PAGE->requires->string_for_js($emote->altidentifier, $emote->altcomponent);
}
}
/**
* Sends the parameters to JS module.
*
* @return array
*/
function atto_emoticon_params_for_js($elementid, $options, $fpoptions) {
$manager = get_emoticon_manager();
return array(
'emoticons' => $manager->get_emoticons()
);
}
@@ -0,0 +1,14 @@
.atto_emoticon_map ul {
padding: 0;
margin: 0;
display: table;
width: 100%;
}
.atto_emoticon_map li {
display: table-row;
white-space: nowrap;
}
.atto_emoticon_map li div {
display: table-cell;
padding: 0 1em;
}
@@ -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 emoticon plugin version file.
*
* @package atto_emoticon
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014013100; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2013110500; // Requires this Moodle version.
$plugin->component = 'atto_emoticon'; // Full name of the plugin (used for diagnostics).
@@ -0,0 +1,170 @@
YUI.add('moodle-atto_emoticon-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/>.
/*
* @package atto_emoticon
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_emoticon-button
*/
var COMPONENTNAME = 'atto_emoticon',
CSS = {
EMOTE: 'atto_emoticon_emote',
MAP: 'atto_emoticon_map'
},
SELECTORS = {
EMOTE: '.atto_emoticon_emote'
},
TEMPLATE = '' +
'<div class="{{CSS.MAP}}">' +
'<ul>' +
'{{#each emoticons}}' +
'<li><div>' +
'<a href="#" class="{{../CSS.EMOTE}}" data-text="{{text}}">' +
'<img ' +
'src="{{image_url imagename imagecomponent}}" ' +
'alt="{{get_string altidentifier altcomponent}}"' +
'/>' +
'</a>' +
'</div>' +
'<div>{{text}}</div>' +
'<div>{{get_string altidentifier altcomponent}}</div>' +
'</li>' +
'{{/each}}' +
'</ul>' +
'</div>';
/**
* Atto text editor emoticon plugin.
*
* @namespace M.atto_emoticon
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_emoticon').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* A reference to the current selection at the time that the dialogue
* was opened.
*
* @property _currentSelection
* @type Range
* @private
*/
_currentSelection: null,
initializer: function() {
this.addButton({
icon: 'e/emoticons',
callback: this._displayDialogue
});
},
/**
* Display the Emoticon chooser.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
// Store the current selection.
this._currentSelection = this.get('host').getSelection();
if (this._currentSelection === false) {
return;
}
var dialogue = this.getDialogue({
headerContent: M.util.get_string('insertemoticon', COMPONENTNAME),
focusAfterHide: true
}, true);
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Insert the emoticon.
*
* @method _insertEmote
* @param {EventFacade} e
* @private
*/
_insertEmote: function(e) {
var target = e.target.ancestor(SELECTORS.EMOTE, true),
host = this.get('host');
e.preventDefault();
// Hide the dialogue.
this.getDialogue({
focusAfterHide: null
}).hide();
// Build the Emoticon text.
var html = ' ' + target.getData('text') + ' ';
// Focus on the previous selection.
host.setSelection(this._currentSelection);
// And add the character.
host.insertContentAtFocusPoint(html);
this.markUpdated();
},
/**
* Generates the content of the dialogue, attaching event listeners to
* the content.
*
* @method _getDialogueContent
* @return {Node} Node containing the dialogue content
* @private
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(TEMPLATE),
content = Y.Node.create(template({
emoticons: this.get('emoticons'),
CSS: CSS
}));
content.delegate('click', this._insertEmote, SELECTORS.EMOTE, this);
content.delegate('key', this._insertEmote, '32', SELECTORS.EMOTE, this);
return content;
}
}, {
ATTRS: {
/**
* The list of emoticons to display.
*
* @attribute emoticons
* @type array
* @default {}
*/
emoticons: {
value: {}
}
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1 @@
YUI.add("moodle-atto_emoticon-button",function(e,t){var n="atto_emoticon",r={EMOTE:"atto_emoticon_emote",MAP:"atto_emoticon_map"},i={EMOTE:".atto_emoticon_emote"},s='<div class="{{CSS.MAP}}"><ul>{{#each emoticons}}<li><div><a href="#" class="{{../CSS.EMOTE}}" data-text="{{text}}"><img src="{{image_url imagename imagecomponent}}" alt="{{get_string altidentifier altcomponent}}"/></a></div><div>{{text}}</div><div>{{get_string altidentifier altcomponent}}</div></li>{{/each}}</ul></div>';e.namespace("M.atto_emoticon").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,initializer:function(){this.addButton({icon:"e/emoticons",callback:this._displayDialogue})},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection===!1)return;var e=this.getDialogue({headerContent:M.util.get_string("insertemoticon",n),focusAfterHide:!0},!0);e.set("bodyContent",this._getDialogueContent()).show()},_insertEmote:function(e){var t=e.target.ancestor(i.EMOTE,!0),n=this.get("host");e.preventDefault(),this.getDialogue({focusAfterHide:null}).hide();var r=" "+t.getData("text")+" ";n.setSelection(this._currentSelection),n.insertContentAtFocusPoint(r),this.markUpdated()},_getDialogueContent:function(){var t=e.Handlebars.compile(s),n=e.Node.create(t({emoticons:this.get("emoticons"),CSS:r}));return n.delegate("click",this._insertEmote,i.EMOTE,this),n.delegate("key",this._insertEmote,"32",i.EMOTE,this),n}},{ATTRS:{emoticons:{value:{}}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
@@ -0,0 +1,170 @@
YUI.add('moodle-atto_emoticon-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/>.
/*
* @package atto_emoticon
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_emoticon-button
*/
var COMPONENTNAME = 'atto_emoticon',
CSS = {
EMOTE: 'atto_emoticon_emote',
MAP: 'atto_emoticon_map'
},
SELECTORS = {
EMOTE: '.atto_emoticon_emote'
},
TEMPLATE = '' +
'<div class="{{CSS.MAP}}">' +
'<ul>' +
'{{#each emoticons}}' +
'<li><div>' +
'<a href="#" class="{{../CSS.EMOTE}}" data-text="{{text}}">' +
'<img ' +
'src="{{image_url imagename imagecomponent}}" ' +
'alt="{{get_string altidentifier altcomponent}}"' +
'/>' +
'</a>' +
'</div>' +
'<div>{{text}}</div>' +
'<div>{{get_string altidentifier altcomponent}}</div>' +
'</li>' +
'{{/each}}' +
'</ul>' +
'</div>';
/**
* Atto text editor emoticon plugin.
*
* @namespace M.atto_emoticon
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_emoticon').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* A reference to the current selection at the time that the dialogue
* was opened.
*
* @property _currentSelection
* @type Range
* @private
*/
_currentSelection: null,
initializer: function() {
this.addButton({
icon: 'e/emoticons',
callback: this._displayDialogue
});
},
/**
* Display the Emoticon chooser.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
// Store the current selection.
this._currentSelection = this.get('host').getSelection();
if (this._currentSelection === false) {
return;
}
var dialogue = this.getDialogue({
headerContent: M.util.get_string('insertemoticon', COMPONENTNAME),
focusAfterHide: true
}, true);
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Insert the emoticon.
*
* @method _insertEmote
* @param {EventFacade} e
* @private
*/
_insertEmote: function(e) {
var target = e.target.ancestor(SELECTORS.EMOTE, true),
host = this.get('host');
e.preventDefault();
// Hide the dialogue.
this.getDialogue({
focusAfterHide: null
}).hide();
// Build the Emoticon text.
var html = ' ' + target.getData('text') + ' ';
// Focus on the previous selection.
host.setSelection(this._currentSelection);
// And add the character.
host.insertContentAtFocusPoint(html);
this.markUpdated();
},
/**
* Generates the content of the dialogue, attaching event listeners to
* the content.
*
* @method _getDialogueContent
* @return {Node} Node containing the dialogue content
* @private
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(TEMPLATE),
content = Y.Node.create(template({
emoticons: this.get('emoticons'),
CSS: CSS
}));
content.delegate('click', this._insertEmote, SELECTORS.EMOTE, this);
content.delegate('key', this._insertEmote, '32', SELECTORS.EMOTE, this);
return content;
}
}, {
ATTRS: {
/**
* The list of emoticons to display.
*
* @attribute emoticons
* @type array
* @default {}
*/
emoticons: {
value: {}
}
}
});
}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]});
@@ -0,0 +1,10 @@
{
"name": "moodle-atto_emoticon-button",
"builds": {
"moodle-atto_emoticon-button": {
"jsfiles": [
"button.js"
]
}
}
}
@@ -0,0 +1,165 @@
// 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/>.
/*
* @package atto_emoticon
* @copyright 2014 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @module moodle-atto_emoticon-button
*/
var COMPONENTNAME = 'atto_emoticon',
CSS = {
EMOTE: 'atto_emoticon_emote',
MAP: 'atto_emoticon_map'
},
SELECTORS = {
EMOTE: '.atto_emoticon_emote'
},
TEMPLATE = '' +
'<div class="{{CSS.MAP}}">' +
'<ul>' +
'{{#each emoticons}}' +
'<li><div>' +
'<a href="#" class="{{../CSS.EMOTE}}" data-text="{{text}}">' +
'<img ' +
'src="{{image_url imagename imagecomponent}}" ' +
'alt="{{get_string altidentifier altcomponent}}"' +
'/>' +
'</a>' +
'</div>' +
'<div>{{text}}</div>' +
'<div>{{get_string altidentifier altcomponent}}</div>' +
'</li>' +
'{{/each}}' +
'</ul>' +
'</div>';
/**
* Atto text editor emoticon plugin.
*
* @namespace M.atto_emoticon
* @class button
* @extends M.editor_atto.EditorPlugin
*/
Y.namespace('M.atto_emoticon').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
/**
* A reference to the current selection at the time that the dialogue
* was opened.
*
* @property _currentSelection
* @type Range
* @private
*/
_currentSelection: null,
initializer: function() {
this.addButton({
icon: 'e/emoticons',
callback: this._displayDialogue
});
},
/**
* Display the Emoticon chooser.
*
* @method _displayDialogue
* @private
*/
_displayDialogue: function() {
// Store the current selection.
this._currentSelection = this.get('host').getSelection();
if (this._currentSelection === false) {
return;
}
var dialogue = this.getDialogue({
headerContent: M.util.get_string('insertemoticon', COMPONENTNAME),
focusAfterHide: true
}, true);
// Set the dialogue content, and then show the dialogue.
dialogue.set('bodyContent', this._getDialogueContent())
.show();
},
/**
* Insert the emoticon.
*
* @method _insertEmote
* @param {EventFacade} e
* @private
*/
_insertEmote: function(e) {
var target = e.target.ancestor(SELECTORS.EMOTE, true),
host = this.get('host');
e.preventDefault();
// Hide the dialogue.
this.getDialogue({
focusAfterHide: null
}).hide();
// Build the Emoticon text.
var html = ' ' + target.getData('text') + ' ';
// Focus on the previous selection.
host.setSelection(this._currentSelection);
// And add the character.
host.insertContentAtFocusPoint(html);
this.markUpdated();
},
/**
* Generates the content of the dialogue, attaching event listeners to
* the content.
*
* @method _getDialogueContent
* @return {Node} Node containing the dialogue content
* @private
*/
_getDialogueContent: function() {
var template = Y.Handlebars.compile(TEMPLATE),
content = Y.Node.create(template({
emoticons: this.get('emoticons'),
CSS: CSS
}));
content.delegate('click', this._insertEmote, SELECTORS.EMOTE, this);
content.delegate('key', this._insertEmote, '32', SELECTORS.EMOTE, this);
return content;
}
}, {
ATTRS: {
/**
* The list of emoticons to display.
*
* @attribute emoticons
* @type array
* @default {}
*/
emoticons: {
value: {}
}
}
});
@@ -0,0 +1,7 @@
{
"moodle-atto_emoticon-button": {
"requires": [
"moodle-editor_atto-plugin"
]
}
}
+50
View File
@@ -0,0 +1,50 @@
<?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/>.
/**
* Renders text with the active filters and returns it. Used to create previews of equations
* using whatever tex filters are enabled.
*
* @package atto_equation
* @copyright 2014 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('AJAX_SCRIPT', true);
require_once(dirname(__FILE__) . '/../../../../../config.php');
$contextid = required_param('contextid', PARAM_INT);
$context = context::instance_by_id($contextid, MUST_EXIST);
$PAGE->set_url('/lib/editor/atto/plugins/equation/ajax.php');
$PAGE->set_context($context);
require_login();
require_sesskey();
$action = required_param('action', PARAM_ALPHA);
if ($action === 'filtertext') {
$text = required_param('text', PARAM_RAW);
$result = filter_manager::instance()->filter_text($text, $context);
echo $OUTPUT->header();
echo $result;
die();
}
print_error('invalidarguments');

Some files were not shown because too many files have changed in this diff Show More