diff --git a/lib/editor/atto/plugins/image/lang/en/atto_image.php b/lib/editor/atto/plugins/image/lang/en/atto_image.php
index 47003098347..05c3bc815ea 100644
--- a/lib/editor/atto/plugins/image/lang/en/atto_image.php
+++ b/lib/editor/atto/plugins/image/lang/en/atto_image.php
@@ -29,14 +29,16 @@ $string['alignment_middle'] = 'Middle';
$string['alignment_right'] = 'Right';
$string['alignment_top'] = 'Top';
$string['browserepositories'] = 'Browse repositories...';
-$string['constrain'] = 'Keep ratio';
+$string['constrain'] = 'Auto size';
$string['createimage'] = 'Insert image';
$string['customstyle'] = 'Custom style';
$string['enteralt'] = 'Describe this image for someone who cannot see it';
$string['enterurl'] = 'Enter URL';
$string['height'] = 'Height';
+$string['imageproperties'] = 'Image properties';
$string['presentation'] = 'Description not necessary';
$string['pluginname'] = 'Image';
$string['presentationoraltrequired'] = 'Images must have a description, except if the description is marked as not necessary.';
$string['preview'] = 'Preview';
+$string['saveimage'] = 'Save image';
$string['width'] = 'Width';
diff --git a/lib/editor/atto/plugins/image/lib.php b/lib/editor/atto/plugins/image/lib.php
index 220ee242e8e..c6c9ad2a016 100644
--- a/lib/editor/atto/plugins/image/lib.php
+++ b/lib/editor/atto/plugins/image/lib.php
@@ -39,7 +39,8 @@ function atto_image_strings_for_js() {
'alignment_top',
'browserepositories',
'constrain',
- 'createimage',
+ 'saveimage',
+ 'imageproperties',
'customstyle',
'enterurl',
'enteralt',
diff --git a/lib/editor/atto/plugins/image/styles.css b/lib/editor/atto/plugins/image/styles.css
index 61d4776234a..3d9ee6a722e 100644
--- a/lib/editor/atto/plugins/image/styles.css
+++ b/lib/editor/atto/plugins/image/styles.css
@@ -1,6 +1,9 @@
.atto_image_preview {
max-width: 150px;
max-height: 150px;
+}
+.atto_image_preview_box {
+ height: 150px;
margin-bottom: 1em;
}
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 9b50f961b7a..47e45b007bf 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
@@ -34,6 +34,7 @@ YUI.add('moodle-atto_image-button', function (Y, NAME) {
*/
var CSS = {
+ RESPONSIVE: 'img-responsive',
INPUTALIGNMENT: 'atto_image_alignment',
INPUTALT: 'atto_image_altentry',
INPUTHEIGHT: 'atto_image_heightentry',
@@ -46,7 +47,8 @@ var CSS = {
IMAGEPRESENTATION: 'atto_image_presentation',
INPUTCONSTRAIN: 'atto_image_constrain',
INPUTCUSTOMSTYLE: 'atto_image_customstyle',
- IMAGEPREVIEW: 'atto_image_preview'
+ IMAGEPREVIEW: 'atto_image_preview',
+ IMAGEPREVIEWBOX: 'atto_image_preview_box'
},
ALIGNMENTS = [
// Vertical alignment.
@@ -84,9 +86,13 @@ var CSS = {
str: 'customstyle',
value: 'style'
}
- ];
+ ],
-var COMPONENTNAME = 'atto_image',
+ REGEX = {
+ ISPERCENT: /\d+%/
+ },
+
+ COMPONENTNAME = 'atto_image',
TEMPLATE = '' +
'
',
@@ -154,6 +162,7 @@ var COMPONENTNAME = 'atto_image',
'{{#if height}}height="{{height}}" {{/if}}' +
'{{#if presentation}}role="presentation" {{/if}}' +
'style="{{alignment}}{{margin}}{{customstyle}}"' +
+ '{{#if classlist}}class="{{classlist}}" {{/if}}' +
'/>';
Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
@@ -242,7 +251,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
var dialogue = this.getDialogue({
- headerContent: M.util.get_string('createimage', COMPONENTNAME),
+ headerContent: M.util.get_string('imageproperties', COMPONENTNAME),
width: '480px',
focusAfterHide: true
});
@@ -273,28 +282,33 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentwidth = input.get('value');
if (currentwidth === '') {
input.set('value', this.width);
- currentwidth = this.width;
+ currentwidth = "" + this.width;
}
input = self._form.one('.' + CSS.INPUTHEIGHT);
currentheight = input.get('value');
if (currentheight === '') {
input.set('value', this.height);
- currentheight = this.height;
+ currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
input.set('src', this.src);
input.setStyle('display', 'inline');
- if (this.width === 0) {
- this.width = 1;
- }
- if (this.height === 0) {
- this.height = 1;
- }
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
- widthRatio = Math.round(parseInt(currentwidth, 10) / this.width);
- heightRatio = Math.round(parseInt(currentheight, 10) / this.height);
- input.set('checked', widthRatio === heightRatio);
+ if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
+ input.set('checked', currentwidth === currentheight);
+ } else {
+ if (this.width === 0) {
+ this.width = 1;
+ }
+ if (this.height === 0) {
+ this.height = 1;
+ }
+ // This is the same as comparing to 3 decimal places.
+ widthRatio = Math.round(1000*parseInt(currentwidth, 10) / this.width);
+ heightRatio = Math.round(1000*parseInt(currentheight, 10) / this.height);
+ input.set('checked', widthRatio === heightRatio);
+ }
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
@@ -332,6 +346,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
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.INPUTCONSTRAIN).on('change', function(event) {
+ if (event.target.get('checked')) {
+ this._autoAdjustHeight();
+ }
+ }, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);
@@ -353,19 +372,36 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_autoAdjustHeight: function() {
var currentWidth, newHeight, currentHeight;
+ // 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 (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
+ 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;
}
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
+ 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);
+
+ 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);
+ }
+ }
},
/**
@@ -377,19 +413,35 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_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 = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
+ 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 = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
- newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
+ 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);
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
+ 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);
+ }
+ }
},
/**
@@ -506,13 +558,20 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
style = image.getAttribute('style');
properties.customstyle = style;
style = style.replace(/ /g, '');
- width = parseInt(image.getAttribute('width'), 10);
- height = parseInt(image.getAttribute('height'), 10);
- if (width > 0) {
+ width = image.getAttribute('width');
+ if (!width.match(REGEX.ISPERCENT)) {
+ width = parseInt(width, 10);
+ }
+ height = image.getAttribute('height');
+ if (!height.match(REGEX.ISPERCENT)) {
+ height = parseInt(height, 10);
+ }
+
+ if (width !== 0) {
properties.width = width;
}
- if (height > 0) {
+ if (height !== 0) {
properties.height = height;
}
for (i in ALIGNMENTS) {
@@ -570,9 +629,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
alignment = form.one('.' + CSS.INPUTALIGNMENT).get('value'),
margin = '',
presentation = form.one('.' + CSS.IMAGEPRESENTATION).get('checked'),
+ constrain = form.one('.' + CSS.INPUTCONSTRAIN).get('checked'),
imagehtml,
customstyle = '',
i,
+ classlist = [],
host = this.get('host');
e.preventDefault();
@@ -582,10 +643,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return;
}
- this.getDialogue({
- focusAfterHide: null
- }).hide();
-
// Focus on the editor in preparation for inserting the image.
host.focus();
if (url !== '') {
@@ -607,6 +664,19 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
}
+ if (constrain) {
+ classlist.push(CSS.RESPONSIVE);
+ }
+
+ if (!width.match(REGEX.ISPERCENT) && isNaN(parseInt(width, 10))) {
+ form.one('.' + CSS.INPUTWIDTH).focus();
+ return;
+ }
+ if (!height.match(REGEX.ISPERCENT) && isNaN(parseInt(height, 10))) {
+ form.one('.' + CSS.INPUTHEIGHT).focus();
+ return;
+ }
+
template = Y.Handlebars.compile(IMAGETEMPLATE);
imagehtml = template({
url: url,
@@ -616,13 +686,19 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
presentation: presentation,
alignment: alignment,
margin: margin,
- customstyle: customstyle
+ customstyle: customstyle,
+ classlist: classlist.join(' ')
});
this.get('host').insertContentAtFocusPoint(imagehtml);
this.markUpdated();
}
+
+ this.getDialogue({
+ focusAfterHide: null
+ }).hide();
+
},
/**
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 7650367ab23..632e4e10a76 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,2 +1,3 @@
-YUI.add("moodle-atto_image-button",function(e,t){var n={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"},r=[{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"}],i="atto_image",s='',o='
';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("createimage",i),width:"480px",focusAfterHide:!0});e.set("bodyContent",this._getDialogueContent()).show()},_loadPreviewImage:function(e){var t=new Image,r=this;t.onload=function(){var e,t,i,s,o;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"),this.width===0&&(this.width=1),this.height===0&&(this.height=1),e=r._form.one("."+n.INPUTCONSTRAIN),s=Math.round(parseInt(t,10)/this.width),o=Math.round(parseInt(i,10)/this.height),e.set("checked",s===o),r.getDialogue().centerDialogue()},t.src=e},_getDialogueContent:function(){var t=e.Handlebars.compile(s),o=this.get("host").canShowFilepicker("image"),u=e.Node.create(t({elementid:this.get("host").get("elementid"),CSS:n,component:i,showFilepicker:o,alignments:r}));return this._form=u,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.INPUTURL).on("blur",this._urlChanged,this),this._form.one("."+n.INPUTSUBMIT).on("click",this._setImage,this),o&&this._form.one("."+n.IMAGEBROWSER).on("click",function(){this.get("host").showFilepicker("image",this._filepickerCallback,this)},this),u},_autoAdjustHeight:function(){var e,t,r;if(!this._form.one("."+n.INPUTCONSTRAIN).get("checked"
-)){e=parseInt(this._form.one("."+n.INPUTWIDTH).get("value"),10),r=parseInt(this._form.one("."+n.INPUTHEIGHT).get("value"),10),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",r),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",e);return}e=parseInt(this._form.one("."+n.INPUTWIDTH).get("value"),10),t=Math.round(e/this._imageRawWidth*this._imageRawHeight),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;if(!this._form.one("."+n.INPUTCONSTRAIN).get("checked")){currentWidth=parseInt(this._form.one("."+n.INPUTWIDTH).get("value"),10),e=parseInt(this._form.one("."+n.INPUTHEIGHT).get("value"),10),this._form.one("."+n.IMAGEPREVIEW).setAttribute("height",e),this._form.one("."+n.IMAGEPREVIEW).setAttribute("width",currentWidth);return}e=parseInt(this._form.one("."+n.INPUTHEIGHT).get("value"),10),t=Math.round(e/this._imageRawHeight*this._imageRawWidth),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(),i=e.one("."+n.IMAGEPREVIEW),s;if(t===!1){i.setStyle("display","none");for(s in r)r[s].isDefault===!0&&(css=r[s].value+":"+r[s].name+";",e.one("."+n.INPUTALIGNMENT).set("value",css));e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(r.length-1);return}t.align?(e.one("."+n.INPUTALIGNMENT).set("value",t.align),e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(r.length-1)):e.one("."+n.INPUTALIGNMENT).set("value","style:customstyle;"),t.customstyle&&e.one("."+n.INPUTCUSTOMSTYLE).set("value",t.customstyle),t.display&&i.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,i,s,o,u;t&&(t=t.filter("img"));if(t&&t.size()){image=t.item(0),this._selectedImage=image,o=image.getAttribute("style"),e.customstyle=o,o=o.replace(/ /g,""),i=parseInt(image.getAttribute("width"),10),s=parseInt(image.getAttribute("height"),10),i>0&&(e.width=i),s>0&&(e.height=s);for(n in r){u=r[n].value+":"+r[n].name+";";if(o.indexOf(u)!==-1){margin="margin:"+r[n].margin+";",margin=margin.replace(/ /g,"");if(o.indexOf(margin)!==-1){e.align=u;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 i=this._form,s=i.one("."+n.INPUTURL).get("value"),u=i.one("."+n.INPUTALT).get("value"),a=i.one("."+n.INPUTWIDTH).get("value"),f=i.one("."+n.INPUTHEIGHT).get("value"),l=i.one("."+n.INPUTALIGNMENT).get("value"),c="",h=i.one("."+n.IMAGEPRESENTATION).get("checked"),p,d="",v,m=this.get("host");t.preventDefault();if(this._updateWarning())return;this.getDialogue({focusAfterHide:null}).hide(),m.focus();if(s!==""){this._selectedImage?m.setSelection(m.getSelectionFromNode(this._selectedImage)):m.setSelection(this._currentSelection);if(l==="style:customstyle;")l="",d=i.one("."+n.INPUTCUSTOMSTYLE).get("value");else for(v in r)css=r[v].value+":"+r[v].name+";",l===css&&(c=" margin: "+r[v].margin+";");template=e.Handlebars.compile(o),p=template({url:s,alt:u,width:a,height:f,presentation:h,alignment:l,margin:c,customstyle:d}),this.get("host").insertContentAtFocusPoint(p),this.markUpdated()}},_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=[{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"}],i={ISPERCENT:/\d+%/},s="atto_image",o='',u='
';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",s),width:"480px",focusAfterHide:!0});e.set("bodyContent",this._getDialogueContent()).show()},_loadPreviewImage:function(e){var t=new Image,r=this;t.onload=function(){var e,t,s,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),s=e.get("value"),s===""&&(e.set("value",this.height),s=""+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(i.ISPERCENT)&&s.match(i.ISPERCENT)?e.set("checked",t===s):(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(s,10)/this.height),e.set("checked",o===u)),r.getDialogue().centerDialogue()},t.src=e},_getDialogueContent:function(){var t=e.Handlebars.compile(o),i=this.get("host").canShowFilepicker("image"),u=e.Node.create(t({elementid:this.get("host").get("elementid"),CSS:n,component:s,showFilepicker:i,alignments:r}));return this._form=u,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),i&&this._form.one("."+n.IMAGEBROWSER).on("click",function(){this.get("host").showFilepicker("image",this._filepickerCallback,this)},this),u},_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(i.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(i.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(),i=e.one("."+n.IMAGEPREVIEW),s;if(t===!1){i.setStyle("display","none");for(s in r)r[s].isDefault===!0&&(css=r[s].value+":"+r[s].name+";",e.one("."+n.INPUTALIGNMENT).set("value",css));e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(r.length-1);return}t.align?(e.one("."+n.INPUTALIGNMENT).set("value",t.align),e.one("."+n.INPUTALIGNMENT).getDOMNode().options.remove(r.length-1)):e.one("."+n.INPUTALIGNMENT).set("value","style:customstyle;"),t.customstyle&&e.one("."+n.INPUTCUSTOMSTYLE).set("value",t.customstyle),t.display&&i.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,s,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,""),s=image.getAttribute("width"),s.match(i.ISPERCENT)||(s=parseInt(s,10)),o=image.getAttribute("height"),o.match(i.ISPERCENT)||(o=parseInt(o,10)),s!==0&&(e.width=s),o!==0&&(e.height=o);for(n in r){a=r[n].value+":"+r[n].name+";";if(u.indexOf(a)!==-1){margin="margin:"+r[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 s=this._form,o=s.one("."+n.INPUTURL).get("value"),a=s.one("."+n.INPUTALT).get("value"),f=s.one("."+n.INPUTWIDTH).get("value"),l=s.one("."+n.INPUTHEIGHT).get("value"),c=s.one("."+n.INPUTALIGNMENT).get("value"),h="",p=s.one("."+n.IMAGEPRESENTATION).get("checked"),d=s.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=s.one("."+n.INPUTCUSTOMSTYLE).get("value");else for(g in r)css=r[g].value+":"+r[g].name+";",c===css&&(h=" margin: "+r[g].margin+";");d&&y.push(n.RESPONSIVE);if(!f.match(i.ISPERCENT)&&isNaN(parseInt(f,10))){s.one("."+n.INPUTWIDTH).focus();return}if(!l.match(i.ISPERCENT)&&isNaN(parseInt(l,10))){s.one("."+n.INPUTHEIGHT).focus();return}template=e.Handlebars.compile(u),v=template({url:o,alt:a,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 9b50f961b7a..47e45b007bf 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
@@ -34,6 +34,7 @@ YUI.add('moodle-atto_image-button', function (Y, NAME) {
*/
var CSS = {
+ RESPONSIVE: 'img-responsive',
INPUTALIGNMENT: 'atto_image_alignment',
INPUTALT: 'atto_image_altentry',
INPUTHEIGHT: 'atto_image_heightentry',
@@ -46,7 +47,8 @@ var CSS = {
IMAGEPRESENTATION: 'atto_image_presentation',
INPUTCONSTRAIN: 'atto_image_constrain',
INPUTCUSTOMSTYLE: 'atto_image_customstyle',
- IMAGEPREVIEW: 'atto_image_preview'
+ IMAGEPREVIEW: 'atto_image_preview',
+ IMAGEPREVIEWBOX: 'atto_image_preview_box'
},
ALIGNMENTS = [
// Vertical alignment.
@@ -84,9 +86,13 @@ var CSS = {
str: 'customstyle',
value: 'style'
}
- ];
+ ],
-var COMPONENTNAME = 'atto_image',
+ REGEX = {
+ ISPERCENT: /\d+%/
+ },
+
+ COMPONENTNAME = 'atto_image',
TEMPLATE = '' +
'',
@@ -154,6 +162,7 @@ var COMPONENTNAME = 'atto_image',
'{{#if height}}height="{{height}}" {{/if}}' +
'{{#if presentation}}role="presentation" {{/if}}' +
'style="{{alignment}}{{margin}}{{customstyle}}"' +
+ '{{#if classlist}}class="{{classlist}}" {{/if}}' +
'/>';
Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
@@ -242,7 +251,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
var dialogue = this.getDialogue({
- headerContent: M.util.get_string('createimage', COMPONENTNAME),
+ headerContent: M.util.get_string('imageproperties', COMPONENTNAME),
width: '480px',
focusAfterHide: true
});
@@ -273,28 +282,33 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentwidth = input.get('value');
if (currentwidth === '') {
input.set('value', this.width);
- currentwidth = this.width;
+ currentwidth = "" + this.width;
}
input = self._form.one('.' + CSS.INPUTHEIGHT);
currentheight = input.get('value');
if (currentheight === '') {
input.set('value', this.height);
- currentheight = this.height;
+ currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
input.set('src', this.src);
input.setStyle('display', 'inline');
- if (this.width === 0) {
- this.width = 1;
- }
- if (this.height === 0) {
- this.height = 1;
- }
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
- widthRatio = Math.round(parseInt(currentwidth, 10) / this.width);
- heightRatio = Math.round(parseInt(currentheight, 10) / this.height);
- input.set('checked', widthRatio === heightRatio);
+ if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
+ input.set('checked', currentwidth === currentheight);
+ } else {
+ if (this.width === 0) {
+ this.width = 1;
+ }
+ if (this.height === 0) {
+ this.height = 1;
+ }
+ // This is the same as comparing to 3 decimal places.
+ widthRatio = Math.round(1000*parseInt(currentwidth, 10) / this.width);
+ heightRatio = Math.round(1000*parseInt(currentheight, 10) / this.height);
+ input.set('checked', widthRatio === heightRatio);
+ }
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
@@ -332,6 +346,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
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.INPUTCONSTRAIN).on('change', function(event) {
+ if (event.target.get('checked')) {
+ this._autoAdjustHeight();
+ }
+ }, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);
@@ -353,19 +372,36 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_autoAdjustHeight: function() {
var currentWidth, newHeight, currentHeight;
+ // 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 (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
+ 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;
}
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
+ 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);
+
+ 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);
+ }
+ }
},
/**
@@ -377,19 +413,35 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_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 = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
+ 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 = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
- newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
+ 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);
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
+ 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);
+ }
+ }
},
/**
@@ -506,13 +558,20 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
style = image.getAttribute('style');
properties.customstyle = style;
style = style.replace(/ /g, '');
- width = parseInt(image.getAttribute('width'), 10);
- height = parseInt(image.getAttribute('height'), 10);
- if (width > 0) {
+ width = image.getAttribute('width');
+ if (!width.match(REGEX.ISPERCENT)) {
+ width = parseInt(width, 10);
+ }
+ height = image.getAttribute('height');
+ if (!height.match(REGEX.ISPERCENT)) {
+ height = parseInt(height, 10);
+ }
+
+ if (width !== 0) {
properties.width = width;
}
- if (height > 0) {
+ if (height !== 0) {
properties.height = height;
}
for (i in ALIGNMENTS) {
@@ -570,9 +629,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
alignment = form.one('.' + CSS.INPUTALIGNMENT).get('value'),
margin = '',
presentation = form.one('.' + CSS.IMAGEPRESENTATION).get('checked'),
+ constrain = form.one('.' + CSS.INPUTCONSTRAIN).get('checked'),
imagehtml,
customstyle = '',
i,
+ classlist = [],
host = this.get('host');
e.preventDefault();
@@ -582,10 +643,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return;
}
- this.getDialogue({
- focusAfterHide: null
- }).hide();
-
// Focus on the editor in preparation for inserting the image.
host.focus();
if (url !== '') {
@@ -607,6 +664,19 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
}
+ if (constrain) {
+ classlist.push(CSS.RESPONSIVE);
+ }
+
+ if (!width.match(REGEX.ISPERCENT) && isNaN(parseInt(width, 10))) {
+ form.one('.' + CSS.INPUTWIDTH).focus();
+ return;
+ }
+ if (!height.match(REGEX.ISPERCENT) && isNaN(parseInt(height, 10))) {
+ form.one('.' + CSS.INPUTHEIGHT).focus();
+ return;
+ }
+
template = Y.Handlebars.compile(IMAGETEMPLATE);
imagehtml = template({
url: url,
@@ -616,13 +686,19 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
presentation: presentation,
alignment: alignment,
margin: margin,
- customstyle: customstyle
+ customstyle: customstyle,
+ classlist: classlist.join(' ')
});
this.get('host').insertContentAtFocusPoint(imagehtml);
this.markUpdated();
}
+
+ this.getDialogue({
+ focusAfterHide: null
+ }).hide();
+
},
/**
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 bec3b9d3c15..333dc5770a3 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
@@ -32,6 +32,7 @@
*/
var CSS = {
+ RESPONSIVE: 'img-responsive',
INPUTALIGNMENT: 'atto_image_alignment',
INPUTALT: 'atto_image_altentry',
INPUTHEIGHT: 'atto_image_heightentry',
@@ -44,7 +45,8 @@ var CSS = {
IMAGEPRESENTATION: 'atto_image_presentation',
INPUTCONSTRAIN: 'atto_image_constrain',
INPUTCUSTOMSTYLE: 'atto_image_customstyle',
- IMAGEPREVIEW: 'atto_image_preview'
+ IMAGEPREVIEW: 'atto_image_preview',
+ IMAGEPREVIEWBOX: 'atto_image_preview_box'
},
ALIGNMENTS = [
// Vertical alignment.
@@ -82,9 +84,13 @@ var CSS = {
str: 'customstyle',
value: 'style'
}
- ];
+ ],
-var COMPONENTNAME = 'atto_image',
+ REGEX = {
+ ISPERCENT: /\d+%/
+ },
+
+ COMPONENTNAME = 'atto_image',
TEMPLATE = '' +
'',
@@ -152,6 +160,7 @@ var COMPONENTNAME = 'atto_image',
'{{#if height}}height="{{height}}" {{/if}}' +
'{{#if presentation}}role="presentation" {{/if}}' +
'style="{{alignment}}{{margin}}{{customstyle}}"' +
+ '{{#if classlist}}class="{{classlist}}" {{/if}}' +
'/>';
Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
@@ -240,7 +249,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
var dialogue = this.getDialogue({
- headerContent: M.util.get_string('createimage', COMPONENTNAME),
+ headerContent: M.util.get_string('imageproperties', COMPONENTNAME),
width: '480px',
focusAfterHide: true
});
@@ -271,28 +280,33 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentwidth = input.get('value');
if (currentwidth === '') {
input.set('value', this.width);
- currentwidth = this.width;
+ currentwidth = "" + this.width;
}
input = self._form.one('.' + CSS.INPUTHEIGHT);
currentheight = input.get('value');
if (currentheight === '') {
input.set('value', this.height);
- currentheight = this.height;
+ currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
input.set('src', this.src);
input.setStyle('display', 'inline');
- if (this.width === 0) {
- this.width = 1;
- }
- if (this.height === 0) {
- this.height = 1;
- }
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
- widthRatio = Math.round(parseInt(currentwidth, 10) / this.width);
- heightRatio = Math.round(parseInt(currentheight, 10) / this.height);
- input.set('checked', widthRatio === heightRatio);
+ if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
+ input.set('checked', currentwidth === currentheight);
+ } else {
+ if (this.width === 0) {
+ this.width = 1;
+ }
+ if (this.height === 0) {
+ this.height = 1;
+ }
+ // This is the same as comparing to 3 decimal places.
+ widthRatio = Math.round(1000*parseInt(currentwidth, 10) / this.width);
+ heightRatio = Math.round(1000*parseInt(currentheight, 10) / this.height);
+ input.set('checked', widthRatio === heightRatio);
+ }
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
@@ -330,6 +344,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
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.INPUTCONSTRAIN).on('change', function(event) {
+ if (event.target.get('checked')) {
+ this._autoAdjustHeight();
+ }
+ }, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);
@@ -351,19 +370,36 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_autoAdjustHeight: function() {
var currentWidth, newHeight, currentHeight;
+ // 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 (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
+ 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;
}
- currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
- this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
+ 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);
+
+ 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);
+ }
+ }
},
/**
@@ -375,19 +411,35 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_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 = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
- currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
+ 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 = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
- newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
+ 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);
- this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
- this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
+ 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);
+ }
+ }
},
/**
@@ -504,13 +556,20 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
style = image.getAttribute('style');
properties.customstyle = style;
style = style.replace(/ /g, '');
- width = parseInt(image.getAttribute('width'), 10);
- height = parseInt(image.getAttribute('height'), 10);
- if (width > 0) {
+ width = image.getAttribute('width');
+ if (!width.match(REGEX.ISPERCENT)) {
+ width = parseInt(width, 10);
+ }
+ height = image.getAttribute('height');
+ if (!height.match(REGEX.ISPERCENT)) {
+ height = parseInt(height, 10);
+ }
+
+ if (width !== 0) {
properties.width = width;
}
- if (height > 0) {
+ if (height !== 0) {
properties.height = height;
}
for (i in ALIGNMENTS) {
@@ -568,9 +627,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
alignment = form.one('.' + CSS.INPUTALIGNMENT).get('value'),
margin = '',
presentation = form.one('.' + CSS.IMAGEPRESENTATION).get('checked'),
+ constrain = form.one('.' + CSS.INPUTCONSTRAIN).get('checked'),
imagehtml,
customstyle = '',
i,
+ classlist = [],
host = this.get('host');
e.preventDefault();
@@ -580,10 +641,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return;
}
- this.getDialogue({
- focusAfterHide: null
- }).hide();
-
// Focus on the editor in preparation for inserting the image.
host.focus();
if (url !== '') {
@@ -605,6 +662,19 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
}
}
+ if (constrain) {
+ classlist.push(CSS.RESPONSIVE);
+ }
+
+ if (!width.match(REGEX.ISPERCENT) && isNaN(parseInt(width, 10))) {
+ form.one('.' + CSS.INPUTWIDTH).focus();
+ return;
+ }
+ if (!height.match(REGEX.ISPERCENT) && isNaN(parseInt(height, 10))) {
+ form.one('.' + CSS.INPUTHEIGHT).focus();
+ return;
+ }
+
template = Y.Handlebars.compile(IMAGETEMPLATE);
imagehtml = template({
url: url,
@@ -614,13 +684,19 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
presentation: presentation,
alignment: alignment,
margin: margin,
- customstyle: customstyle
+ customstyle: customstyle,
+ classlist: classlist.join(' ')
});
this.get('host').insertContentAtFocusPoint(imagehtml);
this.markUpdated();
}
+
+ this.getDialogue({
+ focusAfterHide: null
+ }).hide();
+
},
/**