##// END OF EJS Templates
front-end: use At.js for MentionsAutoComplete...
domruf -
r7387:2e7ffb75 default
parent child Browse files
Show More
@@ -32,6 +32,8 b' syntax: regexp'
32 ^kallithea/public/css/style\.css\.map$
32 ^kallithea/public/css/style\.css\.map$
33 ^kallithea/public/js/bootstrap\.js$
33 ^kallithea/public/js/bootstrap\.js$
34 ^kallithea/public/js/dataTables\.bootstrap\.js$
34 ^kallithea/public/js/dataTables\.bootstrap\.js$
35 ^kallithea/public/js/jquery\.atwho\.min\.js$
36 ^kallithea/public/js/jquery\.caret\.min\.js$
35 ^kallithea/public/js/jquery\.dataTables\.js$
37 ^kallithea/public/js/jquery\.dataTables\.js$
36 ^kallithea/public/js/jquery\.flot\.js$
38 ^kallithea/public/js/jquery\.flot\.js$
37 ^kallithea/public/js/jquery\.flot\.selection\.js$
39 ^kallithea/public/js/jquery\.flot\.selection\.js$
@@ -84,6 +84,38 b" using the ''kallithea-cli front-end-buil"
84
84
85
85
86
86
87 At.js
88 -----
89
90 Kallithea uses the Javascript system called
91 [At.js](http://ichord.github.com/At.js),
92 which can be found together with its Corresponding Source in
93 https://github.com/ichord/At.js at tag v1.5.4.
94
95 It is Copyright 2013 chord.luo@gmail.com and is under an
96 [MIT-permissive license](MIT-Permissive-License.txt).
97
98 It is not distributed with Kallithea, but will be downloaded
99 using the ''kallithea-cli front-end-build'' command.
100
101
102
103 Caret.js
104 --------
105
106 Kallithea uses the Javascript system called
107 [Caret.js](http://ichord.github.com/Caret.js/),
108 which can be found together with its Corresponding Source in
109 https://github.com/ichord/Caret.js at tag v0.3.1.
110
111 It is Copyright 2013 chord.luo@gmail.com and is under an
112 [MIT-permissive license](MIT-Permissive-License.txt).
113
114 It is not distributed with Kallithea, but will be downloaded
115 using the ''kallithea-cli front-end-build'' command.
116
117
118
87 DataTables
119 DataTables
88 ----------
120 ----------
89
121
@@ -66,11 +66,13 b' def front_end_build(install_deps, genera'
66 click.echo("Preparing Bootstrap JS")
66 click.echo("Preparing Bootstrap JS")
67 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'bootstrap', 'dist', 'js', 'bootstrap.js'), os.path.join(public_dir, 'js', 'bootstrap.js'))
67 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'bootstrap', 'dist', 'js', 'bootstrap.js'), os.path.join(public_dir, 'js', 'bootstrap.js'))
68
68
69 click.echo("Preparing jQuery JS with Flot")
69 click.echo("Preparing jQuery JS with Flot, Caret and Atwho")
70 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery', 'dist', 'jquery.min.js'), os.path.join(public_dir, 'js', 'jquery.min.js'))
70 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery', 'dist', 'jquery.min.js'), os.path.join(public_dir, 'js', 'jquery.min.js'))
71 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.js'), os.path.join(public_dir, 'js', 'jquery.flot.js'))
71 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.js'), os.path.join(public_dir, 'js', 'jquery.flot.js'))
72 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.selection.js'), os.path.join(public_dir, 'js', 'jquery.flot.selection.js'))
72 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.selection.js'), os.path.join(public_dir, 'js', 'jquery.flot.selection.js'))
73 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.time.js'), os.path.join(public_dir, 'js', 'jquery.flot.time.js'))
73 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.time.js'), os.path.join(public_dir, 'js', 'jquery.flot.time.js'))
74 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.caret', 'dist', 'jquery.caret.min.js'), os.path.join(public_dir, 'js', 'jquery.caret.min.js'))
75 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'at.js', 'dist', 'js', 'jquery.atwho.min.js'), os.path.join(public_dir, 'js', 'jquery.atwho.min.js'))
74
76
75 click.echo("Preparing DataTables JS")
77 click.echo("Preparing DataTables JS")
76 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'datatables.net', 'js', 'jquery.dataTables.js'), os.path.join(public_dir, 'js', 'jquery.dataTables.js'))
78 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'datatables.net', 'js', 'jquery.dataTables.js'), os.path.join(public_dir, 'js', 'jquery.dataTables.js'))
@@ -2,11 +2,13 b''
2 "name": "kallithea",
2 "name": "kallithea",
3 "private": true,
3 "private": true,
4 "dependencies": {
4 "dependencies": {
5 "at.js": "1.5.4",
5 "bootstrap": "3.3.7",
6 "bootstrap": "3.3.7",
6 "codemirror": "4.7",
7 "codemirror": "4.7",
7 "datatables.net": "1.10.13",
8 "datatables.net": "1.10.13",
8 "datatables.net-bs": "1.10.13",
9 "datatables.net-bs": "1.10.13",
9 "jquery": "1.12.3",
10 "jquery": "1.12.3",
11 "jquery.caret": "0.3.1",
10 "jquery.flot": "0.8.3",
12 "jquery.flot": "0.8.3",
11 "select2": "3.5.1",
13 "select2": "3.5.1",
12 "select2-bootstrap-css": "1.2.4"
14 "select2-bootstrap-css": "1.2.4"
@@ -751,7 +751,7 b' function _comment_div_append_form($comme'
751
751
752 tooltip_activate();
752 tooltip_activate();
753 if ($textarea.length > 0) {
753 if ($textarea.length > 0) {
754 MentionsAutoComplete($textarea, _USERS_AC_DATA);
754 MentionsAutoComplete($textarea);
755 }
755 }
756 if (f_path) {
756 if (f_path) {
757 $textarea.focus();
757 $textarea.focus();
@@ -1155,65 +1155,30 b' var MembersAutoComplete = function ($inp'
1155 });
1155 });
1156 }
1156 }
1157
1157
1158 var MentionsAutoComplete = function ($inputElement, users_list) {
1158 var MentionsAutoComplete = function ($inputElement) {
1159 var $container = $('<div/>').insertAfter($inputElement);
1159 $inputElement.atwho({
1160
1160 at: "@",
1161 var matchUsers = function (sQuery) {
1161 callbacks: {
1162 // use the search string from $inputElement instead of sQuery
1162 remoteFilter: function(query, callback) {
1163 if(!$container.data('search')){
1163 $.getJSON(
1164 // return empty list so the input list isn't shown
1164 pyroutes.url('users_and_groups_data'),
1165 return []
1165 {
1166 }
1166 query: query,
1167 return autocompleteMatchUsers($container.data('search'), users_list);
1167 types: 'users'
1168 }
1168 },
1169
1169 function(data) {
1170 var datasource = new YAHOO.util.FunctionDataSource(matchUsers);
1170 callback(data.results)
1171 var mentionsAC = new YAHOO.widget.AutoComplete($inputElement[0], $container[0], datasource);
1171 }
1172 mentionsAC.useShadow = false;
1172 );
1173 mentionsAC.resultTypeList = false;
1173 },
1174 mentionsAC.animVert = false;
1174 sorter: function(query, items, searchKey) {
1175 mentionsAC.animHoriz = false;
1175 return items;
1176 mentionsAC.animSpeed = 0.1;
1176 }
1177 mentionsAC.suppressInputUpdate = true;
1177 },
1178 mentionsAC.formatResult = function (oResultData, sQuery, sResultMatch) {
1178 displayTpl: "<li>" + autocompleteGravatar('${fname} ${lname} (${nname})', '${gravatar_lnk}', 16) + "</li>",
1179 // use the search string from $inputElement instead of sQuery
1179 insertTpl: "${atwho-at}${nname}"
1180 return autocompleteFormatter(oResultData, $container.data('search'), sResultMatch);
1180 });
1181 }
1181 };
1182
1183 // Handler for selection of an entry
1184 if(mentionsAC.itemSelectEvent){
1185 mentionsAC.itemSelectEvent.subscribe(function (sType, aArgs) {
1186 var myAC = aArgs[0]; // reference back to the AC instance
1187 var elLI = aArgs[1]; // reference to the selected LI element
1188 var oData = aArgs[2]; // object literal of selected item's result data
1189 myAC.getInputEl().value = $container.data('before') + oData.nname + ' ' + $container.data('after');
1190 _setCaretPosition($(myAC.getInputEl()), myAC.dataSource.before.length + oData.nname.length + 1);
1191 });
1192 }
1193
1194 // Must match utils2.py MENTIONS_REGEX.
1195 // Operates on a string from char before @ up to cursor.
1196 // Check that the char before @ doesn't look like an email address, and match to end of string.
1197 var mentionRe = new RegExp('(?:^|[^a-zA-Z0-9])@([a-zA-Z0-9][-_.a-zA-Z0-9]*[a-zA-Z0-9])$');
1198
1199 $inputElement.keyup(function(e){
1200 var currentMessage = $inputElement.val();
1201 var currentCaretPosition = $inputElement[0].selectionStart;
1202
1203 $container.data('search', '');
1204 var messageBeforeCaret = currentMessage.substr(0, currentCaretPosition);
1205 var lastAtPos = messageBeforeCaret.lastIndexOf('@');
1206 if(lastAtPos >= 0){
1207 // Search from one char before last @ ... if possible
1208 var m = mentionRe.exec(messageBeforeCaret.substr(Math.max(0, lastAtPos - 1)));
1209 if(m){
1210 $container.data('before', currentMessage.substr(0, lastAtPos + 1));
1211 $container.data('search', currentMessage.substr(lastAtPos + 1, currentCaretPosition - lastAtPos - 1));
1212 $container.data('after', currentMessage.substr(currentCaretPosition));
1213 }
1214 }
1215 });
1216 }
1217
1182
1218
1183
1219 // Set caret at the given position in the input element
1184 // Set caret at the given position in the input element
@@ -11,6 +11,7 b''
11 /* 3rd party styles */
11 /* 3rd party styles */
12 @import "node_modules/bootstrap/less/bootstrap.less";
12 @import "node_modules/bootstrap/less/bootstrap.less";
13 @import (inline) "node_modules/datatables.net-bs/css/dataTables.bootstrap.css";
13 @import (inline) "node_modules/datatables.net-bs/css/dataTables.bootstrap.css";
14 @import (inline) "node_modules/at.js/dist/css/jquery.atwho.css";
14 @import (less) "node_modules/select2/select2.css";
15 @import (less) "node_modules/select2/select2.css";
15 @import (less) "node_modules/select2-bootstrap-css/select2-bootstrap.css";
16 @import (less) "node_modules/select2-bootstrap-css/select2-bootstrap.css";
16 @import (less) "tmp/pygments.css";
17 @import (less) "tmp/pygments.css";
@@ -929,3 +929,9 b' nav.navbar #quick > li > a,'
929 #context-pages > ul > li > a {
929 #context-pages > ul > li > a {
930 height: @navbar-height;
930 height: @navbar-height;
931 }
931 }
932
933 /* at.js */
934 .atwho-view strong {
935 /* the blue color doesn't look good, use normal color */
936 color: inherit;
937 }
@@ -74,6 +74,8 b''
74 <script type="text/javascript" src="${h.url('/js/bootstrap.js', ver=c.kallithea_version)}"></script>
74 <script type="text/javascript" src="${h.url('/js/bootstrap.js', ver=c.kallithea_version)}"></script>
75 <script type="text/javascript" src="${h.url('/js/select2.js', ver=c.kallithea_version)}"></script>
75 <script type="text/javascript" src="${h.url('/js/select2.js', ver=c.kallithea_version)}"></script>
76 <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.kallithea_version)}"></script>
76 <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.kallithea_version)}"></script>
77 <script type="text/javascript" src="${h.url('/js/jquery.caret.min.js', ver=c.kallithea_version)}"></script>
78 <script type="text/javascript" src="${h.url('/js/jquery.atwho.min.js', ver=c.kallithea_version)}"></script>
77 <script type="text/javascript" src="${h.url('/js/base.js', ver=c.kallithea_version)}"></script>
79 <script type="text/javascript" src="${h.url('/js/base.js', ver=c.kallithea_version)}"></script>
78 ## EXTRA FOR JS
80 ## EXTRA FOR JS
79 <%block name="js_extra"/>
81 <%block name="js_extra"/>
General Comments 0
You need to be logged in to leave comments. Login now