rework autocomplete: initial commit

pull/2449/head
rabuzarus 2016-01-19 18:11:40 +01:00
rodzic a1eb7a8791
commit 16e4e94b29
8 zmienionych plików z 1325 dodań i 6 usunięć

192
js/autocomplete.js 100644
Wyświetl plik

@ -0,0 +1,192 @@
/**
* Red people autocomplete
*
* require jQuery, jquery.textcomplete
*/
function contact_search(term, callback, backend_url, type) {
// Check if there is a cached result that contains the same information we would get with a full server-side search
var bt = backend_url+type;
if(!(bt in contact_search.cache)) contact_search.cache[bt] = {};
var lterm = term.toLowerCase(); // Ignore case
for(var t in contact_search.cache[bt]) {
if(lterm.indexOf(t) >= 0) { // A more broad search has been performed already, so use those results
// Filter old results locally
var matching = contact_search.cache[bt][t].filter(function (x) { return (x.name.toLowerCase().indexOf(lterm) >= 0 || (typeof x.nick !== 'undefined' && x.nick.toLowerCase().indexOf(lterm) >= 0)); }); // Need to check that nick exists because groups don't have one
matching.unshift({taggable:false, text: term, replace: term});
setTimeout(function() { callback(matching); } , 1); // Use "pseudo-thread" to avoid some problems
return;
}
}
var postdata = {
start:0,
count:100,
search:term,
type:type,
};
$.ajax({
type:'POST',
url: backend_url,
data: postdata,
dataType: 'json',
success: function(data){
// Cache results if we got them all (more information would not improve results)
// data.count represents the maximum number of items
if(data.items.length -1 < data.count) {
contact_search.cache[bt][lterm] = data.items;
}
var items = data.items.slice(0);
items.unshift({taggable:false, text: term, replace: term});
callback(items);
},
}).fail(function () {callback([]); }); // Callback must be invoked even if something went wrong.
}
contact_search.cache = {};
function contact_format(item) {
// Show contact information if not explicitly told to show something else
if(typeof item.text === 'undefined') {
var desc = ((item.label) ? item.nick + ' ' + item.label : item.nick);
if(typeof desc === 'undefined') desc = '';
if(desc) desc = ' ('+desc+')';
return "<div class='{0}' title='{4}'><img class='dropdown-menu-img-sm' src='{1}'><span class='contactname'>{2}</span><span class='dropdown-sub-text'>{3}</span><div class='clear'></div></div>".format(item.taggable, item.photo, item.name, desc, item.link);
}
else
return "<div>" + item.text + "</div>";
}
function editor_replace(item) {
if(typeof item.replace !== 'undefined') {
return '$1$2' + item.replace;
}
// $2 ensures that prefix (@,@!) is preserved
var id = item.id;
// 16 chars of hash should be enough. Full hash could be used if it can be done in a visually appealing way.
// 16 chars is also the minimum length in the backend (otherwise it's interpreted as a local id).
if(id.length > 16)
id = item.id.substring(0,16);
return '$1$2' + item.nick.replace(' ', '') + '+' + id + ' ';
}
function basic_replace(item) {
if(typeof item.replace !== 'undefined')
return '$1'+item.replace;
return '$1'+item.name+' ';
}
function trim_replace(item) {
if(typeof item.replace !== 'undefined')
return '$1'+item.replace;
return '$1'+item.name;
}
function submit_form(e) {
$(e).parents('form').submit();
}
/**
* jQuery plugin 'editor_autocomplete'
*/
(function( $ ) {
$.fn.editor_autocomplete = function(backend_url) {
// Autocomplete contacts
contacts = {
match: /(^|\s)(@\!*)([^ \n]+)$/,
index: 3,
search: function(term, callback) { contact_search(term, callback, backend_url, 'c'); },
replace: editor_replace,
template: contact_format,
};
smilies = {
match: /(^|\s)(:[a-z]{2,})$/,
index: 2,
search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); },
template: function(item) { return item.icon + item.text; },
replace: function(item) { return "$1" + item.text + ' '; },
};
this.attr('autocomplete','off');
this.textcomplete([contacts,smilies], {className:'acpopup', zIndex:1020});
};
})( jQuery );
/**
* jQuery plugin 'search_autocomplete'
*/
(function( $ ) {
$.fn.search_autocomplete = function(backend_url) {
// Autocomplete contacts
contacts = {
match: /(^@)([^\n]{2,})$/,
index: 2,
search: function(term, callback) { contact_search(term, callback, backend_url, 'x'); },
replace: basic_replace,
template: contact_format,
};
this.attr('autocomplete', 'off');
var a = this.textcomplete([contacts], {className:'acpopup', maxCount:100, zIndex: 1020, appendTo:'nav'});
a.on('textComplete:select', function(e, value, strategy) { submit_form(this); });
};
})( jQuery );
(function( $ ) {
$.fn.contact_autocomplete = function(backend_url, typ, autosubmit, onselect) {
if(typeof typ === 'undefined') typ = '';
if(typeof autosubmit === 'undefined') autosubmit = false;
// Autocomplete contacts
contacts = {
match: /(^)([^\n]+)$/,
index: 2,
search: function(term, callback) { contact_search(term, callback, backend_url, typ); },
replace: basic_replace,
template: contact_format,
};
this.attr('autocomplete','off');
var a = this.textcomplete([contacts], {className:'acpopup', zIndex:1020});
if(autosubmit)
a.on('textComplete:select', function(e,value,strategy) { submit_form(this); });
if(typeof onselect !== 'undefined')
a.on('textComplete:select', function(e, value, strategy) { onselect(value); });
};
})( jQuery );
(function( $ ) {
$.fn.name_autocomplete = function(backend_url, typ, autosubmit, onselect) {
if(typeof typ === 'undefined') typ = '';
if(typeof autosubmit === 'undefined') autosubmit = false;
// Autocomplete contacts
names = {
match: /(^)([^\n]+)$/,
index: 2,
search: function(term, callback) { contact_search(term, callback, backend_url, typ); },
replace: trim_replace,
template: contact_format,
};
this.attr('autocomplete','off');
var a = this.textcomplete([names], {className:'acpopup', zIndex:1020});
if(autosubmit)
a.on('textComplete:select', function(e,value,strategy) { submit_form(this); });
if(typeof onselect !== 'undefined')
a.on('textComplete:select', function(e, value, strategy) { onselect(value); });
};
})( jQuery );

