diff --git a/lib/editor/atto/plugins/image/yui/build/button/js/button.min.js b/lib/editor/atto/plugins/image/yui/build/button/js/button.min.js
deleted file mode 100644
index cabe94f8c00..00000000000
--- a/lib/editor/atto/plugins/image/yui/build/button/js/button.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-var CSS={RESPONSIVE:"img-responsive",INPUTALIGNMENT:"atto_image_alignment",INPUTALT:"atto_image_altentry",INPUTHEIGHT:"atto_image_heightentry",INPUTSUBMIT:"atto_image_urlentrysubmit",INPUTURL:"atto_image_urlentry",INPUTSIZE:"atto_image_size",INPUTWIDTH:"atto_image_widthentry",IMAGEALTWARNING:"atto_image_altwarning",IMAGEBROWSER:"openimagebrowser",IMAGEPRESENTATION:"atto_image_presentation",INPUTCONSTRAIN:"atto_image_constrain",INPUTCUSTOMSTYLE:"atto_image_customstyle",IMAGEPREVIEW:"atto_image_preview",IMAGEPREVIEWBOX:"atto_image_preview_box",ALIGNSETTINGS:"atto_image_button"},SELECTORS={INPUTURL:"."+CSS.INPUTURL},ALIGNMENTS=[{name:"verticalAlign",str:"alignment_top",value:"text-top",margin:"0 0.5em"},{name:"verticalAlign",str:"alignment_middle",value:"middle",margin:"0 0.5em"},{name:"verticalAlign",str:"alignment_bottom",value:"text-bottom",margin:"0 0.5em",isDefault:!0},{name:"float",str:"alignment_left",value:"left",margin:"0 0.5em 0 0"},{name:"float",str:"alignment_right",value:"right",margin:"0 0 0 0.5em"}],REGEX={ISPERCENT:/\d+%/},COMPONENTNAME="atto_image",TEMPLATE="<form class=\"atto_form\">{{#if showFilepicker}}<div class=\"mb-1\"><label for=\"{{elementid}}_{{CSS.INPUTURL}}\">{{get_string \"enterurl\" component}}</label><div class=\"input-group input-append w-100\"><input class=\"form-control {{CSS.INPUTURL}}\" type=\"url\" id=\"{{elementid}}_{{CSS.INPUTURL}}\" size=\"32\"/><span class=\"input-group-append\"><button class=\"btn btn-secondary {{CSS.IMAGEBROWSER}}\" type=\"button\">{{get_string \"browserepositories\" component}}</button></span></div></div>{{else}}<div class=\"mb-1\"><label for=\"{{elementid}}_{{CSS.INPUTURL}}\">{{get_string \"enterurl\" component}}</label><input class=\"form-control fullwidth {{CSS.INPUTURL}}\" type=\"url\" id=\"{{elementid}}_{{CSS.INPUTURL}}\" size=\"32\"/></div>{{/if}}<div style=\"display:none\" role=\"alert\" class=\"alert alert-warning mb-1 {{CSS.IMAGEALTWARNING}}\">{{get_string \"presentationoraltrequired\" component}}</div><div class=\"mb-1\"><label for=\"{{elementid}}_{{CSS.INPUTALT}}\">{{get_string \"enteralt\" component}}</label><textarea class=\"form-control fullwidth {{CSS.INPUTALT}}\" id=\"{{elementid}}_{{CSS.INPUTALT}}\" maxlength=\"125\"></textarea><div id=\"the-count\" class=\"d-flex justify-content-end small\"><span id=\"currentcount\">0</span><span id=\"maximumcount\"> / 125</span></div><div class=\"form-check\"><input type=\"checkbox\" class=\"form-check-input {{CSS.IMAGEPRESENTATION}}\" id=\"{{elementid}}_{{CSS.IMAGEPRESENTATION}}\"/><label class=\"form-check-label\" for=\"{{elementid}}_{{CSS.IMAGEPRESENTATION}}\">{{get_string \"presentation\" component}}</label></div></div><div class=\"mb-1\"><label class=\"\" for=\"{{elementid}}_{{CSS.INPUTSIZE}}\">{{get_string \"size\" component}}</label><div id=\"{{elementid}}_{{CSS.INPUTSIZE}}\" class=\"form-inline {{CSS.INPUTSIZE}}\"><label class=\"accesshide\" for=\"{{elementid}}_{{CSS.INPUTWIDTH}}\">{{get_string \"width\" component}}</label><input type=\"text\" class=\"form-control mr-1 input-mini {{CSS.INPUTWIDTH}}\" id=\"{{elementid}}_{{CSS.INPUTWIDTH}}\" size=\"4\"/> x<label class=\"accesshide\" for=\"{{elementid}}_{{CSS.INPUTHEIGHT}}\">{{get_string \"height\" component}}</label><input type=\"text\" class=\"form-control ml-1 input-mini {{CSS.INPUTHEIGHT}}\" id=\"{{elementid}}_{{CSS.INPUTHEIGHT}}\" size=\"4\"/><div class=\"form-check ml-2\"><input type=\"checkbox\" class=\"form-check-input {{CSS.INPUTCONSTRAIN}}\" id=\"{{elementid}}_{{CSS.INPUTCONSTRAIN}}\"/><label class=\"form-check-label\" for=\"{{elementid}}_{{CSS.INPUTCONSTRAIN}}\">{{get_string \"constrain\" component}}</label></div></div></div><div class=\"form-inline mb-1\"><label class=\"for=\"{{elementid}}_{{CSS.INPUTALIGNMENT}}\">{{get_string \"alignment\" component}}</label><select class=\"custom-select {{CSS.INPUTALIGNMENT}}\" id=\"{{elementid}}_{{CSS.INPUTALIGNMENT}}\">{{#each alignments}}<option value=\"{{value}}\">{{get_string str ../component}}</option>{{/each}}</select></div><input type=\"hidden\" class=\"{{CSS.INPUTCUSTOMSTYLE}}\"/><br/><div class=\"mdl-align\"><div class=\"{{CSS.IMAGEPREVIEWBOX}}\"><img src=\"#\" class=\"{{CSS.IMAGEPREVIEW}}\" alt=\"\" style=\"display: none;\"/></div><button class=\"btn btn-secondary {{CSS.INPUTSUBMIT}}\" type=\"submit\">{{get_string \"saveimage\" component}}</button></div></form>",IMAGETEMPLATE="<img src=\"{{url}}\" alt=\"{{alt}}\" {{#if width}}width=\"{{width}}\" {{/if}}{{#if height}}height=\"{{height}}\" {{/if}}{{#if presentation}}role=\"presentation\" {{/if}}{{#if customstyle}}style=\"{{customstyle}}\" {{/if}}{{#if classlist}}class=\"{{classlist}}\" {{/if}}{{#if id}}id=\"{{id}}\" {{/if}}/>";Y.namespace("M.atto_image").Button=Y.Base.create("button",Y.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_selectedImage:null,_form:null,_rawImageDimensions:null,initializer:function initializer(){this.addButton({icon:"e/insert_edit_image",callback:this._displayDialogue,tags:"img",tagMatchRequiresAll:!1});this.editor.delegate("dblclick",this._displayDialogue,"img",this);this.editor.delegate("click",this._handleClick,"img",this);this.editor.on("paste",this._handlePaste,this);this.editor.on("drop",this._handleDragDrop,this);this.editor.on("dragover",function(a){a.preventDefault()},this);this.editor.on("dragenter",function(a){a.preventDefault()},this)},_handleDragDrop:function _handleDragDrop(a){if(!a._event||!a._event.dataTransfer){return!0}return this._handlePasteOrDropHelper(a,a._event.dataTransfer)},_handlePaste:function _handlePaste(a){if(!a._event||!a._event.clipboardData){return!0}return this._handlePasteOrDropHelper(a,a._event.clipboardData)},_handlePasteOrDropHelper:function _handlePasteOrDropHelper(a,b){for(var c=b.items,d=!1,e=0,f;e<c.length;e++){f=c[e];if("file"!==f.kind){continue}if(!this._isImage(f.type)){continue}this._uploadImage(f.getAsFile());d=!0}if(d){a.preventDefault();a.stopPropagation();return!1}else{return!0}},_isImage:function _isImage(a){return 0===a.indexOf("image/")},_uploadImage:function _uploadImage(a){var b=this,c=this.get("host"),d=Y.Handlebars.compile(IMAGETEMPLATE);c.saveSelection();var e=c.get("filepickeroptions").image,f=e.savepath===void 0?"/":e.savepath,g=new FormData,h=0,j="",k=new XMLHttpRequest,l="",m=Object.keys(e.repositories);g.append("repo_upload_file",a);g.append("itemid",e.itemid);for(var n=0;n<m.length;n++){if("upload"===e.repositories[m[n]].type){g.append("repo_id",e.repositories[m[n]].id);break}}g.append("env",e.env);g.append("sesskey",M.cfg.sesskey);g.append("client_id",e.client_id);g.append("savepath",f);g.append("ctx_id",e.context.id);h=new Date().getTime();j="moodleimage_"+Math.round(1e5*Math.random())+"-"+h;c.focus();c.restoreSelection();l=d({url:M.util.image_url("i/loading_small","moodle"),alt:M.util.get_string("uploading",COMPONENTNAME),id:j});c.insertContentAtFocusPoint(l);b.markUpdated();k.onreadystatechange=function(){var a=b.editor.one("#"+j),c,e,f,g;if(4===k.readyState){if(200===k.status){c=JSON.parse(k.responseText);if(c){if(c.error){if(a){a.remove(!0)}throw new M.core.ajaxException(c)}e=c;if(c.event&&"fileexists"===c.event){e=c.newfile}f=d({url:e.url,presentation:!0});g=Y.Node.create(f);if(a){a.replace(g)}else{b.editor.appendChild(g)}b.markUpdated()}}else{Y.use("moodle-core-notification-alert",function(){new M.core.alert({message:M.util.get_string("servererror","moodle")})});if(a){a.remove(!0)}}}};k.open("POST",M.cfg.wwwroot+"/repository/repository_ajax.php?action=upload",!0);k.send(g)},_handleClick:function _handleClick(a){var b=a.target,c=this.get("host").getSelectionFromNode(b);if(this.get("host").getSelection()!==c){this.get("host").setSelection(c)}},_displayDialogue:function _displayDialogue(){this._currentSelection=this.get("host").getSelection();if(!1===this._currentSelection){return}this._rawImageDimensions=null;var a=this.getDialogue({headerContent:M.util.get_string("imageproperties",COMPONENTNAME),width:"auto",focusAfterHide:!0,focusOnShowSelector:SELECTORS.INPUTURL});a.get("boundingBox").setStyle("maxWidth","90%");a.set("bodyContent",this._getDialogueContent()).show()},_loadPreviewImage:function _loadPreviewImage(a){var b=new Image,c=this;b.onerror=function(){var a=c._form.one("."+CSS.IMAGEPREVIEW);a.setStyles({display:"none"});c.getDialogue().centerDialogue()};b.onload=function(){var a,b,d,e,f;c._rawImageDimensions={width:this.width,height:this.height};a=c._form.one("."+CSS.INPUTWIDTH);b=a.get("value");if(""===b){a.set("value",this.width);b=""+this.width}a=c._form.one("."+CSS.INPUTHEIGHT);d=a.get("value");if(""===d){a.set("value",this.height);d=""+this.height}a=c._form.one("."+CSS.IMAGEPREVIEW);a.setAttribute("src",this.src);a.setStyles({display:"inline"});a=c._form.one("."+CSS.INPUTCONSTRAIN);if(b.match(REGEX.ISPERCENT)&&d.match(REGEX.ISPERCENT)){a.set("checked",b===d)}else{if(0===this.width){this.width=1}if(0===this.height){this.height=1}e=Math.round(1e3*parseInt(b,10)/this.width);f=Math.round(1e3*parseInt(d,10)/this.height);a.set("checked",e===f)}c._autoAdjustSize(c);c.getDialogue().centerDialogue()};b.src=a},_getDialogueContent:function _getDialogueContent(){var a=Y.Handlebars.compile(TEMPLATE),b=this.get("host").canShowFilepicker("image"),c=Y.Node.create(a({elementid:this.get("host").get("elementid"),CSS:CSS,component:COMPONENTNAME,showFilepicker:b,alignments:ALIGNMENTS}));this._form=c;this._applyImageProperties(this._form);this._form.one("."+CSS.INPUTURL).on("blur",this._urlChanged,this);this._form.one("."+CSS.IMAGEPRESENTATION).on("change",this._updateWarning,this);this._form.one("."+CSS.INPUTALT).on("change",this._updateWarning,this);this._form.one("."+CSS.INPUTWIDTH).on("blur",this._autoAdjustSize,this);this._form.one("."+CSS.INPUTHEIGHT).on("blur",this._autoAdjustSize,this,!0);this._form.one("."+CSS.INPUTCONSTRAIN).on("change",function(a){if(a.target.get("checked")){this._autoAdjustSize(a)}},this);this._form.one("."+CSS.INPUTURL).on("blur",this._urlChanged,this);this._form.one("."+CSS.INPUTSUBMIT).on("click",this._setImage,this);if(b){this._form.one("."+CSS.IMAGEBROWSER).on("click",function(){this.get("host").showFilepicker("image",this._filepickerCallback,this)},this)}this._form.one("."+CSS.INPUTALT).on("keyup",this._handleKeyup,this);return c},_autoAdjustSize:function _autoAdjustSize(a,b){b=b||!1;var c=this._form.one("."+CSS.INPUTWIDTH),d="width",e=this._form.one("."+CSS.INPUTHEIGHT),f="height",g=this._form.one("."+CSS.INPUTCONSTRAIN),h=c.get("value"),i=e.get("value"),j=this._form.one("."+CSS.IMAGEPREVIEW),k,l;if(!this._rawImageDimensions){return}if(""===h){h=this._rawImageDimensions[d];c.set("value",h);h=c.get("value")}j.setStyles({width:null,height:null});if(!g.get("checked")){if(h.match(REGEX.ISPERCENT)){k=parseInt(h,10);l=this._rawImageDimensions.width/100*k;j.setStyle("width",l+"px")}else{j.setStyle("width",h+"px")}if(i.match(REGEX.ISPERCENT)){k=parseInt(i,10);l=this._rawImageDimensions.height/100*k;j.setStyle("height",l+"px")}else{j.setStyle("height",i+"px")}}else{if(b){var m=c;c=e;e=m;m=d;d=f;f=m;m=h;h=i;i=m}if(h.match(REGEX.ISPERCENT)){i=h;k=parseInt(h,10);l=this._rawImageDimensions.width/100*k;j.setStyle("width",l);l=this._rawImageDimensions.height/100*k;j.setStyle("height",l)}else{i=Math.round(h/this._rawImageDimensions[d]*this._rawImageDimensions[f]);if(b){j.setStyles({width:i,height:h})}else{j.setStyles({width:h,height:i})}}e.set("value",i)}},_filepickerCallback:function _filepickerCallback(a){if(""!==a.url){var b=this._form.one("."+CSS.INPUTURL);b.set("value",a.url);this._form.one("."+CSS.INPUTWIDTH).set("value","");this._form.one("."+CSS.INPUTHEIGHT).set("value","");this._loadPreviewImage(a.url)}},_applyImageProperties:function _applyImageProperties(a){var b=this._getSelectedImageProperties(),c=a.one("."+CSS.IMAGEPREVIEW);if(!1===b){c.setStyle("display","none");ALIGNMENTS.some(function(b){if(b.isDefault){a.one("."+CSS.INPUTALIGNMENT).set("value",b.value);return!0}return!1},this);return}if(b.align){a.one("."+CSS.INPUTALIGNMENT).set("value",b.align)}if(b.customstyle){a.one("."+CSS.INPUTCUSTOMSTYLE).set("value",b.customstyle)}if(b.width){a.one("."+CSS.INPUTWIDTH).set("value",b.width)}if(b.height){a.one("."+CSS.INPUTHEIGHT).set("value",b.height)}if(b.alt){a.one("."+CSS.INPUTALT).set("value",b.alt)}if(b.src){a.one("."+CSS.INPUTURL).set("value",b.src);this._loadPreviewImage(b.src)}if(b.presentation){a.one("."+CSS.IMAGEPRESENTATION).set("checked","checked")}this._autoAdjustSize()},_getSelectedImageProperties:function _getSelectedImageProperties(){var a={src:null,alt:null,width:null,height:null,align:"",presentation:!1},b=this.get("host").getSelectedNodes(),c,d,e,f;if(b){b=b.filter("img")}if(b&&b.size()){f=this._removeLegacyAlignment(b.item(0));this._selectedImage=f;e=f.getAttribute("style");a.customstyle=e;c=f.getAttribute("width");if(!c.match(REGEX.ISPERCENT)){c=parseInt(c,10)}d=f.getAttribute("height");if(!d.match(REGEX.ISPERCENT)){d=parseInt(d,10)}if(0!==c){a.width=c}if(0!==d){a.height=d}this._getAlignmentPropeties(f,a);a.src=f.getAttribute("src");a.alt=f.getAttribute("alt")||"";a.presentation="presentation"===f.get("role");return a}this._selectedImage=null;return!1},_getAlignmentPropeties:function _getAlignmentPropeties(a,b){var c=!1,d;c=ALIGNMENTS.some(function(c){var e=this._getAlignmentClass(c.value);if(a.hasClass(e)){b.align=c.value;Y.log("Found alignment "+c.value,"debug","atto_image-button");return!0}if(c.isDefault){d=c.value}return!1},this);if(!c&&d){b.align=d}},_urlChanged:function _urlChanged(){var a=this._form.one("."+CSS.INPUTURL);if(""!==a.get("value")){this._loadPreviewImage(a.get("value"))}},_setImage:function _setImage(a){var b=this._form,c=b.one("."+CSS.INPUTURL).get("value"),d=b.one("."+CSS.INPUTALT).get("value"),e=b.one("."+CSS.INPUTWIDTH).get("value"),f=b.one("."+CSS.INPUTHEIGHT).get("value"),g=this._getAlignmentClass(b.one("."+CSS.INPUTALIGNMENT).get("value")),h=b.one("."+CSS.IMAGEPRESENTATION).get("checked"),i=b.one("."+CSS.INPUTCONSTRAIN).get("checked"),j,k=b.one("."+CSS.INPUTCUSTOMSTYLE).get("value"),l=[],m=this.get("host");a.preventDefault();if(this._updateWarning()){return}m.focus();if(""!==c){if(this._selectedImage){m.setSelection(m.getSelectionFromNode(this._selectedImage))}else{m.setSelection(this._currentSelection)}if(i){l.push(CSS.RESPONSIVE)}l.push(g);if(!e.match(REGEX.ISPERCENT)&&isNaN(parseInt(e,10))){b.one("."+CSS.INPUTWIDTH).focus();return}if(!f.match(REGEX.ISPERCENT)&&isNaN(parseInt(f,10))){b.one("."+CSS.INPUTHEIGHT).focus();return}var n=Y.Handlebars.compile(IMAGETEMPLATE);j=n({url:c,alt:d,width:e,height:f,presentation:h,customstyle:k,classlist:l.join(" ")});this.get("host").insertContentAtFocusPoint(j);this.markUpdated()}this.getDialogue({focusAfterHide:null}).hide()},_removeLegacyAlignment:function _removeLegacyAlignment(a){if(!a.getStyle("margin")){return a}ALIGNMENTS.some(function(b){if(a.getStyle(b.name)!==b.value){return!1}var c=Y.Node.create("<div>");c.setStyle("margin",b.margin);if(a.getStyle("margin")!==c.getStyle("margin")){return!1}Y.log("Legacy alignment found and removed.","info","atto_image-button");a.addClass(this._getAlignmentClass(b.value));a.setStyle(b.name,null);a.setStyle("margin",null);return!0},this);return a},_getAlignmentClass:function _getAlignmentClass(a){return CSS.ALIGNSETTINGS+"_"+a},_updateWarning:function _updateWarning(){var a=this._form,b=!0,c=a.one("."+CSS.INPUTALT).get("value"),d=a.one("."+CSS.IMAGEPRESENTATION).get("checked");if(""===c&&!d){a.one("."+CSS.IMAGEALTWARNING).setStyle("display","block");a.one("."+CSS.INPUTALT).setAttribute("aria-invalid",!0);a.one("."+CSS.IMAGEPRESENTATION).setAttribute("aria-invalid",!0);b=!0}else{a.one("."+CSS.IMAGEALTWARNING).setStyle("display","none");a.one("."+CSS.INPUTALT).setAttribute("aria-invalid",!1);a.one("."+CSS.IMAGEPRESENTATION).setAttribute("aria-invalid",!1);b=!1}this.getDialogue().centerDialogue();return b},_handleKeyup:function _handleKeyup(){var a=this._form,b=a.one("."+CSS.INPUTALT).get("value"),c=b.length,d=a.one("#currentcount");d.setHTML(c)}});
-//# sourceMappingURL=button.min.js.map
diff --git a/lib/editor/atto/plugins/image/yui/build/button/js/button.min.js.map b/lib/editor/atto/plugins/image/yui/build/button/js/button.min.js.map
deleted file mode 100644
index 9a7ab998d87..00000000000
--- a/lib/editor/atto/plugins/image/yui/build/button/js/button.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../../src/button/js/button.js"],"names":["CSS","RESPONSIVE","INPUTALIGNMENT","INPUTALT","INPUTHEIGHT","INPUTSUBMIT","INPUTURL","INPUTSIZE","INPUTWIDTH","IMAGEALTWARNING","IMAGEBROWSER","IMAGEPRESENTATION","INPUTCONSTRAIN","INPUTCUSTOMSTYLE","IMAGEPREVIEW","IMAGEPREVIEWBOX","ALIGNSETTINGS","SELECTORS","ALIGNMENTS","name","str","value","margin","isDefault","REGEX","ISPERCENT","COMPONENTNAME","TEMPLATE","IMAGETEMPLATE","Y","namespace","Button","Base","create","M","editor_atto","EditorPlugin","_currentSelection","_selectedImage","_form","_rawImageDimensions","initializer","addButton","icon","callback","_displayDialogue","tags","tagMatchRequiresAll","editor","delegate","_handleClick","on","_handlePaste","_handleDragDrop","e","preventDefault","_event","dataTransfer","_handlePasteOrDropHelper","clipboardData","items","didUpload","i","item","length","kind","_isImage","type","_uploadImage","getAsFile","stopPropagation","mimeType","indexOf","fileToSave","self","host","get","template","Handlebars","compile","saveSelection","options","image","savepath","formData","FormData","timestamp","uploadid","xhr","XMLHttpRequest","imagehtml","keys","Object","repositories","append","itemid","id","env","cfg","sesskey","client_id","context","Date","getTime","Math","round","random","focus","restoreSelection","url","util","image_url","alt","get_string","insertContentAtFocusPoint","markUpdated","onreadystatechange","placeholder","one","result","file","newhtml","newimage","readyState","status","JSON","parse","responseText","error","remove","core","ajaxException","event","newfile","presentation","Node","replace","appendChild","use","alert","message","open","wwwroot","send","target","selection","getSelectionFromNode","getSelection","setSelection","dialogue","getDialogue","headerContent","width","focusAfterHide","focusOnShowSelector","setStyle","set","_getDialogueContent","show","_loadPreviewImage","Image","onerror","preview","setStyles","centerDialogue","onload","input","currentwidth","currentheight","widthRatio","heightRatio","height","setAttribute","src","match","parseInt","_autoAdjustSize","canShowFilepicker","content","elementid","component","showFilepicker","alignments","_applyImageProperties","_urlChanged","_updateWarning","_setImage","_filepickerCallback","_handleKeyup","forceHeight","keyField","keyFieldType","subField","subFieldType","constrainField","keyFieldValue","subFieldValue","imagePreview","rawPercentage","rawSize","_temporaryValue","params","form","properties","_getSelectedImageProperties","img","some","alignment","align","customstyle","images","getSelectedNodes","style","filter","size","_removeLegacyAlignment","getAttribute","_getAlignmentPropeties","complete","defaultAlignment","classname","_getAlignmentClass","hasClass","log","constrain","classlist","push","isNaN","join","hide","imageNode","getStyle","normalisedNode","addClass","state","characterCount","current","setHTML"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/*\n * @package    atto_image\n * @copyright  2013 Damyon Wiese  <damyon@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * @module moodle-atto_image_alignment-button\n */\n\n/**\n * Atto image selection tool.\n *\n * @namespace M.atto_image\n * @class Button\n * @extends M.editor_atto.EditorPlugin\n */\n\nvar CSS = {\n        RESPONSIVE: 'img-responsive',\n        INPUTALIGNMENT: 'atto_image_alignment',\n        INPUTALT: 'atto_image_altentry',\n        INPUTHEIGHT: 'atto_image_heightentry',\n        INPUTSUBMIT: 'atto_image_urlentrysubmit',\n        INPUTURL: 'atto_image_urlentry',\n        INPUTSIZE: 'atto_image_size',\n        INPUTWIDTH: 'atto_image_widthentry',\n        IMAGEALTWARNING: 'atto_image_altwarning',\n        IMAGEBROWSER: 'openimagebrowser',\n        IMAGEPRESENTATION: 'atto_image_presentation',\n        INPUTCONSTRAIN: 'atto_image_constrain',\n        INPUTCUSTOMSTYLE: 'atto_image_customstyle',\n        IMAGEPREVIEW: 'atto_image_preview',\n        IMAGEPREVIEWBOX: 'atto_image_preview_box',\n        ALIGNSETTINGS: 'atto_image_button'\n    },\n    SELECTORS = {\n        INPUTURL: '.' + CSS.INPUTURL\n    },\n    ALIGNMENTS = [\n        // Vertical alignment.\n        {\n            name: 'verticalAlign',\n            str: 'alignment_top',\n            value: 'text-top',\n            margin: '0 0.5em'\n        }, {\n            name: 'verticalAlign',\n            str: 'alignment_middle',\n            value: 'middle',\n            margin: '0 0.5em'\n        }, {\n            name: 'verticalAlign',\n            str: 'alignment_bottom',\n            value: 'text-bottom',\n            margin: '0 0.5em',\n            isDefault: true\n        },\n\n        // Floats.\n        {\n            name: 'float',\n            str: 'alignment_left',\n            value: 'left',\n            margin: '0 0.5em 0 0'\n        }, {\n            name: 'float',\n            str: 'alignment_right',\n            value: 'right',\n            margin: '0 0 0 0.5em'\n        }\n    ],\n\n    REGEX = {\n        ISPERCENT: /\\d+%/\n    },\n\n    COMPONENTNAME = 'atto_image',\n\n    TEMPLATE = '' +\n            '<form class=\"atto_form\">' +\n\n                // Add the repository browser button.\n                '{{#if showFilepicker}}' +\n                    '<div class=\"mb-1\">' +\n                        '<label for=\"{{elementid}}_{{CSS.INPUTURL}}\">{{get_string \"enterurl\" component}}</label>' +\n                        '<div class=\"input-group input-append w-100\">' +\n                            '<input class=\"form-control {{CSS.INPUTURL}}\" type=\"url\" ' +\n                            'id=\"{{elementid}}_{{CSS.INPUTURL}}\" size=\"32\"/>' +\n                            '<span class=\"input-group-append\">' +\n                                '<button class=\"btn btn-secondary {{CSS.IMAGEBROWSER}}\" type=\"button\">' +\n                                '{{get_string \"browserepositories\" component}}</button>' +\n                            '</span>' +\n                        '</div>' +\n                    '</div>' +\n                '{{else}}' +\n                    '<div class=\"mb-1\">' +\n                        '<label for=\"{{elementid}}_{{CSS.INPUTURL}}\">{{get_string \"enterurl\" component}}</label>' +\n                        '<input class=\"form-control fullwidth {{CSS.INPUTURL}}\" type=\"url\" ' +\n                        'id=\"{{elementid}}_{{CSS.INPUTURL}}\" size=\"32\"/>' +\n                    '</div>' +\n                '{{/if}}' +\n\n                // Add the Alt box.\n                '<div style=\"display:none\" role=\"alert\" class=\"alert alert-warning mb-1 {{CSS.IMAGEALTWARNING}}\">' +\n                    '{{get_string \"presentationoraltrequired\" component}}' +\n                '</div>' +\n                '<div class=\"mb-1\">' +\n                '<label for=\"{{elementid}}_{{CSS.INPUTALT}}\">{{get_string \"enteralt\" component}}</label>' +\n                '<textarea class=\"form-control fullwidth {{CSS.INPUTALT}}\" ' +\n                'id=\"{{elementid}}_{{CSS.INPUTALT}}\" maxlength=\"125\"></textarea>' +\n\n                // Add the character count.\n                '<div id=\"the-count\" class=\"d-flex justify-content-end small\">' +\n                '<span id=\"currentcount\">0</span>' +\n                '<span id=\"maximumcount\"> / 125</span>' +\n                '</div>' +\n\n                // Add the presentation select box.\n                '<div class=\"form-check\">' +\n                '<input type=\"checkbox\" class=\"form-check-input {{CSS.IMAGEPRESENTATION}}\" ' +\n                    'id=\"{{elementid}}_{{CSS.IMAGEPRESENTATION}}\"/>' +\n                '<label class=\"form-check-label\" for=\"{{elementid}}_{{CSS.IMAGEPRESENTATION}}\">' +\n                    '{{get_string \"presentation\" component}}' +\n                '</label>' +\n                '</div>' +\n                '</div>' +\n\n                // Add the size entry boxes.\n                '<div class=\"mb-1\">' +\n                '<label class=\"\" for=\"{{elementid}}_{{CSS.INPUTSIZE}}\">{{get_string \"size\" component}}</label>' +\n                '<div id=\"{{elementid}}_{{CSS.INPUTSIZE}}\" class=\"form-inline {{CSS.INPUTSIZE}}\">' +\n                '<label class=\"accesshide\" for=\"{{elementid}}_{{CSS.INPUTWIDTH}}\">{{get_string \"width\" component}}</label>' +\n                '<input type=\"text\" class=\"form-control mr-1 input-mini {{CSS.INPUTWIDTH}}\" ' +\n                'id=\"{{elementid}}_{{CSS.INPUTWIDTH}}\" size=\"4\"/> x' +\n\n                // Add the height entry box.\n                '<label class=\"accesshide\" for=\"{{elementid}}_{{CSS.INPUTHEIGHT}}\">{{get_string \"height\" component}}</label>' +\n                '<input type=\"text\" class=\"form-control ml-1 input-mini {{CSS.INPUTHEIGHT}}\" ' +\n                'id=\"{{elementid}}_{{CSS.INPUTHEIGHT}}\" size=\"4\"/>' +\n\n                // Add the constrain checkbox.\n                '<div class=\"form-check ml-2\">' +\n                '<input type=\"checkbox\" class=\"form-check-input {{CSS.INPUTCONSTRAIN}}\" ' +\n                'id=\"{{elementid}}_{{CSS.INPUTCONSTRAIN}}\"/>' +\n                '<label class=\"form-check-label\" for=\"{{elementid}}_{{CSS.INPUTCONSTRAIN}}\">' +\n                '{{get_string \"constrain\" component}}</label>' +\n                '</div>' +\n                '</div>' +\n                '</div>' +\n\n                // Add the alignment selector.\n                '<div class=\"form-inline mb-1\">' +\n                '<label class=\"for=\"{{elementid}}_{{CSS.INPUTALIGNMENT}}\">{{get_string \"alignment\" component}}</label>' +\n                '<select class=\"custom-select {{CSS.INPUTALIGNMENT}}\" id=\"{{elementid}}_{{CSS.INPUTALIGNMENT}}\">' +\n                    '{{#each alignments}}' +\n                        '<option value=\"{{value}}\">{{get_string str ../component}}</option>' +\n                    '{{/each}}' +\n                '</select>' +\n                '</div>' +\n                // Hidden input to store custom styles.\n                '<input type=\"hidden\" class=\"{{CSS.INPUTCUSTOMSTYLE}}\"/>' +\n                '<br/>' +\n\n                // Add the image preview.\n                '<div class=\"mdl-align\">' +\n                '<div class=\"{{CSS.IMAGEPREVIEWBOX}}\">' +\n                    '<img src=\"#\" class=\"{{CSS.IMAGEPREVIEW}}\" alt=\"\" style=\"display: none;\"/>' +\n                '</div>' +\n\n                // Add the submit button and close the form.\n                '<button class=\"btn btn-secondary {{CSS.INPUTSUBMIT}}\" type=\"submit\">' + '' +\n                    '{{get_string \"saveimage\" component}}</button>' +\n                '</div>' +\n            '</form>',\n\n        IMAGETEMPLATE = '' +\n            '<img src=\"{{url}}\" alt=\"{{alt}}\" ' +\n                '{{#if width}}width=\"{{width}}\" {{/if}}' +\n                '{{#if height}}height=\"{{height}}\" {{/if}}' +\n                '{{#if presentation}}role=\"presentation\" {{/if}}' +\n                '{{#if customstyle}}style=\"{{customstyle}}\" {{/if}}' +\n                '{{#if classlist}}class=\"{{classlist}}\" {{/if}}' +\n                '{{#if id}}id=\"{{id}}\" {{/if}}' +\n                '/>';\n\nY.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {\n    /**\n     * A reference to the current selection at the time that the dialogue\n     * was opened.\n     *\n     * @property _currentSelection\n     * @type Range\n     * @private\n     */\n    _currentSelection: null,\n\n    /**\n     * The most recently selected image.\n     *\n     * @param _selectedImage\n     * @type Node\n     * @private\n     */\n    _selectedImage: null,\n\n    /**\n     * A reference to the currently open form.\n     *\n     * @param _form\n     * @type Node\n     * @private\n     */\n    _form: null,\n\n    /**\n     * The dimensions of the raw image before we manipulate it.\n     *\n     * @param _rawImageDimensions\n     * @type Object\n     * @private\n     */\n    _rawImageDimensions: null,\n\n    initializer: function() {\n\n        this.addButton({\n            icon: 'e/insert_edit_image',\n            callback: this._displayDialogue,\n            tags: 'img',\n            tagMatchRequiresAll: false\n        });\n        this.editor.delegate('dblclick', this._displayDialogue, 'img', this);\n        this.editor.delegate('click', this._handleClick, 'img', this);\n        this.editor.on('paste', this._handlePaste, this);\n        this.editor.on('drop', this._handleDragDrop, this);\n\n        // e.preventDefault needed to stop the default event from clobbering the desired behaviour in some browsers.\n        this.editor.on('dragover', function(e) {\n            e.preventDefault();\n        }, this);\n        this.editor.on('dragenter', function(e) {\n            e.preventDefault();\n        }, this);\n    },\n\n    /**\n     * Handle a drag and drop event with an image.\n     *\n     * @method _handleDragDrop\n     * @param {EventFacade} e\n     * @return {boolean} false if we handled the event, else true.\n     * @private\n     */\n    _handleDragDrop: function(e) {\n        if (!e._event || !e._event.dataTransfer) {\n            // Drop not fully supported in this browser.\n            return true;\n        }\n\n        return this._handlePasteOrDropHelper(e, e._event.dataTransfer);\n    },\n\n    /**\n     * Handles paste events where - if the thing being pasted is an image.\n     *\n     * @method _handlePaste\n     * @param {EventFacade} e\n     * @return {boolean} false if we handled the event, else true.\n     * @private\n     */\n    _handlePaste: function(e) {\n        if (!e._event || !e._event.clipboardData) {\n            // Paste not fully supported in this browser.\n            return true;\n        }\n\n        return this._handlePasteOrDropHelper(e, e._event.clipboardData);\n    },\n\n    /**\n     * Handle a drag and drop event with an image.\n     *\n     * @method _handleDragDrop\n     * @param {EventFacade} e\n     * @param {DataTransfer} dataTransfer\n     * @return {boolean} false if we handled the event, else true.\n     * @private\n     */\n    _handlePasteOrDropHelper: function(e, dataTransfer) {\n\n        var items = dataTransfer.items,\n            didUpload = false;\n        for (var i = 0; i < items.length; i++) {\n            var item = items[i];\n            if (item.kind !== 'file') {\n                continue;\n            }\n            if (!this._isImage(item.type)) {\n                continue;\n            }\n            this._uploadImage(item.getAsFile());\n            didUpload = true;\n        }\n\n        if (didUpload) {\n            // We handled this.\n            e.preventDefault();\n            e.stopPropagation();\n            return false;\n        } else {\n            // Let someone else try to handle it.\n            return true;\n        }\n    },\n\n    /**\n     * Is this file an image?\n     *\n     * @method _isImage\n     * @param {string} mimeType the file's mime type.\n     * @return {boolean} true if the file has an image mimeType.\n     * @private\n     */\n    _isImage: function(mimeType) {\n        return mimeType.indexOf('image/') === 0;\n    },\n\n    /**\n     * Used by _handleDragDrop and _handlePaste to upload an image and insert it.\n     *\n     * @method _uploadImage\n     * @param {File} fileToSave\n     * @private\n     */\n    _uploadImage: function(fileToSave) {\n\n        var self = this,\n            host = this.get('host'),\n            template = Y.Handlebars.compile(IMAGETEMPLATE);\n\n        host.saveSelection();\n\n        var options = host.get('filepickeroptions').image,\n            savepath = (options.savepath === undefined) ? '/' : options.savepath,\n            formData = new FormData(),\n            timestamp = 0,\n            uploadid = \"\",\n            xhr = new XMLHttpRequest(),\n            imagehtml = \"\",\n            keys = Object.keys(options.repositories);\n\n        formData.append('repo_upload_file', fileToSave);\n        formData.append('itemid', options.itemid);\n\n        // List of repositories is an object rather than an array.  This makes iteration more awkward.\n        for (var i = 0; i < keys.length; i++) {\n            if (options.repositories[keys[i]].type === 'upload') {\n                formData.append('repo_id', options.repositories[keys[i]].id);\n                break;\n            }\n        }\n        formData.append('env', options.env);\n        formData.append('sesskey', M.cfg.sesskey);\n        formData.append('client_id', options.client_id);\n        formData.append('savepath', savepath);\n        formData.append('ctx_id', options.context.id);\n\n        // Insert spinner as a placeholder.\n        timestamp = new Date().getTime();\n        uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;\n        host.focus();\n        host.restoreSelection();\n        imagehtml = template({\n            url: M.util.image_url(\"i/loading_small\", 'moodle'),\n            alt: M.util.get_string('uploading', COMPONENTNAME),\n            id: uploadid\n        });\n        host.insertContentAtFocusPoint(imagehtml);\n        self.markUpdated();\n\n        // Kick off a XMLHttpRequest.\n        xhr.onreadystatechange = function() {\n            var placeholder = self.editor.one('#' + uploadid),\n                result,\n                file,\n                newhtml,\n                newimage;\n\n            if (xhr.readyState === 4) {\n                if (xhr.status === 200) {\n                    result = JSON.parse(xhr.responseText);\n                    if (result) {\n                        if (result.error) {\n                            if (placeholder) {\n                                placeholder.remove(true);\n                            }\n                            throw new M.core.ajaxException(result);\n                        }\n\n                        file = result;\n                        if (result.event && result.event === 'fileexists') {\n                            // A file with this name is already in use here - rename to avoid conflict.\n                            // Chances are, it's a different image (stored in a different folder on the user's computer).\n                            // If the user wants to reuse an existing image, they can copy/paste it within the editor.\n                            file = result.newfile;\n                        }\n\n                        // Replace placeholder with actual image.\n                        newhtml = template({\n                            url: file.url,\n                            presentation: true\n                        });\n                        newimage = Y.Node.create(newhtml);\n                        if (placeholder) {\n                            placeholder.replace(newimage);\n                        } else {\n                            self.editor.appendChild(newimage);\n                        }\n                        self.markUpdated();\n                    }\n                } else {\n                    Y.use('moodle-core-notification-alert', function() {\n                        new M.core.alert({message: M.util.get_string('servererror', 'moodle')});\n                    });\n                    if (placeholder) {\n                        placeholder.remove(true);\n                    }\n                }\n            }\n        };\n        xhr.open(\"POST\", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);\n        xhr.send(formData);\n    },\n\n    /**\n     * Handle a click on an image.\n     *\n     * @method _handleClick\n     * @param {EventFacade} e\n     * @private\n     */\n    _handleClick: function(e) {\n        var image = e.target;\n\n        var selection = this.get('host').getSelectionFromNode(image);\n        if (this.get('host').getSelection() !== selection) {\n            this.get('host').setSelection(selection);\n        }\n    },\n\n    /**\n     * Display the image editing tool.\n     *\n     * @method _displayDialogue\n     * @private\n     */\n    _displayDialogue: function() {\n        // Store the current selection.\n        this._currentSelection = this.get('host').getSelection();\n        if (this._currentSelection === false) {\n            return;\n        }\n\n        // Reset the image dimensions.\n        this._rawImageDimensions = null;\n\n        var dialogue = this.getDialogue({\n            headerContent: M.util.get_string('imageproperties', COMPONENTNAME),\n            width: 'auto',\n            focusAfterHide: true,\n            focusOnShowSelector: SELECTORS.INPUTURL\n        });\n        // Set a maximum width for the dialog. This will prevent the dialog width to extend beyond the screen width\n        // in cases when the uploaded image has larger width.\n        dialogue.get('boundingBox').setStyle('maxWidth', '90%');\n        // Set the dialogue content, and then show the dialogue.\n        dialogue.set('bodyContent', this._getDialogueContent())\n                .show();\n    },\n\n    /**\n     * Set the inputs for width and height if they are not set, and calculate\n     * if the constrain checkbox should be checked or not.\n     *\n     * @method _loadPreviewImage\n     * @param {String} url\n     * @private\n     */\n    _loadPreviewImage: function(url) {\n        var image = new Image();\n        var self = this;\n\n        image.onerror = function() {\n            var preview = self._form.one('.' + CSS.IMAGEPREVIEW);\n            preview.setStyles({\n                'display': 'none'\n            });\n\n            // Centre the dialogue when clearing the image preview.\n            self.getDialogue().centerDialogue();\n        };\n\n        image.onload = function() {\n            var input, currentwidth, currentheight, widthRatio, heightRatio;\n\n            self._rawImageDimensions = {\n                width: this.width,\n                height: this.height\n            };\n\n            input = self._form.one('.' + CSS.INPUTWIDTH);\n            currentwidth = input.get('value');\n            if (currentwidth === '') {\n                input.set('value', this.width);\n                currentwidth = \"\" + this.width;\n            }\n            input = self._form.one('.' + CSS.INPUTHEIGHT);\n            currentheight = input.get('value');\n            if (currentheight === '') {\n                input.set('value', this.height);\n                currentheight = \"\" + this.height;\n            }\n            input = self._form.one('.' + CSS.IMAGEPREVIEW);\n            input.setAttribute('src', this.src);\n            input.setStyles({\n                'display': 'inline'\n            });\n\n            input = self._form.one('.' + CSS.INPUTCONSTRAIN);\n            if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {\n                input.set('checked', currentwidth === currentheight);\n            } else {\n                if (this.width === 0) {\n                    this.width = 1;\n                }\n                if (this.height === 0) {\n                    this.height = 1;\n                }\n                // This is the same as comparing to 3 decimal places.\n                widthRatio = Math.round(1000 * parseInt(currentwidth, 10) / this.width);\n                heightRatio = Math.round(1000 * parseInt(currentheight, 10) / this.height);\n                input.set('checked', widthRatio === heightRatio);\n            }\n\n            // Apply the image sizing.\n            self._autoAdjustSize(self);\n\n            // Centre the dialogue once the preview image has loaded.\n            self.getDialogue().centerDialogue();\n        };\n\n        image.src = url;\n    },\n\n    /**\n     * Return the dialogue content for the tool, attaching any required\n     * events.\n     *\n     * @method _getDialogueContent\n     * @return {Node} The content to place in the dialogue.\n     * @private\n     */\n    _getDialogueContent: function() {\n        var template = Y.Handlebars.compile(TEMPLATE),\n            canShowFilepicker = this.get('host').canShowFilepicker('image'),\n            content = Y.Node.create(template({\n                elementid: this.get('host').get('elementid'),\n                CSS: CSS,\n                component: COMPONENTNAME,\n                showFilepicker: canShowFilepicker,\n                alignments: ALIGNMENTS\n            }));\n\n        this._form = content;\n\n        // Configure the view of the current image.\n        this._applyImageProperties(this._form);\n\n        this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);\n        this._form.one('.' + CSS.IMAGEPRESENTATION).on('change', this._updateWarning, this);\n        this._form.one('.' + CSS.INPUTALT).on('change', this._updateWarning, this);\n        this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);\n        this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);\n        this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {\n            if (event.target.get('checked')) {\n                this._autoAdjustSize(event);\n            }\n        }, this);\n        this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);\n        this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);\n\n        if (canShowFilepicker) {\n            this._form.one('.' + CSS.IMAGEBROWSER).on('click', function() {\n                    this.get('host').showFilepicker('image', this._filepickerCallback, this);\n            }, this);\n        }\n\n        // Character count.\n        this._form.one('.' + CSS.INPUTALT).on('keyup', this._handleKeyup, this);\n\n        return content;\n    },\n\n    _autoAdjustSize: function(e, forceHeight) {\n        forceHeight = forceHeight || false;\n\n        var keyField = this._form.one('.' + CSS.INPUTWIDTH),\n            keyFieldType = 'width',\n            subField = this._form.one('.' + CSS.INPUTHEIGHT),\n            subFieldType = 'height',\n            constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),\n            keyFieldValue = keyField.get('value'),\n            subFieldValue = subField.get('value'),\n            imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),\n            rawPercentage,\n            rawSize;\n\n        // If we do not know the image size, do not do anything.\n        if (!this._rawImageDimensions) {\n            return;\n        }\n\n        // Set the width back to default if it is empty.\n        if (keyFieldValue === '') {\n            keyFieldValue = this._rawImageDimensions[keyFieldType];\n            keyField.set('value', keyFieldValue);\n            keyFieldValue = keyField.get('value');\n        }\n\n        // Clear the existing preview sizes.\n        imagePreview.setStyles({\n            width: null,\n            height: null\n        });\n\n        // Now update with the new values.\n        if (!constrainField.get('checked')) {\n            // We are not keeping the image proportion - update the preview accordingly.\n\n            // Width.\n            if (keyFieldValue.match(REGEX.ISPERCENT)) {\n                rawPercentage = parseInt(keyFieldValue, 10);\n                rawSize = this._rawImageDimensions.width / 100 * rawPercentage;\n                imagePreview.setStyle('width', rawSize + 'px');\n            } else {\n                imagePreview.setStyle('width', keyFieldValue + 'px');\n            }\n\n            // Height.\n            if (subFieldValue.match(REGEX.ISPERCENT)) {\n                rawPercentage = parseInt(subFieldValue, 10);\n                rawSize = this._rawImageDimensions.height / 100 * rawPercentage;\n                imagePreview.setStyle('height', rawSize + 'px');\n            } else {\n                imagePreview.setStyle('height', subFieldValue + 'px');\n            }\n        } else {\n            // We are keeping the image in proportion.\n            if (forceHeight) {\n                // By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.\n                var _temporaryValue;\n                _temporaryValue = keyField;\n                keyField = subField;\n                subField = _temporaryValue;\n\n                _temporaryValue = keyFieldType;\n                keyFieldType = subFieldType;\n                subFieldType = _temporaryValue;\n\n                _temporaryValue = keyFieldValue;\n                keyFieldValue = subFieldValue;\n                subFieldValue = _temporaryValue;\n            }\n\n            if (keyFieldValue.match(REGEX.ISPERCENT)) {\n                // This is a percentage based change. Copy it verbatim.\n                subFieldValue = keyFieldValue;\n\n                // Set the width to the calculated pixel width.\n                rawPercentage = parseInt(keyFieldValue, 10);\n                rawSize = this._rawImageDimensions.width / 100 * rawPercentage;\n\n                // And apply the width/height to the container.\n                imagePreview.setStyle('width', rawSize);\n                rawSize = this._rawImageDimensions.height / 100 * rawPercentage;\n                imagePreview.setStyle('height', rawSize);\n            } else {\n                // Calculate the scaled subFieldValue from the keyFieldValue.\n                subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *\n                        this._rawImageDimensions[subFieldType]);\n\n                if (forceHeight) {\n                    imagePreview.setStyles({\n                        'width': subFieldValue,\n                        'height': keyFieldValue\n                    });\n                } else {\n                    imagePreview.setStyles({\n                        'width': keyFieldValue,\n                        'height': subFieldValue\n                    });\n                }\n            }\n\n            // Update the subField's value within the form to reflect the changes.\n            subField.set('value', subFieldValue);\n        }\n    },\n\n    /**\n     * Update the dialogue after an image was selected in the File Picker.\n     *\n     * @method _filepickerCallback\n     * @param {object} params The parameters provided by the filepicker\n     * containing information about the image.\n     * @private\n     */\n    _filepickerCallback: function(params) {\n        if (params.url !== '') {\n            var input = this._form.one('.' + CSS.INPUTURL);\n            input.set('value', params.url);\n\n            // Auto set the width and height.\n            this._form.one('.' + CSS.INPUTWIDTH).set('value', '');\n            this._form.one('.' + CSS.INPUTHEIGHT).set('value', '');\n\n            // Load the preview image.\n            this._loadPreviewImage(params.url);\n        }\n    },\n\n    /**\n     * Applies properties of an existing image to the image dialogue for editing.\n     *\n     * @method _applyImageProperties\n     * @param {Node} form\n     * @private\n     */\n    _applyImageProperties: function(form) {\n        var properties = this._getSelectedImageProperties(),\n            img = form.one('.' + CSS.IMAGEPREVIEW);\n\n        if (properties === false) {\n            img.setStyle('display', 'none');\n            // Set the default alignment.\n            ALIGNMENTS.some(function(alignment) {\n                if (alignment.isDefault) {\n                    form.one('.' + CSS.INPUTALIGNMENT).set('value', alignment.value);\n                    return true;\n                }\n\n                return false;\n            }, this);\n\n            return;\n        }\n\n        if (properties.align) {\n            form.one('.' + CSS.INPUTALIGNMENT).set('value', properties.align);\n        }\n        if (properties.customstyle) {\n            form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);\n        }\n        if (properties.width) {\n            form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);\n        }\n        if (properties.height) {\n            form.one('.' + CSS.INPUTHEIGHT).set('value', properties.height);\n        }\n        if (properties.alt) {\n            form.one('.' + CSS.INPUTALT).set('value', properties.alt);\n        }\n        if (properties.src) {\n            form.one('.' + CSS.INPUTURL).set('value', properties.src);\n            this._loadPreviewImage(properties.src);\n        }\n        if (properties.presentation) {\n            form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');\n        }\n\n        // Update the image preview based on the form properties.\n        this._autoAdjustSize();\n    },\n\n    /**\n     * Gets the properties of the currently selected image.\n     *\n     * The first image only if multiple images are selected.\n     *\n     * @method _getSelectedImageProperties\n     * @return {object}\n     * @private\n     */\n    _getSelectedImageProperties: function() {\n        var properties = {\n                src: null,\n                alt: null,\n                width: null,\n                height: null,\n                align: '',\n                presentation: false\n            },\n\n            // Get the current selection.\n            images = this.get('host').getSelectedNodes(),\n            width,\n            height,\n            style,\n            image;\n\n        if (images) {\n            images = images.filter('img');\n        }\n\n        if (images && images.size()) {\n            image = this._removeLegacyAlignment(images.item(0));\n            this._selectedImage = image;\n\n            style = image.getAttribute('style');\n            properties.customstyle = style;\n\n            width = image.getAttribute('width');\n            if (!width.match(REGEX.ISPERCENT)) {\n                width = parseInt(width, 10);\n            }\n            height = image.getAttribute('height');\n            if (!height.match(REGEX.ISPERCENT)) {\n                height = parseInt(height, 10);\n            }\n\n            if (width !== 0) {\n                properties.width = width;\n            }\n            if (height !== 0) {\n                properties.height = height;\n            }\n            this._getAlignmentPropeties(image, properties);\n            properties.src = image.getAttribute('src');\n            properties.alt = image.getAttribute('alt') || '';\n            properties.presentation = (image.get('role') === 'presentation');\n            return properties;\n        }\n\n        // No image selected - clean up.\n        this._selectedImage = null;\n        return false;\n    },\n\n    /**\n     * Sets the alignment of a properties object.\n     *\n     * @method _getAlignmentPropeties\n     * @param {Node} image The image that the alignment properties should be found for\n     * @param {Object} properties The properties object that is created in _getSelectedImageProperties()\n     * @private\n     */\n    _getAlignmentPropeties: function(image, properties) {\n        var complete = false,\n            defaultAlignment;\n\n        // Check for an alignment value.\n        complete = ALIGNMENTS.some(function(alignment) {\n            var classname = this._getAlignmentClass(alignment.value);\n            if (image.hasClass(classname)) {\n                properties.align = alignment.value;\n                Y.log('Found alignment ' + alignment.value, 'debug', 'atto_image-button');\n\n                return true;\n            }\n\n            if (alignment.isDefault) {\n                defaultAlignment = alignment.value;\n            }\n\n            return false;\n        }, this);\n\n        if (!complete && defaultAlignment) {\n            properties.align = defaultAlignment;\n        }\n    },\n\n    /**\n     * Update the form when the URL was changed. This includes updating the\n     * height, width, and image preview.\n     *\n     * @method _urlChanged\n     * @private\n     */\n    _urlChanged: function() {\n        var input = this._form.one('.' + CSS.INPUTURL);\n\n        if (input.get('value') !== '') {\n            // Load the preview image.\n            this._loadPreviewImage(input.get('value'));\n        }\n    },\n\n    /**\n     * Update the image in the contenteditable.\n     *\n     * @method _setImage\n     * @param {EventFacade} e\n     * @private\n     */\n    _setImage: function(e) {\n        var form = this._form,\n            url = form.one('.' + CSS.INPUTURL).get('value'),\n            alt = form.one('.' + CSS.INPUTALT).get('value'),\n            width = form.one('.' + CSS.INPUTWIDTH).get('value'),\n            height = form.one('.' + CSS.INPUTHEIGHT).get('value'),\n            alignment = this._getAlignmentClass(form.one('.' + CSS.INPUTALIGNMENT).get('value')),\n            presentation = form.one('.' + CSS.IMAGEPRESENTATION).get('checked'),\n            constrain = form.one('.' + CSS.INPUTCONSTRAIN).get('checked'),\n            imagehtml,\n            customstyle = form.one('.' + CSS.INPUTCUSTOMSTYLE).get('value'),\n            classlist = [],\n            host = this.get('host');\n\n        e.preventDefault();\n\n        // Check if there are any accessibility issues.\n        if (this._updateWarning()) {\n            return;\n        }\n\n        // Focus on the editor in preparation for inserting the image.\n        host.focus();\n        if (url !== '') {\n            if (this._selectedImage) {\n                host.setSelection(host.getSelectionFromNode(this._selectedImage));\n            } else {\n                host.setSelection(this._currentSelection);\n            }\n\n            if (constrain) {\n                classlist.push(CSS.RESPONSIVE);\n            }\n\n            // Add the alignment class for the image.\n            classlist.push(alignment);\n\n            if (!width.match(REGEX.ISPERCENT) && isNaN(parseInt(width, 10))) {\n                form.one('.' + CSS.INPUTWIDTH).focus();\n                return;\n            }\n            if (!height.match(REGEX.ISPERCENT) && isNaN(parseInt(height, 10))) {\n                form.one('.' + CSS.INPUTHEIGHT).focus();\n                return;\n            }\n\n            var template = Y.Handlebars.compile(IMAGETEMPLATE);\n            imagehtml = template({\n                url: url,\n                alt: alt,\n                width: width,\n                height: height,\n                presentation: presentation,\n                customstyle: customstyle,\n                classlist: classlist.join(' ')\n            });\n\n            this.get('host').insertContentAtFocusPoint(imagehtml);\n\n            this.markUpdated();\n        }\n\n        this.getDialogue({\n            focusAfterHide: null\n        }).hide();\n\n    },\n\n    /**\n     * Removes any legacy styles added by previous versions of the atto image button.\n     *\n     * @method _removeLegacyAlignment\n     * @param {Y.Node} imageNode\n     * @return {Y.Node}\n     * @private\n     */\n    _removeLegacyAlignment: function(imageNode) {\n        if (!imageNode.getStyle('margin')) {\n            // There is no margin therefore this cannot match any known alignments.\n            return imageNode;\n        }\n\n        ALIGNMENTS.some(function(alignment) {\n            if (imageNode.getStyle(alignment.name) !== alignment.value) {\n                // The name/value do not match. Skip.\n                return false;\n            }\n\n            var normalisedNode = Y.Node.create('<div>');\n            normalisedNode.setStyle('margin', alignment.margin);\n            if (imageNode.getStyle('margin') !== normalisedNode.getStyle('margin')) {\n                // The margin does not match.\n                return false;\n            }\n\n            Y.log('Legacy alignment found and removed.', 'info', 'atto_image-button');\n            imageNode.addClass(this._getAlignmentClass(alignment.value));\n            imageNode.setStyle(alignment.name, null);\n            imageNode.setStyle('margin', null);\n\n            return true;\n        }, this);\n\n        return imageNode;\n    },\n\n    _getAlignmentClass: function(alignment) {\n        return CSS.ALIGNSETTINGS + '_' + alignment;\n    },\n\n    /**\n     * Update the alt text warning live.\n     *\n     * @method _updateWarning\n     * @return {boolean} whether a warning should be displayed.\n     * @private\n     */\n    _updateWarning: function() {\n        var form = this._form,\n            state = true,\n            alt = form.one('.' + CSS.INPUTALT).get('value'),\n            presentation = form.one('.' + CSS.IMAGEPRESENTATION).get('checked');\n        if (alt === '' && !presentation) {\n            form.one('.' + CSS.IMAGEALTWARNING).setStyle('display', 'block');\n            form.one('.' + CSS.INPUTALT).setAttribute('aria-invalid', true);\n            form.one('.' + CSS.IMAGEPRESENTATION).setAttribute('aria-invalid', true);\n            state = true;\n        } else {\n            form.one('.' + CSS.IMAGEALTWARNING).setStyle('display', 'none');\n            form.one('.' + CSS.INPUTALT).setAttribute('aria-invalid', false);\n            form.one('.' + CSS.IMAGEPRESENTATION).setAttribute('aria-invalid', false);\n            state = false;\n        }\n        this.getDialogue().centerDialogue();\n        return state;\n    },\n\n    /**\n     * Handle the keyup to update the character count.\n     */\n    _handleKeyup: function() {\n        var form = this._form,\n            alt = form.one('.' + CSS.INPUTALT).get('value'),\n            characterCount = alt.length,\n            current = form.one('#currentcount');\n        current.setHTML(characterCount);\n    }\n});\n"],"file":"button.min.js"}
\ No newline at end of file