From f1fa85fe65d46a590a0a6bf9e4e6afc430312e2a Mon Sep 17 00:00:00 2001 From: "Hubert Van de Walle (huvw)" Date: Wed, 23 Mar 2022 15:05:14 +0000 Subject: [PATCH] [FIX] web: FieldBinaryImage size attribute not applied correctly in CSS Steps to follow - Go to the product page - Open studio - Click on the picture and set the size to large - Save and quit studio -> The size doesn't change Cause of the issue Studio sets the size attribute on the field as `[0, 270]` This means the picture should have a height of 270px and an unspecified width. But for that to work, we need to handle the case were only one dimension is set. opw-2745625 closes odoo/odoo#87226 X-original-commit: 50368a9db8ac67986cf64ff84ee625cbf7a90a1f Signed-off-by: Anh Thao PHAM Signed-off-by: Hubert Van De Walle --- .../src/legacy/js/fields/basic_fields.js | 16 ++++ .../tests/legacy/fields/basic_fields_tests.js | 75 +++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/addons/web/static/src/legacy/js/fields/basic_fields.js b/addons/web/static/src/legacy/js/fields/basic_fields.js index e00f3edbb00..5248d245446 100644 --- a/addons/web/static/src/legacy/js/fields/basic_fields.js +++ b/addons/web/static/src/legacy/js/fields/basic_fields.js @@ -2131,10 +2131,18 @@ var FieldBinaryImage = AbstractFieldBinary.extend({ if (width) { $img.attr('width', width); $img.css('max-width', width + 'px'); + if (!height) { + $img.css('height', 'auto'); + $img.css('max-height', '100%'); + } } if (height) { $img.attr('height', height); $img.css('max-height', height + 'px'); + if (!width) { + $img.css('width', 'auto'); + $img.css('max-width', '100%'); + } } this.$('> img').remove(); this.$el.prepend($img); @@ -2241,10 +2249,18 @@ var CharImageUrl = AbstractField.extend({ if (width) { $img.attr('width', width); $img.css('max-width', width + 'px'); + if (!height) { + $img.css('height', 'auto'); + $img.css('max-height', '100%'); + } } if (height) { $img.attr('height', height); $img.css('max-height', height + 'px'); + if (!width) { + $img.css('width', 'auto'); + $img.css('max-width', '100%'); + } } this.$('> img').remove(); this.$el.prepend($img); diff --git a/addons/web/static/tests/legacy/fields/basic_fields_tests.js b/addons/web/static/tests/legacy/fields/basic_fields_tests.js index d0005289f02..fa5bc13d563 100644 --- a/addons/web/static/tests/legacy/fields/basic_fields_tests.js +++ b/addons/web/static/tests/legacy/fields/basic_fields_tests.js @@ -2976,6 +2976,48 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.test('image fields are correctly rendered with one dimension set', async function (assert) { + assert.expect(6); + + this.data.partner.fields.picture = { string: 'Picture', type: 'binary' }; + this.data.partner.records[0].__last_update = '2017-02-08 10:00:00'; + this.data.partner.records[0].document = 'myimage1'; + this.data.partner.records[0].picture = 'myimage2'; + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + ' ' + + ' ' + + '', + res_id: 1, + mockRPC: function (route, args) { + if (route.startsWith('data:image/png;base64,myimage')) { + return Promise.resolve('wow'); + } + return this._super.apply(this, arguments); + }, + }); + + assert.containsOnce(form, 'div[name="document"] > img', "the widget should contain an image"); + assert.hasAttrValue(form.$('div[name="document"] > img'), 'width', "180", + "the image should correctly set its attributes"); + const image1Style = form.$('div[name="document"] > img').attr('style'); + assert.ok(['max-width: 180px', 'height: auto', 'max-height: 100%'].every(e => image1Style.includes(e)), + "the image should correctly set its style"); + + assert.containsOnce(form, 'div[name="picture"] > img', "the widget should contain an image"); + assert.hasAttrValue(form.$('div[name="picture"] > img'), 'height', "270", + "the image should correctly set its attributes"); + const image2Style = form.$('div[name="picture"] > img').attr('style'); + assert.ok(['max-height: 270px', 'width: auto', 'max-width: 100%'].every(e => image2Style.includes(e)), + "the image should correctly set its style"); + + form.destroy(); + }); + QUnit.test('image fields are correctly replaced when given an incorrect value', async function (assert) { assert.expect(6); @@ -3203,6 +3245,39 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.test('image fields are correctly rendered with one dimension set', async function (assert) { + assert.expect(6); + + this.data.partner.fields.tortue = {string: "Tortue", type: "char", default: "a"}; + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + ' ' + + ' ' + + '', + res_id: 6, + }); + + assert.containsOnce(form, 'div[name="foo"] > img', "the widget should contain an image"); + assert.hasAttrValue(form.$('div[name="foo"] > img'), 'width', "180", + "the image should correctly set its attributes"); + const image1Style = form.$('div[name="foo"] > img').attr('style'); + assert.ok(['max-width: 180px', 'height: auto', 'max-height: 100%'].every(e => image1Style.includes(e)), + "the image should correctly set its style"); + + assert.containsOnce(form, 'div[name="tortue"] > img', "the widget should contain an image"); + assert.hasAttrValue(form.$('div[name="tortue"] > img'), 'height', "270", + "the image should correctly set its attributes"); + const image2Style = form.$('div[name="tortue"] > img').attr('style'); + assert.ok(['max-height: 270px', 'width: auto', 'max-width: 100%'].every(e => image2Style.includes(e)), + "the image should correctly set its style"); + + form.destroy(); + }); + QUnit.test('image_url widget in subviews are loaded correctly', async function (assert) { assert.expect(4);