diff rhodecode/public/js/rhodecode.js @ 2368:5143b8df576c beta

Added mentions autocomplete into main comments form - recompiled yui.2.9.js using google compiler
author Marcin Kuzminski <marcin@python-works.com>
date Fri, 01 Jun 2012 18:34:32 +0200
parents 3052f90c568a
children c2f131502037
line wrap: on
line diff
--- a/rhodecode/public/js/rhodecode.js	Fri Jun 01 17:59:57 2012 +0200
+++ b/rhodecode/public/js/rhodecode.js	Fri Jun 01 18:34:32 2012 +0200
@@ -988,6 +988,189 @@
 }
 
 
+var MentionsAutoComplete = function (divid, cont, users_list, groups_list, group_lbl, members_lbl) {
+    var myUsers = users_list;
+    var myGroups = groups_list;
+
+    // Define a custom search function for the DataSource of users
+    var matchUsers = function (sQuery) {
+    	    var org_sQuery = sQuery;
+    	    if(this.mentionQuery == null){
+    	    	return []    	    	
+    	    }
+    	    sQuery = this.mentionQuery;
+            // Case insensitive matching
+            var query = sQuery.toLowerCase();
+            var i = 0;
+            var l = myUsers.length;
+            var matches = [];
+
+            // Match against each name of each contact
+            for (; i < l; i++) {
+                contact = myUsers[i];
+                if ((contact.fname.toLowerCase().indexOf(query) > -1) || (contact.lname.toLowerCase().indexOf(query) > -1) || (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
+                    matches[matches.length] = contact;
+                }
+            }
+            return matches
+        };
+
+    //match all
+    var matchAll = function (sQuery) {
+            u = matchUsers(sQuery);
+            return u
+        };
+
+    // DataScheme for owner
+    var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
+    ownerDS.responseSchema = {
+        fields: ["id", "fname", "lname", "nname", "gravatar_lnk"]
+    };
+
+    // Instantiate AutoComplete for mentions
+    var ownerAC = new YAHOO.widget.AutoComplete(divid, cont, ownerDS);
+    ownerAC.useShadow = false;
+    ownerAC.resultTypeList = false;
+    ownerAC.suppressInputUpdate = true;
+
+    // Helper highlight function for the formatter
+    var highlightMatch = function (full, snippet, matchindex) {
+            return full.substring(0, matchindex) 
+            + "<span class='match'>" 
+            + full.substr(matchindex, snippet.length) 
+            + "</span>" + full.substring(matchindex + snippet.length);
+        };
+
+    // Custom formatter to highlight the matching letters
+    ownerAC.formatResult = function (oResultData, sQuery, sResultMatch) {
+		    var org_sQuery = sQuery;
+		    if(this.dataSource.mentionQuery != null){
+		    	sQuery = this.dataSource.mentionQuery;		    	
+		    }
+
+            var query = sQuery.toLowerCase();
+            var _gravatar = function(res, em, group){
+            	if (group !== undefined){
+            		em = '/images/icons/group.png'
+            	}
+            	tmpl = '<div class="ac-container-wrap"><img class="perm-gravatar-ac" src="{0}"/>{1}</div>'
+            	return tmpl.format(em,res)
+            }
+            if (oResultData.fname != undefined) {
+                var fname = oResultData.fname,
+                    lname = oResultData.lname,
+                    nname = oResultData.nname || "",
+                    // Guard against null value
+                    fnameMatchIndex = fname.toLowerCase().indexOf(query),
+                    lnameMatchIndex = lname.toLowerCase().indexOf(query),
+                    nnameMatchIndex = nname.toLowerCase().indexOf(query),
+                    displayfname, displaylname, displaynname;
+
+                if (fnameMatchIndex > -1) {
+                    displayfname = highlightMatch(fname, query, fnameMatchIndex);
+                } else {
+                    displayfname = fname;
+                }
+
+                if (lnameMatchIndex > -1) {
+                    displaylname = highlightMatch(lname, query, lnameMatchIndex);
+                } else {
+                    displaylname = lname;
+                }
+
+                if (nnameMatchIndex > -1) {
+                    displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
+                } else {
+                    displaynname = nname ? "(" + nname + ")" : "";
+                }
+
+                return _gravatar(displayfname + " " + displaylname + " " + displaynname, oResultData.gravatar_lnk);
+            } else {
+                return '';
+            }
+        };
+
+    if(ownerAC.itemSelectEvent){
+    	ownerAC.itemSelectEvent.subscribe(function (sType, aArgs) {
+
+            var myAC = aArgs[0]; // reference back to the AC instance
+            var elLI = aArgs[1]; // reference to the selected LI element
+            var oData = aArgs[2]; // object literal of selected item's result data
+            //fill the autocomplete with value
+            if (oData.nname != undefined) {
+                //users
+            	//Replace the mention name with replaced
+            	var re = new RegExp();
+            	var org = myAC.getInputEl().value;
+            	var chunks = myAC.dataSource.chunks
+            	// replace middle chunk(the search term) with actuall  match
+            	chunks[1] = chunks[1].replace('@'+myAC.dataSource.mentionQuery,
+            								  '@'+oData.nname+' ');
+                myAC.getInputEl().value = chunks.join('')
+                YUD.get(myAC.getInputEl()).focus(); // Y U NO WORK !?
+            } else {
+                //groups
+                myAC.getInputEl().value = oData.grname;
+                YUD.get('perm_new_member_type').value = 'users_group';
+            }
+        });
+    }
+
+    // in this keybuffer we will gather current value of search !
+    // since we need to get this just when someone does `@` then we do the
+    // search
+    ownerAC.dataSource.chunks = [];
+    ownerAC.dataSource.mentionQuery = null;
+
+    ownerAC.get_mention = function(msg, max_pos) {
+    	var org = msg;
+    	var re = new RegExp('(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)$')
+    	var chunks  = [];
+
+		
+    	// cut first chunk until curret pos
+		var to_max = msg.substr(0, max_pos);		
+		var at_pos = Math.max(0,to_max.lastIndexOf('@')-1);
+		var msg2 = to_max.substr(at_pos);
+
+		chunks.push(org.substr(0,at_pos))// prefix chunk
+		chunks.push(msg2)                // search chunk
+		chunks.push(org.substr(max_pos)) // postfix chunk
+
+		// clean up msg2 for filtering and regex match
+		var msg2 = msg2.replace(' ','').replace('\n','');
+
+		if(re.test(msg2)){
+			var unam = re.exec(msg2)[1];
+			return [unam, chunks];
+		}
+		return [null, null];
+    };    
+	ownerAC.textboxKeyUpEvent.subscribe(function(type, args){
+		
+		var ac_obj = args[0];
+		var currentMessage = args[1];
+		var currentCaretPosition = args[0]._elTextbox.selectionStart;
+
+		var unam = ownerAC.get_mention(currentMessage, currentCaretPosition); 
+		var curr_search = null;
+		if(unam[0]){
+			curr_search = unam[0];
+		}
+		
+		ownerAC.dataSource.chunks = unam[1];
+		ownerAC.dataSource.mentionQuery = curr_search;
+
+	})
+
+    return {
+        ownerDS: ownerDS,
+        ownerAC: ownerAC,
+    };
+}
+
+
+
 
 /**
  * QUICK REPO MENU