diff --git a/phpBB/assets/javascript/editor.js b/phpBB/assets/javascript/editor.js
index 9972ffdd6a..b6382304bc 100644
--- a/phpBB/assets/javascript/editor.js
+++ b/phpBB/assets/javascript/editor.js
@@ -387,15 +387,35 @@ function getCaretPosition(txtarea) {
(function($) {
function Mentions() {
let $mentionDataContainer = $('[data-mention-url]:first');
+ let mentionURL = $mentionDataContainer.data('mentionUrl');
+ let mentionBatchSize = $mentionDataContainer.data('mentionBatchSize');
+ let mentionNamesLimit = $mentionDataContainer.data('mentionNamesLimit');
+ let mentionTopicId = $mentionDataContainer.data('topicId');
let queryInProgress = null;
- let cachedNames = null;
- let cachedFor = null;
+ let cachedNames = [];
let cachedSearchKey = 'name';
function defaultAvatar(type) {
return (type === 'group') ? '' : '';
}
+ function getCachedNames(query) {
+ if (!cachedNames) {
+ return null;
+ }
+
+ let i;
+
+ for (i = query.length; i > 0; i--) {
+ let startStr = query.substr(0, i);
+ if (cachedNames[startStr]) {
+ return cachedNames[startStr];
+ }
+ }
+
+ return cachedNames[''];
+ }
+
function getMatchedNames(query, items, searchKey) {
let i;
let len;
@@ -413,15 +433,50 @@ function getCaretPosition(txtarea) {
return getMatchedNames(query, cachedNames, cachedSearchKey).length;
}
+ function remoteFilter(query, callback) {
+ /*
+ * Do not make a new request until the previous one for the same query is returned
+ * This fixes duplicate server queries e.g. when arrow keys are pressed
+ */
+ if (queryInProgress === query) {
+ setTimeout(function() {
+ remoteFilter(query, callback);
+ }, 1000);
+ return;
+ }
+
+ let cachedNamesForQuery = getCachedNames(query);
+
+ /*
+ * Use cached values when we can:
+ * 1) There are some names in the cache relevant for the query
+ * (cache for the query with the same first characters cointains some data)
+ * 2) We have enough names to display OR
+ * all relevant names have been fetched from the server
+ */
+ if (cachedNamesForQuery &&
+ (getNumberOfMatchedCachedNames(query) >= mentionNamesLimit ||
+ cachedNamesForQuery.length < mentionBatchSize)) {
+ callback(cachedNamesForQuery);
+ return;
+ }
+
+ queryInProgress = query;
+
+ let params = {keyword: query, topic_id: mentionTopicId, _referer: location.href};
+ $.getJSON(mentionURL, params, function(data) {
+ cachedNames[query] = data;
+ callback(data);
+ }).always(function() {
+ queryInProgress = null;
+ });
+ }
+
this.isEnabled = function() {
return $mentionDataContainer.length;
};
this.handle = function(txtarea) {
- let mentionURL = $mentionDataContainer.data('mentionUrl');
- let mentionBatchSize = $mentionDataContainer.data('mentionBatchSize');
- let mentionNamesLimit = $mentionDataContainer.data('mentionNamesLimit');
- let mentionTopicId = $mentionDataContainer.data('topicId');
$(txtarea).atwho({
at: "@",
acceptSpaceBar: true,
@@ -434,40 +489,7 @@ function getCaretPosition(txtarea) {
insertTpl: "[mention=${type}:${id}]${name}[/mention]",
limit: mentionNamesLimit,
callbacks: {
- remoteFilter: function(query, callback) {
- /*
- * Use cached values when we can:
- * 1) There are some names in the cache
- * 2) The cache contains relevant data for the query
- * (it was made for the query with the same first characters)
- * 3) We have enough names to display OR
- * all relevant names have been fetched from the server
- */
- if (cachedNames &&
- query.indexOf(cachedFor) === 0 &&
- (getNumberOfMatchedCachedNames(query) >= mentionNamesLimit ||
- cachedNames.length < mentionBatchSize)) {
- callback(cachedNames);
- return;
- }
-
- /*
- * Do not make a new request until the previous one for the same query is returned
- * This fixes duplicate server queries e.g. when arrow keys are pressed
- */
- if (queryInProgress === query) {
- return;
- }
- queryInProgress = query;
-
- let params = {keyword: query, topic_id: mentionTopicId, _referer: location.href};
- $.getJSON(mentionURL, params, function (data) {
- cachedNames = data;
- cachedFor = query;
- queryInProgress = null;
- callback(data);
- });
- },
+ remoteFilter: remoteFilter,
sorter: function(query, items, searchKey) {
let i;
let len;