From bbf724e4012e983d56bea27b66caa204294ebda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Mon, 29 May 2017 11:22:26 +0200 Subject: [PATCH] [FIX] web: properly support password attribute for fields With the new views, the special attribute password was no longer supported. We simply reintroduce in this commit proper support to display password fields with *. Note: we may want to display passwords with a static number of *, but this requires some thoughts on the usability of the change. We simply reintroduce the previous behaviour here. --- .../web/static/src/js/fields/basic_fields.js | 3 ++- .../web/static/src/js/fields/field_utils.js | 14 ++++++++++- .../static/src/js/views/list/list_renderer.js | 1 + addons/web/static/tests/views/form_tests.js | 23 +++++++++++++++++++ addons/web/static/tests/views/list_tests.js | 19 +++++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 3f279eeeec7..cdaed1d7b4f 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -165,6 +165,7 @@ var InputField = DebouncedField.extend({ */ init: function () { this._super.apply(this, arguments); + this.nodeOptions.isPassword = 'password' in this.attrs; if (this.mode === 'edit') { this.tagName = 'input'; } @@ -222,7 +223,7 @@ var InputField = DebouncedField.extend({ this.$input = $input || $(""); this.$input.addClass('o_input'); this.$input.attr({ - type: 'text', + type: this.nodeOptions.isPassword ? 'password' : 'text', placeholder: this.attrs.placeholder || "", }); this.$input.val(this._formatValue(this.value)); diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js index 0606af0d662..75403c288e5 100644 --- a/addons/web/static/src/js/fields/field_utils.js +++ b/addons/web/static/src/js/fields/field_utils.js @@ -56,10 +56,15 @@ function formatBoolean(value) { * a description of the field (note: this parameter is ignored) * @param {Object} [options] additional options * @param {boolean} [options.escape=false] if true, escapes the formatted value + * @param {boolean} [options.isPassword=false] if true, returns '********' + * instead of the formatted value * @returns {string} */ function formatChar(value, field, options) { value = typeof value === 'string' ? value : ''; + if (options && options.isPassword) { + return _.str.repeat('*', value ? value.length : 0); + } if (options && options.escape) { value = _.escape(value); } @@ -177,9 +182,16 @@ function formatFloatTime(value) { * return an empty string. * * @param {integer|false} value + * @param {Object} [field] + * a description of the field (note: this parameter is ignored) + * @param {Object} [options] additional options + * @param {boolean} [options.isPassword=false] if true, returns '********' * @returns {string} */ -function formatInteger(value) { +function formatInteger(value, field, options) { + if (options && options.isPassword) { + return _.str.repeat('*', String(value).length); + } if (!value && value !== 0) { // previously, it returned 'false'. I don't know why. But for the Pivot // view, I want to display the concept of 'no value' with an empty diff --git a/addons/web/static/src/js/views/list/list_renderer.js b/addons/web/static/src/js/views/list/list_renderer.js index 059e2aeccad..e589c0d430a 100644 --- a/addons/web/static/src/js/views/list/list_renderer.js +++ b/addons/web/static/src/js/views/list/list_renderer.js @@ -254,6 +254,7 @@ var ListRenderer = BasicRenderer.extend({ var formattedValue = field_utils.format[field.type](value, field, { data: record.data, escape: true, + isPassword: 'password' in node.attrs, }); return $td.html(formattedValue); }, diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index a36cfec075a..c67d8a1bff6 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -4618,5 +4618,28 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('support password attribute', function (assert) { + assert.expect(3); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '', + res_id: 1, + }); + + assert.strictEqual(form.$('span[name="foo"]').text(), '***', + "password should be displayed with stars"); + form.$buttons.find('.o_form_button_edit').click(); + assert.strictEqual(form.$('input[name="foo"]').val(), '***', + "password should be displayed with stars"); + assert.strictEqual(form.$('input[name="foo"]').prop('type'), 'password', + "input should be of type password"); + form.destroy(); + }); + }); }); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 3753634c239..601e7a23533 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -2243,6 +2243,25 @@ QUnit.module('Views', { "should not have a visible save button"); list.destroy(); }); + + QUnit.test('field with password attribute', function (assert) { + assert.expect(2); + + var list = createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '', + }); + + assert.strictEqual(list.$('td.o_data_cell:eq(0)').text(), '***', + "should display string as password"); + assert.strictEqual(list.$('td.o_data_cell:eq(1)').text(), '****', + "should display string as password"); + + list.destroy(); + }); + }); });