Merge branch 'MDL-45034-master' of git://github.com/damyon/moodle
authorSam Hemelryk <sam@moodle.com>
Tue, 15 Apr 2014 21:23:30 +0000 (09:23 +1200)
committerSam Hemelryk <sam@moodle.com>
Tue, 15 Apr 2014 21:23:30 +0000 (09:23 +1200)
Conflicts:
lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js

lib/editor/atto/plugins/image/lang/en/atto_image.php
lib/editor/atto/plugins/image/lib.php
lib/editor/atto/plugins/image/styles.css
lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js
lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js
lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js
lib/editor/atto/plugins/image/yui/src/button/js/button.js

index 4700309..05c3bc8 100644 (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';
index 220ee24..c6c9ad2 100644 (file)
@@ -39,7 +39,8 @@ function atto_image_strings_for_js() {
         'alignment_top',
         'browserepositories',
         'constrain',
-        'createimage',
+        'saveimage',
+        'imageproperties',
         'customstyle',
         'enterurl',
         'enteralt',
index 61d4776..3d9ee6a 100644 (file)
@@ -1,6 +1,9 @@
 .atto_image_preview {
     max-width: 150px;
     max-height: 150px;
+}
+.atto_image_preview_box {
+    height: 150px;
     margin-bottom: 1em;
 }
 
index 9b50f96..47e45b0 100644 (file)
Binary files a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js and b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-debug.js differ
index 7650367..632e4e1 100644 (file)
Binary files a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js and b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button-min.js differ
index 9b50f96..47e45b0 100644 (file)
Binary files a/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js and b/lib/editor/atto/plugins/image/yui/build/moodle-atto_image-button/moodle-atto_image-button.js differ
index bec3b9d..333dc57 100644 (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();
+
     },
 
     /**