X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=view%2Fjs%2Fautocomplete.js;h=dc649084afe83b45ae7a91d8c6907cba83aa125c;hb=96d2cddb54f3ea3ead6e43e5ca1f814ed6327987;hp=18deaa1d3052717a8ca027f5889dc7373327d906;hpb=9a8f6256e3ff6490a539c36d4f2affb4cfb2c15d;p=friendica.git
diff --git a/view/js/autocomplete.js b/view/js/autocomplete.js
index 18deaa1d30..dc649084af 100644
--- a/view/js/autocomplete.js
+++ b/view/js/autocomplete.js
@@ -1,6 +1,6 @@
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat
/**
- * @brief Friendica people autocomplete
+ * Friendica people autocomplete
*
* require jQuery, jquery.textcomplete
*
@@ -13,7 +13,7 @@
function contact_search(term, callback, backend_url, type, mode) {
- // Check if there is a conversation id to include the unkonwn contacts of the conversation
+ // Check if there is a conversation id to include the unknown contacts of the conversation
var conv_id = document.activeElement.id.match(/\d+$/);
// Check if there is a cached result that contains the same information we would get with a full server-side search
@@ -24,8 +24,8 @@ function contact_search(term, callback, backend_url, type, mode) {
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({forum:false, text: term, replace: term});
+ 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 circles don't have one
+ matching.unshift({group: false, text: term, replace: term});
setTimeout(function() { callback(matching); } , 1); // Use "pseudo-thread" to avoid some problems
return;
}
@@ -69,10 +69,10 @@ 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);
- var forum = ((item.forum) ? 'forum' : '');
+ var group = ((item.group) ? 'group' : '');
if(typeof desc === 'undefined') desc = '';
if(desc) desc = ' ('+desc+')';
- return "
".format(forum, item.photo, item.name, desc, item.link);
+ return "".format(group, item.photo, item.name, desc, item.link);
}
else
return "" + item.text + "
";
@@ -197,6 +197,56 @@ function string2bb(element) {
* jQuery plugin 'editor_autocomplete'
*/
(function( $ ) {
+ let textcompleteObjects = [];
+
+ // jQuery wrapper for yuku/old-textcomplete
+ // uses a local object directory to avoid recreating Textcomplete objects
+ $.fn.textcomplete = function (strategies, options) {
+ return this.each(function () {
+ let $this = $(this);
+ if (!($this.data('textcompleteId') in textcompleteObjects)) {
+ let editor = new Textcomplete.editors.Textarea($this.get(0));
+
+ $this.data('textcompleteId', textcompleteObjects.length);
+ textcompleteObjects.push(new Textcomplete(editor, options));
+ }
+
+ textcompleteObjects[$this.data('textcompleteId')].register(strategies);
+ });
+ };
+
+ /**
+ * This function should be called immediately after $.textcomplete() to prevent the escape key press to propagate
+ * after the autocompletion dropdown has closed.
+ * This avoids the input textarea to lose focus, the modal window to close, etc... when the expected behavior is
+ * to just close the autocomplete dropdown.
+ *
+ * The custom event listener name allows removing this specific event listener, the "real" event this listens to
+ * is the part before the first dot.
+ *
+ * @returns {*}
+ */
+ $.fn.fixTextcompleteEscape = function () {
+ if (this.data('textcompleteEscapeFixed')) {
+ return this;
+ }
+
+ this.data('textcompleteEscapeFixed', true);
+
+ return this.on({
+ 'textComplete:show': function (e) {
+ $(this).on('keydown.friendica.escape', function (e) {
+ if (e.key === 'Escape') {
+ e.stopPropagation();
+ }
+ });
+ },
+ 'textComplete:hide': function (e) {
+ $(this).off('keydown.friendica.escape');
+ },
+ });
+ }
+
$.fn.editor_autocomplete = function(backend_url) {
// Autocomplete contacts
@@ -208,8 +258,8 @@ function string2bb(element) {
template: contact_format,
};
- // Autocomplete forums
- forums = {
+ // Autocomplete groups
+ groups = {
match: /(^|\s)(!\!*)([^ \n]+)$/,
index: 3,
search: function(term, callback) { contact_search(term, callback, backend_url, 'f'); },
@@ -222,7 +272,7 @@ function string2bb(element) {
match: /(^|\s)(\#)([^ \n]{2,})$/,
index: 3,
search: function(term, callback) {
- $.getJSON(baseurl + '/hashtag/' + '?f=&t=' + term)
+ $.getJSON(baseurl + '/hashtag/' + '?t=' + term)
.done(function(data) {
callback($.map(data, function(entry) {
// .toLowerCase() enables case-insensitive search
@@ -244,14 +294,12 @@ function string2bb(element) {
};
this.attr('autocomplete','off');
- this.textcomplete([contacts, forums, smilies, tags], {className:'acpopup', zIndex:10000});
+ this.textcomplete([contacts, groups, smilies, tags], {dropdown: {className:'acpopup'}});
+ this.fixTextcompleteEscape();
+
+ return this;
};
-})( jQuery );
-/**
- * jQuery plugin 'search_autocomplete'
- */
-(function( $ ) {
$.fn.search_autocomplete = function(backend_url) {
// Autocomplete contacts
contacts = {
@@ -262,7 +310,7 @@ function string2bb(element) {
template: contact_format,
};
- // Autocomplete forum accounts
+ // Autocomplete group accounts
community = {
match: /(^!)([^\n]{2,})$/,
index: 2,
@@ -275,22 +323,50 @@ function string2bb(element) {
tags = {
match: /(^|\s)(\#)([^ \n]{2,})$/,
index: 3,
- search: function(term, callback) { $.getJSON(baseurl + '/hashtag/' + '?f=&t=' + term).done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); },
+ search: function(term, callback) { $.getJSON(baseurl + '/hashtag/' + '?t=' + term).done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); },
replace: function(item) { return "$1$2" + item.text; },
template: tag_format
};
this.attr('autocomplete', 'off');
- var a = this.textcomplete([contacts, community, tags], {className:'acpopup', maxCount:100, zIndex: 10000, appendTo:'nav'});
- a.on('textComplete:select', function(e, value, strategy) { submit_form(this); });
+ this.textcomplete([contacts, community, tags], {dropdown: {className:'acpopup', maxCount:100}});
+ this.fixTextcompleteEscape();
+ this.on('textComplete:select', function(e, value, strategy) { submit_form(this); });
+
+ return this;
};
-})( jQuery );
-(function( $ ) {
- $.fn.bbco_autocomplete = function(type) {
+ $.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');
+ this.textcomplete([names], {dropdown: {className:'acpopup'}});
+ this.fixTextcompleteEscape();
- if(type=='bbcode') {
- var open_close_elements = ['bold', 'italic', 'underline', 'overline', 'strike', 'quote', 'code', 'spoiler', 'map', 'img', 'url', 'audio', 'video', 'embed', 'youtube', 'vimeo', 'list', 'ul', 'ol', 'li', 'table', 'tr', 'th', 'td', 'center', 'color', 'font', 'size', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'nobb', 'noparse', 'pre', 'abstract'];
+ if(autosubmit) {
+ this.on('textComplete:select', function(e,value,strategy) { submit_form(this); });
+ }
+
+ if(typeof onselect !== 'undefined') {
+ this.on('textComplete:select', function(e, value, strategy) { onselect(value); });
+ }
+
+ return this;
+ };
+
+ $.fn.bbco_autocomplete = function(type) {
+ if (type === 'bbcode') {
+ var open_close_elements = ['bold', 'italic', 'underline', 'overline', 'strike', 'quote', 'code', 'spoiler', 'map', 'img', 'url', 'audio', 'video', 'embed', 'youtube', 'vimeo', 'list', 'ul', 'ol', 'li', 'table', 'tr', 'th', 'td', 'center', 'color', 'font', 'size', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'nobb', 'noparse', 'pre', 'abstract', 'share'];
var open_elements = ['*', 'hr'];
var elements = open_close_elements.concat(open_elements);
@@ -324,11 +400,12 @@ function string2bb(element) {
};
this.attr('autocomplete','off');
- var a = this.textcomplete([bbco], {className:'acpopup', zIndex:10000});
+ this.textcomplete([bbco], {dropdown: {className:'acpopup'}});
+ this.fixTextcompleteEscape();
- a.on('textComplete:select', function(e, value, strategy) { value; });
+ this.on('textComplete:select', function(e, value, strategy) { value; });
- a.keypress(function(e){
+ this.keypress(function(e){
if (e.keyCode == 13) {
var x = listNewLineAutocomplete(this.id);
if(x) {
@@ -337,135 +414,8 @@ function string2bb(element) {
}
}
});
+
+ return this;
};
})( jQuery );
-
-/**
- * Friendica people autocomplete legacy code
- *
- * require jQuery, jquery.textareas
- */
-function ACPopup(elm, backend_url){
- this.idsel = -1;
- this.element = elm;
- this.searchText = '';
- this.ready = true;
- this.kp_timer = false;
- this.url = backend_url;
-
- this.conversation_id = null;
- var conv_id = this.element.id.match(/\d+$/);
- if (conv_id) {
- this.conversation_id = conv_id[0];
- }
-
- var w = $(elm).width();
- var h = $(elm).height();
-
- var style = $(elm).offset();
- style.top = style.top + h;
- style.width = w;
- style.position = 'absolute';
- style.display = 'none';
-
- this.cont = $('');
- this.cont.css(style);
-
- $('body').append(this.cont);
-}
-
-ACPopup.prototype.close = function(){
- $(this.cont).remove();
- this.ready=false;
-}
-ACPopup.prototype.search = function(text){
- var that = this;
- this.searchText=text;
- if (this.kp_timer) clearTimeout(this.kp_timer);
- this.kp_timer = setTimeout( function(){that._search();}, 500);
-}
-
-ACPopup.prototype._search = function(){
- console.log("_search");
- var that = this;
- var postdata = {
- start:0,
- count:100,
- search:this.searchText,
- type:'c',
- conversation: this.conversation_id,
- }
-
- $.ajax({
- type:'POST',
- url: this.url,
- data: postdata,
- dataType: 'json',
- success:function(data){
- that.cont.html("");
- if (data.tot>0){
- that.cont.show();
- $(data.items).each(function(){
- var html = "{1} ({2})".format(this.photo, this.name, this.nick);
- var nick = this.nick.replace(' ','');
- if (this.id!=='') nick += '+' + this.id;
- that.add(html, nick + ' - ' + this.link);
- });
- } else {
- that.cont.hide();
- }
- }
- });
-
-}
-
-ACPopup.prototype.add = function(label, value){
- var that = this;
- var elm = $('');
- elm.click(function(e){
- t = $(this).attr('title').replace(new RegExp(' \- .*'), '');
- el = $(that.element);
- sel = el.getSelection();
- sel.start = sel.start - that.searchText.length;
- el.setSelection(sel.start, sel.end).replaceSelectedText(t + ' ').collapseSelection(false);
- that.close();
- });
- $(this.cont).append(elm);
-}
-
-ACPopup.prototype.onkey = function(event){
- if (event.keyCode == '13') {
- if(this.idsel > -1) {
- this.cont.children()[this.idsel].click();
- event.preventDefault();
- } else {
- this.close();
- }
- }
- if (event.keyCode == '38') { //cursor up
- var cmax = this.cont.children().size() - 1;
- this.idsel--;
- if (this.idsel < 0) {
- this.idsel = cmax;
- }
- event.preventDefault();
- }
- if (event.keyCode == '40' || event.keyCode == '9') { //cursor down
- var cmax = this.cont.children().size() - 1;
- this.idsel++;
- if (this.idsel > cmax) {
- this.idsel = 0;
- }
- event.preventDefault();
- }
-
- if (event.keyCode == '38' || event.keyCode == '40' || event.keyCode == '9') {
- this.cont.children().removeClass('selected');
- $(this.cont.children()[this.idsel]).addClass('selected');
- }
-
- if (event.keyCode == '27') { //ESC
- this.close();
- }
-}
// @license-end