[FIX] mail: make clicking on chat window's emoji button properly work

Before this commit, clicking on the button opened the emoji popover
then closed it immediately. This was because of a handler which said
that clicking on any part of the composer should focus the input
element. This is indeed required when the UI is blocked (thanks to
the `blockUI` function). Solution is to not force this focus when
clicking on any composer's button element.

To prevent breaking those two behaviors (blockUI focus and emoji), two
tests were implemented.
This commit is contained in:
qsm-odoo
2017-09-20 15:03:56 +02:00
parent 85a0399d4f
commit 26e079f246
2 changed files with 92 additions and 5 deletions
+17 -3
View File
@@ -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
*/
+75 -2
View File
@@ -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 = $('<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);
});
});
});