diff --git a/client/js/autocompletion.js b/client/js/autocompletion.js index dad11900..87c173f2 100644 --- a/client/js/autocompletion.js +++ b/client/js/autocompletion.js @@ -3,11 +3,20 @@ const $ = require("jquery"); const fuzzy = require("fuzzy"); const emojiMap = require("./libs/simplemap.json"); -const options = require("./options"); const constants = require("./constants"); -require("jquery-textcomplete"); 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), +}; + const chat = $("#chat"); const sidebar = $("#sidebar"); const emojiSearchTerms = Object.keys(emojiMap); @@ -138,31 +147,44 @@ const backgroundColorStrategy = { index: 2, }; -const input = $("#input") +input .tab((word) => completeNicks(word, false), {hint: false}) .on("autocomplete:on", function() { enableAutocomplete(); }); -if (options.autocomplete) { - enableAutocomplete(); -} - function enableAutocomplete() { - input.textcomplete([ - emojiStrategy, nicksStrategy, chanStrategy, commandStrategy, - foregroundColorStrategy, backgroundColorStrategy, - ], { - dropdownClassName: "textcomplete-menu", - placement: "top", - }).on({ - "textComplete:show": function() { - $(this).data("autocompleting", true); - }, - "textComplete:hide": function() { - $(this).data("autocompleting", false); + textcomplete = new Textcomplete(editor, { + dropdown: { + className: "textcomplete-menu", + placement: "top", }, }); + + textcomplete.register([ + emojiStrategy, + nicksStrategy, + chanStrategy, + commandStrategy, + foregroundColorStrategy, + backgroundColorStrategy, + ]); + + // Activate the first item by default + // https://github.com/yuku-t/textcomplete/issues/93 + textcomplete.on("rendered", () => { + if (textcomplete.dropdown.items.length > 0) { + textcomplete.dropdown.items[0].activate(); + } + }); + + textcomplete.on("show", () => { + input.data("autocompleting", true); + }); + + textcomplete.on("hidden", () => { + input.data("autocompleting", false); + }); } function fuzzyGrep(term, array) { diff --git a/client/js/lounge.js b/client/js/lounge.js index 3adf2881..0aaa9b76 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -17,7 +17,6 @@ const render = require("./render"); require("./socket-events"); const storage = require("./localStorage"); const utils = require("./utils"); -require("./autocompletion"); require("./webpush"); require("./keybinds"); require("./clipboard"); diff --git a/client/js/options.js b/client/js/options.js index 0c62bee1..4b5e2b80 100644 --- a/client/js/options.js +++ b/client/js/options.js @@ -1,11 +1,11 @@ "use strict"; const $ = require("jquery"); -require("jquery-textcomplete"); const escapeRegExp = require("lodash/escapeRegExp"); const userStyles = $("#user-specified-css"); const storage = require("./localStorage"); const tz = require("./libs/handlebars/tz"); +const autocompletion = require("./autocompletion"); const windows = $("#windows"); const chat = $("#chat"); @@ -123,9 +123,9 @@ module.exports.initialize = () => { chat.toggleClass("show-seconds", self.prop("checked")); } else if (name === "autocomplete") { if (self.prop("checked")) { - $("#input").trigger("autocomplete:on"); + autocompletion.enable(); } else { - $("#input").textcomplete("destroy"); + autocompletion.disable(); } } }).find("input") diff --git a/package.json b/package.json index c4521de5..d0d6de5e 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,6 @@ "handlebars-loader": "1.6.0", "intersection-observer": "0.5.0", "jquery": "3.2.1", - "jquery-textcomplete": "1.8.4", "jquery-ui": "1.12.1", "mocha": "4.0.1", "mousetrap": "1.6.1", @@ -85,6 +84,7 @@ "socket.io-client": "2.0.4", "stylelint": "8.3.1", "stylelint-config-standard": "18.0.0", + "textcomplete": "0.14.5", "webpack": "3.10.0" } }