diff --git a/addons/mail/static/src/js/chat_window.js b/addons/mail/static/src/js/chat_window.js index d65660ef90c..95988d27424 100644 --- a/addons/mail/static/src/js/chat_window.js +++ b/addons/mail/static/src/js/chat_window.js @@ -19,7 +19,7 @@ return Widget.extend({ escape_pressed: '_onEscapePressed' }, events: { - "click .o_chat_composer": "focus_input", // focus even if jquery's blockUI is enabled + 'click .o_chat_composer': '_onComposerClick', "click .o_mail_thread": "_onChatWindowClicked", "keydown .o_chat_composer": "on_keydown", "keypress .o_chat_composer": "on_keypress", @@ -103,9 +103,10 @@ return Widget.extend({ this.fold(); }, focus_input: function () { - if (!config.device.touch) { - this.$input.focus(); + if (config.device.touch && config.device.size_class <= config.device.SIZES.SM) { + return; } + this.$input.focus(); }, do_show: function () { this.is_hidden = false; @@ -166,6 +167,19 @@ return Widget.extend({ this.$input.focus(); } }, + /** + * Called when the composer is clicked -> forces focus on input even if + * jquery's blockUI is enabled. + * + * @private + * @param {Event} ev + */ + _onComposerClick: function (ev) { + if ($(ev.target).closest('a, button').length) { + return; + } + this.focus_input(); + }, /** * @private */ diff --git a/addons/mail/static/tests/chat_window_test.js b/addons/mail/static/tests/chat_window_test.js index 6f5d03710d1..832b9fa4fe8 100644 --- a/addons/mail/static/tests/chat_window_test.js +++ b/addons/mail/static/tests/chat_window_test.js @@ -1,6 +1,7 @@ odoo.define('mail.chat_window_test', function (require) { "use strict"; +var framework = require('web.framework'); var testUtils = require('web.test_utils'); var Widget = require('web.Widget'); var ChatWindow = require('mail.ExtendedChatWindow'); @@ -41,13 +42,85 @@ QUnit.module('mail', {}, function () { assert.ok(true, "chat window should trigger a close event"); }); chatWindow.thread.$el.trigger("click"); - assert.strictEqual(chatWindow.$input[0], document.activeElement, + assert.strictEqual(document.activeElement, chatWindow.$input[0], "input should be focused"); var upKeyEvent = jQuery.Event( "keyup", {which: 27}); chatWindow.$('.o_composer_input').trigger(upKeyEvent); assert.strictEqual(chatWindow.folded, false, "Closed chat Window"); - chatWindow.destroy(); + parent.destroy(); }); + QUnit.test('chat window\'s input can still be focused when the UI is blocked', function (assert) { + assert.expect(2); + + function createParent(params) { + var widget = new Widget(); + + testUtils.addMockEnvironment(widget, params); + return widget; + } + var parent = createParent({ + data: {}, + }); + + var $dom = $('#qunit-fixture'); + + var chatWindow = new ChatWindow(parent, 1, "user", false, [], {}); + chatWindow.appendTo($dom); + var $input = $('', {type: 'text'}).appendTo($dom); + $input.focus().click(); + assert.strictEqual(document.activeElement, $input[0], + "fake input should be focused"); + + framework.blockUI(); + chatWindow.$input.click(); // cannot force focus here otherwise the test + // makes no sense, this test is just about + // making sure that the code which forces the + // focus on click is not removed + assert.strictEqual(document.activeElement, chatWindow.$input[0], + "chat window's input should now be focused"); + + framework.unblockUI(); + parent.destroy(); + }); + + QUnit.test('emoji popover should open correctly in chat windows', function (assert) { + assert.expect(1); + + function createParent(params) { + var widget = new Widget(); + + widget.on('get_emojis', widget, function (ev) { + ev.data.callback([]); + }); + + testUtils.addMockEnvironment(widget, params); + return widget; + } + var parent = createParent({ + data: {}, + }); + + var $dom = $('#qunit-fixture'); + + var chatWindow = new ChatWindow(parent, 1, "user", false, [], {}); + chatWindow.appendTo($dom); + + // Simulate clicking: 1) the focus event is fired, 2) we remove the + // 'fade' class of the generated popover so that animations do not break + // the test, 3) fire the click event which was the cause of the problem + var $emojiButton = chatWindow.$('.o_composer_button_emoji'); + $emojiButton.trigger('focusin').focus(); + var $popover = chatWindow.$('.o_composer_emoji .popover'); + $popover.removeClass('fade'); + $emojiButton.click(); + + var done = assert.async(); + setTimeout(function () { + assert.ok($popover.is(':visible'), "emoji popover should have stayed opened"); + parent.destroy(); + done(); + }, 0); + }); }); });