Merge branch 'MDL-45034-master' of git://github.com/damyon/moodle

Conflicts:
	lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js
This commit is contained in:
Sam Hemelryk 2014-04-16 09:23:30 +12:00
commit d668060fdc
7 changed files with 356 additions and 121 deletions

View File

@ -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';

View File

@ -39,7 +39,8 @@ function atto_image_strings_for_js() {
'alignment_top',
'browserepositories',
'constrain',
'createimage',
'saveimage',
'imageproperties',
'customstyle',
'enterurl',
'enteralt',

View File

@ -1,6 +1,9 @@
.atto_image_preview {
max-width: 150px;
max-height: 150px;
}
.atto_image_preview_box {
height: 150px;
margin-bottom: 1em;
}

View File

@ -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 = '' +
'<form class="atto_form">' +
@ -140,11 +146,13 @@ var COMPONENTNAME = 'atto_image',
// Add the image preview.
'<div class="mdl-align">' +
'<div class="{{CSS.IMAGEPREVIEWBOX}}">' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" id="{{elementid}}_{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'</div>' +
'<br/>' +
// Add the submit button and close the form.
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "createimage" component}}</button>' +
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "saveimage" component}}</button>' +
'</div>' +
'</form>',
@ -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();
},
/**

File diff suppressed because one or more lines are too long

View File

@ -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 = '' +
'<form class="atto_form">' +
@ -140,11 +146,13 @@ var COMPONENTNAME = 'atto_image',
// Add the image preview.
'<div class="mdl-align">' +
'<div class="{{CSS.IMAGEPREVIEWBOX}}">' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" id="{{elementid}}_{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'</div>' +
'<br/>' +
// Add the submit button and close the form.
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "createimage" component}}</button>' +
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "saveimage" component}}</button>' +
'</div>' +
'</form>',
@ -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();
},
/**

View File

@ -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 = '' +
'<form class="atto_form">' +
@ -138,11 +144,13 @@ var COMPONENTNAME = 'atto_image',
// Add the image preview.
'<div class="mdl-align">' +
'<div class="{{CSS.IMAGEPREVIEWBOX}}">' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" id="{{elementid}}_{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'</div>' +
'<br/>' +
// Add the submit button and close the form.
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "createimage" component}}</button>' +
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "saveimage" component}}</button>' +
'</div>' +
'</form>',
@ -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();
},
/**