Wyświetl plik

@ -86,7 +86,7 @@ ACPopup.prototype._search = function(){
if (data.tot>0){ if (data.tot>0){
that.cont.show(); that.cont.show();
$(data.items).each(function(){ $(data.items).each(function(){
var html = "<img src='{0}' height='16px' width='16px'>{1} ({2})".format(this.photo, this.name, this.nick); var html = "<img class='acpopup-img' src='{0}' height='16px' width='16px'> <span class='acpopup-name'>{1}</span> <span class='acpopup-addr'>({2})</span>".format(this.photo, this.name, this.addr);
var nick = this.nick.replace(' ',''); var nick = this.nick.replace(' ','');
if (this.id!=='') nick += '+' + this.id; if (this.id!=='') nick += '+' + this.id;
that.add(html, nick + ' - ' + this.link); that.add(html, nick + ' - ' + this.link);

Wyświetl plik

@ -493,7 +493,7 @@
$('body').css('cursor', 'auto'); $('body').css('cursor', 'auto');
} }
/* autocomplete @nicknames */ /* autocomplete @nicknames */
$(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl"); $(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl");
// setup videos, since VideoJS won't take care of any loaded via AJAX // setup videos, since VideoJS won't take care of any loaded via AJAX
if(typeof videojs != 'undefined') videojs.autoSetup(); if(typeof videojs != 'undefined') videojs.autoSetup();

Wyświetl plik

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013-2014 Yuku Takahashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Wyświetl plik

@ -1,9 +1,9 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$(".comment-edit-wrapper textarea").contact_autocomplete(baseurl+"/acl"); $(".comment-edit-wrapper textarea").editor_autocomplete(baseurl+"/acl");
// make auto-complete work in more places // make auto-complete work in more places
$(".wall-item-comment-wrapper textarea").contact_autocomplete(baseurl+"/acl"); $(".wall-item-comment-wrapper textarea").editor_autocomplete(baseurl+"/acl");
}); });
</script> </script>

Wyświetl plik

@ -33,7 +33,9 @@
<!-- <script type="text/javascript" src="{{$baseurl}}/js/jquery-migrate.js" ></script>--> <!-- <script type="text/javascript" src="{{$baseurl}}/js/jquery-migrate.js" ></script>-->
<script type="text/javascript" src="{{$baseurl}}/js/jquery-migrate.js" ></script> <script type="text/javascript" src="{{$baseurl}}/js/jquery-migrate.js" ></script>
<script type="text/javascript" src="{{$baseurl}}/js/jquery.textinputs.js" ></script> <script type="text/javascript" src="{{$baseurl}}/js/jquery.textinputs.js" ></script>
<script type="text/javascript" src="{{$baseurl}}/js/fk.autocomplete.js" ></script> <script type="text/javascript" src="{{$baseurl}}/library/jquery-textcomplete/jquery.textcomplete.js" ></script>
<script type="text/javascript" src="{{$baseurl}}/js/autocomplete.js" ></script>
<!--<script type="text/javascript" src="{{$baseurl}}/js/fk.autocomplete.js" ></script>-->
<script type="text/javascript" src="{{$baseurl}}/library/colorbox/jquery.colorbox-min.js"></script> <script type="text/javascript" src="{{$baseurl}}/library/colorbox/jquery.colorbox-min.js"></script>
<script type="text/javascript" src="{{$baseurl}}/library/jgrowl/jquery.jgrowl_minimized.js"></script> <script type="text/javascript" src="{{$baseurl}}/library/jgrowl/jquery.jgrowl_minimized.js"></script>
<script type="text/javascript" src="{{$baseurl}}/library/datetimepicker/jquery.datetimepicker.js"></script> <script type="text/javascript" src="{{$baseurl}}/library/datetimepicker/jquery.datetimepicker.js"></script>

Wyświetl plik

@ -12,7 +12,7 @@ function initEditor(cb){
if(plaintext == 'none') { if(plaintext == 'none') {
$("#profile-jot-text-loading").hide(); $("#profile-jot-text-loading").hide();
$("#profile-jot-text").css({ 'height': 200, 'color': '#000' }); $("#profile-jot-text").css({ 'height': 200, 'color': '#000' });
$("#profile-jot-text").contact_autocomplete(baseurl+"/acl"); $("#profile-jot-text").editor_autocomplete(baseurl+"/acl");
editor = true; editor = true;
$("a#jot-perms-icon").colorbox({ $("a#jot-perms-icon").colorbox({
'inline' : true, 'inline' : true,