[FIX] mail: composer: correctly erase mentions
The problem was that mentions weren't correctly erased with DELETE key (in some conditions), or when replacing mention text. When this happened, the mention didn't appear in the message, but the message was even tough sent to the erased mentioned people. With this rev., we don't try to detect erasing on the fly anymore, but we rather validate mentions before sending the message with the content of the input. opw 669362
This commit is contained in:
@@ -27,6 +27,8 @@ var accented_letters_mapping = {
|
||||
' ': '[()\\[\\]]',
|
||||
};
|
||||
|
||||
var NON_BREAKING_SPACE = '\u00a0';
|
||||
|
||||
var MENTION_PARTNER_DELIMITER = '@';
|
||||
var MENTION_CHANNEL_DELIMITER = '#';
|
||||
|
||||
@@ -71,6 +73,8 @@ var MentionManager = Widget.extend({
|
||||
var selected_suggestion = _.find(_.flatten(this.get('mention_suggestions')), function (s) {
|
||||
return s.id === id;
|
||||
});
|
||||
// replace white spaces with non-breaking spaces to facilitate mentions detection in text
|
||||
selected_suggestion.name = selected_suggestion.name.replace(/ /g, NON_BREAKING_SPACE);
|
||||
var get_mention_index = function (matches, cursor_position) {
|
||||
for (var i=0; i<matches.length; i++) {
|
||||
if (cursor_position <= matches[i].index) {
|
||||
@@ -121,9 +125,16 @@ var MentionManager = Widget.extend({
|
||||
return this.open;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the mentions of the given listener that haven't been erased from the composer's input
|
||||
*/
|
||||
get_listener_selection: function (delimiter) {
|
||||
var listener = _.findWhere(this.listeners, {delimiter: delimiter});
|
||||
return listener ? listener.selection : [];
|
||||
if (listener) {
|
||||
var input_mentions = this.composer.$input.val().match(new RegExp(delimiter+'[^ ]+', 'g'));
|
||||
return this._validate_selection(listener.selection, input_mentions);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
get_listener_selections: function () {
|
||||
@@ -199,33 +210,6 @@ var MentionManager = Widget.extend({
|
||||
}, this.options.typing_speed);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if a listener's selection should be updated after DELETE or BACKSPACE keypress
|
||||
*/
|
||||
check_remove: function () {
|
||||
var self = this;
|
||||
var to_remove = [];
|
||||
var selection = this._get_selection_positions();
|
||||
var deleted_binf = selection.start;
|
||||
var deleted_bsup = selection.end;
|
||||
|
||||
_.each(this.listeners, function (listener) {
|
||||
var mention_selection = listener.selection;
|
||||
var matches = self._get_match(self.composer.$input.val(), listener);
|
||||
for (var i=0; i<matches.length; i++) {
|
||||
var m = matches[i];
|
||||
var m1 = m.index;
|
||||
var m2 = m.index + m[0].length;
|
||||
if (deleted_binf <= m2 && m1 < deleted_bsup) {
|
||||
to_remove.push(mention_selection[i]);
|
||||
}
|
||||
}
|
||||
if (to_remove.length) {
|
||||
listener.selection = _.difference(mention_selection, to_remove);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Replaces mentions appearing in the string 's' by html links with proper redirection
|
||||
*/
|
||||
@@ -242,7 +226,8 @@ var MentionManager = Widget.extend({
|
||||
for (var i=0; i<matches.length; i++) {
|
||||
var match = matches[i];
|
||||
var end_index = match.index + match[0].length;
|
||||
var match_name = match[0].substring(1);
|
||||
// put back white spaces instead of non-breaking spaces in mention's name
|
||||
var match_name = match[0].substring(1).replace(new RegExp(NON_BREAKING_SPACE, 'g'), ' ');
|
||||
var href = base_href + _.str.sprintf("#model=%s&id=%s", listener.model, selection[i].id);
|
||||
var processed_text = _.str.sprintf(mention_link, href, listener.redirect_classname, selection[i].id, listener.model, listener.delimiter, match_name);
|
||||
var subtext = s.substring(start_index, end_index).replace(match[0], processed_text);
|
||||
@@ -303,6 +288,16 @@ var MentionManager = Widget.extend({
|
||||
this.open = false;
|
||||
}
|
||||
},
|
||||
_validate_selection: function (selection, input_mentions) {
|
||||
var validated_selection = [];
|
||||
_.each(input_mentions, function (mention) {
|
||||
var validated_mention = _.findWhere(selection, {name: mention.slice(1)});
|
||||
if (validated_mention) {
|
||||
validated_selection.push(validated_mention);
|
||||
}
|
||||
});
|
||||
return validated_selection;
|
||||
},
|
||||
|
||||
// Cursor position and selection utils
|
||||
_get_selection_positions: function () {
|
||||
@@ -477,11 +472,6 @@ var BasicComposer = Widget.extend({
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
// BACKSPACE, DELETE: check if need to remove a mention
|
||||
case $.ui.keyCode.BACKSPACE:
|
||||
case $.ui.keyCode.DELETE:
|
||||
this.mention_manager.check_remove();
|
||||
break;
|
||||
// ENTER: submit the message only if the dropdown mention proposition is not displayed
|
||||
case $.ui.keyCode.ENTER:
|
||||
if (this.mention_manager.is_open()) {
|
||||
|
||||
Reference in New Issue
Block a user