From dcf8c67fe386cfe7005288c179e829bab9aefb31 Mon Sep 17 00:00:00 2001 From: Martin Geubelle Date: Tue, 5 Mar 2019 15:44:31 +0000 Subject: [PATCH] [FIX] web: hide CopyClipboard widget button when pointless The widget has been moved in rev. odoo/odoo@15f3bbe but was not very generic. In particular, there was a traceback when clicking on the button if the field had no value (the button was displayed for readonly fields in create mode). The button is now only appended in readonly mode (a `button` inside an `input` or a `textarea` is not very DOM friendly) if the field has a value. Task 1941996 closes odoo/odoo#31635 Signed-off-by: Aaron Bohy (aab) --- .../web/static/src/js/fields/basic_fields.js | 55 ++++++------ addons/web/static/src/scss/fields.scss | 5 +- .../static/tests/fields/basic_fields_tests.js | 86 +++++++++++++------ 3 files changed, 88 insertions(+), 58 deletions(-) diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index a5f7649929c..2c8968ca453 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1331,7 +1331,9 @@ var CopyClipboard = { */ destroy: function () { this._super.apply(this, arguments); - this.clipboard.destroy(); + if (this.clipboard) { + this.clipboard.destroy(); + } }, //-------------------------------------------------------------------------- @@ -1346,8 +1348,8 @@ var CopyClipboard = { var $clipboardBtn = this.$('.o_clipboard_button'); $clipboardBtn.tooltip({title: _t('Copied !'), trigger: 'manual', placement: 'right'}); this.clipboard = new ClipboardJS($clipboardBtn[0], { - text: function (_) { - return self.value.trim(); + text: function () { + return self.value.trim(); }, // Container added because of Bootstrap modal that give the focus to another element. // We need to give to correct focus to ClipboardJS (see in ClipboardJS doc) @@ -1363,40 +1365,31 @@ var CopyClipboard = { }); }); }, + /** + * @override + */ + _render: function () { + this._super.apply(this, arguments); + this.$el.addClass('o_field_copy'); + }, + /** + * @override + */ + _renderReadonly: function () { + this._super.apply(this, arguments); + if (this.value) { + this.$el.append($(qweb.render(this.clipboardTemplate))); + this._initClipboard(); + } + } }; var TextCopyClipboard = FieldText.extend(CopyClipboard, { - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - */ - _render: function() { - this._super.apply(this, arguments); - this.$el.addClass('o_field_copy'); - this.$el.append($(qweb.render('CopyClipboardText'))); - this._initClipboard(); - } + clipboardTemplate: 'CopyClipboardText', }); var CharCopyClipboard = FieldChar.extend(CopyClipboard, { - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - */ - _render: function() { - this._super.apply(this, arguments); - this.$el.addClass('o_field_copy'); - this.$el.append($(qweb.render('CopyClipboardChar'))); - this._initClipboard(); - } + clipboardTemplate: 'CopyClipboardChar', }); var AbstractFieldBinary = AbstractField.extend({ diff --git a/addons/web/static/src/scss/fields.scss b/addons/web/static/src/scss/fields.scss index 81a59743788..2ba631575f7 100644 --- a/addons/web/static/src/scss/fields.scss +++ b/addons/web/static/src/scss/fields.scss @@ -178,7 +178,7 @@ } } } - } + } .o_tag_error { box-shadow: inset 0 0 0 2px #FF0000; @@ -443,7 +443,10 @@ } } } +} +span.o_field_copy:empty { + border: none; } button.o_field_float_toggle { diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index 978e6de226f..40593480099 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1412,45 +1412,79 @@ QUnit.module('basic_fields', { list.destroy(); }); - QUnit.module('copy_clipboard', { - beforeEach: function () { - this.data = { - partner: { - fields: { - script_external: {string: "Script External", type: "text"}, - web_page: {string: "Web page link", type: "char"} - }, - records: [{ - id: 1, - script_external:'Random Text', - web_page: 'web page links' - },], - }, - }; - } - }); + QUnit.module('CopyClipboard'); QUnit.test('Char & Text Fields: Copy to clipboard button', function (assert) { assert.expect(2); - var done = assert.async(); - testUtils.createAsyncView({ + + var form = createView({ View: FormView, model: 'partner', data: this.data, arch: '
' + '' + '
' + - '' + - '' + + '' + + '' + '
' + '
' + '
', - }).then(function (form) { - assert.strictEqual(form.$('.o_clipboard_button.o_btn_text_copy').length, 1,"Should have copy button on text type field"); - assert.strictEqual(form.$('.o_clipboard_button.o_btn_char_copy').length, 1,"Should have copy button on char type field"); - form.destroy(); - done(); + res_id: 1, }); + + assert.strictEqual(form.$('.o_clipboard_button.o_btn_text_copy').length, 1,"Should have copy button on text type field"); + assert.strictEqual(form.$('.o_clipboard_button.o_btn_char_copy').length, 1,"Should have copy button on char type field"); + + form.destroy(); + }); + + QUnit.test('CopyClipboard widget on unset field', function (assert) { + assert.expect(1); + + this.data.partner.records[0].foo = false; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + }); + + assert.containsNone(form, '.o_field_copy[name="foo"] .o_clipboard_button', + "foo (unset) should not contain a button"); + + form.destroy(); + }); + + QUnit.test('CopyClipboard widget on readonly unset fields in create mode', function (assert) { + assert.expect(1); + + this.data.partner.fields.display_name.readonly = true; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '
', + }); + + assert.containsNone(form, '.o_field_copy[name="display_name"] .o_clipboard_button', + "the readonly unset field should not contain a button"); + + form.destroy(); }); QUnit.module('FieldText');