diff --git a/core/block_render_svg.js b/core/block_render_svg.js index a1d4af37e..be058b91a 100644 --- a/core/block_render_svg.js +++ b/core/block_render_svg.js @@ -370,21 +370,30 @@ Blockly.BlockSvg.prototype.renderFields_ = function(fieldList, continue; } + var translateX; + var scale = ''; if (this.RTL) { cursorX -= field.renderSep + field.renderWidth; - root.setAttribute('transform', - 'translate(' + cursorX + ',' + cursorY + ')'); + translateX = cursorX; if (field.renderWidth) { cursorX -= Blockly.BlockSvg.SEP_SPACE_X; } } else { - root.setAttribute('transform', - 'translate(' + (cursorX + field.renderSep) + ',' + cursorY + ')'); + translateX = cursorX + field.renderSep; if (field.renderWidth) { cursorX += field.renderSep + field.renderWidth + Blockly.BlockSvg.SEP_SPACE_X; } } + if (this.RTL && + field instanceof Blockly.FieldImage && + field.getFlipRtl()) { + scale = 'scale(-1 1)'; + translateX += field.renderWidth; + } + root.setAttribute('transform', + 'translate(' + translateX + ',' + cursorY + ')' + scale); + // Fields are invisible on insertion marker. They still have to be rendered // so that the block can be sized correctly. if (this.isInsertionMarker()) { diff --git a/core/field_image.js b/core/field_image.js index 42683e321..e32bf7c1c 100644 --- a/core/field_image.js +++ b/core/field_image.js @@ -40,10 +40,12 @@ goog.require('goog.math.Size'); * @param {string=} opt_alt Optional alt text for when block is collapsed. * @param {Function=} opt_onClick Optional function to be called when the image * is clicked. If opt_onClick is defined, opt_alt must also be defined. + * @param {boolean=} opt_flipRtl Whether to flip the icon in RTL. * @extends {Blockly.Field} * @constructor */ -Blockly.FieldImage = function(src, width, height, opt_alt, opt_onClick) { +Blockly.FieldImage = function(src, width, height, + opt_alt, opt_onClick, opt_flipRtl) { this.sourceBlock_ = null; // Ensure height and width are numbers. Strings are bad at math. @@ -51,6 +53,7 @@ Blockly.FieldImage = function(src, width, height, opt_alt, opt_onClick) { this.width_ = Number(width); this.size_ = new goog.math.Size(this.width_, this.height_ + 2 * Blockly.BlockSvg.INLINE_PADDING_Y); + this.flipRtl_ = opt_flipRtl; this.tooltip_ = ''; this.setValue(src); this.setText(opt_alt); @@ -64,8 +67,8 @@ goog.inherits(Blockly.FieldImage, Blockly.Field); /** * Construct a FieldImage from a JSON arg object, * dereferencing any string table references. - * @param {!Object} options A JSON object with options (src, width, height, and - * alt). + * @param {!Object} options A JSON object with options (src, width, height, + * alt, and flipRtl). * @returns {!Blockly.FieldImage} The new field instance. * @package * @nocollapse @@ -76,7 +79,8 @@ Blockly.FieldImage.fromJson = function(options) { var height = Number(Blockly.utils.replaceMessageReferences(options['height'])); var alt = Blockly.utils.replaceMessageReferences(options['alt']); - return new Blockly.FieldImage(src, width, height, alt); + var flipRtl = !!options['flipRtl']; + return new Blockly.FieldImage(src, width, height, alt, null, flipRtl); }; /** @@ -183,6 +187,14 @@ Blockly.FieldImage.prototype.setValue = function(src) { } }; +/** + * Get whether to flip this image in RTL + * @return {boolean} True if we should flip in RTL. + */ +Blockly.FieldImage.prototype.getFlipRtl = function() { + return this.flipRtl_; +}; + /** * Set the alt text of this image. * @param {?string} alt New alt text. diff --git a/demos/blockfactory/blocks.js b/demos/blockfactory/blocks.js index 4f10b091a..15a7f2a41 100644 --- a/demos/blockfactory/blocks.js +++ b/demos/blockfactory/blocks.js @@ -603,7 +603,9 @@ Blockly.Blocks['field_image'] = { .appendField('height') .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'HEIGHT') .appendField('alt text') - .appendField(new Blockly.FieldTextInput('*'), 'ALT'); + .appendField(new Blockly.FieldTextInput('*'), 'ALT') + .appendField('flip RTL') + .appendField(new Blockly.FieldCheckbox('false'), 'FLIP_RTL'); this.setPreviousStatement(true, 'Field'); this.setNextStatement(true, 'Field'); this.setTooltip('Static image (JPEG, PNG, GIF, SVG, BMP).\n' + diff --git a/demos/blockfactory/factory_utils.js b/demos/blockfactory/factory_utils.js index 17a26ac56..4006d4308 100644 --- a/demos/blockfactory/factory_utils.js +++ b/demos/blockfactory/factory_utils.js @@ -593,7 +593,8 @@ FactoryUtils.getFieldsJson_ = function(block) { src: block.getFieldValue('SRC'), width: Number(block.getFieldValue('WIDTH')), height: Number(block.getFieldValue('HEIGHT')), - alt: block.getFieldValue('ALT') + alt: block.getFieldValue('ALT'), + flipRtl: block.getFieldValue('FLIP_RTL') == 'TRUE' }); break; } diff --git a/tests/blocks/test_blocks.js b/tests/blocks/test_blocks.js index f094b1131..092f2d3a6 100644 --- a/tests/blocks/test_blocks.js +++ b/tests/blocks/test_blocks.js @@ -292,6 +292,21 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT ], "colour": 160 }, + { + "type": "image_fliprtl", + "message0": "Image flipped RTL %1", + "args0": [ + { + "type": "field_image", + "src": "media/arrow.png", + "width": 50, + "height": 50, + "alt": "*", + "flipRtl": true + } + ], + "colour": 160 + }, { "type": "image_missing", "message0": "Image missing %1", diff --git a/tests/media/arrow.png b/tests/media/arrow.png new file mode 100644 index 000000000..d310bd2a6 Binary files /dev/null and b/tests/media/arrow.png differ diff --git a/tests/playground.html b/tests/playground.html index d2f5d50a7..b13f0db2e 100644 --- a/tests/playground.html +++ b/tests/playground.html @@ -1212,6 +1212,7 @@ h1 { +