diff --git a/lib/editor/atto/plugins/image/styles.css b/lib/editor/atto/plugins/image/styles.css
index 3d9ee6a722e..95a6b9769fd 100644
--- a/lib/editor/atto/plugins/image/styles.css
+++ b/lib/editor/atto/plugins/image/styles.css
@@ -1,10 +1,13 @@
.atto_image_preview {
- max-width: 150px;
- max-height: 150px;
+ width: 100%;
+ height: 100%;
+ margin-left: auto;
+ margin-right: auto;
}
.atto_image_preview_box {
- height: 150px;
+ max-height: 200px;
margin-bottom: 1em;
+ overflow: auto;
}
.editor_atto_content img {
diff --git a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js
index b92532c4e6e..24abed2559d 100644
--- a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js
+++ b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js
@@ -150,9 +150,8 @@ var CSS = {
// Add the image preview.
'
' +
'
' +
- '

' +
+ '

' +
'
' +
- '
' +
// Add the submit button and close the form.
'
' +
@@ -198,22 +197,13 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_form: null,
/**
- * Remember the image true dimensions so we can constrain resizing.
+ * The dimensions of the raw image before we manipulate it.
*
- * @param _imageRawWidth
- * @type Integer
+ * @param _rawImageDimensions
+ * @type Object
* @private
*/
- _imageRawWidth: 0,
-
- /**
- * Remember the image true dimensions so we can constrain resizing.
- *
- * @param _imageRawHeight
- * @type Integer
- * @private
- */
- _imageRawHeight: 0,
+ _rawImageDimensions: null,
initializer: function() {
this.addButton({
@@ -276,11 +266,23 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_loadPreviewImage: function(url) {
var image = new Image(), self = this;
+ image.onerror = function() {
+ var preview = self._form.one('.' + CSS.IMAGEPREVIEW);
+ preview.setStyles({
+ 'display': 'none'
+ });
+
+ // Centre the dialogue when clearing the image preview.
+ self.getDialogue().centerDialogue();
+ };
+
image.onload = function() {
var input, currentwidth, currentheight, widthRatio, heightRatio;
- self._imageRawWidth = this.width;
- self._imageRawHeight = this.height;
+ self._rawImageDimensions = {
+ width: this.width,
+ height: this.height
+ };
input = self._form.one('.' + CSS.INPUTWIDTH);
currentwidth = input.get('value');
@@ -295,8 +297,10 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
- input.set('src', this.src);
- input.setStyle('display', 'inline');
+ input.setAttribute('src', this.src);
+ input.setStyles({
+ 'display': 'inline'
+ });
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
@@ -314,6 +318,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
input.set('checked', widthRatio === heightRatio);
}
+ // Apply the image sizing.
+ self._autoAdjustSize(self);
+
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
};
@@ -348,11 +355,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
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._autoAdjustHeight, this);
- this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustWidth, this);
+ this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);
+ this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);
this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {
if (event.target.get('checked')) {
- this._autoAdjustHeight();
+ this._autoAdjustSize(event);
}
}, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
@@ -367,84 +374,104 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return content;
},
- /**
- * Adjust the height to keep the aspect ratio.
- *
- * @method _autoAdjustHeight
- * @private
- */
- _autoAdjustHeight: function() {
- var currentWidth, newHeight, currentHeight;
+ _autoAdjustSize: function(e, forceHeight) {
+ forceHeight = forceHeight || false;
+
+ var keyField = this._form.one('.' + CSS.INPUTWIDTH),
+ keyFieldType = 'width',
+ subField = this._form.one('.' + CSS.INPUTHEIGHT),
+ subFieldType = 'height',
+ constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),
+ keyFieldValue = keyField.get('value'),
+ subFieldValue = subField.get('value'),
+ imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),
+ rawPercentage,
+ rawSize;
// Set the width back to default if it is empty.
- if (this._form.one('.' + CSS.INPUTWIDTH).get('value') === '') {
- this._form.one('.' + CSS.INPUTWIDTH).set('value', this._imageRawWidth);
+ if (keyFieldValue === '') {
+ keyFieldValue = this._rawImageDimensions[keyFieldType];
+ keyField.set('value', keyFieldValue);
+ keyFieldValue = keyField.get('value');
}
- if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- return;
- }
+ // Clear the existing preview sizes.
+ imagePreview.setStyles({
+ width: null,
+ height: null
+ });
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value').trim();
- // If this is a percentage based width, copy it verbatim to the height.
- if (currentWidth.match(REGEX.ISPERCENT)) {
- newHeight = currentWidth;
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- } else {
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
+ // Now update with the new values.
+ if (!constrainField.get('checked')) {
+ // We are not keeping the image proportion - update the preview accordingly.
- if (!isNaN(newHeight)) {
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
+ // Width.
+ if (keyFieldValue.match(REGEX.ISPERCENT)) {
+ rawPercentage = parseInt(keyFieldValue, 10);
+ rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
+ imagePreview.setStyle('width', rawSize + 'px');
+ } else {
+ imagePreview.setStyle('width', keyFieldValue + 'px');
}
- }
- },
- /**
- * Adjust the width to keep the aspect ratio.
- *
- * @method _autoAdjustWidth
- * @private
- */
- _autoAdjustWidth: function() {
- var currentHeight, newWidth;
-
- // Set the height back to default if it is empty.
- if (this._form.one('.' + CSS.INPUTHEIGHT).get('value') === '') {
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', this._imageRawHeight);
- }
-
- if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- return;
- }
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value').trim();
- // If this is a percentage based width, copy it verbatim to the height.
- if (currentHeight.match(REGEX.ISPERCENT)) {
- newWidth = currentHeight;
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- } else {
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
- newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
-
- if (!isNaN(newWidth)) {
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
+ // Height.
+ if (subFieldValue.match(REGEX.ISPERCENT)) {
+ rawPercentage = parseInt(subFieldValue, 10);
+ rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
+ imagePreview.setStyle('height', rawSize + 'px');
+ } else {
+ imagePreview.setStyle('height', subFieldValue + 'px');
}
+ } else {
+ // We are keeping the image in proportion.
+ if (forceHeight) {
+ // By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.
+ var _temporaryValue;
+ _temporaryValue = keyField;
+ keyField = subField;
+ subField = _temporaryValue;
+
+ _temporaryValue = keyFieldType;
+ keyFieldType = subFieldType;
+ subFieldType = _temporaryValue;
+
+ _temporaryValue = keyFieldValue;
+ keyFieldValue = subFieldValue;
+ subFieldValue = _temporaryValue;
+ }
+
+ if (keyFieldValue.match(REGEX.ISPERCENT)) {
+ // This is a percentage based change. Copy it verbatim.
+ subFieldValue = keyFieldValue;
+
+ // Set the width to the calculated pixel width.
+ rawPercentage = parseInt(keyFieldValue, 10);
+ rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
+
+ // And apply the width/height to the container.
+ imagePreview.setStyle('width', rawSize);
+ rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
+ imagePreview.setStyle('height', rawSize);
+ } else {
+ // Calculate the scaled subFieldValue from the keyFieldValue.
+ subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *
+ this._rawImageDimensions[subFieldType]);
+
+ if (forceHeight) {
+ imagePreview.setStyles({
+ 'width': subFieldValue,
+ 'height': keyFieldValue
+ });
+ } else {
+ imagePreview.setStyles({
+ 'width': keyFieldValue,
+ 'height': subFieldValue
+ });
+ }
+ }
+
+ // Update the subField's value within the form to reflect the changes.
+ subField.set('value', subFieldValue);
}
},
@@ -506,9 +533,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.customstyle) {
form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);
}
- if (properties.display) {
- img.setStyle('display', properties.display);
- }
if (properties.width) {
form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);
}
@@ -525,6 +549,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.presentation) {
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
}
+
+ // Update the image preview based on the form properties.
+ this._autoAdjustSize();
},
/**
@@ -543,7 +570,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
width: null,
height: null,
align: '',
- display: 'inline',
presentation: false
},
diff --git a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js
index df9ace1255e..cf584420140 100644
--- a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js
+++ b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js
@@ -1,3 +1,2 @@
-YUI.add("moodle-atto_image-button",function(e,t){var n={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"},r={INPUTURL:"."+n.INPUTURL},i=[{name:"text-top",str:"alignment_top",value:"vertical-align",margin:"0 .5em"},{name:"middle",str:"alignment_middle",value:"vertical-align",margin:"0 .5em"},{name:"text-bottom",str:"alignment_bottom",value:"vertical-align",margin:"0 .5em",isDefault:!0},{name:"left",str:"alignment_left",value:"float",margin:"0 .5em 0 0"},{name:"right",str:"alignment_right",value:"float",margin:"0 0 .5em 0"},{name:"customstyle",str:"customstyle",value:"style"}],s={ISPERCENT:/\d+%/},o="atto_image",u='
',a='

';e.namespace("M.atto_image").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_selectedImage:null,_form:null,_imageRawWidth:0,_imageRawHeight:0,initializer:function(){this.addButton({icon:"e/insert_edit_image",callback:this._displayDialogue,tags:"img",tagMatchRequiresAll:!1}),this.editor.delegate("dblclick",this._handleDoubleClick,"img",this)},_handleDoubleClick:function(e){var t=e.target,n=this.get("host").getSelectionFromNode(t);this.get("host").setSelection(n),this._displayDialogue()},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection===!1)return;var e=this.getDialogue({headerContent:M.util.get_string("imageproperties",o),width:"480px",focusAfterHide:!0,focusOnShowSelector:r.INPUTURL});e.set("bodyContent",this._getDialogueContent()).show()},_loadPreviewImage:function(e){var t=new Image,r=this;t.onload=function(){var e,t,i,o,u;r._imageRawWidth=this.width,r._imageRawHeight=this.height,e=r._form.one("."+n.INPUTWIDTH),t=e.get("value"),t===""&&(e.set("value",this.width),t=""+this.width),e=r._form.one("."+n.INPUTHEIGHT),i=e.get("value"),i===""&&(e.set("value",this.height),i=""+this.height),e=r._form.one("."+n.IMAGEPREVIEW),e.set("src",this.src),e.setStyle("display","inline"),e=r._form.one("."+n.INPUTCONSTRAIN),t.match(s.ISPERCENT)&&i.match(s.ISPERCENT)?e.set("checked",t===i):(this.width===0&&(this.width=1),this.height===0&&(this.height=1),o=Math.round(1e3*parseInt(t,10)/this.width),u=Math.round(1e3*parseInt(i,10)/this.height),e.set("checked",o===u)),r.getDialogue().centerDialogue()},t.src=e},_getDialogueContent:function(){var t=e.Handlebars.compile(u),r=this.get("host").canShowFilepicker("image"),s=e.Node.create(t({elementid:this.get("host").get("elementid"),CSS:n,component:o,showFilepicker:r,alignments:i}));return this._form=s,this._applyImageProperties(this._form),this._form.one("."+n.INPUTURL).on("blur",this._urlChanged,this),this._form.one("."+n.IMAGEPRESENTATION).on("change",this._updateWarning,this),this._form.one("."+n.INPUTALT).on("change",this._updateWarning,this),this._form.one("."+n.INPUTWIDTH).on("blur",this._autoAdjustHeight,this),this._form.one("."+n.INPUTHEIGHT).on("blur",this._autoAdjustWidth,this),this._form.one
-("."+n.INPUTCONSTRAIN).on("change",function(e){e.target.get("checked")&&this._autoAdjustHeight()},this),this._form.one("."+n.INPUTURL).on("blur",this._urlChanged,this),this._form.one("."+n.INPUTSUBMIT).on("click",this._setImage,this),r&&this._form.one("."+n.IMAGEBROWSER).on("click",function(){this.get("host").showFilepicker("image",this._filepickerCallback,this)},this),s},_autoAdjustHeight:function(){var e,t,r;this._form.one("."+n.INPUTWIDTH).get("value")===""&&this._form.one("."+n.INPUTWIDTH).set("value",this._imageRawWidth);if(!this._form.one("."+n.INPUTCONSTRAIN).get("checked")){e=this._form.one("."+n.INPUTWIDTH).get("value"),r=this._form.one("."+n.INPUTHEIGHT).get("value"),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",r),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",e);return}e=this._form.one("."+n.INPUTWIDTH).get("value").trim(),e.match(s.ISPERCENT)?(t=e,this._form.one("."+n.INPUTHEIGHT).set("value",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",e)):(e=parseInt(this._form.one("."+n.INPUTWIDTH).get("value"),10),t=Math.round(e/this._imageRawWidth*this._imageRawHeight),isNaN(t)||(this._form.one("."+n.INPUTHEIGHT).set("value",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",e)))},_autoAdjustWidth:function(){var e,t;this._form.one("."+n.INPUTHEIGHT).get("value")===""&&this._form.one("."+n.INPUTHEIGHT).set("value",this._imageRawHeight);if(!this._form.one("."+n.INPUTCONSTRAIN).get("checked")){currentWidth=this._form.one("."+n.INPUTWIDTH).get("value"),e=this._form.one("."+n.INPUTHEIGHT).get("value"),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",e),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",currentWidth);return}e=this._form.one("."+n.INPUTHEIGHT).get("value").trim(),e.match(s.ISPERCENT)?(t=e,this._form.one("."+n.INPUTWIDTH).set("value",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",e)):(e=parseInt(this._form.one("."+n.INPUTHEIGHT).get("value"),10),t=Math.round(e/this._imageRawHeight*this._imageRawWidth),isNaN(t)||(this._form.one("."+n.INPUTWIDTH).set("value",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",t),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",e)))},_filepickerCallback:function(e){if(e.url!==""){var t=this._form.one("."+n.INPUTURL);t.set("value",e.url),this._form.one("."+n.INPUTWIDTH).set("value",""),this._form.one("."+n.INPUTHEIGHT).set("value",""),this._loadPreviewImage(e.url)}},_applyImageProperties:function(e){var t=this._getSelectedImageProperties(),r=e.one("."+n.IMAGEPREVIEW),s;if(t===!1){r.setStyle("display","none");for(s in i)i[s].isDefault===!0&&(css=i[s].value+":"+i[s].name+";",e.one("."+n.INPUTALIGNMENT).set("value",css));e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(i.length-1);return}t.align?(e.one("."+n.INPUTALIGNMENT).set("value",t.align),e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(i.length-1)):e.one("."+n.INPUTALIGNMENT).set("value","style:customstyle;"),t.customstyle&&e.one("."+n.INPUTCUSTOMSTYLE).set("value",t.customstyle),t.display&&r.setStyle("display",t.display),t.width&&e.one("."+n.INPUTWIDTH).set("value",t.width),t.height&&e.one("."+n.INPUTHEIGHT).set("value",t.height),t.alt&&e.one("."+n.INPUTALT).set("value",t.alt),t.src&&(e.one("."+n.INPUTURL).set("value",t.src),this._loadPreviewImage(t.src)),t.presentation&&e.one("."+n.IMAGEPRESENTATION).set("checked","checked")},_getSelectedImageProperties:function(){var e={src:null,alt:null,width:null,height:null,align:"",display:"inline",presentation:!1},t=this.get("host").getSelectedNodes(),n,r,o,u,a;t&&(t=t.filter("img"));if(t&&t.size()){image=t.item(0),this._selectedImage=image,u=image.getAttribute("style"),e.customstyle=u,u=u.replace(/ /g,""),r=image.getAttribute("width"),r.match(s.ISPERCENT)||(r=parseInt(r,10)),o=image.getAttribute("height"),o.match(s.ISPERCENT)||(o=parseInt(o,10)),r!==0&&(e.width=r),o!==0&&(e.height=o);for(n in i){a=i[n].value+":"+i[n].name+";";if(u.indexOf(a)!==-1){margin="margin:"+i[n].margin+";",margin=margin.replace(/ /g,"");if(u.indexOf(margin)!==-1){e.align=a;break}}}return e.src=image.getAttribute("src"),e.alt=image.getAttribute("alt")||"",e.presentation=image.get("role")==="presentation",e}return this._selectedImage=null,!1},_urlChanged:function(){var e=this._form.one("."+n.INPUTURL);e.get("value")!==""&&this._loadPreviewImage(e.get("value"))},_setImage:function(t){var r=this._form,o=r.one("."+n.INPUTURL).get("value"),u=r.one("."+n.INPUTALT).get("value"),f=r.one("."+n.INPUTWIDTH).get("value"),l=r.one("."+n.INPUTHEIGHT).get("value"),c=r.one("."+n.INPUTALIGNMENT).get("value"),h="",p=r.one("."+n.IMAGEPRESENTATION).get("checked"),d=r.one("."+n.INPUTCONSTRAIN).get("checked"),v,m="",g,y=[],b=this.get("host");t.preventDefault();if(this._updateWarning())return;b.focus();if(o!==""){this._selectedImage?b.setSelection(b.getSelectionFromNode(this._selectedImage)):b.setSelection(this._currentSelection);if(c==="style:customstyle;")c="",m=r.one("."+n.INPUTCUSTOMSTYLE).get("value");else for(g in i)css=i[g].value+":"+i[g].name+";",c===css&&(h=" margin: "+i[g].margin+";");d&&y.push(n.RESPONSIVE);if(!f.match(s.ISPERCENT)&&isNaN(parseInt(f,10))){r.one("."+n.INPUTWIDTH).focus();return}if(!l.match(s.ISPERCENT)&&isNaN(parseInt(l,10))){r.one("."+n.INPUTHEIGHT).focus();return}template=e.Handlebars.compile(a),v=template({url:o,alt:u,width:f,height:l,presentation:p,alignment:c,margin:h,customstyle:m,classlist:y.join(" ")}),this.get("host").insertContentAtFocusPoint(v),this.markUpdated()}this.getDialogue({focusAfterHide:null}).hide()},_updateWarning:function(){var e=this._form,t=!0,r=e.one("."+n.INPUTALT).get("value"),i=e.one("."+n.IMAGEPRESENTATION).get("checked");return r===""&&!i?(e.one("."+n.IMAGEALTWARNING).setStyle("display","block"),e.one("."+n.INPUTALT).setAttribute("aria-invalid",!0),e.one("."+n.IMAGEPRESENTATION
-).setAttribute("aria-invalid",!0),t=!0):(e.one("."+n.IMAGEALTWARNING).setStyle("display","none"),e.one("."+n.INPUTALT).setAttribute("aria-invalid",!1),e.one("."+n.IMAGEPRESENTATION).setAttribute("aria-invalid",!1),t=!1),this.getDialogue().centerDialogue(),t}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
+YUI.add("moodle-atto_image-button",function(e,t){var n={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"},r={INPUTURL:"."+n.INPUTURL},i=[{name:"text-top",str:"alignment_top",value:"vertical-align",margin:"0 .5em"},{name:"middle",str:"alignment_middle",value:"vertical-align",margin:"0 .5em"},{name:"text-bottom",str:"alignment_bottom",value:"vertical-align",margin:"0 .5em",isDefault:!0},{name:"left",str:"alignment_left",value:"float",margin:"0 .5em 0 0"},{name:"right",str:"alignment_right",value:"float",margin:"0 0 .5em 0"},{name:"customstyle",str:"customstyle",value:"style"}],s={ISPERCENT:/\d+%/},o="atto_image",u='
',a='

';e.namespace("M.atto_image").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_selectedImage:null,_form:null,_rawImageDimensions:null,initializer:function(){this.addButton({icon:"e/insert_edit_image",callback:this._displayDialogue,tags:"img",tagMatchRequiresAll:!1}),this.editor.delegate("dblclick",this._handleDoubleClick,"img",this)},_handleDoubleClick:function(e){var t=e.target,n=this.get("host").getSelectionFromNode(t);this.get("host").setSelection(n),this._displayDialogue()},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection===!1)return;var e=this.getDialogue({headerContent:M.util.get_string("imageproperties",o),width:"480px",focusAfterHide:!0,focusOnShowSelector:r.INPUTURL});e.set("bodyContent",this._getDialogueContent()).show()},_loadPreviewImage:function(e){var t=new Image,r=this;t.onerror=function(){var e=r._form.one("."+n.IMAGEPREVIEW);e.setStyles({display:"none"}),r.getDialogue().centerDialogue()},t.onload=function(){var e,t,i,o,u;r._rawImageDimensions={width:this.width,height:this.height},e=r._form.one("."+n.INPUTWIDTH),t=e.get("value"),t===""&&(e.set("value",this.width),t=""+this.width),e=r._form.one("."+n.INPUTHEIGHT),i=e.get("value"),i===""&&(e.set("value",this.height),i=""+this.height),e=r._form.one("."+n.IMAGEPREVIEW),e.setAttribute("src",this.src),e.setStyles({display:"inline"}),e=r._form.one("."+n.INPUTCONSTRAIN),t.match(s.ISPERCENT)&&i.match(s.ISPERCENT)?e.set("checked",t===i):(this.width===0&&(this.width=1),this.height===0&&(this.height=1),o=Math.round(1e3*parseInt(t,10)/this.width),u=Math.round(1e3*parseInt(i,10)/this.height),e.set("checked",o===u)),r._autoAdjustSize(r),r.getDialogue().centerDialogue()},t.src=e},_getDialogueContent:function(){var t=e.Handlebars.compile(u),r=this.get("host").canShowFilepicker("image"),s=e.Node.create(t({elementid:this.get("host").get("elementid"),CSS:n,component:o,showFilepicker:r,alignments:i}));return this._form=s,this._applyImageProperties(this._form),this._form.one("."+n.INPUTURL).on("blur",this._urlChanged,this),this._form.one("."+n.IMAGEPRESENTATION).on("change",this._updateWarning,this),this._form.one("."+n.INPUTALT).on("change",this._updateWarning,this),this._form.one("."+n.INPUTWIDTH).on("blur",this._autoAdjustSize
+,this),this._form.one("."+n.INPUTHEIGHT).on("blur",this._autoAdjustSize,this,!0),this._form.one("."+n.INPUTCONSTRAIN).on("change",function(e){e.target.get("checked")&&this._autoAdjustSize(e)},this),this._form.one("."+n.INPUTURL).on("blur",this._urlChanged,this),this._form.one("."+n.INPUTSUBMIT).on("click",this._setImage,this),r&&this._form.one("."+n.IMAGEBROWSER).on("click",function(){this.get("host").showFilepicker("image",this._filepickerCallback,this)},this),s},_autoAdjustSize:function(e,t){t=t||!1;var r=this._form.one("."+n.INPUTWIDTH),i="width",o=this._form.one("."+n.INPUTHEIGHT),u="height",a=this._form.one("."+n.INPUTCONSTRAIN),f=r.get("value"),l=o.get("value"),c=this._form.one("."+n.IMAGEPREVIEW),h,p;f===""&&(f=this._rawImageDimensions[i],r.set("value",f),f=r.get("value")),c.setStyles({width:null,height:null});if(!a.get("checked"))f.match(s.ISPERCENT)?(h=parseInt(f,10),p=this._rawImageDimensions.width/100*h,c.setStyle("width",p+"px")):c.setStyle("width",f+"px"),l.match(s.ISPERCENT)?(h=parseInt(l,10),p=this._rawImageDimensions.height/100*h,c.setStyle("height",p+"px")):c.setStyle("height",l+"px");else{if(t){var d;d=r,r=o,o=d,d=i,i=u,u=d,d=f,f=l,l=d}f.match(s.ISPERCENT)?(l=f,h=parseInt(f,10),p=this._rawImageDimensions.width/100*h,c.setStyle("width",p),p=this._rawImageDimensions.height/100*h,c.setStyle("height",p)):(l=Math.round(f/this._rawImageDimensions[i]*this._rawImageDimensions[u]),t?c.setStyles({width:l,height:f}):c.setStyles({width:f,height:l})),o.set("value",l)}},_filepickerCallback:function(e){if(e.url!==""){var t=this._form.one("."+n.INPUTURL);t.set("value",e.url),this._form.one("."+n.INPUTWIDTH).set("value",""),this._form.one("."+n.INPUTHEIGHT).set("value",""),this._loadPreviewImage(e.url)}},_applyImageProperties:function(e){var t=this._getSelectedImageProperties(),r=e.one("."+n.IMAGEPREVIEW),s;if(t===!1){r.setStyle("display","none");for(s in i)i[s].isDefault===!0&&(css=i[s].value+":"+i[s].name+";",e.one("."+n.INPUTALIGNMENT).set("value",css));e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(i.length-1);return}t.align?(e.one("."+n.INPUTALIGNMENT).set("value",t.align),e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(i.length-1)):e.one("."+n.INPUTALIGNMENT).set("value","style:customstyle;"),t.customstyle&&e.one("."+n.INPUTCUSTOMSTYLE).set("value",t.customstyle),t.width&&e.one("."+n.INPUTWIDTH).set("value",t.width),t.height&&e.one("."+n.INPUTHEIGHT).set("value",t.height),t.alt&&e.one("."+n.INPUTALT).set("value",t.alt),t.src&&(e.one("."+n.INPUTURL).set("value",t.src),this._loadPreviewImage(t.src)),t.presentation&&e.one("."+n.IMAGEPRESENTATION).set("checked","checked"),this._autoAdjustSize()},_getSelectedImageProperties:function(){var e={src:null,alt:null,width:null,height:null,align:"",presentation:!1},t=this.get("host").getSelectedNodes(),n,r,o,u,a;t&&(t=t.filter("img"));if(t&&t.size()){image=t.item(0),this._selectedImage=image,u=image.getAttribute("style"),e.customstyle=u,u=u.replace(/ /g,""),r=image.getAttribute("width"),r.match(s.ISPERCENT)||(r=parseInt(r,10)),o=image.getAttribute("height"),o.match(s.ISPERCENT)||(o=parseInt(o,10)),r!==0&&(e.width=r),o!==0&&(e.height=o);for(n in i){a=i[n].value+":"+i[n].name+";";if(u.indexOf(a)!==-1){margin="margin:"+i[n].margin+";",margin=margin.replace(/ /g,"");if(u.indexOf(margin)!==-1){e.align=a;break}}}return e.src=image.getAttribute("src"),e.alt=image.getAttribute("alt")||"",e.presentation=image.get("role")==="presentation",e}return this._selectedImage=null,!1},_urlChanged:function(){var e=this._form.one("."+n.INPUTURL);e.get("value")!==""&&this._loadPreviewImage(e.get("value"))},_setImage:function(t){var r=this._form,o=r.one("."+n.INPUTURL).get("value"),u=r.one("."+n.INPUTALT).get("value"),f=r.one("."+n.INPUTWIDTH).get("value"),l=r.one("."+n.INPUTHEIGHT).get("value"),c=r.one("."+n.INPUTALIGNMENT).get("value"),h="",p=r.one("."+n.IMAGEPRESENTATION).get("checked"),d=r.one("."+n.INPUTCONSTRAIN).get("checked"),v,m="",g,y=[],b=this.get("host");t.preventDefault();if(this._updateWarning())return;b.focus();if(o!==""){this._selectedImage?b.setSelection(b.getSelectionFromNode(this._selectedImage)):b.setSelection(this._currentSelection);if(c==="style:customstyle;")c="",m=r.one("."+n.INPUTCUSTOMSTYLE).get("value");else for(g in i)css=i[g].value+":"+i[g].name+";",c===css&&(h=" margin: "+i[g].margin+";");d&&y.push(n.RESPONSIVE);if(!f.match(s.ISPERCENT)&&isNaN(parseInt(f,10))){r.one("."+n.INPUTWIDTH).focus();return}if(!l.match(s.ISPERCENT)&&isNaN(parseInt(l,10))){r.one("."+n.INPUTHEIGHT).focus();return}template=e.Handlebars.compile(a),v=template({url:o,alt:u,width:f,height:l,presentation:p,alignment:c,margin:h,customstyle:m,classlist:y.join(" ")}),this.get("host").insertContentAtFocusPoint(v),this.markUpdated()}this.getDialogue({focusAfterHide:null}).hide()},_updateWarning:function(){var e=this._form,t=!0,r=e.one("."+n.INPUTALT).get("value"),i=e.one("."+n.IMAGEPRESENTATION).get("checked");return r===""&&!i?(e.one("."+n.IMAGEALTWARNING).setStyle("display","block"),e.one("."+n.INPUTALT).setAttribute("aria-invalid",!0),e.one("."+n.IMAGEPRESENTATION).setAttribute("aria-invalid",!0),t=!0):(e.one("."+n.IMAGEALTWARNING).setStyle("display","none"),e.one("."+n.INPUTALT).setAttribute("aria-invalid",!1),e.one("."+n.IMAGEPRESENTATION).setAttribute("aria-invalid",!1),t=!1),this.getDialogue().centerDialogue(),t}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]});
diff --git a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js
index b92532c4e6e..24abed2559d 100644
--- a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js
+++ b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js
@@ -150,9 +150,8 @@ var CSS = {
// Add the image preview.
'
' +
'
' +
- '

' +
+ '

' +
'
' +
- '
' +
// Add the submit button and close the form.
'
' +
@@ -198,22 +197,13 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_form: null,
/**
- * Remember the image true dimensions so we can constrain resizing.
+ * The dimensions of the raw image before we manipulate it.
*
- * @param _imageRawWidth
- * @type Integer
+ * @param _rawImageDimensions
+ * @type Object
* @private
*/
- _imageRawWidth: 0,
-
- /**
- * Remember the image true dimensions so we can constrain resizing.
- *
- * @param _imageRawHeight
- * @type Integer
- * @private
- */
- _imageRawHeight: 0,
+ _rawImageDimensions: null,
initializer: function() {
this.addButton({
@@ -276,11 +266,23 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_loadPreviewImage: function(url) {
var image = new Image(), self = this;
+ image.onerror = function() {
+ var preview = self._form.one('.' + CSS.IMAGEPREVIEW);
+ preview.setStyles({
+ 'display': 'none'
+ });
+
+ // Centre the dialogue when clearing the image preview.
+ self.getDialogue().centerDialogue();
+ };
+
image.onload = function() {
var input, currentwidth, currentheight, widthRatio, heightRatio;
- self._imageRawWidth = this.width;
- self._imageRawHeight = this.height;
+ self._rawImageDimensions = {
+ width: this.width,
+ height: this.height
+ };
input = self._form.one('.' + CSS.INPUTWIDTH);
currentwidth = input.get('value');
@@ -295,8 +297,10 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
- input.set('src', this.src);
- input.setStyle('display', 'inline');
+ input.setAttribute('src', this.src);
+ input.setStyles({
+ 'display': 'inline'
+ });
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
@@ -314,6 +318,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
input.set('checked', widthRatio === heightRatio);
}
+ // Apply the image sizing.
+ self._autoAdjustSize(self);
+
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
};
@@ -348,11 +355,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
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._autoAdjustHeight, this);
- this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustWidth, this);
+ this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);
+ this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);
this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {
if (event.target.get('checked')) {
- this._autoAdjustHeight();
+ this._autoAdjustSize(event);
}
}, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
@@ -367,84 +374,104 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return content;
},
- /**
- * Adjust the height to keep the aspect ratio.
- *
- * @method _autoAdjustHeight
- * @private
- */
- _autoAdjustHeight: function() {
- var currentWidth, newHeight, currentHeight;
+ _autoAdjustSize: function(e, forceHeight) {
+ forceHeight = forceHeight || false;
+
+ var keyField = this._form.one('.' + CSS.INPUTWIDTH),
+ keyFieldType = 'width',
+ subField = this._form.one('.' + CSS.INPUTHEIGHT),
+ subFieldType = 'height',
+ constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),
+ keyFieldValue = keyField.get('value'),
+ subFieldValue = subField.get('value'),
+ imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),
+ rawPercentage,
+ rawSize;
// Set the width back to default if it is empty.
- if (this._form.one('.' + CSS.INPUTWIDTH).get('value') === '') {
- this._form.one('.' + CSS.INPUTWIDTH).set('value', this._imageRawWidth);
+ if (keyFieldValue === '') {
+ keyFieldValue = this._rawImageDimensions[keyFieldType];
+ keyField.set('value', keyFieldValue);
+ keyFieldValue = keyField.get('value');
}
- if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- return;
- }
+ // Clear the existing preview sizes.
+ imagePreview.setStyles({
+ width: null,
+ height: null
+ });
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value').trim();
- // If this is a percentage based width, copy it verbatim to the height.
- if (currentWidth.match(REGEX.ISPERCENT)) {
- newHeight = currentWidth;
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- } else {
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
+ // Now update with the new values.
+ if (!constrainField.get('checked')) {
+ // We are not keeping the image proportion - update the preview accordingly.
- if (!isNaN(newHeight)) {
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
+ // Width.
+ if (keyFieldValue.match(REGEX.ISPERCENT)) {
+ rawPercentage = parseInt(keyFieldValue, 10);
+ rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
+ imagePreview.setStyle('width', rawSize + 'px');
+ } else {
+ imagePreview.setStyle('width', keyFieldValue + 'px');
}
- }
- },
- /**
- * Adjust the width to keep the aspect ratio.
- *
- * @method _autoAdjustWidth
- * @private
- */
- _autoAdjustWidth: function() {
- var currentHeight, newWidth;
-
- // Set the height back to default if it is empty.
- if (this._form.one('.' + CSS.INPUTHEIGHT).get('value') === '') {
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', this._imageRawHeight);
- }
-
- if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- return;
- }
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value').trim();
- // If this is a percentage based width, copy it verbatim to the height.
- if (currentHeight.match(REGEX.ISPERCENT)) {
- newWidth = currentHeight;
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- } else {
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
- newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
-
- if (!isNaN(newWidth)) {
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
+ // Height.
+ if (subFieldValue.match(REGEX.ISPERCENT)) {
+ rawPercentage = parseInt(subFieldValue, 10);
+ rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
+ imagePreview.setStyle('height', rawSize + 'px');
+ } else {
+ imagePreview.setStyle('height', subFieldValue + 'px');
}
+ } else {
+ // We are keeping the image in proportion.
+ if (forceHeight) {
+ // By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.
+ var _temporaryValue;
+ _temporaryValue = keyField;
+ keyField = subField;
+ subField = _temporaryValue;
+
+ _temporaryValue = keyFieldType;
+ keyFieldType = subFieldType;
+ subFieldType = _temporaryValue;
+
+ _temporaryValue = keyFieldValue;
+ keyFieldValue = subFieldValue;
+ subFieldValue = _temporaryValue;
+ }
+
+ if (keyFieldValue.match(REGEX.ISPERCENT)) {
+ // This is a percentage based change. Copy it verbatim.
+ subFieldValue = keyFieldValue;
+
+ // Set the width to the calculated pixel width.
+ rawPercentage = parseInt(keyFieldValue, 10);
+ rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
+
+ // And apply the width/height to the container.
+ imagePreview.setStyle('width', rawSize);
+ rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
+ imagePreview.setStyle('height', rawSize);
+ } else {
+ // Calculate the scaled subFieldValue from the keyFieldValue.
+ subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *
+ this._rawImageDimensions[subFieldType]);
+
+ if (forceHeight) {
+ imagePreview.setStyles({
+ 'width': subFieldValue,
+ 'height': keyFieldValue
+ });
+ } else {
+ imagePreview.setStyles({
+ 'width': keyFieldValue,
+ 'height': subFieldValue
+ });
+ }
+ }
+
+ // Update the subField's value within the form to reflect the changes.
+ subField.set('value', subFieldValue);
}
},
@@ -506,9 +533,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.customstyle) {
form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);
}
- if (properties.display) {
- img.setStyle('display', properties.display);
- }
if (properties.width) {
form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);
}
@@ -525,6 +549,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.presentation) {
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
}
+
+ // Update the image preview based on the form properties.
+ this._autoAdjustSize();
},
/**
@@ -543,7 +570,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
width: null,
height: null,
align: '',
- display: 'inline',
presentation: false
},
diff --git a/lib/editor/atto/plugins/image/yui/src/button/js/button.js b/lib/editor/atto/plugins/image/yui/src/button/js/button.js
index c34a74805ad..eba4d81ca07 100644
--- a/lib/editor/atto/plugins/image/yui/src/button/js/button.js
+++ b/lib/editor/atto/plugins/image/yui/src/button/js/button.js
@@ -148,9 +148,8 @@ var CSS = {
// Add the image preview.
'
' +
'
' +
- '

' +
+ '

' +
'
' +
- '
' +
// Add the submit button and close the form.
'
' +
@@ -196,22 +195,13 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_form: null,
/**
- * Remember the image true dimensions so we can constrain resizing.
+ * The dimensions of the raw image before we manipulate it.
*
- * @param _imageRawWidth
- * @type Integer
+ * @param _rawImageDimensions
+ * @type Object
* @private
*/
- _imageRawWidth: 0,
-
- /**
- * Remember the image true dimensions so we can constrain resizing.
- *
- * @param _imageRawHeight
- * @type Integer
- * @private
- */
- _imageRawHeight: 0,
+ _rawImageDimensions: null,
initializer: function() {
this.addButton({
@@ -274,11 +264,23 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_loadPreviewImage: function(url) {
var image = new Image(), self = this;
+ image.onerror = function() {
+ var preview = self._form.one('.' + CSS.IMAGEPREVIEW);
+ preview.setStyles({
+ 'display': 'none'
+ });
+
+ // Centre the dialogue when clearing the image preview.
+ self.getDialogue().centerDialogue();
+ };
+
image.onload = function() {
var input, currentwidth, currentheight, widthRatio, heightRatio;
- self._imageRawWidth = this.width;
- self._imageRawHeight = this.height;
+ self._rawImageDimensions = {
+ width: this.width,
+ height: this.height
+ };
input = self._form.one('.' + CSS.INPUTWIDTH);
currentwidth = input.get('value');
@@ -293,8 +295,10 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
- input.set('src', this.src);
- input.setStyle('display', 'inline');
+ input.setAttribute('src', this.src);
+ input.setStyles({
+ 'display': 'inline'
+ });
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
@@ -312,6 +316,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
input.set('checked', widthRatio === heightRatio);
}
+ // Apply the image sizing.
+ self._autoAdjustSize(self);
+
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
};
@@ -346,11 +353,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
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._autoAdjustHeight, this);
- this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustWidth, this);
+ this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);
+ this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);
this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {
if (event.target.get('checked')) {
- this._autoAdjustHeight();
+ this._autoAdjustSize(event);
}
}, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
@@ -365,84 +372,104 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return content;
},
- /**
- * Adjust the height to keep the aspect ratio.
- *
- * @method _autoAdjustHeight
- * @private
- */
- _autoAdjustHeight: function() {
- var currentWidth, newHeight, currentHeight;
+ _autoAdjustSize: function(e, forceHeight) {
+ forceHeight = forceHeight || false;
+
+ var keyField = this._form.one('.' + CSS.INPUTWIDTH),
+ keyFieldType = 'width',
+ subField = this._form.one('.' + CSS.INPUTHEIGHT),
+ subFieldType = 'height',
+ constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),
+ keyFieldValue = keyField.get('value'),
+ subFieldValue = subField.get('value'),
+ imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),
+ rawPercentage,
+ rawSize;
// Set the width back to default if it is empty.
- if (this._form.one('.' + CSS.INPUTWIDTH).get('value') === '') {
- this._form.one('.' + CSS.INPUTWIDTH).set('value', this._imageRawWidth);
+ if (keyFieldValue === '') {
+ keyFieldValue = this._rawImageDimensions[keyFieldType];
+ keyField.set('value', keyFieldValue);
+ keyFieldValue = keyField.get('value');
}
- if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- return;
- }
+ // Clear the existing preview sizes.
+ imagePreview.setStyles({
+ width: null,
+ height: null
+ });
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value').trim();
- // If this is a percentage based width, copy it verbatim to the height.
- if (currentWidth.match(REGEX.ISPERCENT)) {
- newHeight = currentWidth;
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- } else {
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
+ // Now update with the new values.
+ if (!constrainField.get('checked')) {
+ // We are not keeping the image proportion - update the preview accordingly.
- if (!isNaN(newHeight)) {
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
+ // Width.
+ if (keyFieldValue.match(REGEX.ISPERCENT)) {
+ rawPercentage = parseInt(keyFieldValue, 10);
+ rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
+ imagePreview.setStyle('width', rawSize + 'px');
+ } else {
+ imagePreview.setStyle('width', keyFieldValue + 'px');
}
- }
- },
- /**
- * Adjust the width to keep the aspect ratio.
- *
- * @method _autoAdjustWidth
- * @private
- */
- _autoAdjustWidth: function() {
- var currentHeight, newWidth;
-
- // Set the height back to default if it is empty.
- if (this._form.one('.' + CSS.INPUTHEIGHT).get('value') === '') {
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', this._imageRawHeight);
- }
-
- if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
- return;
- }
- currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value').trim();
- // If this is a percentage based width, copy it verbatim to the height.
- if (currentHeight.match(REGEX.ISPERCENT)) {
- newWidth = currentHeight;
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
- } else {
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
- newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
-
- if (!isNaN(newWidth)) {
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
+ // Height.
+ if (subFieldValue.match(REGEX.ISPERCENT)) {
+ rawPercentage = parseInt(subFieldValue, 10);
+ rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
+ imagePreview.setStyle('height', rawSize + 'px');
+ } else {
+ imagePreview.setStyle('height', subFieldValue + 'px');
}
+ } else {
+ // We are keeping the image in proportion.
+ if (forceHeight) {
+ // By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.
+ var _temporaryValue;
+ _temporaryValue = keyField;
+ keyField = subField;
+ subField = _temporaryValue;
+
+ _temporaryValue = keyFieldType;
+ keyFieldType = subFieldType;
+ subFieldType = _temporaryValue;
+
+ _temporaryValue = keyFieldValue;
+ keyFieldValue = subFieldValue;
+ subFieldValue = _temporaryValue;
+ }
+
+ if (keyFieldValue.match(REGEX.ISPERCENT)) {
+ // This is a percentage based change. Copy it verbatim.
+ subFieldValue = keyFieldValue;
+
+ // Set the width to the calculated pixel width.
+ rawPercentage = parseInt(keyFieldValue, 10);
+ rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
+
+ // And apply the width/height to the container.
+ imagePreview.setStyle('width', rawSize);
+ rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
+ imagePreview.setStyle('height', rawSize);
+ } else {
+ // Calculate the scaled subFieldValue from the keyFieldValue.
+ subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *
+ this._rawImageDimensions[subFieldType]);
+
+ if (forceHeight) {
+ imagePreview.setStyles({
+ 'width': subFieldValue,
+ 'height': keyFieldValue
+ });
+ } else {
+ imagePreview.setStyles({
+ 'width': keyFieldValue,
+ 'height': subFieldValue
+ });
+ }
+ }
+
+ // Update the subField's value within the form to reflect the changes.
+ subField.set('value', subFieldValue);
}
},
@@ -504,9 +531,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.customstyle) {
form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);
}
- if (properties.display) {
- img.setStyle('display', properties.display);
- }
if (properties.width) {
form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);
}
@@ -523,6 +547,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.presentation) {
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
}
+
+ // Update the image preview based on the form properties.
+ this._autoAdjustSize();
},
/**
@@ -541,7 +568,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
width: null,
height: null,
align: '',
- display: 'inline',
presentation: false
},