logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe
commit: 4adccf2216effa7fe945d6e8d90197e41bc58706
parent 02ea1739473bace638aeb215ab84843e9e304dfb
Author: lain <lain@soykaf.club>
Date:   Thu,  3 Sep 2020 14:08:36 +0000

Merge branch 'fix/autocomplete-fixes' into 'develop'

Rewrite word split for autocomplete, fix #930 fix #681

Closes #681 and #930

See merge request pleroma/pleroma-fe!1218

Diffstat:

MCHANGELOG.md5+++++
Msrc/services/completion/completion.js50+++++++++++++++++++++++++-------------------------
Mtest/unit/specs/services/completion/completion.spec.js43+++++++++++++++++++++++++++++--------------
3 files changed, 59 insertions(+), 39 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -5,9 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ## [Unreleased patch] + ### Changed - Polls will be hidden with status content if "Collapse posts with subjects" is enabled and the post is collapsed. +### Fixed +- Autocomplete won't stop at the second @, so it'll still work with "@lain@l" and not start over. +- Fixed weird autocomplete behavior when you write ":custom_emoji: ?" + ## [2.1.0] - 2020-08-28 ### Added - Autocomplete domains from list of known instances diff --git a/src/services/completion/completion.js b/src/services/completion/completion.js @@ -5,7 +5,7 @@ export const replaceWord = (str, toReplace, replacement) => { } export const wordAtPosition = (str, pos) => { - const words = splitIntoWords(str) + const words = splitByWhitespaceBoundary(str) const wordsWithPosition = addPositionToWords(words) return find(wordsWithPosition, ({ start, end }) => start <= pos && end > pos) @@ -34,36 +34,36 @@ export const addPositionToWords = (words) => { }, []) } -export const splitIntoWords = (str) => { - // Split at word boundaries - const regex = /\b/ - const triggers = /[@#:]+$/ - - let split = str.split(regex) - - // Add trailing @ and # to the following word. - const words = reduce(split, (result, word) => { - if (result.length > 0) { - let previous = result.pop() - const matches = previous.match(triggers) - if (matches) { - previous = previous.replace(triggers, '') - word = matches[0] + word - } - result.push(previous) +export const splitByWhitespaceBoundary = (str) => { + let result = [] + let currentWord = '' + for (let i = 0; i < str.length; i++) { + const currentChar = str[i] + // Starting a new word + if (!currentWord) { + currentWord = currentChar + continue } - result.push(word) - - return result - }, []) - - return words + // current character is whitespace while word isn't, or vice versa: + // add our current word to results, start over the current word. + if (!!currentChar.trim() !== !!currentWord.trim()) { + result.push(currentWord) + currentWord = currentChar + continue + } + currentWord += currentChar + } + // Add the last word we were working on + if (currentWord) { + result.push(currentWord) + } + return result } const completion = { wordAtPosition, addPositionToWords, - splitIntoWords, + splitByWhitespaceBoundary, replaceWord } diff --git a/test/unit/specs/services/completion/completion.spec.js b/test/unit/specs/services/completion/completion.spec.js @@ -1,8 +1,8 @@ -import { replaceWord, addPositionToWords, wordAtPosition, splitIntoWords } from '../../../../../src/services/completion/completion.js' +import { replaceWord, addPositionToWords, wordAtPosition, splitByWhitespaceBoundary } from '../../../../../src/services/completion/completion.js' describe('addPositiontoWords', () => { it('adds the position to a word list', () => { - const words = ['hey', 'this', 'is', 'fun'] + const words = ['hey', ' ', 'this', ' ', 'is', ' ', 'fun'] const expected = [ { @@ -11,19 +11,34 @@ describe('addPositiontoWords', () => { end: 3 }, { - word: 'this', + word: ' ', start: 3, - end: 7 + end: 4 }, { - word: 'is', - start: 7, + word: 'this', + start: 4, + end: 8 + }, + { + word: ' ', + start: 8, end: 9 }, { - word: 'fun', + word: 'is', start: 9, + end: 11 + }, + { + word: ' ', + start: 11, end: 12 + }, + { + word: 'fun', + start: 12, + end: 15 } ] @@ -33,11 +48,11 @@ describe('addPositiontoWords', () => { }) }) -describe('splitIntoWords', () => { +describe('splitByWhitespaceBoundary', () => { it('splits at whitespace boundaries', () => { - const str = 'This is a #nice @test for you, @idiot.' - const expected = ['This', ' ', 'is', ' ', 'a', ' ', '#nice', ' ', '@test', ' ', 'for', ' ', 'you', ', ', '@idiot', '.'] - const res = splitIntoWords(str) + const str = 'This is a #nice @test for you, @idiot@idiot.com' + const expected = ['This', ' ', 'is', ' ', 'a', ' ', '#nice', ' ', '@test', ' ', 'for', ' ', 'you,', ' ', '@idiot@idiot.com'] + const res = splitByWhitespaceBoundary(str) expect(res).to.eql(expected) }) @@ -57,13 +72,13 @@ describe('wordAtPosition', () => { describe('replaceWord', () => { it('replaces a word (with start and end) with another word in a given string', () => { - const str = 'hey @take, how are you' - const wordsWithPosition = addPositionToWords(splitIntoWords(str)) + const str = 'hey @take , how are you' + const wordsWithPosition = addPositionToWords(splitByWhitespaceBoundary(str)) const toReplace = wordsWithPosition[2] expect(toReplace.word).to.eql('@take') - const expected = 'hey @takeshitakenji, how are you' + const expected = 'hey @takeshitakenji , how are you' const res = replaceWord(str, toReplace, '@takeshitakenji') expect(res).to.eql(expected) })