[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
This commit is contained in:
committed by
Thibault Delavallée
parent
47115a3a2a
commit
8bee94f260
@@ -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 <span class="o_mail_emoji"> 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);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<div t-name="mail.EmojisDropdown" t-attf-class="o_mail_emojis_dropdown o_mail_add_emoji dropdown">
|
||||
<div t-name="mail.EmojisDropdown" class="o_mail_emojis_dropdown o_mail_add_emoji dropdown">
|
||||
<button class="btn btn-block dropdown-toggle px-3 py-1"
|
||||
type="button" t-att-id="emojisDropdownId"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
title="Add an emoji">
|
||||
<i class="fa fa-smile-o"></i>
|
||||
<i class="fa fa-smile-o"/>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right border-0 p-2" t-att-aria-labelledby="emojisDropdownId" style="width: 406px">
|
||||
<div class="dropdown-menu dropdown-menu-right border-0 p-2" style="width: 406px">
|
||||
<t t-call="mail.Composer.emojis">
|
||||
<t t-set="emojis" t-value="widget.emojis"></t>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user