summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Schippefilt <vsc@odoo.com>2018-04-12 16:38:14 +0200
committerVincent Schippefilt <vsc@odoo.com>2018-04-16 09:35:33 +0200
commit65d8a082df02d72a37c5e9d06539a69adab04c4a (patch)
tree2a3781ecc09adce9cf796a2f7a1faef568ca3e75
parent9b2b5eddd4d6feac3926da8242d0b063bb26c9ed (diff)
[FIX] web: fix keyboard related crash in client actions
-rw-r--r--addons/web/static/src/js/chrome/abstract_action.js5
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js4
-rw-r--r--addons/web/static/tests/chrome/action_manager_tests.js61
-rw-r--r--addons/web/static/tests/helpers/test_utils.js9
4 files changed, 73 insertions, 6 deletions
diff --git a/addons/web/static/src/js/chrome/abstract_action.js b/addons/web/static/src/js/chrome/abstract_action.js
index eb305b3a0d0..8c06d887431 100644
--- a/addons/web/static/src/js/chrome/abstract_action.js
+++ b/addons/web/static/src/js/chrome/abstract_action.js
@@ -52,6 +52,11 @@ var AbstractAction = Widget.extend({
return $.when();
},
/**
+ * Gives the focus to the action
+ */
+ giveFocus: function () {
+ },
+ /**
* Renders the buttons to append, in most cases, to the control panel (in
* the bottom left corner). When the action is rendered in a dialog, those
* buttons might be moved to the dialog's footer.
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index ae0da5427ad..0f426dedd3b 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -319,7 +319,9 @@ var InputField = DebouncedField.extend({
|| (ev.data.direction === "right" && (selecting || input.selectionStart !== input.value.length))) {
ev.stopPropagation();
}
- if (ev.data.direction ==='next' && this.attrs.modifiersValue.required) {
+ if (ev.data.direction ==='next' &&
+ this.attrs.modifiersValue &&
+ this.attrs.modifiersValue.required) {
if (!this.$input.val()){
this.setInvalidClass();
ev.stopPropagation();
diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js
index 3308d7325ce..b640add63c1 100644
--- a/addons/web/static/tests/chrome/action_manager_tests.js
+++ b/addons/web/static/tests/chrome/action_manager_tests.js
@@ -5,14 +5,15 @@ var ReportClientAction = require('report.client_action');
var AbstractAction = require('web.AbstractAction');
var AbstractStorageService = require('web.AbstractStorageService');
+var BasicFields = require('web.basic_fields');
var ControlPanelMixin = require('web.ControlPanelMixin');
var core = require('web.core');
var ListController = require('web.ListController');
+var StandaloneFieldManagerMixin = require('web.StandaloneFieldManagerMixin');
var RamStorage = require('web.RamStorage');
var ReportService = require('web.ReportService');
var testUtils = require('web.test_utils');
var Widget = require('web.Widget');
-
var createActionManager = testUtils.createActionManager;
QUnit.module('ActionManager', {
@@ -3094,6 +3095,64 @@ QUnit.module('ActionManager', {
delete core.action_registry.map.slowAction;
});
+
+ QUnit.test('abstract action does not crash on navigation_moves', function (assert) {
+ assert.expect(1);
+ var ClientAction = AbstractAction.extend({
+ });
+ core.action_registry.add('ClientAction', ClientAction);
+ var actionManager = createActionManager({
+ actions: this.actions,
+ archs: this.archs,
+ data: this.data,
+ });
+ actionManager.doAction('ClientAction');
+ actionManager.trigger_up('navigation_move', {direction:'down'});
+
+ assert.ok(true); // no error so it's good
+ actionManager.destroy();
+ delete core.action_registry.ClientAction;
+ });
+
+ QUnit.test('fields in abstract action do not crash on navigation_moves', function (assert) {
+ assert.expect(1);
+ var self = this;
+
+ // create a client action with 1 input field
+ var inputWidget;
+ var ClientAction = AbstractAction.extend(StandaloneFieldManagerMixin,{
+ init: function() {
+ this._super.apply(this, arguments);
+ StandaloneFieldManagerMixin.init.call(this);
+ },
+ start: function(){
+ var _self = this;
+
+ return this.model.makeRecord('partner', [{
+ name: 'display_name',
+ type: 'char',
+ }]).then(function (recordID) {
+ var record = _self.model.get(recordID);
+ inputWidget = new BasicFields.InputField(_self, 'display_name', record, {mode: 'edit',});
+ _self._registerWidget(recordID, 'display_name', inputWidget);
+ inputWidget.appendTo(_self.$el);
+ });
+ }
+ });
+ core.action_registry.add('ClientAction', ClientAction);
+ var actionManager = createActionManager({
+ actions: this.actions,
+ archs: this.archs,
+ data: this.data,
+ });
+ actionManager.doAction('ClientAction');
+ inputWidget.$el.trigger($.Event('keydown', {which: $.ui.keyCode.TAB}));
+
+ assert.ok(true); // no error so it's good
+ actionManager.destroy();
+ delete core.action_registry.ClientAction;
+ });
+
});
});
diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js
index c2d82775e70..f993a2f9250 100644
--- a/addons/web/static/tests/helpers/test_utils.js
+++ b/addons/web/static/tests/helpers/test_utils.js
@@ -77,6 +77,7 @@ var createActionManager = function (params) {
var $target = $('#qunit-fixture');
if (params.debug) {
$target = $('body');
+ $target.addClass('debug');
}
var widget = new Widget();
@@ -733,17 +734,17 @@ function patch (target, props) {
* In Phantomjs, there is a crash when calling window.getSelection
* in order for the tests to work, for the specific test that uses it, replace
* the default window.getSelection by a mock
- *
+ *
* usage:
* QUnit.test('...',function(done){
* var unpatchWindowGetSelection = testUtils.patchWindowGetSelection();
- *
+ *
* // do something that needs to use window.getSelection()
* assert.strictEqual(....);
- *
+ *
* // restore the original function
* unpatchWindowGetSelection();
- *
+ *
* // finish the test
* done();
* })