From 8bee94f2607e27cf89ffa036b8921503b67fc340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Debauche=20St=C3=A9phane?= Date: Fri, 8 Nov 2019 14:38:56 +0000 Subject: [PATCH] [IMP] mail: clean the emoji widget (mixin, text_emojis, char_emojis) PURPOSE Allow to use the text field with integrated emojis support in other apps notably mass mailing SPECIFICATIONS In this commit we somehow clean code related to emojis widgets * simplify some code bits; * update comments; * add an option on the emojis widget to trigger ``onchange`` on a ``keydown`` event; LINKS Task #2117238 PR #40045 Enterprise PR odoo/enterprise#6630 --- addons/mail/static/src/js/emojis_mixin.js | 34 +++++------------ .../mail/static/src/js/text_emojis_fields.js | 37 ++++++++----------- addons/mail/static/src/scss/emojis.scss | 7 +++- addons/mail/static/src/xml/text_emojis.xml | 8 ++-- 4 files changed, 35 insertions(+), 51 deletions(-) diff --git a/addons/mail/static/src/js/emojis_mixin.js b/addons/mail/static/src/js/emojis_mixin.js index ed5aaa52bac..aa535d1d61f 100644 --- a/addons/mail/static/src/js/emojis_mixin.js +++ b/addons/mail/static/src/js/emojis_mixin.js @@ -1,7 +1,6 @@ odoo.define('mail.emoji_mixin', function (require) { "use strict"; -var dom = require('web.dom'); var emojis = require('mail.emojis'); /** @@ -9,8 +8,7 @@ var emojis = require('mail.emojis'); * * It's used to: * - * - handle the click on an emoji from a dropdown panel and add it to the related textarea - * - replace the emoji code with the actual character, ex: ' :) ' -> ' 😊 ' + * - handle the click on an emoji from a dropdown panel and add it to the related textarea/input * - format text and wrap the emojis around to make them look nicer * * Methods are based on the collections of emojis available in mail.emojis @@ -23,33 +21,21 @@ return { /** * This method should be bound to a click event on an emoji. - * (used in textarea's emojis dropdown list) + * (used in text element's emojis dropdown list) * - * It assumes that a '_getTargetTextArea' method is defined that will return the related - * $textarea element. - * - * Some code from 'basic_composer.js' was copy/pasted to handle the cursor position in the - * textarea and handle text replacement if text was selected by the user. + * It assumes that a ``_getTargetTextElement`` method is defined that will return the related + * textarea/input element in which the emoji will be inserted. * * @param {MouseEvent} ev */ _onEmojiClick: function (ev) { - ev.preventDefault(); + var unicode = ev.currentTarget.textContent.trim(); + var textInput = this._getTargetTextElement($(ev.currentTarget))[0]; + var selectionStart = textInput.selectionStart; - var $target = $(ev.currentTarget); - var $textarea = this._getTargetTextArea($target); - - // copy/pasted from 'basic_composer.js' - var inputElement = $textarea.get(0); - var cursorPosition = inputElement ? dom.getSelectionRange(inputElement) : {start: 0, end: 0}; - var inputVal = $textarea.val(); - var leftSubstring = inputVal.substring(0, cursorPosition.start); - var rightSubstring = inputVal.substring(cursorPosition.end); - var newInputVal = [leftSubstring , $target.text().trim(), rightSubstring].join(""); - var newCursorPosition = newInputVal.length - rightSubstring.length; - $textarea.val(newInputVal); - $textarea.focus(); - $textarea[0].setSelectionRange(newCursorPosition, newCursorPosition); + textInput.value = textInput.value.slice(0, selectionStart) + unicode + textInput.value.slice(selectionStart); + textInput.focus(); + textInput.setSelectionRange(selectionStart + unicode.length, selectionStart + unicode.length); }, //-------------------------------------------------------------------------- diff --git a/addons/mail/static/src/js/text_emojis_fields.js b/addons/mail/static/src/js/text_emojis_fields.js index 6402c3eb62c..1a30751c19c 100644 --- a/addons/mail/static/src/js/text_emojis_fields.js +++ b/addons/mail/static/src/js/text_emojis_fields.js @@ -10,7 +10,7 @@ var _onEmojiClickMixin = MailEmojisMixin._onEmojiClick; var QWeb = core.qweb; /* - * Common code for FieldText and FieldChar + * Common code for FieldTextEmojis and FieldCharEmojis */ var FieldEmojiCommon = { /** @@ -19,7 +19,7 @@ var FieldEmojiCommon = { */ init: function () { this._super.apply(this, arguments); - this._updatePreview =_.throttle(this._updatePreview, 1000, {leading: false}); + this._triggerOnchange =_.throttle(this._triggerOnchange, 1000, {leading: false}); this.emojis = emojis; }, @@ -28,24 +28,15 @@ var FieldEmojiCommon = { * * We use 'on_attach_callback' because we need the element to be attached to the form first. * That's because the $emojisIcon element needs to be rendered outside of this $el - * (which is an textarea, that can't 'contain' any other elements). + * (which is an text element, that can't 'contain' any other elements). * * @override */ on_attach_callback: function () { var self = this; - if (!this.$emojisIcon) { - this.$emojisIcon = $(QWeb.render( - 'mail.EmojisDropdown', { - widget: this, - emojisDropdownId: 'emojis_dropdown' - } - )); - this.$emojisIcon.find('.o_mail_emoji').on('click', function (ev) { - self._onEmojiClick(ev); - self._isDirty = true; - }); + this.$emojisIcon = $(QWeb.render('mail.EmojisDropdown', {widget: this})); + this.$emojisIcon.find('.o_mail_emoji').on('click', this._onEmojiClick.bind(this)); this.$el.after(this.$emojisIcon); } @@ -74,21 +65,22 @@ var FieldEmojiCommon = { /** * Overridden because we need to add the Emoji to the input AND trigger - * the 'change' event to refresh the various post previews. + * the 'change' event to refresh the value. * * @override * @private */ _onEmojiClick: function () { _onEmojiClickMixin.apply(this, arguments); + self._isDirty = true; this.$input.trigger('change'); }, /** * - * By default, the 'change' event is only triggered when the textarea is blurred. + * By default, the 'change' event is only triggered when the text element is blurred. * - * We override this method because we want to update the various post previews while + * We override this method because we want to update the value while * the user is typing his message (and not only on blur). * * @override @@ -96,7 +88,9 @@ var FieldEmojiCommon = { */ _onKeydown: function () { this._super.apply(this, arguments); - this._updatePreview(); + if (this.nodeOptions.onchange_on_keydown) { + this._triggerOnchange(); + } }, //-------------------------------------------------------------------------- @@ -106,21 +100,20 @@ var FieldEmojiCommon = { /** * Used by MailEmojisMixin, check its document for more info. * - * @param {$.Element} $emoji * @private */ - _getTargetTextArea($emoji) { + _getTargetTextElement() { return this.$el; }, /** - * Triggers the 'change' event to refresh the various post previews. + * Triggers the 'change' event to refresh the value. * This method is throttled to run at most once every second. * (to avoid spamming the server while the user is typing his message) * * @private */ - _updatePreview: function () { + _triggerOnchange: function () { this.$input.trigger('change'); } }; diff --git a/addons/mail/static/src/scss/emojis.scss b/addons/mail/static/src/scss/emojis.scss index 62ddb073e4c..daa1cc38ace 100644 --- a/addons/mail/static/src/scss/emojis.scss +++ b/addons/mail/static/src/scss/emojis.scss @@ -14,11 +14,16 @@ } .o_mail_emojis_dropdown { - height: 35px; + height: 25px; width: 40px; float: right; margin-top: -35px; + * { + outline: none!important; + box-shadow: none!important; + } + .dropdown-toggle:after { display: none; } diff --git a/addons/mail/static/src/xml/text_emojis.xml b/addons/mail/static/src/xml/text_emojis.xml index 89f26daf18c..0343d86b7b7 100644 --- a/addons/mail/static/src/xml/text_emojis.xml +++ b/addons/mail/static/src/xml/text_emojis.xml @@ -1,15 +1,15 @@ -
+