MDL-44000 Atto: Add option to constrain image size
(Keep aspect ratio) Also some small improvements to the edit image dialogue.
This commit is contained in:
@@ -34,6 +34,7 @@ $string['alignment_textbottom'] = 'Text bottom';
|
||||
$string['alignment_texttop'] = 'Text top';
|
||||
$string['alignment_top'] = 'Top';
|
||||
$string['browserepositories'] = 'Browse repositories...';
|
||||
$string['constrain'] = 'Keep ratio';
|
||||
$string['createimage'] = 'Insert image';
|
||||
$string['enteralt'] = 'Describe this image for someone who cannot see it';
|
||||
$string['enterurl'] = 'Enter URL';
|
||||
|
||||
@@ -43,6 +43,7 @@ function atto_image_strings_for_js() {
|
||||
'alignment_texttop',
|
||||
'alignment_top',
|
||||
'browserepositories',
|
||||
'constrain',
|
||||
'createimage',
|
||||
'enterurl',
|
||||
'enteralt',
|
||||
|
||||
@@ -2,3 +2,17 @@
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
}
|
||||
|
||||
.atto_image_size {
|
||||
display: inline-block;
|
||||
}
|
||||
.atto_image_size input[type=checkbox] {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.atto_image_size input[type=text] {
|
||||
width: 3em;
|
||||
}
|
||||
.atto_image_size label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
Vendored
+143
-43
@@ -39,10 +39,12 @@ var CSS = {
|
||||
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',
|
||||
IMAGEPREVIEW: 'atto_image_preview'
|
||||
},
|
||||
ALIGNMENTS = [
|
||||
@@ -119,15 +121,20 @@ var COMPONENTNAME = 'atto_image',
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.IMAGEPRESENTATION}}">{{get_string "presentation" component}}</label>' +
|
||||
'<br/>' +
|
||||
|
||||
// Add the width entry box.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTWIDTH}}">{{get_string "width" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTWIDTH}} id="{{elementid}}_{{CSS.INPUTWIDTH}}" size="10"/>' +
|
||||
'<br/>' +
|
||||
// Add the size entry boxes.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTSIZE}}">Size</label>' +
|
||||
'<div id="{{elementid}}_{{CSS.INPUTSIZE}}" class="{{CSS.INPUTSIZE}}">' +
|
||||
'<label class="accesshide" for="{{elementid}}_{{CSS.INPUTWIDTH}}">{{get_string "width" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTWIDTH}} input-mini" id="{{elementid}}_{{CSS.INPUTWIDTH}}" size="4"/> x ' +
|
||||
|
||||
// Add the height entry box.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTHEIGHT}}">{{get_string "height" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTHEIGHT}}" id="{{elementid}}_{{CSS.INPUTHEIGHT}}" size="10"/>' +
|
||||
'<br/>' +
|
||||
'<label class="accesshide" for="{{elementid}}_{{CSS.INPUTHEIGHT}}">{{get_string "height" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTHEIGHT}} input-mini" id="{{elementid}}_{{CSS.INPUTHEIGHT}}" size="4"/>' +
|
||||
|
||||
// Add the constrain checkbox.
|
||||
'<input type="checkbox" class="{{CSS.INPUTCONSTRAIN}} sameline" id="{{elementid}}_{{CSS.INPUTCONSTRAIN}}"/>' +
|
||||
'<label for="{{elementid}}_{{CSS.INPUTCONSTRAIN}}">{{get_string "constrain" component}}</label>' +
|
||||
'</div>' +
|
||||
|
||||
// Add the alignment selector.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTALIGNMENT}}">{{get_string "alignment" component}}</label>' +
|
||||
@@ -186,6 +193,24 @@ 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.
|
||||
*
|
||||
* @param _imageRawWidth
|
||||
* @type Integer
|
||||
* @private
|
||||
*/
|
||||
_imageRawWidth: 0,
|
||||
|
||||
/**
|
||||
* Remember the image true dimensions so we can constrain resizing.
|
||||
*
|
||||
* @param _imageRawHeight
|
||||
* @type Integer
|
||||
* @private
|
||||
*/
|
||||
_imageRawHeight: 0,
|
||||
|
||||
initializer: function() {
|
||||
this.addButton({
|
||||
icon: 'e/insert_edit_image',
|
||||
@@ -219,6 +244,57 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
.show();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the inputs for width and height if they are not set, and calculate
|
||||
* if the constrain checkbox should be checked or not.
|
||||
*
|
||||
* @method _loadPreviewImage
|
||||
* @param {String} url
|
||||
* @private
|
||||
*/
|
||||
_loadPreviewImage: function(url) {
|
||||
var image = new Image(), self = this;
|
||||
|
||||
image.onload = function() {
|
||||
var input, currentwidth, currentheight, widthRatio, heightRatio;
|
||||
|
||||
self._imageRawWidth = this.width;
|
||||
self._imageRawHeight = this.height;
|
||||
|
||||
input = self._form.one('.' + CSS.INPUTWIDTH);
|
||||
currentwidth = input.get('value');
|
||||
if (currentwidth === '') {
|
||||
input.set('value', 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;
|
||||
}
|
||||
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);
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
|
||||
image.src = url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the dialogue content for the tool, attaching any required
|
||||
* events.
|
||||
@@ -243,6 +319,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
// Configure the view of the current image.
|
||||
this._applyImageProperties(this._form);
|
||||
|
||||
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, 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.INPUTURL).on('blur', this._urlChanged, this);
|
||||
this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);
|
||||
|
||||
@@ -255,6 +334,54 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust the width to keep the aspect ratio.
|
||||
*
|
||||
* @method _autoAdjustWidth
|
||||
* @private
|
||||
*/
|
||||
_autoAdjustWidth: function() {
|
||||
var currentHeight, newWidth;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
|
||||
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
|
||||
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the dialogue after an image was selected in the File Picker.
|
||||
*
|
||||
@@ -265,22 +392,15 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
*/
|
||||
_filepickerCallback: function(params) {
|
||||
if (params.url !== '') {
|
||||
var input = this._form.one('.' + CSS.INPUTURL),
|
||||
self = this;
|
||||
var input = this._form.one('.' + CSS.INPUTURL);
|
||||
input.set('value', params.url);
|
||||
|
||||
// Auto set the width and height.
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
self._form.one('.' + CSS.INPUTWIDTH).set('value', this.width);
|
||||
self._form.one('.' + CSS.INPUTHEIGHT).set('value', this.height);
|
||||
self._form.one('.' + CSS.IMAGEPREVIEW).set('src', this.src);
|
||||
self._form.one('.' + CSS.IMAGEPREVIEW).setStyle('display', 'inline');
|
||||
self._form.one('.' + CSS.INPUTWIDTH).set('value', '');
|
||||
self._form.one('.' + CSS.INPUTHEIGHT).set('value', '');
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
image.src = params.url;
|
||||
// Load the preview image.
|
||||
this._loadPreviewImage(params.url);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -317,7 +437,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
}
|
||||
if (properties.src) {
|
||||
form.one('.' + CSS.INPUTURL).set('value', properties.src);
|
||||
img.setAttribute('src', properties.src);
|
||||
this._loadPreviewImage(properties.src);
|
||||
}
|
||||
if (properties.presentation) {
|
||||
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
|
||||
@@ -392,31 +512,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
* @private
|
||||
*/
|
||||
_urlChanged: function() {
|
||||
var input = this._form.one('.' + CSS.INPUTURL),
|
||||
self = this;
|
||||
var input = this._form.one('.' + CSS.INPUTURL);
|
||||
|
||||
if (input.get('value') !== '') {
|
||||
// Auto set the width and height.
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
var input;
|
||||
|
||||
input = self._form.one('.' + CSS.INPUTWIDTH);
|
||||
if (input.get('value') === '') {
|
||||
input.set('value', this.width);
|
||||
}
|
||||
input = self._form.one('.' + CSS.INPUTHEIGHT);
|
||||
if (input.get('value') === '') {
|
||||
input.set('value', this.height);
|
||||
}
|
||||
input = self._form.one('.' + CSS.IMAGEPREVIEW);
|
||||
input.set('src', this.src);
|
||||
input.setStyle('display', 'inline');
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
image.src = input.get('value');
|
||||
// Load the preview image.
|
||||
this._loadPreviewImage(input.get('value'));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+143
-43
@@ -39,10 +39,12 @@ var CSS = {
|
||||
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',
|
||||
IMAGEPREVIEW: 'atto_image_preview'
|
||||
},
|
||||
ALIGNMENTS = [
|
||||
@@ -119,15 +121,20 @@ var COMPONENTNAME = 'atto_image',
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.IMAGEPRESENTATION}}">{{get_string "presentation" component}}</label>' +
|
||||
'<br/>' +
|
||||
|
||||
// Add the width entry box.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTWIDTH}}">{{get_string "width" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTWIDTH}} id="{{elementid}}_{{CSS.INPUTWIDTH}}" size="10"/>' +
|
||||
'<br/>' +
|
||||
// Add the size entry boxes.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTSIZE}}">Size</label>' +
|
||||
'<div id="{{elementid}}_{{CSS.INPUTSIZE}}" class="{{CSS.INPUTSIZE}}">' +
|
||||
'<label class="accesshide" for="{{elementid}}_{{CSS.INPUTWIDTH}}">{{get_string "width" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTWIDTH}} input-mini" id="{{elementid}}_{{CSS.INPUTWIDTH}}" size="4"/> x ' +
|
||||
|
||||
// Add the height entry box.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTHEIGHT}}">{{get_string "height" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTHEIGHT}}" id="{{elementid}}_{{CSS.INPUTHEIGHT}}" size="10"/>' +
|
||||
'<br/>' +
|
||||
'<label class="accesshide" for="{{elementid}}_{{CSS.INPUTHEIGHT}}">{{get_string "height" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTHEIGHT}} input-mini" id="{{elementid}}_{{CSS.INPUTHEIGHT}}" size="4"/>' +
|
||||
|
||||
// Add the constrain checkbox.
|
||||
'<input type="checkbox" class="{{CSS.INPUTCONSTRAIN}} sameline" id="{{elementid}}_{{CSS.INPUTCONSTRAIN}}"/>' +
|
||||
'<label for="{{elementid}}_{{CSS.INPUTCONSTRAIN}}">{{get_string "constrain" component}}</label>' +
|
||||
'</div>' +
|
||||
|
||||
// Add the alignment selector.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTALIGNMENT}}">{{get_string "alignment" component}}</label>' +
|
||||
@@ -186,6 +193,24 @@ 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.
|
||||
*
|
||||
* @param _imageRawWidth
|
||||
* @type Integer
|
||||
* @private
|
||||
*/
|
||||
_imageRawWidth: 0,
|
||||
|
||||
/**
|
||||
* Remember the image true dimensions so we can constrain resizing.
|
||||
*
|
||||
* @param _imageRawHeight
|
||||
* @type Integer
|
||||
* @private
|
||||
*/
|
||||
_imageRawHeight: 0,
|
||||
|
||||
initializer: function() {
|
||||
this.addButton({
|
||||
icon: 'e/insert_edit_image',
|
||||
@@ -219,6 +244,57 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
.show();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the inputs for width and height if they are not set, and calculate
|
||||
* if the constrain checkbox should be checked or not.
|
||||
*
|
||||
* @method _loadPreviewImage
|
||||
* @param {String} url
|
||||
* @private
|
||||
*/
|
||||
_loadPreviewImage: function(url) {
|
||||
var image = new Image(), self = this;
|
||||
|
||||
image.onload = function() {
|
||||
var input, currentwidth, currentheight, widthRatio, heightRatio;
|
||||
|
||||
self._imageRawWidth = this.width;
|
||||
self._imageRawHeight = this.height;
|
||||
|
||||
input = self._form.one('.' + CSS.INPUTWIDTH);
|
||||
currentwidth = input.get('value');
|
||||
if (currentwidth === '') {
|
||||
input.set('value', 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;
|
||||
}
|
||||
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);
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
|
||||
image.src = url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the dialogue content for the tool, attaching any required
|
||||
* events.
|
||||
@@ -243,6 +319,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
// Configure the view of the current image.
|
||||
this._applyImageProperties(this._form);
|
||||
|
||||
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, 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.INPUTURL).on('blur', this._urlChanged, this);
|
||||
this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);
|
||||
|
||||
@@ -255,6 +334,54 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust the width to keep the aspect ratio.
|
||||
*
|
||||
* @method _autoAdjustWidth
|
||||
* @private
|
||||
*/
|
||||
_autoAdjustWidth: function() {
|
||||
var currentHeight, newWidth;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
|
||||
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
|
||||
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the dialogue after an image was selected in the File Picker.
|
||||
*
|
||||
@@ -265,22 +392,15 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
*/
|
||||
_filepickerCallback: function(params) {
|
||||
if (params.url !== '') {
|
||||
var input = this._form.one('.' + CSS.INPUTURL),
|
||||
self = this;
|
||||
var input = this._form.one('.' + CSS.INPUTURL);
|
||||
input.set('value', params.url);
|
||||
|
||||
// Auto set the width and height.
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
self._form.one('.' + CSS.INPUTWIDTH).set('value', this.width);
|
||||
self._form.one('.' + CSS.INPUTHEIGHT).set('value', this.height);
|
||||
self._form.one('.' + CSS.IMAGEPREVIEW).set('src', this.src);
|
||||
self._form.one('.' + CSS.IMAGEPREVIEW).setStyle('display', 'inline');
|
||||
self._form.one('.' + CSS.INPUTWIDTH).set('value', '');
|
||||
self._form.one('.' + CSS.INPUTHEIGHT).set('value', '');
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
image.src = params.url;
|
||||
// Load the preview image.
|
||||
this._loadPreviewImage(params.url);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -317,7 +437,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
}
|
||||
if (properties.src) {
|
||||
form.one('.' + CSS.INPUTURL).set('value', properties.src);
|
||||
img.setAttribute('src', properties.src);
|
||||
this._loadPreviewImage(properties.src);
|
||||
}
|
||||
if (properties.presentation) {
|
||||
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
|
||||
@@ -392,31 +512,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
* @private
|
||||
*/
|
||||
_urlChanged: function() {
|
||||
var input = this._form.one('.' + CSS.INPUTURL),
|
||||
self = this;
|
||||
var input = this._form.one('.' + CSS.INPUTURL);
|
||||
|
||||
if (input.get('value') !== '') {
|
||||
// Auto set the width and height.
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
var input;
|
||||
|
||||
input = self._form.one('.' + CSS.INPUTWIDTH);
|
||||
if (input.get('value') === '') {
|
||||
input.set('value', this.width);
|
||||
}
|
||||
input = self._form.one('.' + CSS.INPUTHEIGHT);
|
||||
if (input.get('value') === '') {
|
||||
input.set('value', this.height);
|
||||
}
|
||||
input = self._form.one('.' + CSS.IMAGEPREVIEW);
|
||||
input.set('src', this.src);
|
||||
input.setStyle('display', 'inline');
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
image.src = input.get('value');
|
||||
// Load the preview image.
|
||||
this._loadPreviewImage(input.get('value'));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+143
-43
@@ -37,10 +37,12 @@ var CSS = {
|
||||
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',
|
||||
IMAGEPREVIEW: 'atto_image_preview'
|
||||
},
|
||||
ALIGNMENTS = [
|
||||
@@ -117,15 +119,20 @@ var COMPONENTNAME = 'atto_image',
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.IMAGEPRESENTATION}}">{{get_string "presentation" component}}</label>' +
|
||||
'<br/>' +
|
||||
|
||||
// Add the width entry box.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTWIDTH}}">{{get_string "width" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTWIDTH}} id="{{elementid}}_{{CSS.INPUTWIDTH}}" size="10"/>' +
|
||||
'<br/>' +
|
||||
// Add the size entry boxes.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTSIZE}}">Size</label>' +
|
||||
'<div id="{{elementid}}_{{CSS.INPUTSIZE}}" class="{{CSS.INPUTSIZE}}">' +
|
||||
'<label class="accesshide" for="{{elementid}}_{{CSS.INPUTWIDTH}}">{{get_string "width" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTWIDTH}} input-mini" id="{{elementid}}_{{CSS.INPUTWIDTH}}" size="4"/> x ' +
|
||||
|
||||
// Add the height entry box.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTHEIGHT}}">{{get_string "height" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTHEIGHT}}" id="{{elementid}}_{{CSS.INPUTHEIGHT}}" size="10"/>' +
|
||||
'<br/>' +
|
||||
'<label class="accesshide" for="{{elementid}}_{{CSS.INPUTHEIGHT}}">{{get_string "height" component}}</label>' +
|
||||
'<input type="text" class="{{CSS.INPUTHEIGHT}} input-mini" id="{{elementid}}_{{CSS.INPUTHEIGHT}}" size="4"/>' +
|
||||
|
||||
// Add the constrain checkbox.
|
||||
'<input type="checkbox" class="{{CSS.INPUTCONSTRAIN}} sameline" id="{{elementid}}_{{CSS.INPUTCONSTRAIN}}"/>' +
|
||||
'<label for="{{elementid}}_{{CSS.INPUTCONSTRAIN}}">{{get_string "constrain" component}}</label>' +
|
||||
'</div>' +
|
||||
|
||||
// Add the alignment selector.
|
||||
'<label class="sameline" for="{{elementid}}_{{CSS.INPUTALIGNMENT}}">{{get_string "alignment" component}}</label>' +
|
||||
@@ -184,6 +191,24 @@ 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.
|
||||
*
|
||||
* @param _imageRawWidth
|
||||
* @type Integer
|
||||
* @private
|
||||
*/
|
||||
_imageRawWidth: 0,
|
||||
|
||||
/**
|
||||
* Remember the image true dimensions so we can constrain resizing.
|
||||
*
|
||||
* @param _imageRawHeight
|
||||
* @type Integer
|
||||
* @private
|
||||
*/
|
||||
_imageRawHeight: 0,
|
||||
|
||||
initializer: function() {
|
||||
this.addButton({
|
||||
icon: 'e/insert_edit_image',
|
||||
@@ -217,6 +242,57 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
.show();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the inputs for width and height if they are not set, and calculate
|
||||
* if the constrain checkbox should be checked or not.
|
||||
*
|
||||
* @method _loadPreviewImage
|
||||
* @param {String} url
|
||||
* @private
|
||||
*/
|
||||
_loadPreviewImage: function(url) {
|
||||
var image = new Image(), self = this;
|
||||
|
||||
image.onload = function() {
|
||||
var input, currentwidth, currentheight, widthRatio, heightRatio;
|
||||
|
||||
self._imageRawWidth = this.width;
|
||||
self._imageRawHeight = this.height;
|
||||
|
||||
input = self._form.one('.' + CSS.INPUTWIDTH);
|
||||
currentwidth = input.get('value');
|
||||
if (currentwidth === '') {
|
||||
input.set('value', 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;
|
||||
}
|
||||
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);
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
|
||||
image.src = url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the dialogue content for the tool, attaching any required
|
||||
* events.
|
||||
@@ -241,6 +317,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
// Configure the view of the current image.
|
||||
this._applyImageProperties(this._form);
|
||||
|
||||
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, 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.INPUTURL).on('blur', this._urlChanged, this);
|
||||
this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._setImage, this);
|
||||
|
||||
@@ -253,6 +332,54 @@ 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust the width to keep the aspect ratio.
|
||||
*
|
||||
* @method _autoAdjustWidth
|
||||
* @private
|
||||
*/
|
||||
_autoAdjustWidth: function() {
|
||||
var currentHeight, newWidth;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
|
||||
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
|
||||
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the dialogue after an image was selected in the File Picker.
|
||||
*
|
||||
@@ -263,22 +390,15 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
*/
|
||||
_filepickerCallback: function(params) {
|
||||
if (params.url !== '') {
|
||||
var input = this._form.one('.' + CSS.INPUTURL),
|
||||
self = this;
|
||||
var input = this._form.one('.' + CSS.INPUTURL);
|
||||
input.set('value', params.url);
|
||||
|
||||
// Auto set the width and height.
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
self._form.one('.' + CSS.INPUTWIDTH).set('value', this.width);
|
||||
self._form.one('.' + CSS.INPUTHEIGHT).set('value', this.height);
|
||||
self._form.one('.' + CSS.IMAGEPREVIEW).set('src', this.src);
|
||||
self._form.one('.' + CSS.IMAGEPREVIEW).setStyle('display', 'inline');
|
||||
self._form.one('.' + CSS.INPUTWIDTH).set('value', '');
|
||||
self._form.one('.' + CSS.INPUTHEIGHT).set('value', '');
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
image.src = params.url;
|
||||
// Load the preview image.
|
||||
this._loadPreviewImage(params.url);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -315,7 +435,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
}
|
||||
if (properties.src) {
|
||||
form.one('.' + CSS.INPUTURL).set('value', properties.src);
|
||||
img.setAttribute('src', properties.src);
|
||||
this._loadPreviewImage(properties.src);
|
||||
}
|
||||
if (properties.presentation) {
|
||||
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
|
||||
@@ -390,31 +510,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
* @private
|
||||
*/
|
||||
_urlChanged: function() {
|
||||
var input = this._form.one('.' + CSS.INPUTURL),
|
||||
self = this;
|
||||
var input = this._form.one('.' + CSS.INPUTURL);
|
||||
|
||||
if (input.get('value') !== '') {
|
||||
// Auto set the width and height.
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
var input;
|
||||
|
||||
input = self._form.one('.' + CSS.INPUTWIDTH);
|
||||
if (input.get('value') === '') {
|
||||
input.set('value', this.width);
|
||||
}
|
||||
input = self._form.one('.' + CSS.INPUTHEIGHT);
|
||||
if (input.get('value') === '') {
|
||||
input.set('value', this.height);
|
||||
}
|
||||
input = self._form.one('.' + CSS.IMAGEPREVIEW);
|
||||
input.set('src', this.src);
|
||||
input.setStyle('display', 'inline');
|
||||
|
||||
// Centre the dialogue once the preview image has loaded.
|
||||
self.getDialogue().centerDialogue();
|
||||
};
|
||||
image.src = input.get('value');
|
||||
// Load the preview image.
|
||||
this._loadPreviewImage(input.get('value'));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user