diff --git a/client/js/autocompletion.js b/client/js/autocompletion.js index 87c173f2..ff1fb259 100644 --- a/client/js/autocompletion.js +++ b/client/js/autocompletion.js @@ -2,19 +2,22 @@ const $ = require("jquery"); const fuzzy = require("fuzzy"); +const Mousetrap = require("mousetrap"); const emojiMap = require("./libs/simplemap.json"); const constants = require("./constants"); -require("./libs/jquery/tabcomplete"); const input = $("#input"); const Textcomplete = require("textcomplete/lib/textcomplete").default; const Textarea = require("textcomplete/lib/textarea").default; -const editor = new Textarea(input.get(0)); let textcomplete; module.exports = { enable: enableAutocomplete, - disable: () => textcomplete.destroy(false), + disable: () => { + input.unbind("input.tabcomplete"); + Mousetrap(input.get(0)).unbind("tab", "keydown"); + textcomplete.destroy(); + }, }; const chat = $("#chat"); @@ -147,13 +150,53 @@ const backgroundColorStrategy = { index: 2, }; -input - .tab((word) => completeNicks(word, false), {hint: false}) - .on("autocomplete:on", function() { - enableAutocomplete(); +function enableAutocomplete() { + let tabCount = 0; + let currentMatches = []; + + input.on("input.tabcomplete", () => { + tabCount = 0; + currentMatches = []; }); -function enableAutocomplete() { + Mousetrap(input.get(0)).bind("tab", (e) => { + if (input.data("autocompleting")) { + return; + } + + e.preventDefault(); + + const text = input.val(); + + if (input.get(0).selectionStart !== text.length) { + return; + } + + let lastWord; + + if (tabCount === 0) { + lastWord = text.split(/\s/).pop(); + + if (lastWord.length === 0) { + return; + } + + currentMatches = completeNicks(lastWord, false); + + if (currentMatches.length === 0) { + return; + } + } else { + lastWord = nicksStrategy.replace([0, currentMatches[(tabCount - 1) % currentMatches.length]]); + } + + const matchedNick = currentMatches[tabCount % currentMatches.length]; + input.val(text.substr(0, input.get(0).selectionStart - lastWord.length) + nicksStrategy.replace([0, matchedNick])); + + tabCount++; + }, "keydown"); + + const editor = new Textarea(input.get(0)); textcomplete = new Textcomplete(editor, { dropdown: { className: "textcomplete-menu", diff --git a/client/js/libs/jquery/tabcomplete.js b/client/js/libs/jquery/tabcomplete.js deleted file mode 100644 index 5d04794c..00000000 --- a/client/js/libs/jquery/tabcomplete.js +++ /dev/null @@ -1,258 +0,0 @@ -import jQuery from "jquery"; - -/*! - * tabcomplete - * http://github.com/erming/tabcomplete - * v1.3.1 - */ -(function($) { - var keys = { - backspace: 8, - tab: 9, - up: 38, - down: 40 - }; - - $.tabcomplete = {}; - $.tabcomplete.defaultOptions = { - after: "", - arrowKeys: false, - caseSensitive: false, - hint: "placeholder", - minLength: 1 - }; - - $.fn.tab = // Alias - $.fn.tabcomplete = function(args, options) { - if (this.length > 1) { - return this.each(function() { - $(this).tabcomplete(args, options); - }); - } - - // Only enable the plugin on and