diff --git a/lib/editor/atto/lang/en/editor_atto.php b/lib/editor/atto/lang/en/editor_atto.php
index 31fa65a95f3..b9e84548959 100644
--- a/lib/editor/atto/lang/en/editor_atto.php
+++ b/lib/editor/atto/lang/en/editor_atto.php
@@ -39,4 +39,6 @@ $string['plugin_title_shortcut'] = '{$a->title} [{$a->shortcut}]';
$string['confirm'] = 'Confirm';
$string['cancel'] = 'Cancel';
$string['recover'] = 'Recover';
+$string['infostatus'] = 'Information';
+$string['warningstatus'] = 'Warning';
$string['confirmrecover'] = 'A previously unsaved version of the text for field "{$a->label}" was found. Do you want to recover it?';
diff --git a/lib/editor/atto/styles.css b/lib/editor/atto/styles.css
index 284ba8edd8f..e7c79a017cc 100644
--- a/lib/editor/atto/styles.css
+++ b/lib/editor/atto/styles.css
@@ -181,3 +181,34 @@ div.editor_atto_content:hover .atto_control {
padding-top: 5px;
padding-bottom: 5px;
}
+
+.editor_atto_notification {
+ position: relative;
+ bottom: 0px;
+ height: 1.5em;
+ margin-top: -2.5em;
+ margin-left: 1px;
+ margin-right: 1px;
+ margin-bottom: 1em;
+}
+.editor_atto_notification .atto_info {
+ display: inline-block;
+ background-color: #F2F2F2;
+ padding: 0.5em;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-top-right-radius: 1em;
+}
+.editor_atto_notification .atto_warning {
+ display: inline-block;
+ background-color: #FFD700;
+ padding: 0.5em;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-top-right-radius: 1em;
+}
+.dir-rtl .editor_atto_notification .atto_info,
+.dir-rtl .editor_atto_notification .atto_warning {
+ border-top-right-radius: 0;
+ border-top-left-radius: 1em;
+}
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 b9f1d996c87..d8650234e2c 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
@@ -478,6 +478,95 @@ Y.namespace('M.editor_atto.Editor').init = function(config) {
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * A notify function for the Atto editor.
+ *
+ * @module moodle-editor_atto-notify
+ * @submodule notify-base
+ * @package editor_atto
+ * @copyright 2014 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function EditorNotify() {}
+
+EditorNotify.ATTRS= {
+};
+
+// There is no error type here - because you should make errors more obvious.
+var NOTIFY_WARNING = 'atto_warning',
+ NOTIFY_INFO = 'atto_info';
+
+EditorNotify.prototype = {
+
+ /**
+ * A single Y.Overlay for this editor. There is only ever one - it is replaced if a new message comes in.
+ *
+ * @property messageOverlay
+ * @type {Y.Overlay}
+ */
+ messageOverlay: null,
+
+ /**
+ * Show a notification in a floaty overlay somewhere in the atto editor text area.
+ *
+ * @method showMessage
+ * @chainable
+ */
+ showMessage: function(message, type) {
+
+ if (this.messageOverlay === null) {
+ this.messageOverlay = Y.Node.create('
');
+
+ this.messageOverlay.hide();
+ this._wrapper.append(this.messageOverlay);
+
+ this.messageOverlay.on('click', function() {
+ this.messageOverlay.hide();
+ }, this);
+
+ }
+
+ var messageTypeIcon = '';
+ if (type === NOTIFY_WARNING) {
+ messageTypeIcon = '
';
+ } else if (type === NOTIFY_INFO) {
+ messageTypeIcon = '
';
+ }
+
+ var bodyContent = Y.Node.create('' +
+ messageTypeIcon + ' ' +
+ Y.Escape.html(message) +
+ '
');
+ this.messageOverlay.empty();
+ this.messageOverlay.append(bodyContent);
+ this.messageOverlay.show();
+
+ return this;
+ }
+
+};
+
+Y.Base.mix(Y.M.editor_atto.Editor, [EditorNotify]);
+// 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 textarea
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 c1cdb8faa2e..09b2e603896 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(){i.superclass.constructor.apply(this,arguments)}function s(){}function u(){}function a(){}function f(){}function l(){}function c(){}function h(){}function p(){}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),this.textarea.hide(),this.updateFromTextArea(),this.publishEvents(),this.setupSelectionWatchers(),this.setupAutomaticPolling(),this.setupPlugins(),this.setupAutosave()},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","paste","cut"],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},autosaveEnabled:{value:!0,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)},s.ATTRS={},s.prototype={_getEmptyContent:function(){return e.UA.ie&&e.UA.ie<10?"":"
"},updateFromTextArea:function(){this.editor.setHTML(""),this.editor.append(this.textarea.get("value")),this.cleanEditorHTML(),this.editor.getHTML()===""&&this.editor.setHTML(this._getEmptyContent())},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,[s]);var o=5e3;u.ATTRS={},u.prototype={lastText:null,autosaveInstance:null,setupAutosave:function(){if(!this.get("autosaveEnabled"))return;this.autosaveInstance=e.stamp(this);var t=-1,n,r=this.get("filepickeroptions");for(n in r)typeof r[n].itemid!="undefined"&&(t=r[n].itemid);return url=M.cfg.wwwroot+"/lib/editor/atto/autosave-ajax.php",params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"resume",drafttext:"",draftid:t,elementid:this.get("elementid"),pageinstance:this.autosaveInstance,pagedomid:e.one("body").get("id")},e.io(url,{method:"POST",data:params,on:{success:function(e,t){typeof t.responseText!="undefined"&&t.responseText!==""&&t.responseText!==this.textarea.get("value")&&this.recoverText(t.responseText)}},context:this}),e.later(o,this,this.saveDraft,!1,!0),this.textarea.ancestor("form").on("submit",this.resetAutosave,this),this},resetAutosave:function(){return url=M.cfg.wwwroot+"/lib/editor/atto/autosave-ajax.php",params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"reset",elementid:this.get("elementid"),pageinstance:this.autosaveInstance,pagedomid:e.one("body").get("id")},e.io(url,{method:"POST",data:params,sync:!0}),this},recoverText:function(e){var t=new M.core.confirm({title:M.util.get_string("confirm","editor_atto"),question:M.util.get_string("confirmrecover","editor_atto",{label:this.textareaLabel.get("text")}),yesLabel:M.util.get_string("recover","editor_atto"),noLabel:M.util.get_string("cancel","editor_atto")});return t.on("complete-yes",function(){t.hide(),t.destroy(),this.editor.setHTML(e),this.saveSelection(),this.updateOriginal(),this.lastText=e},this),t.show(),this},saveDraft:function(){this.updateOriginal();var t=this.textarea.get("value");return t!==this.lastText&&(url=M.cfg.wwwroot+"/lib/editor/atto/autosave-ajax.php",params={sesskey
-:M.cfg.sesskey,contextid:this.get("contextid"),action:"save",drafttext:t,elementid:this.get("elementid"),pagedomid:e.one("body").get("id"),pageinstance:this.autosaveInstance},e.io(url,{method:"POST",data:params,on:{success:function(){this.lastText=t}},context:this}),this.lastText=t),this}},e.Base.mix(e.M.editor_atto.Editor,[u]),a.ATTRS={},a.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://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;for(n=0;n'),this.openMenus=[],this._wrapper.appendChild(this.toolbar),this.textareaLabel&&this.toolbar.setAttribute("aria-labelledby",this.textareaLabel.get("id")),this.setupToolbarNavigation(),this}},e.Base.mix(e.M.editor_atto.Editor,[f]),l.ATTRS={},l.prototype={_tabFocus:null,setupToolbarNavigation:function(){return this._wrapper.delegate("key",this.toolbarKeyboardNavigation,"down:37,39","."+r.TOOLBAR,this),this._wrapper.delegate("focus",function(e){this._setTabFocus(e.currentTarget)},"."+r.TOOLBAR+" button",this),this},toolbarKeyboardNavigation:function(e){e.preventDefault();var t=this.toolbar.all("button"),n=1,r,i=e.target.ancestor("button",!0);e.keyCode===37&&(n=-1),r=this._findFirstFocusable(t,i,n),r&&(r.focus(),this._setTabFocus(r))},_findFirstFocusable:function(e,t,n){var r=0,i,s,o,u;u=e.indexOf(t),u<-1&&(u=0);while(r=e.size()&&(u=0),s=e.item(u),r++;if(s.hasAttribute("hidden")||s.hasAttribute("disabled"))continue;i=s.ancestor(".atto_group");if(i.hasAttribute("hidden"))continue;o=s;break}return o},checkTabFocus:function(){return this._tabFocus&&(this._tabFocus.hasAttribute("disabled")||this._tabFocus.hasAttribute("hidden")||this._tabFocus.ancestor(".atto_group").hasAttribute("hidden"))&&(button=this._findFirstFocusable(this.toolbar.all("button"),this._tabFocus,-1),button&&(this._tabFocus.compareTo(document.activeElement)&&button.focus(),this._setTabFocus(button))),this},_setTabFocus:function(e){return this._tabFocus&&this._tabFocus.setAttribute("tabindex","-1"),this._tabFocus=e,this._tabFocus.setAttribute("tabindex",0),this.toolbar.setAttribute("aria-activedescendant",this._tabFocus.generateID()),this}},e.Base.mix(e.M.editor_atto.Editor,[l]),c.ATTRS={},c.prototype={_selections:null,_lastSelection:null,_focusFromClick:!1,setupSelectionWatchers:function(){return this.on("atto:selectionchanged",this.saveSelection,this),this.editor.on("focus",this.restoreSelection,this),this.editor.on("mousedown",function(){this._focusFromClick=!0},this),this.editor.on("blur",function(){this._focusFromClick=!1,this.updateOriginal()},this),e.delegate(["keyup","focus"],function(t){e.soon(e.bind(this._hasSelectionChanged,this,t))},document.body,"#"+this.editor.get("id"),this),e.delegate("gesturemoveend",function(t){e.soon(e.bind(this._hasSelectionChanged,this,t))},document.body,"#"+this.editor.get("id"),{standAlone:!0},this),this},isActive:function(){var t=rangy.createRange(),n=rangy.getSelection();return n.rangeCount?!document.activeElement||e.one(document.activeElement)!==this.editor?!1:(t.selectNode(this.editor.getDOMNode()),t.intersectsRange(n.getRangeAt(0))):!1},getSelectionFromNode:function(e){var t=rangy.createRange();return t.selectNode(e.getDOMNode()),[t]},saveSelection:function(){this.isActive()&&(this._selections=this.getSelection())},restoreSelection:function(){this._focusFromClick||this._selections&&this.setSelection(this._selections),this._focusFromClick=!1},getSelection:function(){return rangy.getSelection().getAllRanges()},selectionContainsNode:function(e){return rangy.getSelection().containsNode(e.getDOMNode(),!0)},selectionFilterMatches:function(e,t,n){typeof n=="undefined"&&(n=!0),t||(t=this.getSelectedNodes());var r=t.size()>0,i=!1,s=this.editor,o=function(e){return e===s};return s.one(e)?(t.each(function(t){if(n){if(!r||!t.ancestor(e,!0,o))r=!1}else!i&&t.ancestor(e,!0,o)&&(i=!0)},this),n?r:i):!1},getSelectedNodes:function(){var t=new e.NodeList,n,r,i,s,o;r=rangy.getSelection(),r.rangeCount?i=r.getRangeAt(0):i=rangy.createRange(),i.collapsed&&i.commonAncestorContainer!==this.editor.getDOMNode()&&i.commonAncestorContainer!==e.config.doc&&(i=i.cloneRange(),i.selectNode(i.commonAncestorContainer)),n=i.getNodes();for(o=0;o"),i.get("childNodes").each(function(e){u.append(e.remove())}),i.append(u),o=u),t&&t!==""&&(f=e.Node.create("<"+t+">"+t+">"),f.setAttrs(o.getAttrs()),o.get("childNodes").each(function(e){e.remove(),f.append(e)}),o.replace(f),o=f),n&&o.setAttrs(n);var l=this.getSelectionFromNode(o);return this.setSelection(l),o}},e.Base.mix(e.M.editor_atto.Editor,[h]),p.ATTRS={filepickeroptions:{value:{}}},p.prototype={canShowFilepicker:function(e){return typeof this.get("filepickeroptions")[e]!="undefined"},showFilepicker:function(t,n,r){var i=this;e.use("core_filepicker",function(e){var s=e.clone(i.get("filepickeroptions")[t],!0);s.formcallback=n,r&&(s.magicscope=r),M.core_filepicker.show(e,s)})}},e.Base.mix(e.M.editor_atto.Editor,[p])},"@VERSION@",{requires:["node","io","overlay","escape","event","event-simulate","event-custom","yui-throttle","moodle-core-notification-dialogue","moodle-core-notification-confirm","moodle-editor_atto-rangy","handlebars","timers"]});
+YUI.add("moodle-editor_atto-editor",function(e,t){function i(){i.superclass.constructor.apply(this,arguments)}function s(){}function a(){}function l(){}function c(){}function h(){}function p(){}function d(){}function v(){}function m(){}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),this.textarea.hide(),this.updateFromTextArea(),this.publishEvents(),this.setupSelectionWatchers(),this.setupAutomaticPolling(),this.setupPlugins(),this.setupAutosave()},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","paste","cut"],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},autosaveEnabled:{value:!0,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)},s.ATTRS={};var o="atto_warning",u="atto_info";s.prototype={messageOverlay:null,showMessage:function(t,n){this.messageOverlay===null&&(this.messageOverlay=e.Node.create(''),this.messageOverlay.hide(),this._wrapper.append(this.messageOverlay),this.messageOverlay.on("click",function(){this.messageOverlay.hide()},this));var r="";n===o?r='
':n===u&&(r='
');var i=e.Node.create(''+r+" "+e.Escape.html(t)+"
");return this.messageOverlay.empty(),this.messageOverlay.append(i),this.messageOverlay.show(),this}},e.Base.mix(e.M.editor_atto.Editor,[s]),a.ATTRS={},a.prototype={_getEmptyContent:function(){return e.UA.ie&&e.UA.ie<10?"":"
"},updateFromTextArea:function(){this.editor.setHTML(""),this.editor.append(this.textarea.get("value")),this.cleanEditorHTML(),this.editor.getHTML()===""&&this.editor.setHTML(this._getEmptyContent())},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,[a]);var f=5e3;l.ATTRS={},l.prototype={lastText:null,autosaveInstance:null,setupAutosave:function(){if(!this.get("autosaveEnabled"))return;this.autosaveInstance=e.stamp(this);var t=-1,n,r=this.get("filepickeroptions");for(n in r)typeof r[n].itemid!="undefined"&&(t=r[n].itemid);return url=M.cfg.wwwroot+"/lib/editor/atto/autosave-ajax.php",params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"resume",drafttext:"",draftid:t,elementid:this.get("elementid"),pageinstance:this.autosaveInstance,pagedomid:e.one("body").get("id")},e.io(url,{method:"POST",data:params,on:{success:function(e,t){typeof t.responseText!="undefined"&&t.responseText!==""&&t.responseText!==this.textarea.get("value")&&this.recoverText(t.responseText)}},context:this}),e.later(f,this,this.saveDraft,!1,!0),this.textarea.ancestor("form").on("submit",this.resetAutosave,this),this},resetAutosave:function(){return url=M.cfg.wwwroot+"/lib/editor/atto/autosave-ajax.php"
+,params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"reset",elementid:this.get("elementid"),pageinstance:this.autosaveInstance,pagedomid:e.one("body").get("id")},e.io(url,{method:"POST",data:params,sync:!0}),this},recoverText:function(e){var t=new M.core.confirm({title:M.util.get_string("confirm","editor_atto"),question:M.util.get_string("confirmrecover","editor_atto",{label:this.textareaLabel.get("text")}),yesLabel:M.util.get_string("recover","editor_atto"),noLabel:M.util.get_string("cancel","editor_atto")});return t.on("complete-yes",function(){t.hide(),t.destroy(),this.editor.setHTML(e),this.saveSelection(),this.updateOriginal(),this.lastText=e},this),t.show(),this},saveDraft:function(){this.updateOriginal();var t=this.textarea.get("value");return t!==this.lastText&&(url=M.cfg.wwwroot+"/lib/editor/atto/autosave-ajax.php",params={sesskey:M.cfg.sesskey,contextid:this.get("contextid"),action:"save",drafttext:t,elementid:this.get("elementid"),pagedomid:e.one("body").get("id"),pageinstance:this.autosaveInstance},e.io(url,{method:"POST",data:params,on:{success:function(){this.lastText=t}},context:this}),this.lastText=t),this}},e.Base.mix(e.M.editor_atto.Editor,[l]),c.ATTRS={},c.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://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;for(n=0;n'),this.openMenus=[],this._wrapper.appendChild(this.toolbar),this.textareaLabel&&this.toolbar.setAttribute("aria-labelledby",this.textareaLabel.get("id")),this.setupToolbarNavigation(),this}},e.Base.mix(e.M.editor_atto.Editor,[h]),p.ATTRS={},p.prototype={_tabFocus:null,setupToolbarNavigation:function(){return this._wrapper.delegate("key",this.toolbarKeyboardNavigation,"down:37,39","."+r.TOOLBAR,this),this._wrapper.delegate("focus",function(e){this._setTabFocus(e.currentTarget)},"."+r.TOOLBAR+" button",this),this},toolbarKeyboardNavigation:function(e){e.preventDefault();var t=this.toolbar.all("button"),n=1,r,i=e.target.ancestor("button",!0);e.keyCode===37&&(n=-1),r=this._findFirstFocusable(t,i,n),r&&(r.focus(),this._setTabFocus(r))},_findFirstFocusable:function(e,t,n){var r=0,i,s,o,u;u=e.indexOf(t),u<-1&&(u=0);while(r=e.size()&&(u=0),s=e.item(u),r++;if(s.hasAttribute("hidden")||s.hasAttribute("disabled"))continue;i=s.ancestor(".atto_group");if(i.hasAttribute("hidden"))continue;o=s;break}return o},checkTabFocus:function(){return this._tabFocus&&(this._tabFocus.hasAttribute("disabled")||this._tabFocus.hasAttribute("hidden")||this._tabFocus.ancestor(".atto_group").hasAttribute("hidden"))&&(button=this._findFirstFocusable(this.toolbar.all("button"),this._tabFocus,-1),button&&(this._tabFocus.compareTo(document.activeElement)&&button.focus(),this._setTabFocus(button))),this},_setTabFocus:function(e){return this._tabFocus&&this._tabFocus.setAttribute("tabindex","-1"),this._tabFocus=e,this._tabFocus.setAttribute("tabindex",0),this.toolbar.setAttribute("aria-activedescendant",this._tabFocus.generateID()),this}},e.Base.mix(e.M.editor_atto.Editor,[p]),d.ATTRS={},d.prototype={_selections:null,_lastSelection:null,_focusFromClick:!1,setupSelectionWatchers:function(){return this.on("atto:selectionchanged",this.saveSelection,this),this.editor.on("focus",this.restoreSelection,this),this.editor.on("mousedown",function(){this._focusFromClick=!0},this),this.editor.on("blur",function(){this._focusFromClick=!1,this.updateOriginal()},this),e.delegate(["keyup","focus"],function(t){e.soon(e.bind(this._hasSelectionChanged,this,t))},document.body,"#"+this.editor.get("id"),this),e.delegate("gesturemoveend",function(t){e.soon(e.bind(this._hasSelectionChanged,this,t))},document.body,"#"+this.editor.get("id"),{standAlone:!0},this),this},isActive:function(){var t=rangy.createRange(),n=rangy.getSelection();return n.rangeCount?!document.activeElement||e.one(document.activeElement)!==this.editor?!1:(t.selectNode(this.editor.getDOMNode()),t.intersectsRange(n.getRangeAt(0))):!1},getSelectionFromNode:function(e){var t=rangy.createRange();return t.selectNode(e.getDOMNode()),[t]},saveSelection:function(){this.isActive()&&(this._selections=this.getSelection())},restoreSelection:function(){this._focusFromClick||this._selections&&this.setSelection(this._selections),this._focusFromClick=!1},getSelection:function(){return rangy.getSelection().getAllRanges()},selectionContainsNode:function(e){return rangy
+.getSelection().containsNode(e.getDOMNode(),!0)},selectionFilterMatches:function(e,t,n){typeof n=="undefined"&&(n=!0),t||(t=this.getSelectedNodes());var r=t.size()>0,i=!1,s=this.editor,o=function(e){return e===s};return s.one(e)?(t.each(function(t){if(n){if(!r||!t.ancestor(e,!0,o))r=!1}else!i&&t.ancestor(e,!0,o)&&(i=!0)},this),n?r:i):!1},getSelectedNodes:function(){var t=new e.NodeList,n,r,i,s,o;r=rangy.getSelection(),r.rangeCount?i=r.getRangeAt(0):i=rangy.createRange(),i.collapsed&&i.commonAncestorContainer!==this.editor.getDOMNode()&&i.commonAncestorContainer!==e.config.doc&&(i=i.cloneRange(),i.selectNode(i.commonAncestorContainer)),n=i.getNodes();for(o=0;o"),i.get("childNodes").each(function(e){u.append(e.remove())}),i.append(u),o=u),t&&t!==""&&(f=e.Node.create("<"+t+">"+t+">"),f.setAttrs(o.getAttrs()),o.get("childNodes").each(function(e){e.remove(),f.append(e)}),o.replace(f),o=f),n&&o.setAttrs(n);var l=this.getSelectionFromNode(o);return this.setSelection(l),o}},e.Base.mix(e.M.editor_atto.Editor,[v]),m.ATTRS={filepickeroptions:{value:{}}},m.prototype={canShowFilepicker:function(e){return typeof this.get("filepickeroptions")[e]!="undefined"},showFilepicker:function(t,n,r){var i=this;e.use("core_filepicker",function(e){var s=e.clone(i.get("filepickeroptions")[t],!0);s.formcallback=n,r&&(s.magicscope=r),M.core_filepicker.show(e,s)})}},e.Base.mix(e.M.editor_atto.Editor,[m])},"@VERSION@",{requires:["node","io","overlay","escape","event","event-simulate","event-custom","yui-throttle","moodle-core-notification-dialogue","moodle-core-notification-confirm","moodle-editor_atto-rangy","handlebars","timers"]});
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 5433192c8a7..72eb87f4c85 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
@@ -475,6 +475,95 @@ Y.namespace('M.editor_atto.Editor').init = function(config) {
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+/**
+ * A notify function for the Atto editor.
+ *
+ * @module moodle-editor_atto-notify
+ * @submodule notify-base
+ * @package editor_atto
+ * @copyright 2014 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function EditorNotify() {}
+
+EditorNotify.ATTRS= {
+};
+
+// There is no error type here - because you should make errors more obvious.
+var NOTIFY_WARNING = 'atto_warning',
+ NOTIFY_INFO = 'atto_info';
+
+EditorNotify.prototype = {
+
+ /**
+ * A single Y.Overlay for this editor. There is only ever one - it is replaced if a new message comes in.
+ *
+ * @property messageOverlay
+ * @type {Y.Overlay}
+ */
+ messageOverlay: null,
+
+ /**
+ * Show a notification in a floaty overlay somewhere in the atto editor text area.
+ *
+ * @method showMessage
+ * @chainable
+ */
+ showMessage: function(message, type) {
+
+ if (this.messageOverlay === null) {
+ this.messageOverlay = Y.Node.create('');
+
+ this.messageOverlay.hide();
+ this._wrapper.append(this.messageOverlay);
+
+ this.messageOverlay.on('click', function() {
+ this.messageOverlay.hide();
+ }, this);
+
+ }
+
+ var messageTypeIcon = '';
+ if (type === NOTIFY_WARNING) {
+ messageTypeIcon = '
';
+ } else if (type === NOTIFY_INFO) {
+ messageTypeIcon = '
';
+ }
+
+ var bodyContent = Y.Node.create('' +
+ messageTypeIcon + ' ' +
+ Y.Escape.html(message) +
+ '
');
+ this.messageOverlay.empty();
+ this.messageOverlay.append(bodyContent);
+ this.messageOverlay.show();
+
+ return this;
+ }
+
+};
+
+Y.Base.mix(Y.M.editor_atto.Editor, [EditorNotify]);
+// 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 textarea
diff --git a/lib/editor/atto/yui/src/editor/build.json b/lib/editor/atto/yui/src/editor/build.json
index 7b2696aaa95..f781a68d91a 100644
--- a/lib/editor/atto/yui/src/editor/build.json
+++ b/lib/editor/atto/yui/src/editor/build.json
@@ -4,6 +4,7 @@
"moodle-editor_atto-editor": {
"jsfiles": [
"editor.js",
+ "notify.js",
"textarea.js",
"autosave.js",
"clean.js",
diff --git a/lib/editor/atto/yui/src/editor/js/notify.js b/lib/editor/atto/yui/src/editor/js/notify.js
new file mode 100644
index 00000000000..7cc1bc08654
--- /dev/null
+++ b/lib/editor/atto/yui/src/editor/js/notify.js
@@ -0,0 +1,89 @@
+// 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 .
+
+/**
+ * A notify function for the Atto editor.
+ *
+ * @module moodle-editor_atto-notify
+ * @submodule notify-base
+ * @package editor_atto
+ * @copyright 2014 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function EditorNotify() {}
+
+EditorNotify.ATTRS= {
+};
+
+// There is no error type here - because you should make errors more obvious.
+var NOTIFY_WARNING = 'atto_warning',
+ NOTIFY_INFO = 'atto_info';
+
+EditorNotify.prototype = {
+
+ /**
+ * A single Y.Overlay for this editor. There is only ever one - it is replaced if a new message comes in.
+ *
+ * @property messageOverlay
+ * @type {Y.Overlay}
+ */
+ messageOverlay: null,
+
+ /**
+ * Show a notification in a floaty overlay somewhere in the atto editor text area.
+ *
+ * @method showMessage
+ * @chainable
+ */
+ showMessage: function(message, type) {
+
+ if (this.messageOverlay === null) {
+ this.messageOverlay = Y.Node.create('');
+
+ this.messageOverlay.hide();
+ this._wrapper.append(this.messageOverlay);
+
+ this.messageOverlay.on('click', function() {
+ this.messageOverlay.hide();
+ }, this);
+
+ }
+
+ var messageTypeIcon = '';
+ if (type === NOTIFY_WARNING) {
+ messageTypeIcon = '
';
+ } else if (type === NOTIFY_INFO) {
+ messageTypeIcon = '
';
+ }
+
+ var bodyContent = Y.Node.create('' +
+ messageTypeIcon + ' ' +
+ Y.Escape.html(message) +
+ '
');
+ this.messageOverlay.empty();
+ this.messageOverlay.append(bodyContent);
+ this.messageOverlay.show();
+
+ return this;
+ }
+
+};
+
+Y.Base.mix(Y.M.editor_atto.Editor, [EditorNotify]);