mirror of
https://github.com/YunoHost-Apps/jappix_ynh.git
synced 2024-09-03 19:26:19 +02:00
256 lines
6.5 KiB
JavaScript
256 lines
6.5 KiB
JavaScript
/*
|
|
|
|
Jappix - An open social platform
|
|
These are the autocompletion tools JS script for Jappix
|
|
|
|
-------------------------------------------------
|
|
|
|
License: AGPL
|
|
Author: Valérian Saliou
|
|
|
|
*/
|
|
|
|
// Bundle
|
|
var Autocompletion = (function () {
|
|
|
|
/**
|
|
* Alias of this
|
|
* @private
|
|
*/
|
|
var self = {};
|
|
|
|
|
|
/**
|
|
* Sort an autocompletion result array with insensitivity to the case,
|
|
* using the 1st elements (a[0] and b[0]) to process comparison
|
|
* @public
|
|
* @param {array} a
|
|
* @param {array} b
|
|
* @return {undefined}
|
|
*/
|
|
self.caseInsensitiveSort = function(a, b) {
|
|
|
|
try {
|
|
// Put the two strings into lower case
|
|
var sort_a = a[0].toLowerCase();
|
|
var sort_b = b[0].toLowerCase();
|
|
|
|
// Process the sort
|
|
if(sort_a > sort_b) {
|
|
return 1;
|
|
}
|
|
|
|
if(sort_a < sort_b) {
|
|
return -1;
|
|
}
|
|
} catch(e) {
|
|
Console.error('Autocompletion.caseInsensitiveSort', e);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Split a query into its subqueries ready to be used in autocompletion
|
|
* @public
|
|
* @param {string} query
|
|
* @return {object}
|
|
*/
|
|
self.getSubQueries = function(query) {
|
|
|
|
var result = [];
|
|
|
|
try {
|
|
var subqueries = [];
|
|
var remnants = [];
|
|
|
|
var query_last_char_pos = query.length - 1;
|
|
var space_counter = 0;
|
|
var cur_char;
|
|
|
|
for(var i = query_last_char_pos; i >= 0; i--) {
|
|
// Search from the end of the query
|
|
cur_char = query.charAt(i);
|
|
|
|
if(space_counter === 0 && cur_char.search(/\s/) === 0) {
|
|
// The first "local" space was found
|
|
// Add the subquery and its remnant to results
|
|
subqueries.push(query.slice(i+1));
|
|
remnants.push(query.slice(0, i+1));
|
|
|
|
space_counter++;
|
|
} else {
|
|
space_counter = 0;
|
|
}
|
|
}
|
|
|
|
if(space_counter === 0) {
|
|
// If the first char of the query is not a space, add the full query to results
|
|
subqueries.push(query);
|
|
remnants.push('');
|
|
}
|
|
|
|
result = [subqueries, remnants];
|
|
} catch(e) {
|
|
Console.error('Autocompletion.getSubQueries', e);
|
|
} finally {
|
|
return result;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Creates an array with the autocompletion results. An autocompletion result
|
|
* is an array containing the result himself and the rank of the query which
|
|
* matched this answer
|
|
* @public
|
|
* @param {Array} query
|
|
* @param {string} id
|
|
* @return {Array}
|
|
*/
|
|
self.process = function(query, id) {
|
|
|
|
var results = [];
|
|
|
|
try {
|
|
// Replace forbidden characters in regex
|
|
query = Common.escapeRegex(query);
|
|
|
|
// Build an array of regex to use
|
|
var query_reg_exp = [];
|
|
|
|
for(i = 0; i < query.length; i++) {
|
|
if(query[i] !== null) {
|
|
query_reg_exp.push(
|
|
new RegExp('(^)' + query[i], 'gi')
|
|
);
|
|
}
|
|
}
|
|
|
|
// Search in the roster
|
|
var nick, regex;
|
|
|
|
$('#' + id + ' .user').each(function() {
|
|
nick = $(this).find('.name').text();
|
|
|
|
for(i = 0; i < query_reg_exp.length; i++) {
|
|
regex = query_reg_exp[i];
|
|
|
|
if(nick.match(regex)) {
|
|
results.push([nick, i]);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Sort the array
|
|
results = results.sort(
|
|
self.caseInsensitiveSort
|
|
);
|
|
} catch(e) {
|
|
Console.error('Autocompletion.process', e);
|
|
} finally {
|
|
return results;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Resets the autocompletion tools
|
|
* @public
|
|
* @param {string} hash
|
|
* @return {undefined}
|
|
*/
|
|
self.reset = function(hash) {
|
|
|
|
try {
|
|
$('#' + hash + ' .message-area').removeAttr('data-autocompletion-pointer')
|
|
.removeAttr('data-autocompletion-query');
|
|
} catch(e) {
|
|
Console.error('Autocompletion.reset', e);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Autocompletes the chat input nick
|
|
* @public
|
|
* @param {string} hash
|
|
* @return {undefined}
|
|
*/
|
|
self.create = function(hash) {
|
|
|
|
try {
|
|
// Initialize
|
|
var message_area_sel = $('#' + hash + ' .message-area');
|
|
var value = message_area_sel.val();
|
|
|
|
if(!value) {
|
|
self.reset(hash);
|
|
}
|
|
|
|
var query = message_area_sel.attr('data-autocompletion-query');
|
|
|
|
if(query === undefined) {
|
|
// The autocompletion has not been yet launched
|
|
query = self.getSubQueries(value);
|
|
message_area_sel.attr('data-autocompletion-query', JSON.stringify(query));
|
|
} else {
|
|
// The autocompletion has already stored a query
|
|
query = JSON.parse(query);
|
|
}
|
|
|
|
// Get the pointer
|
|
var pointer = message_area_sel.attr('data-autocompletion-pointer');
|
|
var i = pointer ? parseInt(pointer, 10) : 0;
|
|
|
|
// We get the nickname
|
|
var nick_result = self.process(query[0], hash)[i];
|
|
var nick;
|
|
|
|
if(nick_result !== undefined) {
|
|
nick = nick_result[0];
|
|
}
|
|
|
|
// Shit, this is my nick!
|
|
if((nick !== undefined) && (nick.toLowerCase() == Name.getMUCNick(hash).toLowerCase())) {
|
|
// Increment
|
|
i++;
|
|
|
|
// Get the next nick
|
|
nick_result = self.process(query[0], hash)[i];
|
|
|
|
if (nick_result !== undefined) {
|
|
nick = nick_result[0];
|
|
}
|
|
}
|
|
|
|
// We quote the nick
|
|
if((nick_result !== undefined) && (nick !== undefined)) {
|
|
// Increment
|
|
i++;
|
|
|
|
Utils.quoteMyNick(
|
|
hash,
|
|
nick,
|
|
query[1][nick_result[1]]
|
|
);
|
|
|
|
// Put a pointer
|
|
message_area_sel.attr('data-autocompletion-pointer', i);
|
|
}
|
|
} catch(e) {
|
|
Console.error('Autocompletion.create', e);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Return class scope
|
|
*/
|
|
return self;
|
|
|
|
})();
|