Mercurial > kallithea
changeset 7467:2e7ffb755d4f
front-end: use At.js for MentionsAutoComplete
We want to get rid of YUI, and select2 is not well suited for this purpose.
So use At.js, which is made just for this use case.
Original implementation was modified by Mads Kiilerich.
author | domruf <dominikruf@gmail.com> |
---|---|
date | Mon, 10 Dec 2018 22:54:04 +0100 |
parents | bf514091b27f |
children | 1f3b311e865f |
files | .hgignore LICENSE.md kallithea/bin/kallithea_cli_front_end.py kallithea/front-end/package.json kallithea/public/js/base.js kallithea/public/less/main.less kallithea/public/less/style.less kallithea/templates/base/root.html |
diffstat | 8 files changed, 73 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Mon Dec 10 23:32:39 2018 +0100 +++ b/.hgignore Mon Dec 10 22:54:04 2018 +0100 @@ -32,6 +32,8 @@ ^kallithea/public/css/style\.css\.map$ ^kallithea/public/js/bootstrap\.js$ ^kallithea/public/js/dataTables\.bootstrap\.js$ +^kallithea/public/js/jquery\.atwho\.min\.js$ +^kallithea/public/js/jquery\.caret\.min\.js$ ^kallithea/public/js/jquery\.dataTables\.js$ ^kallithea/public/js/jquery\.flot\.js$ ^kallithea/public/js/jquery\.flot\.selection\.js$
--- a/LICENSE.md Mon Dec 10 23:32:39 2018 +0100 +++ b/LICENSE.md Mon Dec 10 22:54:04 2018 +0100 @@ -84,6 +84,38 @@ +At.js +----- + +Kallithea uses the Javascript system called +[At.js](http://ichord.github.com/At.js), +which can be found together with its Corresponding Source in +https://github.com/ichord/At.js at tag v1.5.4. + +It is Copyright 2013 chord.luo@gmail.com and is under an +[MIT-permissive license](MIT-Permissive-License.txt). + +It is not distributed with Kallithea, but will be downloaded +using the ''kallithea-cli front-end-build'' command. + + + +Caret.js +-------- + +Kallithea uses the Javascript system called +[Caret.js](http://ichord.github.com/Caret.js/), +which can be found together with its Corresponding Source in +https://github.com/ichord/Caret.js at tag v0.3.1. + +It is Copyright 2013 chord.luo@gmail.com and is under an +[MIT-permissive license](MIT-Permissive-License.txt). + +It is not distributed with Kallithea, but will be downloaded +using the ''kallithea-cli front-end-build'' command. + + + DataTables ----------
--- a/kallithea/bin/kallithea_cli_front_end.py Mon Dec 10 23:32:39 2018 +0100 +++ b/kallithea/bin/kallithea_cli_front_end.py Mon Dec 10 22:54:04 2018 +0100 @@ -66,11 +66,13 @@ click.echo("Preparing Bootstrap JS") shutil.copy(os.path.join(front_end_dir, 'node_modules', 'bootstrap', 'dist', 'js', 'bootstrap.js'), os.path.join(public_dir, 'js', 'bootstrap.js')) - click.echo("Preparing jQuery JS with Flot") + click.echo("Preparing jQuery JS with Flot, Caret and Atwho") shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery', 'dist', 'jquery.min.js'), os.path.join(public_dir, 'js', 'jquery.min.js')) shutil.copy(os.path.join(front_end_dir, 'node_modules', 'jquery.flot', 'jquery.flot.js'), os.path.join(public_dir, 'js', 'jquery.flot.js')) 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')) 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')) + 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')) + 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')) click.echo("Preparing DataTables JS") 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'))
--- a/kallithea/front-end/package.json Mon Dec 10 23:32:39 2018 +0100 +++ b/kallithea/front-end/package.json Mon Dec 10 22:54:04 2018 +0100 @@ -2,11 +2,13 @@ "name": "kallithea", "private": true, "dependencies": { + "at.js": "1.5.4", "bootstrap": "3.3.7", "codemirror": "4.7", "datatables.net": "1.10.13", "datatables.net-bs": "1.10.13", "jquery": "1.12.3", + "jquery.caret": "0.3.1", "jquery.flot": "0.8.3", "select2": "3.5.1", "select2-bootstrap-css": "1.2.4"
--- a/kallithea/public/js/base.js Mon Dec 10 23:32:39 2018 +0100 +++ b/kallithea/public/js/base.js Mon Dec 10 22:54:04 2018 +0100 @@ -751,7 +751,7 @@ tooltip_activate(); if ($textarea.length > 0) { - MentionsAutoComplete($textarea, _USERS_AC_DATA); + MentionsAutoComplete($textarea); } if (f_path) { $textarea.focus(); @@ -1155,65 +1155,30 @@ }); } -var MentionsAutoComplete = function ($inputElement, users_list) { - var $container = $('<div/>').insertAfter($inputElement); - - var matchUsers = function (sQuery) { - // use the search string from $inputElement instead of sQuery - if(!$container.data('search')){ - // return empty list so the input list isn't shown - return [] - } - return autocompleteMatchUsers($container.data('search'), users_list); - } - - var datasource = new YAHOO.util.FunctionDataSource(matchUsers); - var mentionsAC = new YAHOO.widget.AutoComplete($inputElement[0], $container[0], datasource); - mentionsAC.useShadow = false; - mentionsAC.resultTypeList = false; - mentionsAC.animVert = false; - mentionsAC.animHoriz = false; - mentionsAC.animSpeed = 0.1; - mentionsAC.suppressInputUpdate = true; - mentionsAC.formatResult = function (oResultData, sQuery, sResultMatch) { - // use the search string from $inputElement instead of sQuery - return autocompleteFormatter(oResultData, $container.data('search'), sResultMatch); - } - - // Handler for selection of an entry - if(mentionsAC.itemSelectEvent){ - mentionsAC.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 - myAC.getInputEl().value = $container.data('before') + oData.nname + ' ' + $container.data('after'); - _setCaretPosition($(myAC.getInputEl()), myAC.dataSource.before.length + oData.nname.length + 1); - }); - } - - // Must match utils2.py MENTIONS_REGEX. - // Operates on a string from char before @ up to cursor. - // Check that the char before @ doesn't look like an email address, and match to end of string. - var mentionRe = new RegExp('(?:^|[^a-zA-Z0-9])@([a-zA-Z0-9][-_.a-zA-Z0-9]*[a-zA-Z0-9])$'); - - $inputElement.keyup(function(e){ - var currentMessage = $inputElement.val(); - var currentCaretPosition = $inputElement[0].selectionStart; - - $container.data('search', ''); - var messageBeforeCaret = currentMessage.substr(0, currentCaretPosition); - var lastAtPos = messageBeforeCaret.lastIndexOf('@'); - if(lastAtPos >= 0){ - // Search from one char before last @ ... if possible - var m = mentionRe.exec(messageBeforeCaret.substr(Math.max(0, lastAtPos - 1))); - if(m){ - $container.data('before', currentMessage.substr(0, lastAtPos + 1)); - $container.data('search', currentMessage.substr(lastAtPos + 1, currentCaretPosition - lastAtPos - 1)); - $container.data('after', currentMessage.substr(currentCaretPosition)); - } - } - }); -} +var MentionsAutoComplete = function ($inputElement) { + $inputElement.atwho({ + at: "@", + callbacks: { + remoteFilter: function(query, callback) { + $.getJSON( + pyroutes.url('users_and_groups_data'), + { + query: query, + types: 'users' + }, + function(data) { + callback(data.results) + } + ); + }, + sorter: function(query, items, searchKey) { + return items; + } + }, + displayTpl: "<li>" + autocompleteGravatar('${fname} ${lname} (${nname})', '${gravatar_lnk}', 16) + "</li>", + insertTpl: "${atwho-at}${nname}" + }); +}; // Set caret at the given position in the input element
--- a/kallithea/public/less/main.less Mon Dec 10 23:32:39 2018 +0100 +++ b/kallithea/public/less/main.less Mon Dec 10 22:54:04 2018 +0100 @@ -11,6 +11,7 @@ /* 3rd party styles */ @import "node_modules/bootstrap/less/bootstrap.less"; @import (inline) "node_modules/datatables.net-bs/css/dataTables.bootstrap.css"; +@import (inline) "node_modules/at.js/dist/css/jquery.atwho.css"; @import (less) "node_modules/select2/select2.css"; @import (less) "node_modules/select2-bootstrap-css/select2-bootstrap.css"; @import (less) "tmp/pygments.css";
--- a/kallithea/public/less/style.less Mon Dec 10 23:32:39 2018 +0100 +++ b/kallithea/public/less/style.less Mon Dec 10 22:54:04 2018 +0100 @@ -929,3 +929,9 @@ #context-pages > ul > li > a { height: @navbar-height; } + +/* at.js */ +.atwho-view strong { + /* the blue color doesn't look good, use normal color */ + color: inherit; +}
--- a/kallithea/templates/base/root.html Mon Dec 10 23:32:39 2018 +0100 +++ b/kallithea/templates/base/root.html Mon Dec 10 22:54:04 2018 +0100 @@ -74,6 +74,8 @@ <script type="text/javascript" src="${h.url('/js/bootstrap.js', ver=c.kallithea_version)}"></script> <script type="text/javascript" src="${h.url('/js/select2.js', ver=c.kallithea_version)}"></script> <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.kallithea_version)}"></script> + <script type="text/javascript" src="${h.url('/js/jquery.caret.min.js', ver=c.kallithea_version)}"></script> + <script type="text/javascript" src="${h.url('/js/jquery.atwho.min.js', ver=c.kallithea_version)}"></script> <script type="text/javascript" src="${h.url('/js/base.js', ver=c.kallithea_version)}"></script> ## EXTRA FOR JS <%block name="js_extra"/>