diff --git a/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-debug.js b/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-debug.js index a9d5e22d7db..43a8d5ecaf1 100644 --- a/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-debug.js +++ b/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-debug.js @@ -34,13 +34,55 @@ YUI.add('moodle-atto_subscript-button', function (Y, NAME) { */ Y.namespace('M.atto_subscript').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + /** + * A rangy object to alter CSS classes. + * + * @property _subscriptApplier + * @type Object + * @private + */ + _subscriptApplier: null, + + /** + * A rangy object to alter CSS classes. + * + * @property _superscriptApplier + * @type Object + * @private + */ + _superscriptApplier: null, + initializer: function() { - this.addBasicButton({ - exec: 'subscript', + this.addButton({ + buttonName: 'subscript', + callback: this.toggleSubscript, + icon: 'e/subscript', + inlineFormat: true, // Watch the following tags and add/remove highlighting as appropriate: tags: 'sub' }); + this._subscriptApplier = window.rangy.createCssClassApplier("editor-subscript"); + this._superscriptApplier = window.rangy.createCssClassApplier("editor-superscript"); + }, + + /** + * Toggle subscripts in selection + * + * @method toggleSubscript + */ + toggleSubscript: function() { + // Replace all the sub and sup tags. + this.get('host').changeToCSS('sup', 'editor-superscript'); + this.get('host').changeToCSS('sub', 'editor-subscript'); + + // Remove all superscripts inselection and toggle subscript. + this._superscriptApplier.undoToSelection(); + this._subscriptApplier.toggleSelection(); + + // Replace CSS classes with tags. + this.get('host').changeToTags('editor-subscript', 'sub'); + this.get('host').changeToTags('editor-superscript', 'sup'); } }); diff --git a/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-min.js b/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-min.js index 9510f931d8e..e92ce238c83 100644 --- a/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-min.js +++ b/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button-min.js @@ -1 +1 @@ -YUI.add("moodle-atto_subscript-button",function(e,t){e.namespace("M.atto_subscript").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){this.addBasicButton({exec:"subscript",tags:"sub"})}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); +YUI.add("moodle-atto_subscript-button",function(e,t){e.namespace("M.atto_subscript").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_subscriptApplier:null,_superscriptApplier:null,initializer:function(){this.addButton({buttonName:"subscript",callback:this.toggleSubscript,icon:"e/subscript",inlineFormat:!0,tags:"sub"}),this._subscriptApplier=window.rangy.createCssClassApplier("editor-subscript"),this._superscriptApplier=window.rangy.createCssClassApplier("editor-superscript")},toggleSubscript:function(){this.get("host").changeToCSS("sup","editor-superscript"),this.get("host").changeToCSS("sub","editor-subscript"),this._superscriptApplier.undoToSelection(),this._subscriptApplier.toggleSelection(),this.get("host").changeToTags("editor-subscript","sub"),this.get("host").changeToTags("editor-superscript","sup")}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); diff --git a/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button.js b/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button.js index a9d5e22d7db..43a8d5ecaf1 100644 --- a/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button.js +++ b/lib/editor/atto/plugins/subscript/yui/build/moodle-atto_subscript-button/moodle-atto_subscript-button.js @@ -34,13 +34,55 @@ YUI.add('moodle-atto_subscript-button', function (Y, NAME) { */ Y.namespace('M.atto_subscript').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + /** + * A rangy object to alter CSS classes. + * + * @property _subscriptApplier + * @type Object + * @private + */ + _subscriptApplier: null, + + /** + * A rangy object to alter CSS classes. + * + * @property _superscriptApplier + * @type Object + * @private + */ + _superscriptApplier: null, + initializer: function() { - this.addBasicButton({ - exec: 'subscript', + this.addButton({ + buttonName: 'subscript', + callback: this.toggleSubscript, + icon: 'e/subscript', + inlineFormat: true, // Watch the following tags and add/remove highlighting as appropriate: tags: 'sub' }); + this._subscriptApplier = window.rangy.createCssClassApplier("editor-subscript"); + this._superscriptApplier = window.rangy.createCssClassApplier("editor-superscript"); + }, + + /** + * Toggle subscripts in selection + * + * @method toggleSubscript + */ + toggleSubscript: function() { + // Replace all the sub and sup tags. + this.get('host').changeToCSS('sup', 'editor-superscript'); + this.get('host').changeToCSS('sub', 'editor-subscript'); + + // Remove all superscripts inselection and toggle subscript. + this._superscriptApplier.undoToSelection(); + this._subscriptApplier.toggleSelection(); + + // Replace CSS classes with tags. + this.get('host').changeToTags('editor-subscript', 'sub'); + this.get('host').changeToTags('editor-superscript', 'sup'); } }); diff --git a/lib/editor/atto/plugins/subscript/yui/src/button/js/button.js b/lib/editor/atto/plugins/subscript/yui/src/button/js/button.js index 337d3628e40..07dc361b32f 100644 --- a/lib/editor/atto/plugins/subscript/yui/src/button/js/button.js +++ b/lib/editor/atto/plugins/subscript/yui/src/button/js/button.js @@ -32,12 +32,54 @@ */ Y.namespace('M.atto_subscript').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + /** + * A rangy object to alter CSS classes. + * + * @property _subscriptApplier + * @type Object + * @private + */ + _subscriptApplier: null, + + /** + * A rangy object to alter CSS classes. + * + * @property _superscriptApplier + * @type Object + * @private + */ + _superscriptApplier: null, + initializer: function() { - this.addBasicButton({ - exec: 'subscript', + this.addButton({ + buttonName: 'subscript', + callback: this.toggleSubscript, + icon: 'e/subscript', + inlineFormat: true, // Watch the following tags and add/remove highlighting as appropriate: tags: 'sub' }); + this._subscriptApplier = window.rangy.createCssClassApplier("editor-subscript"); + this._superscriptApplier = window.rangy.createCssClassApplier("editor-superscript"); + }, + + /** + * Toggle subscripts in selection + * + * @method toggleSubscript + */ + toggleSubscript: function() { + // Replace all the sub and sup tags. + this.get('host').changeToCSS('sup', 'editor-superscript'); + this.get('host').changeToCSS('sub', 'editor-subscript'); + + // Remove all superscripts inselection and toggle subscript. + this._superscriptApplier.undoToSelection(); + this._subscriptApplier.toggleSelection(); + + // Replace CSS classes with tags. + this.get('host').changeToTags('editor-subscript', 'sub'); + this.get('host').changeToTags('editor-superscript', 'sup'); } }); diff --git a/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-debug.js b/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-debug.js index bcad8e55b01..d5285d34734 100644 --- a/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-debug.js +++ b/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-debug.js @@ -34,13 +34,55 @@ YUI.add('moodle-atto_superscript-button', function (Y, NAME) { */ Y.namespace('M.atto_superscript').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + /** + * A rangy object to alter CSS classes. + * + * @property _subscriptApplier + * @type Object + * @private + */ + _subscriptApplier: null, + + /** + * A rangy object to alter CSS classes. + * + * @property _superscriptApplier + * @type Object + * @private + */ + _superscriptApplier: null, + initializer: function() { - this.addBasicButton({ - exec: 'superscript', + this.addButton({ + buttonName: 'superscript', + inlineFormat: true, + callback: this.toggleSuperscript, + icon: 'e/superscript', // Watch the following tags and add/remove highlighting as appropriate: tags: 'sup' }); + this._subscriptApplier = window.rangy.createCssClassApplier("editor-subscript"); + this._superscriptApplier = window.rangy.createCssClassApplier("editor-superscript"); + }, + + /** + * Toggle superscripts in selection + * + * @method toggleSuperscript + */ + toggleSuperscript: function() { + // Replace all the sub and sup tags. + this.get('host').changeToCSS('sub', 'editor-subscript'); + this.get('host').changeToCSS('sup', 'editor-superscript'); + + // Remove all subscripts inselection and toggle superscript. + this._superscriptApplier.toggleSelection(); + this._subscriptApplier.undoToSelection(); + + // Replace CSS classes with tags. + this.get('host').changeToTags('editor-superscript', 'sup'); + this.get('host').changeToTags('editor-subscript', 'sub'); } }); diff --git a/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-min.js b/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-min.js index 70ac08d0fc7..d7dcc400135 100644 --- a/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-min.js +++ b/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button-min.js @@ -1 +1 @@ -YUI.add("moodle-atto_superscript-button",function(e,t){e.namespace("M.atto_superscript").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{initializer:function(){this.addBasicButton({exec:"superscript",tags:"sup"})}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); +YUI.add("moodle-atto_superscript-button",function(e,t){e.namespace("M.atto_superscript").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_subscriptApplier:null,_superscriptApplier:null,initializer:function(){this.addButton({buttonName:"superscript",inlineFormat:!0,callback:this.toggleSuperscript,icon:"e/superscript",tags:"sup"}),this._subscriptApplier=window.rangy.createCssClassApplier("editor-subscript"),this._superscriptApplier=window.rangy.createCssClassApplier("editor-superscript")},toggleSuperscript:function(){this.get("host").changeToCSS("sub","editor-subscript"),this.get("host").changeToCSS("sup","editor-superscript"),this._superscriptApplier.toggleSelection(),this._subscriptApplier.undoToSelection(),this.get("host").changeToTags("editor-superscript","sup"),this.get("host").changeToTags("editor-subscript","sub")}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); diff --git a/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button.js b/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button.js index bcad8e55b01..d5285d34734 100644 --- a/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button.js +++ b/lib/editor/atto/plugins/superscript/yui/build/moodle-atto_superscript-button/moodle-atto_superscript-button.js @@ -34,13 +34,55 @@ YUI.add('moodle-atto_superscript-button', function (Y, NAME) { */ Y.namespace('M.atto_superscript').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + /** + * A rangy object to alter CSS classes. + * + * @property _subscriptApplier + * @type Object + * @private + */ + _subscriptApplier: null, + + /** + * A rangy object to alter CSS classes. + * + * @property _superscriptApplier + * @type Object + * @private + */ + _superscriptApplier: null, + initializer: function() { - this.addBasicButton({ - exec: 'superscript', + this.addButton({ + buttonName: 'superscript', + inlineFormat: true, + callback: this.toggleSuperscript, + icon: 'e/superscript', // Watch the following tags and add/remove highlighting as appropriate: tags: 'sup' }); + this._subscriptApplier = window.rangy.createCssClassApplier("editor-subscript"); + this._superscriptApplier = window.rangy.createCssClassApplier("editor-superscript"); + }, + + /** + * Toggle superscripts in selection + * + * @method toggleSuperscript + */ + toggleSuperscript: function() { + // Replace all the sub and sup tags. + this.get('host').changeToCSS('sub', 'editor-subscript'); + this.get('host').changeToCSS('sup', 'editor-superscript'); + + // Remove all subscripts inselection and toggle superscript. + this._superscriptApplier.toggleSelection(); + this._subscriptApplier.undoToSelection(); + + // Replace CSS classes with tags. + this.get('host').changeToTags('editor-superscript', 'sup'); + this.get('host').changeToTags('editor-subscript', 'sub'); } }); diff --git a/lib/editor/atto/plugins/superscript/yui/src/button/js/button.js b/lib/editor/atto/plugins/superscript/yui/src/button/js/button.js index 80bfeece74e..fce14a12bb2 100644 --- a/lib/editor/atto/plugins/superscript/yui/src/button/js/button.js +++ b/lib/editor/atto/plugins/superscript/yui/src/button/js/button.js @@ -32,12 +32,54 @@ */ Y.namespace('M.atto_superscript').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + /** + * A rangy object to alter CSS classes. + * + * @property _subscriptApplier + * @type Object + * @private + */ + _subscriptApplier: null, + + /** + * A rangy object to alter CSS classes. + * + * @property _superscriptApplier + * @type Object + * @private + */ + _superscriptApplier: null, + initializer: function() { - this.addBasicButton({ - exec: 'superscript', + this.addButton({ + buttonName: 'superscript', + callback: this.toggleSuperscript, + icon: 'e/superscript', + inlineFormat: true, // Watch the following tags and add/remove highlighting as appropriate: tags: 'sup' }); + this._subscriptApplier = window.rangy.createCssClassApplier("editor-subscript"); + this._superscriptApplier = window.rangy.createCssClassApplier("editor-superscript"); + }, + + /** + * Toggle superscripts in selection + * + * @method toggleSuperscript + */ + toggleSuperscript: function() { + // Replace all the sub and sup tags. + this.get('host').changeToCSS('sub', 'editor-subscript'); + this.get('host').changeToCSS('sup', 'editor-superscript'); + + // Remove all subscripts inselection and toggle superscript. + this._superscriptApplier.toggleSelection(); + this._subscriptApplier.undoToSelection(); + + // Replace CSS classes with tags. + this.get('host').changeToTags('editor-superscript', 'sup'); + this.get('host').changeToTags('editor-subscript', 'sub'); } }); 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 04823a04705..22162fc1a89 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 @@ -1401,6 +1401,175 @@ Y.Base.mix(Y.M.editor_atto.Editor, [EditorClean]); // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . +/** + * @module moodle-editor_atto-editor + * @submodule commands + */ + +/** + * Selection functions for the Atto editor. + * + * See {{#crossLink "M.editor_atto.Editor"}}{{/crossLink}} for details. + * + * @namespace M.editor_atto + * @class EditorCommand + */ + +function EditorCommand() {} + +EditorCommand.ATTRS= { +}; + +EditorCommand.prototype = { + /** + * Applies a callback method to editor if selection is uncollapsed or waits for input to select first. + * @method applyFormat + * @param e EventTarget Event to be passed to callback if selection is uncollapsed + * @param method callback A callback method which changes editor when text is selected. + * @param object context Context to be used for callback method + * @param array args Array of arguments to pass to callback + */ + applyFormat: function(e, callback, context, args) { + function handleInsert(e, callback, context, args, anchorNode, anchorOffset) { + // After something is inputed, select it and apply the formating function. + Y.soon(Y.bind(function(e, callback, context, args, anchorNode, anchorOffset) { + var selection = window.rangy.getSelection(); + + // Set the start of the selection to where it was when the method was first called. + var range = selection.getRangeAt(0); + range.setStart(anchorNode, anchorOffset); + selection.setSingleRange(range); + + // Now apply callback to the new text that is selected. + callback.apply(context, [e, args]); + + // Collapse selection so cursor is at end of inserted material. + selection.collapseToEnd(); + }, this, e, callback, context, args, anchorNode, anchorOffset)); + } + + // Set default context for the method. + context = context || this; + + // Check whether range is collapsed. + var selection = window.rangy.getSelection(); + + if (selection.isCollapsed) { + // Selection is collapsed so listen for input into editor. + var handle = this.editor.once('input', handleInsert, this, callback, context, args, + selection.anchorNode, selection.anchorOffset); + + // Cancel if selection changes before input. + this.editor.onceAfter(['click', 'selectstart'], handle.detach, handle); + + return; + } + + // The range is not collapsed; so apply callback method immediately. + callback.apply(context, [e, args]); + + }, + + /** + * Replaces all the tags in a node list with new type. + * @method replaceTags + * @param NodeList nodelist + * @param String tag + */ + replaceTags: function(nodelist, tag) { + // We mark elements in the node list for iterations. + nodelist.setAttribute('data-iterate', true); + var node = this.editor.one('[data-iterate="true"]'); + while (node) { + var clone = Y.Node.create('<' + tag + ' />') + .setAttrs(node.getAttrs()) + .removeAttribute('data-iterate'); + // Copy class and style if not blank. + if (node.getAttribute('style')) { + clone.setAttribute('style', node.getAttribute('style')); + } + if (node.getAttribute('class')) { + clone.setAttribute('class', node.getAttribute('class')); + } + // We use childNodes here because we are interested in both type 1 and 3 child nodes. + var children = node.getDOMNode().childNodes, child; + child = children[0]; + while (typeof child !== "undefined") { + clone.append(child); + child = children[0]; + } + node.replace(clone); + node = this.editor.one('[data-iterate="true"]'); + } + }, + + /** + * Change all tags with given type to a span with CSS class attribute. + * @method changeToCSS + * @param String tag Tag type to be changed to span + * @param String markerClass CSS class that corresponds to desired tag + */ + changeToCSS: function(tag, markerClass) { + // Save the selection. + var selection = window.rangy.saveSelection(); + + // Remove display:none from rangy markers so browser doesn't delete them. + this.editor.all('.rangySelectionBoundary').setStyle('display', null); + + // Replace tags with CSS classes. + this.editor.all(tag).addClass(markerClass); + this.replaceTags(this.editor.all('.' + markerClass), 'span'); + + // Restore selection and toggle class. + window.rangy.restoreSelection(selection); + }, + + /** + * Change spans with CSS classes in editor into elements with given tag. + * @method changeToCSS + * @param String markerClass CSS class that corresponds to desired tag + * @param String tag New tag type to be created + */ + changeToTags: function(markerClass, tag) { + // Save the selection. + var selection = window.rangy.saveSelection(); + + // Remove display:none from rangy markers so browser doesn't delete them. + this.editor.all('.rangySelectionBoundary').setStyle('display', null); + + // Replace spans with given tag. + this.replaceTags(this.editor.all('span[class="' + markerClass + '"]'), tag); + this.editor.all(tag + '[class="' + markerClass + '"]').removeAttribute('class'); + this.editor.all('.' + markerClass).each(function(n) { + n.wrap('<' + tag + '/>'); + n.removeClass(markerClass); + }); + + // Remove CSS classes. + this.editor.all('[class="' + markerClass + '"]').removeAttribute('class'); + this.editor.all(tag).removeClass(markerClass); + + // Restore selection. + window.rangy.restoreSelection(selection); + } +}; + +Y.Base.mix(Y.M.editor_atto.Editor, [EditorCommand]); +// 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 . + /** * @module moodle-editor_atto-editor * @submodule toolbar @@ -2383,6 +2552,7 @@ Y.Base.mix(Y.M.editor_atto.Editor, [EditorFilepicker]); "event", "event-simulate", "event-custom", + "node-event-html5", "yui-throttle", "moodle-core-notification-dialogue", "moodle-core-notification-confirm", 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 a8fac2b38eb..a27465ad534 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,4 +1,4 @@ -YUI.add("moodle-editor_atto-editor",function(e,t){function i(){i.superclass.constructor.apply(this,arguments)}function a(){}function f(){}function p(){}function d(){}function v(){}function m(){}function g(){}function y(){}function b(){}var n="moodle-editor_atto-editor",r={CONTENT:"editor_atto_content",CONTENTWRAPPER:"editor_atto_content_wrap",TOOLBAR:"editor_atto_toolbar",WRAPPER:"editor_atto",HIGHLIGHT:"highlight"};e.extend(i,e.Base,{BLOCK_TAGS:["address","article","aside","audio","blockquote","canvas","dd","div","dl","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","noscript","ol","output","p","pre","section","table","tfoot","ul","video"],PLACEHOLDER_CLASS:"atto-tmp-class",ALL_NODES_SELECTOR:"[style],font[face]",FONT_FAMILY:"fontFamily",_wrapper:null,editor:null,textarea:null,textareaLabel:null,plugins:null,_eventHandles:null,initializer:function(){var t;this.textarea=e.one(document.getElementById(this.get("elementid")));if(!this.textarea)return;this._eventHandles=[],this._wrapper=e.Node.create('
'),t=e.Handlebars.compile('
'),this.editor=e.Node.create(t({elementid:this.get("elementid"),CSS:r})),this.textareaLabel=e.one('[for="'+this.get("elementid")+'"]'),this.textareaLabel&&(this.textareaLabel.generateID(),this.editor.setAttribute("aria-labelledby",this.textareaLabel.get("id"))),this.setupToolbar();var n=e.Node.create('
');n.appendChild(this.editor),this._wrapper.appendChild(n),this.editor.setStyle("minHeight",20*this.textarea.getAttribute("rows")+8+"px"),e.UA.ie===0&&this.editor.setStyle("height",20*this.textarea.getAttribute("rows")+8+"px"),this.disableCssStyling(),document.queryCommandSupported("DefaultParagraphSeparator")&&document.execCommand("DefaultParagraphSeparator",!1,"p"),this.textarea.get("parentNode").insert(this._wrapper,this.textarea).setAttribute("class","editor_atto_wrap"),this.textarea.hide(),this.updateFromTextArea(),this.publishEvents(),this.setupSelectionWatchers(),this.setupAutomaticPolling(),this.setupPlugins(),this.setupAutosave(),this.setupNotifications()},focus:function(){return this.editor.focus(),this},publishEvents:function(){return this.publish("change",{broadcast:!0,preventable:!0}),this.publish("pluginsloaded",{fireOnce:!0}),this.publish("atto:selectionchanged",{prefix:"atto"}),this},setupAutomaticPolling:function(){return this._registerEventHandle(this.editor.on(["keyup","cut"],this.updateOriginal,this)),this._registerEventHandle(this.editor.on("paste",this.pasteCleanup,this)),this._registerEventHandle(this.editor.on("drop",this.updateOriginalDelayed,this)),this},updateOriginalDelayed:function(){return e.soon(e.bind(this.updateOriginal,this)),this},setupPlugins:function(){this.plugins={};var t=this.get("plugins"),n,r,i,s,o;for(n in t){r=t[n];if(!r.plugins)continue;for(i in r.plugins){s=r.plugins[i],o=e.mix({name:s.name,group:r.group,editor:this.editor,toolbar:this.toolbar,host:this},s);if(typeof e.M["atto_"+s.name]=="undefined")continue;this.plugins[s.name]=new e.M["atto_"+s.name].Button(o)}}return this.fire("pluginsloaded"),this},enablePlugins:function(e){this._setPluginState(!0,e)},disablePlugins:function(e){this._setPluginState(!1,e)},_setPluginState:function(t,n){var r="disableButtons";t&&(r="enableButtons"),n?this.plugins[n][r]():e.Object.each(this.plugins,function(e){e[r]()},this)},_registerEventHandle:function(e){this._eventHandles.push(e)}},{NS:"editor_atto",ATTRS:{elementid:{value:null,writeOnce:!0},contextid:{value:null,writeOnce:!0},plugins:{value:{},writeOnce:!0}}}),e.augment(i,e.EventTarget),e.namespace("M.editor_atto").Editor=i,e.namespace("M.editor_atto.Editor").init=function(t){return new e.M.editor_atto.Editor(t)};var s="moodle-editor_atto-editor-notify",o="info",u="warning";a.ATTRS={},a.prototype={messageOverlay:null,hideTimer:null,setupNotifications:function(){var e=new Image,t=new Image;return e.src=M.util.image_url("i/warning","moodle"),t.src=M.util.image_url("i/info","moodle"),this},showMessage:function(t,n,r){var i="",s,a;return this.messageOverlay===null&&(this.messageOverlay=e.Node.create('
'),this.messageOverlay.hide(!0),this.textarea.get("parentNode").append(this.messageOverlay),this.messageOverlay.on("click",function(){this.messageOverlay.hide(!0)},this)),this.hideTimer!==null&&this.hideTimer.cancel(),n===u?i=''+M.util.get_string(':n===o&&(i=''+M.util.get_string('),s=parseInt(r,10),s<=0&&(s=6e4),n="atto_"+n,a=e.Node.create('"),this.messageOverlay.empty(),this.messageOverlay.append(a),this.messageOverlay.show(!0),this.hideTimer=e.later(s,this,function(){this.hideTimer=null,this.messageOverlay.hide(!0)}),this}},e.Base.mix(e.M.editor_atto.Editor,[a]),f.ATTRS={},f.prototype={_getEmptyContent:function(){return e.UA.ie&&e.UA.ie<10?"

":"


"},updateFromTextArea:function(){return this.editor.setHTML(""),this.editor.append(this._cleanHTML(this.textarea.get("value"))),this.editor.getHTML()===""&&this.editor.setHTML(this._getEmptyContent()),this},updateOriginal:function(){var e=this.textarea.get("value"),t=this.getCleanHTML();return t===""&&this.isActive()&&(t=this._getEmptyContent()),e!==t&&(this.textarea.set("value",t),this.textarea.simulate("change"),this.fire("change")),this}},e.Base.mix(e.M.editor_atto.Editor,[f]);var l=5e3,c=6e4,h="moodle-editor_atto-editor-autosave";p.ATTRS={autosaveEnabled:{value:!0,writeOnce:!0},autosaveFrequency:{value:60,writeOnce:!0},pageHash:{value:"",writeOnce:!0},autosaveAjaxScript:{value:"/lib/editor/atto/autosave-ajax.php",readOnly:!0}},p.prototype={lastText:"",autosaveInstance -:null,setupAutosave:function(){var t=-1,n,r=null,i=this.get("filepickeroptions");if(!this.get("autosaveEnabled"))return;this.autosaveInstance=e.stamp(this);for(r in i)typeof i[r].itemid!="undefined"&&(t=i[r].itemid);url=M.cfg.wwwroot+this.get("autosaveAjaxScript"),params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"resume",drafttext:"",draftid:t,elementid:this.get("elementid"),pageinstance:this.autosaveInstance,pagehash:this.get("pageHash")},e.io(url,{method:"POST",data:params,context:this,on:{success:function(e,t){if(typeof t.responseText!="undefined"&&t.responseText!==""){response_json=JSON.parse(t.responseText);if(response_json.result==="

"||response_json.result==="


"||response_json.result==="
")response_json.result="";if(response_json.result==="

 

"||response_json.result==="


 

")response_json.result="";response_json.error||typeof response_json.result=="undefined"?this.showMessage(M.util.get_string("errortextrecovery","editor_atto"),u,c):response_json.result!==this.textarea.get("value")&&response_json.result!==""&&this.recoverText(response_json.result),this._fireSelectionChanged()}},failure:function(){this.showMessage(M.util.get_string("errortextrecovery","editor_atto"),u,c)}}});var s=parseInt(this.get("autosaveFrequency"),10)*1e3;return e.later(s,this,this.saveDraft,!1,!0),n=this.textarea.ancestor("form"),n&&n.on("submit",this.resetAutosave,this),this},resetAutosave:function(){return url=M.cfg.wwwroot+this.get("autosaveAjaxScript"),params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"reset",elementid:this.get("elementid"),pageinstance:this.autosaveInstance,pagehash:this.get("pageHash")},e.io(url,{method:"POST",data:params,sync:!0}),this},recoverText:function(e){return this.editor.setHTML(e),this.saveSelection(),this.updateOriginal(),this.lastText=e,this.showMessage(M.util.get_string("textrecovered","editor_atto"),o,c),this},saveDraft:function(){this.editor.get("hidden")||this.updateOriginal();var t=this.textarea.get("value");if(t!==this.lastText){url=M.cfg.wwwroot+this.get("autosaveAjaxScript"),params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"save",drafttext:t,elementid:this.get("elementid"),pagehash:this.get("pageHash"),pageinstance:this.autosaveInstance};var n=function(e,t){var n=parseInt(this.get("autosaveFrequency"),10)*1e3;this.showMessage(M.util.get_string("autosavefailed","editor_atto"),u,n)};e.io(url,{method:"POST",data:params,context:this,on:{error:n,failure:n,success:function(r,i){i.responseText!==""?e.soon(e.bind(n,this,[r,i])):(this.lastText=t,this.showMessage(M.util.get_string("autosavesucceeded","editor_atto"),o,l))}}})}return this}},e.Base.mix(e.M.editor_atto.Editor,[p]),d.ATTRS={},d.prototype={getCleanHTML:function(){var t=this.editor.cloneNode(!0),n;return e.each(t.all('[id^="yui"]'),function(e){e.removeAttribute("id")}),t.all(".atto_control").remove(!0),n=t.get("innerHTML"),n==="

"||n==="


"?"":this._cleanHTML(n)},cleanEditorHTML:function(){var e=this.editor.get("innerHTML");return this.editor.set("innerHTML",this._cleanHTML(e)),this},_cleanHTML:function(e){var t=[{regex:/]*>[\s\S]*?<\/style>/gi,replace:""},{regex:/)/gi,replace:""},{regex:/<\/?(?:title|meta|style|st\d|head|font|html|body|link)[^>]*?>/gi,replace:""}];return this._filterContentWithRules(e,t)},_filterContentWithRules:function(e,t){var n=0;for(n=0;n-1);if(r){var i;try{i=t.clipboardData.getData("text/html")}catch(s){return this.fallbackPasteCleanupDelayed(),!0}e.preventDefault(),i=this._cleanPasteHTML(i);var o=window.rangy.saveSelection();return this.insertContentAtFocusPoint(i),window.rangy.restoreSelection(o),window.rangy.getSelection().collapseToEnd(),this.updateOriginal(),!1}return this.fallbackPasteCleanupDelayed(),!0}return this.fallbackPasteCleanupDelayed(),!0}return this.updateOriginalDelayed(),!0},fallbackPasteCleanup:function(){var e=window.rangy.saveSelection(),t=this.editor.get("innerHTML");return this.editor.set("innerHTML",this._cleanPasteHTML(t)),this.updateOriginal(),window.rangy.restoreSelection(e),this},fallbackPasteCleanupDelayed:function(){return e.soon(e.bind(this.fallbackPasteCleanup,this)),this},_cleanPasteHTML:function(e){if(!e||e.length===0)return"";var t=[{regex:/<\s*\/html\s*>([\s\S]+)$/gi,replace:""},{regex://gi,replace:""},{regex://gi,replace:""},{regex:/]*>[\s\S]*?<\/xml>/gi,replace:""},{regex:/<\?xml[^>]*>[\s\S]*?<\\\?xml>/gi,replace:""},{regex:/<\/?\w+:[^>]*>/gi,replace:""}];e=this._filterContentWithRules(e,t),e=this._cleanHTML(e);if(e.length===0||!e.match(/\S/))return e;var n=document.createElement("div");return n.innerHTML=e,e=n.innerHTML,n.innerHTML="",t=[{regex:/(<[^>]*?style\s*?=\s*?")([^>"]*)(")/gi,replace:function(e,t,n,r){return n=n.replace(/(?:^|;)[\s]*MSO[-:](?:&[\w]*;|[^;"])*/gi,""),t+n+r}},{regex:/(<[^>]*?class\s*?=\s*?")([^>"]*)(")/gi,replace:function(e,t,n,r){return n=n.replace(/(?:^|[\s])[\s]*MSO[_a-zA-Z0-9\-]*/gi,""),n=n.replace(/(?:^|[\s])[\s]*Apple-[_a-zA-Z0-9\-]*/gi,""),t+n+r}},{regex:/]*?name\s*?=\s*?"OLE_LINK\d*?"[^>]*?>\s*?<\/a>/gi,replace:""}],e=this._filterContentWithRules(e,t),e=this._cleanHTML(e),e=this._cleanSpans(e),e},_cleanSpans:function(e){if(!e||e.length===0)return"";if(e.length===0||!e.match(/\S/))return e;var t=[{regex:/(<[^>]*?)(?:[\s]*(?:class|style|id)\s*?=\s*?"\s*?")+/gi,replace:"$1"}];e=this._filterContentWithRules(e,t);var n=document.createElement("div");n.innerHTML=e;var r=n.getElementsByTagName("span"),i=Array.prototype.slice.call(r,0);return i.forEach(function(e){if(!e.hasAttributes()){while(e.firstChild -)e.parentNode.insertBefore(e.firstChild,e);e.parentNode.removeChild(e)}}),n.innerHTML}},e.Base.mix(e.M.editor_atto.Editor,[d]),v.ATTRS={},v.prototype={toolbar:null,openMenus:null,setupToolbar:function(){return this.toolbar=e.Node.create('