Browse Source

Allow mention autocomplete to trigger right after a new line (#2267)

* catch all whitespace characters instead of just new line
Xavi 4 years ago
parent
commit
86c04b876b
2 changed files with 55 additions and 1 deletions
  1. 54 0
      spec/autocomplete.js
  2. 1 1
      src/headless/utils/core.js

+ 54 - 0
spec/autocomplete.js

@@ -60,6 +60,60 @@ describe("The nickname autocomplete feature", function () {
         done();
     }));
 
+    it("shows all autocompletion options when the user presses @ right after a new line",
+        mock.initConverse(
+            ['rosterGroupsFetched', 'chatBoxesFetched'], {},
+                async function (done, _converse) {
+
+        await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom');
+        const view = _converse.chatboxviews.get('lounge@montague.lit');
+
+        // Nicknames from presences
+        ['dick', 'harry'].forEach((nick) => {
+            _converse.connection._dataRecv(mock.createRequest(
+                $pres({
+                    'to': 'tom@montague.lit/resource',
+                    'from': `lounge@montague.lit/${nick}`
+                })
+                .c('x', {xmlns: Strophe.NS.MUC_USER})
+                .c('item', {
+                    'affiliation': 'none',
+                    'jid': `${nick}@montague.lit/resource`,
+                    'role': 'participant'
+                })));
+        });
+
+        // Nicknames from messages
+        const msg = $msg({
+                from: 'lounge@montague.lit/jane',
+                id: u.getUniqueId(),
+                to: 'romeo@montague.lit',
+                type: 'groupchat'
+            }).c('body').t('Hello world').tree();
+        await view.model.handleMessageStanza(msg);
+
+        // Test that pressing @ brings up all options
+        const textarea = view.el.querySelector('textarea.chat-textarea');
+        const at_event = {
+            'target': textarea,
+            'preventDefault': function preventDefault () {},
+            'stopPropagation': function stopPropagation () {},
+            'keyCode': 50,
+            'key': '@'
+        };
+        textarea.value = '\n'
+        view.onKeyDown(at_event);
+        textarea.value = '\n@';
+        view.onKeyUp(at_event);
+
+        await u.waitUntil(() => view.el.querySelectorAll('.suggestion-box__results li').length === 4);
+        expect(view.el.querySelector('.suggestion-box__results li:first-child').textContent).toBe('dick');
+        expect(view.el.querySelector('.suggestion-box__results li:nth-child(2)').textContent).toBe('harry');
+        expect(view.el.querySelector('.suggestion-box__results li:nth-child(3)').textContent).toBe('jane');
+        expect(view.el.querySelector('.suggestion-box__results li:nth-child(4)').textContent).toBe('tom');
+        done();
+    }));
+
     it("should order by query index position and length", mock.initConverse(
         ['rosterGroupsFetched', 'chatBoxesFetched'], {}, async function (done, _converse) {
             await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'tom');

+ 1 - 1
src/headless/utils/core.js

@@ -412,7 +412,7 @@ u.getCurrentWord = function (input, index, delineator) {
     if (!index) {
         index = input.selectionEnd || undefined;
     }
-    let [word] = input.value.slice(0, index).split(' ').slice(-1);
+    let [word] = input.value.slice(0, index).split(/\s/).slice(-1);
     if (delineator) {
         [word] = word.split(delineator).slice(-1);
     }