/* 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; })();