diff --git a/lib/editor/atto/classes/plugininfo/atto.php b/lib/editor/atto/classes/plugininfo/atto.php
index ed52dc48610..b3b742cc9c2 100644
--- a/lib/editor/atto/classes/plugininfo/atto.php
+++ b/lib/editor/atto/classes/plugininfo/atto.php
@@ -29,7 +29,48 @@ 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);
+ }
+ }
}
diff --git a/lib/editor/atto/plugins/collapse/lang/en/atto_collapse.php b/lib/editor/atto/plugins/collapse/lang/en/atto_collapse.php
new file mode 100644
index 00000000000..b9f75ed72a7
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/lang/en/atto_collapse.php
@@ -0,0 +1,30 @@
+.
+
+/**
+ * Strings for component 'atto_collapse', language 'en'.
+ *
+ * @package atto_collapse
+ * @copyright 2013 Damyon Wiese
+ * @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['showless'] = 'Show less 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.';
diff --git a/lib/editor/atto/plugins/collapse/lib.php b/lib/editor/atto/plugins/collapse/lib.php
new file mode 100644
index 00000000000..6b0987ccc57
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/lib.php
@@ -0,0 +1,44 @@
+.
+
+/**
+ * Atto text editor integration version file.
+ *
+ * @package atto_collapse
+ * @copyright 2013 Damyon Wiese
+ * @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', 'showless'), '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;
+}
diff --git a/lib/editor/atto/plugins/collapse/pix/icon.png b/lib/editor/atto/plugins/collapse/pix/icon.png
new file mode 100644
index 00000000000..db0be7cac30
Binary files /dev/null and b/lib/editor/atto/plugins/collapse/pix/icon.png differ
diff --git a/lib/editor/atto/plugins/collapse/pix/icon.svg b/lib/editor/atto/plugins/collapse/pix/icon.svg
new file mode 100644
index 00000000000..4ec6f93031b
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/pix/icon.svg
@@ -0,0 +1,74 @@
+
+
+
+
diff --git a/lib/editor/atto/plugins/collapse/settings.php b/lib/editor/atto/plugins/collapse/settings.php
new file mode 100644
index 00000000000..dac6a5d859f
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/settings.php
@@ -0,0 +1,43 @@
+.
+
+/**
+ * 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 = 3;
+ $options = array_combine(range(1, 10), range(1, 10));
+
+ $setting = new admin_setting_configselect('atto_collapse/showgroups',
+ $name,
+ $desc,
+ $default,
+ $options);
+ $settings->add($setting);
+}
diff --git a/lib/editor/atto/plugins/collapse/version.php b/lib/editor/atto/plugins/collapse/version.php
new file mode 100644
index 00000000000..c454ddabb6d
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/version.php
@@ -0,0 +1,29 @@
+.
+
+/**
+ * Atto text editor integration version file.
+ *
+ * @package atto_collapse
+ * @copyright 2013 Damyon Wiese
+ * @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).
diff --git a/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-debug.js b/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-debug.js
new file mode 100644
index 00000000000..d99e8bc14fa
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-debug.js
@@ -0,0 +1,110 @@
+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 .
+
+/**
+ * CSS Selectors
+ *
+ * @type {Object}
+ */
+var SELECTORS = {
+ GROUPS: '.atto_group',
+ BUTTON: '.atto_collapse_button'
+};
+
+/**
+ * Atto text editor collapse plugin.
+ *
+ * @package atto_collapse
+ * @copyright 2013 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+M.atto_collapse = M.atto_collapse || {
+
+ /**
+ * How many groups to show when collapsed.
+ *
+ * @property showgroups
+ * @type {Integer}
+ * @default 3
+ */
+ showgroups : 3,
+
+ /**
+ * Init.
+ *
+ * @param {Object} params
+ *
+ * @return {Void}
+ */
+ init : function(params) {
+ var click = function(e, elementid) {
+ e.preventDefault();
+ M.atto_collapse.toggle(elementid);
+ };
+
+ this.showgroups = params.showgroups;
+
+ var iconurl = M.util.image_url('icon', 'atto_collapse');
+
+ // Add the button to the toolbar.
+ M.editor_atto.add_toolbar_button(params.elementid, 'collapse', iconurl, params.group, click);
+ },
+
+ /**
+ * Either hide or show the extra groups in the toolbar.
+ *
+ * @param {String} elementid
+ *
+ * @return {Void}
+ */
+ toggle : function(elementid) {
+ var toolbar = M.editor_atto.get_toolbar_node(elementid);
+ var button = toolbar.one(SELECTORS.BUTTON);
+ var groups = toolbar.all(SELECTORS.GROUPS).slice(this.showgroups);
+
+ if (button.getData('collapsed')) {
+ button.set('title', M.util.get_string('showmore', 'atto_collapse'));
+ groups.show();
+ button.setData('collapsed', false);
+ } else {
+ button.set('title', M.util.get_string('showless', 'atto_collapse'));
+ groups.hide();
+ button.setData('collapsed', true);
+ }
+ },
+
+ /**
+ * After init function called after all plugins init() has been run.
+ *
+ * @param {Object} params
+ *
+ * @return {Void}
+ */
+ after_init : function(params) {
+ var toolbar = M.editor_atto.get_toolbar_node(params.elementid);
+ var button = toolbar.one(SELECTORS.BUTTON);
+
+ // Set the state to "not collapsed" (which is the state when the page loads).
+ button.setData('collapsed', false);
+ // Call toggle to change the state when the page loads to "collapsed".
+ M.atto_collapse.toggle(params.elementid);
+ }
+
+};
+
+
+}, '@VERSION@', {"requires": ["node"]});
diff --git a/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-min.js b/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-min.js
new file mode 100644
index 00000000000..6e9ef1224d2
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-min.js
@@ -0,0 +1 @@
+YUI.add("moodle-atto_collapse-button",function(e,t){var n={GROUPS:".atto_group",BUTTON:".atto_collapse_button"};M.atto_collapse=M.atto_collapse||{showgroups:3,init:function(e){var t=function(e,t){e.preventDefault(),M.atto_collapse.toggle(t)};this.showgroups=e.showgroups;var n=M.util.image_url("icon","atto_collapse");M.editor_atto.add_toolbar_button(e.elementid,"collapse",n,e.group,t)},toggle:function(e){var t=M.editor_atto.get_toolbar_node(e),r=t.one(n.BUTTON),i=t.all(n.GROUPS).slice(this.showgroups);r.getData("collapsed")?(r.set("title",M.util.get_string("showmore","atto_collapse")),i.show(),r.setData("collapsed",!1)):(r.set("title",M.util.get_string("showless","atto_collapse")),i.hide(),r.setData("collapsed",!0))},after_init:function(e){var t=M.editor_atto.get_toolbar_node(e.elementid),r=t.one(n.BUTTON);r.setData("collapsed",!1),M.atto_collapse.toggle(e.elementid)}}},"@VERSION@",{requires:["node"]});
diff --git a/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button.js b/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button.js
new file mode 100644
index 00000000000..d99e8bc14fa
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button.js
@@ -0,0 +1,110 @@
+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 .
+
+/**
+ * CSS Selectors
+ *
+ * @type {Object}
+ */
+var SELECTORS = {
+ GROUPS: '.atto_group',
+ BUTTON: '.atto_collapse_button'
+};
+
+/**
+ * Atto text editor collapse plugin.
+ *
+ * @package atto_collapse
+ * @copyright 2013 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+M.atto_collapse = M.atto_collapse || {
+
+ /**
+ * How many groups to show when collapsed.
+ *
+ * @property showgroups
+ * @type {Integer}
+ * @default 3
+ */
+ showgroups : 3,
+
+ /**
+ * Init.
+ *
+ * @param {Object} params
+ *
+ * @return {Void}
+ */
+ init : function(params) {
+ var click = function(e, elementid) {
+ e.preventDefault();
+ M.atto_collapse.toggle(elementid);
+ };
+
+ this.showgroups = params.showgroups;
+
+ var iconurl = M.util.image_url('icon', 'atto_collapse');
+
+ // Add the button to the toolbar.
+ M.editor_atto.add_toolbar_button(params.elementid, 'collapse', iconurl, params.group, click);
+ },
+
+ /**
+ * Either hide or show the extra groups in the toolbar.
+ *
+ * @param {String} elementid
+ *
+ * @return {Void}
+ */
+ toggle : function(elementid) {
+ var toolbar = M.editor_atto.get_toolbar_node(elementid);
+ var button = toolbar.one(SELECTORS.BUTTON);
+ var groups = toolbar.all(SELECTORS.GROUPS).slice(this.showgroups);
+
+ if (button.getData('collapsed')) {
+ button.set('title', M.util.get_string('showmore', 'atto_collapse'));
+ groups.show();
+ button.setData('collapsed', false);
+ } else {
+ button.set('title', M.util.get_string('showless', 'atto_collapse'));
+ groups.hide();
+ button.setData('collapsed', true);
+ }
+ },
+
+ /**
+ * After init function called after all plugins init() has been run.
+ *
+ * @param {Object} params
+ *
+ * @return {Void}
+ */
+ after_init : function(params) {
+ var toolbar = M.editor_atto.get_toolbar_node(params.elementid);
+ var button = toolbar.one(SELECTORS.BUTTON);
+
+ // Set the state to "not collapsed" (which is the state when the page loads).
+ button.setData('collapsed', false);
+ // Call toggle to change the state when the page loads to "collapsed".
+ M.atto_collapse.toggle(params.elementid);
+ }
+
+};
+
+
+}, '@VERSION@', {"requires": ["node"]});
diff --git a/lib/editor/atto/plugins/collapse/yui/src/button/build.json b/lib/editor/atto/plugins/collapse/yui/src/button/build.json
new file mode 100644
index 00000000000..c0f7f198ed0
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/yui/src/button/build.json
@@ -0,0 +1,10 @@
+{
+ "name": "moodle-atto_collapse-button",
+ "builds": {
+ "moodle-atto_collapse-button": {
+ "jsfiles": [
+ "button.js"
+ ]
+ }
+ }
+}
diff --git a/lib/editor/atto/plugins/collapse/yui/src/button/js/button.js b/lib/editor/atto/plugins/collapse/yui/src/button/js/button.js
new file mode 100644
index 00000000000..2715e711f50
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/yui/src/button/js/button.js
@@ -0,0 +1,105 @@
+// 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 .
+
+/**
+ * CSS Selectors
+ *
+ * @type {Object}
+ */
+var SELECTORS = {
+ GROUPS: '.atto_group',
+ BUTTON: '.atto_collapse_button'
+};
+
+/**
+ * Atto text editor collapse plugin.
+ *
+ * @package atto_collapse
+ * @copyright 2013 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+M.atto_collapse = M.atto_collapse || {
+
+ /**
+ * How many groups to show when collapsed.
+ *
+ * @property showgroups
+ * @type {Integer}
+ * @default 3
+ */
+ showgroups : 3,
+
+ /**
+ * Init.
+ *
+ * @param {Object} params
+ *
+ * @return {Void}
+ */
+ init : function(params) {
+ var click = function(e, elementid) {
+ e.preventDefault();
+ M.atto_collapse.toggle(elementid);
+ };
+
+ this.showgroups = params.showgroups;
+
+ var iconurl = M.util.image_url('icon', 'atto_collapse');
+
+ // Add the button to the toolbar.
+ M.editor_atto.add_toolbar_button(params.elementid, 'collapse', iconurl, params.group, click);
+ },
+
+ /**
+ * Either hide or show the extra groups in the toolbar.
+ *
+ * @param {String} elementid
+ *
+ * @return {Void}
+ */
+ toggle : function(elementid) {
+ var toolbar = M.editor_atto.get_toolbar_node(elementid);
+ var button = toolbar.one(SELECTORS.BUTTON);
+ var groups = toolbar.all(SELECTORS.GROUPS).slice(this.showgroups);
+
+ if (button.getData('collapsed')) {
+ button.set('title', M.util.get_string('showmore', 'atto_collapse'));
+ groups.show();
+ button.setData('collapsed', false);
+ } else {
+ button.set('title', M.util.get_string('showless', 'atto_collapse'));
+ groups.hide();
+ button.setData('collapsed', true);
+ }
+ },
+
+ /**
+ * After init function called after all plugins init() has been run.
+ *
+ * @param {Object} params
+ *
+ * @return {Void}
+ */
+ after_init : function(params) {
+ var toolbar = M.editor_atto.get_toolbar_node(params.elementid);
+ var button = toolbar.one(SELECTORS.BUTTON);
+
+ // Set the state to "not collapsed" (which is the state when the page loads).
+ button.setData('collapsed', false);
+ // Call toggle to change the state when the page loads to "collapsed".
+ M.atto_collapse.toggle(params.elementid);
+ }
+
+};
diff --git a/lib/editor/atto/plugins/collapse/yui/src/button/meta/button.json b/lib/editor/atto/plugins/collapse/yui/src/button/meta/button.json
new file mode 100644
index 00000000000..a88cdaa4727
--- /dev/null
+++ b/lib/editor/atto/plugins/collapse/yui/src/button/meta/button.json
@@ -0,0 +1,5 @@
+{
+ "moodle-atto_collapse-button": {
+ "requires": ["node"]
+ }
+}
diff --git a/lib/editor/atto/settings.php b/lib/editor/atto/settings.php
index c775dbb2e5c..c0b483fd01b 100644
--- a/lib/editor/atto/settings.php
+++ b/lib/editor/atto/settings.php
@@ -30,7 +30,8 @@ $settings = new admin_settingpage('editorsettingsatto', new lang_string('setting
if ($ADMIN->fulltree) {
$name = new lang_string('toolbarconfig', 'editor_atto');
$desc = new lang_string('toolbarconfig_desc', 'editor_atto');
- $default = 'style = bold, italic, underline, strike, clear, title' . "\n" .
+ $default = 'collapse = collapse' . "\n" .
+ 'style = bold, italic, underline, strike, clear, title' . "\n" .
'paragraph = subscript, superscript, indent, outdent, orderedlist, unorderedlist' . "\n" .
'links = link, unlink' . "\n" .
'insert = table, image, media, managefiles, charmap, emoticon' . "\n" .
@@ -44,10 +45,12 @@ if ($ADMIN->fulltree) {
}
$ADMIN->add('editoratto', $settings);
-unset($settings);
foreach (core_plugin_manager::instance()->get_plugins_of_type('atto') as $plugin) {
+ /** @var \editor_atto\plugininfo\atto $plugin */
$plugin->load_settings($ADMIN, 'editoratto', $hassiteconfig);
}
+// Required or the editor plugininfo will add this section twice.
+unset($settings);
$settings = null;
diff --git a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js
index 04f6078a7e0..fe4af1c16cc 100644
--- a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js
+++ b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js
@@ -161,6 +161,18 @@ M.editor_atto = M.editor_atto || {
var plugin = this.getAttribute('data-plugin');
var handler = this.getAttribute('data-handler');
var overlay = M.editor_atto.menus[plugin + '_' + elementid];
+ var toolbar = M.editor_atto.get_toolbar_node(elementid);
+ var currentid = toolbar.getAttribute('aria-activedescendant');
+
+ // Right now, currentid is the id of the previously selected button.
+ if (currentid) {
+ current = Y.one('#' + currentid);
+ // We only ever want one button with a tabindex of 0 at any one time.
+ current.setAttribute('tabindex', '-1');
+ }
+ this.setAttribute('tabindex', 0);
+ // And update the activedescendant to point at the currently selected button.
+ toolbar.setAttribute('aria-activedescendant', this.generateID());
if (overlay) {
overlay.hide();
@@ -323,6 +335,7 @@ M.editor_atto = M.editor_atto || {
currentfocus = toolbar.getAttribute('aria-activedescendant');
if (!currentfocus) {
+ // Initially set the first button in the toolbar to be the default on keyboard focus.
button.setAttribute('tabindex', '0');
toolbar.setAttribute('aria-activedescendant', button.generateID());
}
@@ -406,6 +419,7 @@ M.editor_atto = M.editor_atto || {
currentfocus = toolbar.getAttribute('aria-activedescendant');
if (!currentfocus) {
+ // Initially set the first button in the toolbar to be the default on keyboard focus.
button.setAttribute('tabindex', '0');
toolbar.setAttribute('aria-activedescendant', button.generateID());
}
@@ -540,17 +554,31 @@ M.editor_atto = M.editor_atto || {
M.editor_atto.filepickeroptions[params.elementid] = params.filepickeroptions;
// Init each of the plugins
- var i, j;
+ var i, j, group, plugin;
for (i = 0; i < params.plugins.length; i++) {
- var group = params.plugins[i].group;
+ group = params.plugins[i].group;
for (j = 0; j < params.plugins[i].plugins.length; j++) {
- var plugin = params.plugins[i].plugins[j];
+ plugin = params.plugins[i].plugins[j];
plugin.params.elementid = params.elementid;
plugin.params.group = group;
M['atto_' + plugin.name].init(plugin.params);
}
}
+
+ // Let the plugins run some init code once all plugins are in the page.
+ for (i = 0; i < params.plugins.length; i++) {
+ group = params.plugins[i].group;
+ for (j = 0; j < params.plugins[i].plugins.length; j++) {
+ plugin = params.plugins[i].plugins[j];
+ plugin.params.elementid = params.elementid;
+ plugin.params.group = group;
+
+ if (typeof M['atto_' + plugin.name].after_init !== 'undefined') {
+ M['atto_' + plugin.name].after_init(plugin.params);
+ }
+ }
+ }
},
/**
@@ -613,11 +641,21 @@ M.editor_atto = M.editor_atto || {
e.preventDefault();
- buttons = toolbar.all('button');
+ // This workaround is because we cannot do ".atto_group:not([hidden]) button" in ie8 (even with selector-css3).
+ // Create an empty NodeList.
+ buttons = toolbar.all('empty');
+ toolbar.all('.atto_group').each(function(group) {
+ if (!group.hasAttribute('hidden')) {
+ // Append the visible buttons to the buttons list.
+ buttons = buttons.concat(group.all('button'));
+ }
+ });
+ // The currentid is the id of the previously selected button.
currentid = toolbar.getAttribute('aria-activedescendant');
if (!currentid) {
return;
}
+ // We only ever want one button with a tabindex of 0.
current = Y.one('#' + currentid);
current.setAttribute('tabindex', '-1');
@@ -636,7 +674,7 @@ M.editor_atto = M.editor_atto || {
currentindex = 0;
}
}
-
+ // Currentindex has been updated to point to the new button.
current = buttons.item(currentindex);
current.setAttribute('tabindex', '0');
current.focus();
diff --git a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js
index 844b40b15e7..c9b21c868d0 100644
--- a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js
+++ b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-min.js
@@ -1,3 +1,3 @@
-YUI.add("moodle-editor_atto-editor",function(e,t){function i(){var e=this.getHTML(),t=[{regex://gi,replace:""},{regex:/<\\?\?xml[^>]*>/gi,replace:""},{regex:/<\/?\w+:[^>]*>/gi,replace:""},{regex:/\s*MSO[-:][^;"']*;?/gi,replace:""},{regex:/]*>( |\s)*<\/span>/gi,replace:""},{regex:/class="Mso[^"]*"/gi,replace:""},{regex:/<(\/?title|\/?meta|\/?style|\/?st\d|\/?head|\/?font|\/?html|\/?body|!\[)[^>]*?>/gi,replace:""},{regex:new RegExp(String.fromCharCode(8220),"gi"),replace:'"'},{regex:new RegExp(String.fromCharCode(8216),"gi"),replace:"'"},{regex:new RegExp(String.fromCharCode(8217),"gi"),replace:"'"},{regex:new RegExp(String.fromCharCode(8211),"gi"),replace:"-"},{regex:new RegExp(String.fromCharCode(8212),"gi"),replace:"--"},{regex:new RegExp(String.fromCharCode(189),"gi"),replace:"1/2"},{regex:new RegExp(String.fromCharCode(188),"gi"),replace:"1/4"},{regex:new RegExp(String.fromCharCode(190),"gi"),replace:"3/4"},{regex:new RegExp(String.fromCharCode(169),"gi"),replace:"(c)"},{regex:new RegExp(String.fromCharCode(174),"gi"),replace:"(r)"},{regex:new RegExp(String.fromCharCode(8230),"gi"),replace:"..."}],n=0,r;for(n=0;n'),a.append(f)),h=M.util.image_url("t/expanded","moodle"),c=e.Node.create('"),f.append(c),l=a.getAttribute("aria-activedescendant"),l||(c.setAttribute("tabindex","0"),a.setAttribute("aria-activedescendant",c.generateID())),M.editor_atto.widgets[n]=n;var p=e.Node.create(''),d=0,v={};for(d=0;d'+v.text+""+"")),M.editor_atto.buttonhandlers[n+"_action_"+d]||(e.one("body").delegate("click",M.editor_atto.buttonclicked_handler,".atto_"+n+"_action_"+d),e.one("body").delegate("key",M.editor_atto.buttonclicked_handler,"space,enter",".atto_"+n+"_action_"+d),M.editor_atto.buttonhandlers[n+"_action_"+d]=v.handler);M.editor_atto.buttonhandlers[n]||(e.one("body").delegate("click",M.editor_atto.showhide_menu_handler,".atto_"+n+"_button"),M.editor_atto.buttonhandlers[n]=!0);var m=new M.core.dialogue({bodyContent:p,visible:!1,width:o+"em",lightbox:!1,closeButton:!1,center:!1});M.editor_atto.menus[n+"_"+t]=m,m.align(c,[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BL]),m.hide(),m.headerNode.hide(),m.render()},add_toolbar_button:function(t,n,r,i,s){var o=M.editor_atto.get_toolbar_node(t),u=o.one(".atto_group."+i+"_group"),a,f;u||(u=e.Node.create(''),o.append(u)),a=e.Node.create('"),u.append(a),f=o.getAttribute("aria-activedescendant"),f||(a.setAttribute("tabindex","0"),o.setAttribute("aria-activedescendant",a.generateID())),M.editor_atto.buttonhandlers[n]||(e.one("body").delegate("click",M.editor_atto.buttonclicked_handler,".atto_"+n+"_button"),M.editor_atto.buttonhandlers[n]=s),M.editor_atto.widgets[n]=n},is_active:function(t){var n=M.editor_atto.get_selection();n.length&&(n=n.pop());var r=null;n.parentElement?r=e.one(n.parentElement()):r=e.one(n.startContainer);var i=M.editor_atto.get_editable_node(t);return r&&i.contains(r)},focus:function(e){M.editor_atto.get_editable_node(e).focus()},init:function(t){var n=e.Node.create(''),r=e.Node.create(''),i=e.Node.create(''),s=e.Node.create(''),o=M.editor_atto.get_textarea_node(t.elementid),u=e.one('[for="'+t.elementid+'"]');u&&(u.generateID(),r.setAttribute("aria-labelledby",u.get("id")),i.setAttribute("aria-labelledby",u.get("id"))),s.appendChild(r),n.appendChild(i),n.appendChild(s),r.setStyle("minHeight",1.2*o.getAttribute("rows")+"em"),r.append(o.get("value")),r.cleanHTML(),o.get("parentNode").insert(n,o);try{document.execCommand("styleWithCSS",0,!1)}catch(a){try{document.execCommand("useCSS",0,!0)}catch(f){try{document.execCommand("styleWithCSS",!1,!1)}catch(l){}}}o.hide(),r.on("keydown",this.save_selection,this,t.elementid),r.on("mouseup",this.save_selection,this,t.elementid),r.on("focus",this.restore_selection,this,t.elementid),r.on("mousedown",function(){this.focusfromclick=!0},this),r.on("blur",function(){this.focusfromclick=!1,this.text_updated(t.elementid)},this),e.one(e.config.doc.body).delegate("key",this.keyboard_navigation,"down:37,39","#"+t.elementid+"_toolbar",this,t.elementid),M.editor_atto.filepickeroptions[t.elementid]=t.filepickeroptions;var c,h;for(c=0;c=r.size()&&(o=0)),i=r.item(o),i.setAttribute("tabindex","0"),i.focus(),u.setAttribute("aria-activedescendant",i.generateID())},can_show_filepicker:function(e,t){var n=M.editor_atto.filepickeroptions[e];return typeof n[t]!="undefined"},show_filepicker:function(t,n,r){e.use("core_filepicker",function(e){var i=M.editor_atto.filepickeroptions[t][n];i.formcallback=r,M.core_filepicker.show(e,i)})},get_selection_from_node:function(e){var t;return window.getSelection?(t=document.createRange(),t.setStartBefore(e.getDOMNode()),t.setEndAfter(e.getDOMNode()),[t]):document.selection?(t=document.body.createTextRange(),t.moveToElementText(e.getDOMNode()),t):!1},save_selection:function(e,t){if(this.is_active(t)){var n=this.get_selection();n.length>0&&(this.selections[t]=n)}},restore_selection:function(e,t){e.preventDefault(),this.focusfromclick||typeof this.selections[t]!="undefined"&&this.set_selection(this.selections[t]),this.focusfromclick=!1},get_selection:function(){if(window.getSelection){var e=window.getSelection(),t=[],n=0;for(n=0;n0&&e[0].cloneContents)return e[0].cloneContents()},set_selection:function(e){var t,n;if(window.getSelection){t=window.getSelection(),t.removeAllRanges();for(n=0;n
"),s.get("childNodes").each(function(e){a.append(e.remove())}),s.append(a),u=a),n&&n!==""&&(l=e.Node.create("<"+n+">"+n+">"),l.setAttrs(u.getAttrs()),u.get("childNodes").each
-(function(e){e.remove(),l.append(e)}),u.replace(l),u=l),r&&u.setAttrs(r);var c=M.editor_atto.get_selection_from_node(u);return M.editor_atto.set_selection(c),u}};var n="Controlmenu",r;r=function(e){e.draggable=!1,e.center=!1,e.width="auto",e.lightbox=!1,e.footerContent="",r.superclass.constructor.apply(this,[e])},e.extend(r,M.core.dialogue,{initializer:function(t){var n,i,s;r.superclass.initializer.call(this,t),s=this.get("boundingBox"),s.addClass("editor_atto_controlmenu"),n=this.bodyNode,i=e.Node.create(""),i.addClass("accesshide"),i.setHTML(this.get("headerText")),n.prepend(i),n.on("clickoutside",function(e){this.get("visible")&&(e.target.ancestor(".atto_control")||(e.preventDefault(),this.hide()))},this)}},{NAME:n,ATTRS:{headerText:{value:""}}}),M.editor_atto=M.editor_atto||{},M.editor_atto.controlmenu=r,e.Node.addMethod("cleanHTML",i),e.NodeList.importMethod(e.Node.prototype,"cleanHTML")},"@VERSION@",{requires:["node","io","overlay","escape","event","event-simulate","moodle-core-notification"]});
+YUI.add("moodle-editor_atto-editor",function(e,t){function i(){var e=this.getHTML(),t=[{regex://gi,replace:""},{regex:/<\\?\?xml[^>]*>/gi,replace:""},{regex:/<\/?\w+:[^>]*>/gi,replace:""},{regex:/\s*MSO[-:][^;"']*;?/gi,replace:""},{regex:/]*>( |\s)*<\/span>/gi,replace:""},{regex:/class="Mso[^"]*"/gi,replace:""},{regex:/<(\/?title|\/?meta|\/?style|\/?st\d|\/?head|\/?font|\/?html|\/?body|!\[)[^>]*?>/gi,replace:""},{regex:new RegExp(String.fromCharCode(8220),"gi"),replace:'"'},{regex:new RegExp(String.fromCharCode(8216),"gi"),replace:"'"},{regex:new RegExp(String.fromCharCode(8217),"gi"),replace:"'"},{regex:new RegExp(String.fromCharCode(8211),"gi"),replace:"-"},{regex:new RegExp(String.fromCharCode(8212),"gi"),replace:"--"},{regex:new RegExp(String.fromCharCode(189),"gi"),replace:"1/2"},{regex:new RegExp(String.fromCharCode(188),"gi"),replace:"1/4"},{regex:new RegExp(String.fromCharCode(190),"gi"),replace:"3/4"},{regex:new RegExp(String.fromCharCode(169),"gi"),replace:"(c)"},{regex:new RegExp(String.fromCharCode(174),"gi"),replace:"(r)"},{regex:new RegExp(String.fromCharCode(8230),"gi"),replace:"..."}],n=0,r;for(n=0;n'),a.append(f)),h=M.util.image_url("t/expanded","moodle"),c=e.Node.create('"),f.append(c),l=a.getAttribute("aria-activedescendant"),l||(c.setAttribute("tabindex","0"),a.setAttribute("aria-activedescendant",c.generateID())),M.editor_atto.widgets[n]=n;var p=e.Node.create(''),d=0,v={};for(d=0;d'+v.text+""+"")),M.editor_atto.buttonhandlers[n+"_action_"+d]||(e.one("body").delegate("click",M.editor_atto.buttonclicked_handler,".atto_"+n+"_action_"+d),e.one("body").delegate("key",M.editor_atto.buttonclicked_handler,"space,enter",".atto_"+n+"_action_"+d),M.editor_atto.buttonhandlers[n+"_action_"+d]=v.handler);M.editor_atto.buttonhandlers[n]||(e.one("body").delegate("click",M.editor_atto.showhide_menu_handler,".atto_"+n+"_button"),M.editor_atto.buttonhandlers[n]=!0);var m=new M.core.dialogue({bodyContent:p,visible:!1,width:o+"em",lightbox:!1,closeButton:!1,center:!1});M.editor_atto.menus[n+"_"+t]=m,m.align(c,[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BL]),m.hide(),m.headerNode.hide(),m.render
+()},add_toolbar_button:function(t,n,r,i,s){var o=M.editor_atto.get_toolbar_node(t),u=o.one(".atto_group."+i+"_group"),a,f;u||(u=e.Node.create(''),o.append(u)),a=e.Node.create('"),u.append(a),f=o.getAttribute("aria-activedescendant"),f||(a.setAttribute("tabindex","0"),o.setAttribute("aria-activedescendant",a.generateID())),M.editor_atto.buttonhandlers[n]||(e.one("body").delegate("click",M.editor_atto.buttonclicked_handler,".atto_"+n+"_button"),M.editor_atto.buttonhandlers[n]=s),M.editor_atto.widgets[n]=n},is_active:function(t){var n=M.editor_atto.get_selection();n.length&&(n=n.pop());var r=null;n.parentElement?r=e.one(n.parentElement()):r=e.one(n.startContainer);var i=M.editor_atto.get_editable_node(t);return r&&i.contains(r)},focus:function(e){M.editor_atto.get_editable_node(e).focus()},init:function(t){var n=e.Node.create(''),r=e.Node.create(''),i=e.Node.create(''),s=e.Node.create(''),o=M.editor_atto.get_textarea_node(t.elementid),u=e.one('[for="'+t.elementid+'"]');u&&(u.generateID(),r.setAttribute("aria-labelledby",u.get("id")),i.setAttribute("aria-labelledby",u.get("id"))),s.appendChild(r),n.appendChild(i),n.appendChild(s),r.setStyle("minHeight",1.2*o.getAttribute("rows")+"em"),r.append(o.get("value")),r.cleanHTML(),o.get("parentNode").insert(n,o);try{document.execCommand("styleWithCSS",0,!1)}catch(a){try{document.execCommand("useCSS",0,!0)}catch(f){try{document.execCommand("styleWithCSS",!1,!1)}catch(l){}}}o.hide(),r.on("keydown",this.save_selection,this,t.elementid),r.on("mouseup",this.save_selection,this,t.elementid),r.on("focus",this.restore_selection,this,t.elementid),r.on("mousedown",function(){this.focusfromclick=!0},this),r.on("blur",function(){this.focusfromclick=!1,this.text_updated(t.elementid)},this),e.one(e.config.doc.body).delegate("key",this.keyboard_navigation,"down:37,39","#"+t.elementid+"_toolbar",this,t.elementid),M.editor_atto.filepickeroptions[t.elementid]=t.filepickeroptions;var c,h,p,d;for(c=0;c=r.size()&&(o=0)),i=r.item(o),i.setAttribute("tabindex","0"),i.focus(),u.setAttribute("aria-activedescendant",i.generateID())},can_show_filepicker:function(e,t){var n=M.editor_atto.filepickeroptions[e];return typeof n[t]!="undefined"},show_filepicker:function(t,n,r){e.use("core_filepicker",function(e){var i=M.editor_atto.filepickeroptions[t][n];i.formcallback=r,M.core_filepicker.show(e,i)})},get_selection_from_node:function(e){var t;return window.getSelection?(t=document.createRange(),t.setStartBefore(e.getDOMNode()),t.setEndAfter(e.getDOMNode()),[t]):document.selection?(t=document.body.createTextRange(),t.moveToElementText(e.getDOMNode()),t):!1},save_selection:function(e,t){if(this.is_active(t)){var n=this.get_selection();n.length>0&&(this.selections[t]=n)}},restore_selection:function(e,t){e.preventDefault(),this.focusfromclick||typeof this.selections[t]!="undefined"&&this.set_selection(this.selections[t]),this.focusfromclick=!1},get_selection:function(){if(window.getSelection){var e=window.getSelection(),t=[],n=0;for(n=0;n0&&e[0].cloneContents)return e[0].cloneContents()},set_selection:function(e){var t,n;if(window.getSelection){t=window.getSelection(),t.removeAllRanges();for(n=0;n"),s.get("childNodes").each(function(e){a.append(e.remove())}),s.append(a),u=a),n&&n!==""&&(l=e.Node.create("<"+n+">"+n+">"),l.setAttrs(u.getAttrs()),u.get("childNodes").each(function(e){e.remove(),l.append(e)}),u.replace(l),u=l),r&&u.setAttrs(r);var c=M.editor_atto.get_selection_from_node(u);return M.editor_atto.set_selection(c),u}};var n="Controlmenu",r;r=function(e){e.draggable=!1,e.center=!1,e.width="auto",e.lightbox=!1,e.footerContent="",r.superclass.constructor.apply(this,[e])},e.extend(r,M.core.dialogue,{initializer:function(t){var n,i,s;r.superclass.initializer.call(this,t),s=this.get("boundingBox"),s.addClass("editor_atto_controlmenu"),n=this.bodyNode,i=e.Node.create(""),i.addClass("accesshide"),i.setHTML(this.get("headerText")),n.prepend(i),n.on("clickoutside",function(e){this.get("visible")&&(e.target.ancestor(".atto_control")||(e.preventDefault(),this.hide()))},this)}},{NAME:n,ATTRS:{headerText:{value:""}}}),M.editor_atto=M.editor_atto||{},M.editor_atto.controlmenu=r,e.Node.addMethod("cleanHTML",i),e.NodeList.importMethod(e.Node.prototype,"cleanHTML")},"@VERSION@",{requires:["node","io","overlay","escape","event","event-simulate","moodle-core-notification"]});
diff --git a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js
index 04f6078a7e0..fe4af1c16cc 100644
--- a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js
+++ b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js
@@ -161,6 +161,18 @@ M.editor_atto = M.editor_atto || {
var plugin = this.getAttribute('data-plugin');
var handler = this.getAttribute('data-handler');
var overlay = M.editor_atto.menus[plugin + '_' + elementid];
+ var toolbar = M.editor_atto.get_toolbar_node(elementid);
+ var currentid = toolbar.getAttribute('aria-activedescendant');
+
+ // Right now, currentid is the id of the previously selected button.
+ if (currentid) {
+ current = Y.one('#' + currentid);
+ // We only ever want one button with a tabindex of 0 at any one time.
+ current.setAttribute('tabindex', '-1');
+ }
+ this.setAttribute('tabindex', 0);
+ // And update the activedescendant to point at the currently selected button.
+ toolbar.setAttribute('aria-activedescendant', this.generateID());
if (overlay) {
overlay.hide();
@@ -323,6 +335,7 @@ M.editor_atto = M.editor_atto || {
currentfocus = toolbar.getAttribute('aria-activedescendant');
if (!currentfocus) {
+ // Initially set the first button in the toolbar to be the default on keyboard focus.
button.setAttribute('tabindex', '0');
toolbar.setAttribute('aria-activedescendant', button.generateID());
}
@@ -406,6 +419,7 @@ M.editor_atto = M.editor_atto || {
currentfocus = toolbar.getAttribute('aria-activedescendant');
if (!currentfocus) {
+ // Initially set the first button in the toolbar to be the default on keyboard focus.
button.setAttribute('tabindex', '0');
toolbar.setAttribute('aria-activedescendant', button.generateID());
}
@@ -540,17 +554,31 @@ M.editor_atto = M.editor_atto || {
M.editor_atto.filepickeroptions[params.elementid] = params.filepickeroptions;
// Init each of the plugins
- var i, j;
+ var i, j, group, plugin;
for (i = 0; i < params.plugins.length; i++) {
- var group = params.plugins[i].group;
+ group = params.plugins[i].group;
for (j = 0; j < params.plugins[i].plugins.length; j++) {
- var plugin = params.plugins[i].plugins[j];
+ plugin = params.plugins[i].plugins[j];
plugin.params.elementid = params.elementid;
plugin.params.group = group;
M['atto_' + plugin.name].init(plugin.params);
}
}
+
+ // Let the plugins run some init code once all plugins are in the page.
+ for (i = 0; i < params.plugins.length; i++) {
+ group = params.plugins[i].group;
+ for (j = 0; j < params.plugins[i].plugins.length; j++) {
+ plugin = params.plugins[i].plugins[j];
+ plugin.params.elementid = params.elementid;
+ plugin.params.group = group;
+
+ if (typeof M['atto_' + plugin.name].after_init !== 'undefined') {
+ M['atto_' + plugin.name].after_init(plugin.params);
+ }
+ }
+ }
},
/**
@@ -613,11 +641,21 @@ M.editor_atto = M.editor_atto || {
e.preventDefault();
- buttons = toolbar.all('button');
+ // This workaround is because we cannot do ".atto_group:not([hidden]) button" in ie8 (even with selector-css3).
+ // Create an empty NodeList.
+ buttons = toolbar.all('empty');
+ toolbar.all('.atto_group').each(function(group) {
+ if (!group.hasAttribute('hidden')) {
+ // Append the visible buttons to the buttons list.
+ buttons = buttons.concat(group.all('button'));
+ }
+ });
+ // The currentid is the id of the previously selected button.
currentid = toolbar.getAttribute('aria-activedescendant');
if (!currentid) {
return;
}
+ // We only ever want one button with a tabindex of 0.
current = Y.one('#' + currentid);
current.setAttribute('tabindex', '-1');
@@ -636,7 +674,7 @@ M.editor_atto = M.editor_atto || {
currentindex = 0;
}
}
-
+ // Currentindex has been updated to point to the new button.
current = buttons.item(currentindex);
current.setAttribute('tabindex', '0');
current.focus();
diff --git a/lib/editor/atto/yui/src/editor/js/editor.js b/lib/editor/atto/yui/src/editor/js/editor.js
index 26aad700965..ce3a7425312 100644
--- a/lib/editor/atto/yui/src/editor/js/editor.js
+++ b/lib/editor/atto/yui/src/editor/js/editor.js
@@ -159,6 +159,18 @@ M.editor_atto = M.editor_atto || {
var plugin = this.getAttribute('data-plugin');
var handler = this.getAttribute('data-handler');
var overlay = M.editor_atto.menus[plugin + '_' + elementid];
+ var toolbar = M.editor_atto.get_toolbar_node(elementid);
+ var currentid = toolbar.getAttribute('aria-activedescendant');
+
+ // Right now, currentid is the id of the previously selected button.
+ if (currentid) {
+ current = Y.one('#' + currentid);
+ // We only ever want one button with a tabindex of 0 at any one time.
+ current.setAttribute('tabindex', '-1');
+ }
+ this.setAttribute('tabindex', 0);
+ // And update the activedescendant to point at the currently selected button.
+ toolbar.setAttribute('aria-activedescendant', this.generateID());
if (overlay) {
overlay.hide();
@@ -321,6 +333,7 @@ M.editor_atto = M.editor_atto || {
currentfocus = toolbar.getAttribute('aria-activedescendant');
if (!currentfocus) {
+ // Initially set the first button in the toolbar to be the default on keyboard focus.
button.setAttribute('tabindex', '0');
toolbar.setAttribute('aria-activedescendant', button.generateID());
}
@@ -404,6 +417,7 @@ M.editor_atto = M.editor_atto || {
currentfocus = toolbar.getAttribute('aria-activedescendant');
if (!currentfocus) {
+ // Initially set the first button in the toolbar to be the default on keyboard focus.
button.setAttribute('tabindex', '0');
toolbar.setAttribute('aria-activedescendant', button.generateID());
}
@@ -538,17 +552,31 @@ M.editor_atto = M.editor_atto || {
M.editor_atto.filepickeroptions[params.elementid] = params.filepickeroptions;
// Init each of the plugins
- var i, j;
+ var i, j, group, plugin;
for (i = 0; i < params.plugins.length; i++) {
- var group = params.plugins[i].group;
+ group = params.plugins[i].group;
for (j = 0; j < params.plugins[i].plugins.length; j++) {
- var plugin = params.plugins[i].plugins[j];
+ plugin = params.plugins[i].plugins[j];
plugin.params.elementid = params.elementid;
plugin.params.group = group;
M['atto_' + plugin.name].init(plugin.params);
}
}
+
+ // Let the plugins run some init code once all plugins are in the page.
+ for (i = 0; i < params.plugins.length; i++) {
+ group = params.plugins[i].group;
+ for (j = 0; j < params.plugins[i].plugins.length; j++) {
+ plugin = params.plugins[i].plugins[j];
+ plugin.params.elementid = params.elementid;
+ plugin.params.group = group;
+
+ if (typeof M['atto_' + plugin.name].after_init !== 'undefined') {
+ M['atto_' + plugin.name].after_init(plugin.params);
+ }
+ }
+ }
},
/**
@@ -611,11 +639,21 @@ M.editor_atto = M.editor_atto || {
e.preventDefault();
- buttons = toolbar.all('button');
+ // This workaround is because we cannot do ".atto_group:not([hidden]) button" in ie8 (even with selector-css3).
+ // Create an empty NodeList.
+ buttons = toolbar.all('empty');
+ toolbar.all('.atto_group').each(function(group) {
+ if (!group.hasAttribute('hidden')) {
+ // Append the visible buttons to the buttons list.
+ buttons = buttons.concat(group.all('button'));
+ }
+ });
+ // The currentid is the id of the previously selected button.
currentid = toolbar.getAttribute('aria-activedescendant');
if (!currentid) {
return;
}
+ // We only ever want one button with a tabindex of 0.
current = Y.one('#' + currentid);
current.setAttribute('tabindex', '-1');
@@ -634,7 +672,7 @@ M.editor_atto = M.editor_atto || {
currentindex = 0;
}
}
-
+ // Currentindex has been updated to point to the new button.
current = buttons.item(currentindex);
current.setAttribute('tabindex', '0');
current.focus();