Pārlūkot izejas kodu

Return a WordResult object (containing the length of string with spaces/newlines)

Silvan Engeler 7 gadi atpakaļ
vecāks
revīzija
94f8d4f6fe

+ 5 - 6
src/directives/compose_area.ts

@@ -288,7 +288,6 @@ export default [
                     // At link time, the element is not yet evaluated.
                     // Therefore add following code to end of event loop.
                     $timeout(() => {
-
                         // If the compose area contains only a single <br>, make it fully empty.
                         // See also: https://stackoverflow.com/q/14638887/284318
                         const text = getText(false);
@@ -297,12 +296,12 @@ export default [
                         } else if (ev.keyCode === 190) {
                             // A ':' is pressed, try to parse
                             const currentWord = stringService.getWord(text, caretPosition.fromBytes, [':']);
-                            if (currentWord.length > 2
-                                && currentWord.substr(0, 1) === ':') {
-                                const unicodeEmoji = emojione.shortnameToUnicode(currentWord);
-                                if (unicodeEmoji && unicodeEmoji !== currentWord) {
+                            if (currentWord.realLength > 2
+                                && currentWord.word.substr(0, 1) === ':') {
+                                const unicodeEmoji = emojione.shortnameToUnicode(currentWord.word);
+                                if (unicodeEmoji && unicodeEmoji !== currentWord.word) {
                                     return insertEmoji(unicodeEmoji,
-                                        caretPosition.from - currentWord.length,
+                                        caretPosition.from - currentWord.realLength,
                                         caretPosition.to);
                                 }
                             }

+ 1 - 1
src/partials/messenger.ts

@@ -585,7 +585,7 @@ class ConversationController {
      * In contrast to startTyping, this method is is always called, not just if
      * the text field is non-empty.
      */
-    public onTyping = (text: string, currentWord: string = null) => {
+    public onTyping = (text: string, currentWord: threema.WordResult = null) => {
         // Update draft
         this.webClientService.setDraft(this.receiver, text);
 

+ 30 - 24
src/services/string.ts

@@ -58,43 +58,49 @@ export class StringService {
         });
         return chunks;
     }
-    public getWord(input: string, pos: number, additionalSeparators: string[] = null): string {
+
+    public getWord(input: string, pos: number, additionalSeparators: string[] = null): threema.WordResult {
+        const result = {
+            word: null,
+            realLength: 0,
+        };
         if (input !== null && input.length > 0) {
             const chars = [...input];
             let charFound = false;
             const realPos = Math.min(pos, chars.length) - 1;
 
-            if (realPos < 0) {
-                return '';
-            }
-
-            const wordChars = new Array(realPos);
-            for (let n = realPos; n >= 0; n--) {
-                const realChar = chars[n].trim();
-                if (realChar === '') {
-                    // Abort
-                    if (charFound === false) {
-                        continue;
-                    } else {
-                        break;
-                    }
-                } else if (additionalSeparators !== null) {
-                    if (additionalSeparators.indexOf(chars[n]) > -1) {
-                        // append char
-                        wordChars[n] = realChar;
+            if (realPos > 0) {
+                const wordChars = new Array(realPos);
+                for (let n = realPos; n >= 0; n--) {
+                    const realChar = chars[n].trim();
+                    if (realChar === '') {
+                        // Abort
                         if (charFound === false) {
+                            result.realLength++;
                             continue;
                         } else {
                             break;
                         }
+                    } else if (additionalSeparators !== null) {
+                        if (additionalSeparators.indexOf(chars[n]) > -1) {
+                            // append char
+                            result.realLength++;
+                            wordChars[n] = realChar;
+                            if (charFound === false) {
+                                continue;
+                            } else {
+                                break;
+                            }
+                        }
                     }
+                    result.realLength++;
+                    wordChars[n] = realChar;
+                    charFound = true;
                 }
-
-                wordChars[n] = realChar;
-                charFound = true;
+                result.word = wordChars.join('');
             }
-            return wordChars.join('');
+
         }
-        return '';
+        return result;
     }
 }

+ 9 - 4
src/threema.d.ts

@@ -148,7 +148,7 @@ declare namespace threema {
 
     const enum IdentityType {
         Regular = 0,
-        Work
+        Work,
     }
 
     /**
@@ -348,7 +348,7 @@ declare namespace threema {
         // File bytes
         data: ArrayBuffer;
         // Caption string
-        caption?: String;
+        caption?: string;
         // Send as file message
         sendAsFile?: boolean;
     }
@@ -386,7 +386,7 @@ declare namespace threema {
 
     interface Identity {
         identity: string;
-        publicNickname: String;
+        publicNickname: string;
         publicKey: ArrayBuffer;
         fingerprint: string;
     }
@@ -495,6 +495,11 @@ declare namespace threema {
         isAll: boolean;
     }
 
+    interface WordResult {
+        word: string;
+        realLength: number;
+    }
+
     namespace Container {
         interface ReceiverData {
             me: MeReceiver;
@@ -546,7 +551,7 @@ declare namespace threema {
             converter: (data: Message) => Message;
             getList(receiver: Receiver): Message[];
             clear($scope: ng.IScope): void;
-            clearReceiverMessages(receiver: Receiver): Number;
+            clearReceiverMessages(receiver: Receiver): number;
             contains(receiver: Receiver): boolean;
             hasMore(receiver: Receiver): boolean;
             setMore(receiver: Receiver, more: boolean): void;

+ 60 - 14
tests/service/string.js

@@ -17,40 +17,86 @@ describe('StringService', function() {
     });
 
     it('parse null string', () => {
-        expect($service.getWord(null, 1)).toEqual('');
+        expect($service.getWord(null, 1)).toEqual(jasmine.objectContaining({
+            word: null,
+            realLength: 0
+        }));
     });
 
     it('parse empty string', () => {
-        expect($service.getWord('', 1)).toEqual('');
+        expect($service.getWord('', 1)).toEqual(jasmine.objectContaining({
+            word: null,
+            realLength: 0
+        }));
     });
 
     it('parse string (spaces)', () => {
-        expect($service.getWord('When the man comes around.', 12)).toEqual('man');
-        expect($service.getWord('When the man comes around.', 13)).toEqual('man');
-        expect($service.getWord('When the man        comes around.', 16)).toEqual('man');
+        expect($service.getWord('When the man comes around.', 12)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 3
+        }));
+        expect($service.getWord('When the man comes around.', 13)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 4
+        }));
+        expect($service.getWord('When the man        comes around.', 16)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 7
+        }));
     });
 
     it('parse string (newline)', () => {
-        expect($service.getWord("When\nthe\nman\ncomes\naround.", 12)).toEqual('man');
-        expect($service.getWord("When\nthe\nman\ncomes\naround.", 13)).toEqual('man');
-        expect($service.getWord("When\nthe\nman\n\n\n\n\n\n\n\ncomes\naround.", 16)).toEqual('man');
+        expect($service.getWord("When\nthe\nman\ncomes\naround.", 12)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 3
+        }));
+        expect($service.getWord("When\nthe\nman\ncomes\naround.", 13)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 4
+        }));
+        expect($service.getWord("When\nthe\nman\n\n\n\n\n\n\n\ncomes\naround.", 16)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 7
+        }));
     });
 
     it('parse string (newline/spaces)', () => {
-        expect($service.getWord("When the\nman comes around.", 12)).toEqual('man');
-        expect($service.getWord("When the\nman \ncomes around.", 13)).toEqual('man');
-        expect($service.getWord("When the\nman \n \n \n \ncomes around.", 16)).toEqual('man');
+        expect($service.getWord("When the\nman comes around.", 12)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 3
+        }));
+        expect($service.getWord("When the\nman \ncomes around.", 13)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 4
+        }));
+        expect($service.getWord("When the\nman \n \n \n \ncomes around.", 16)).toEqual(jasmine.objectContaining({
+            word: 'man',
+            realLength: 7
+        }));
     });
 
     it('parse string (special character)', () => {
-        expect($service.getWord('When the :man: comes around.', 15)).toEqual(':man:');
+        expect($service.getWord('When the :man: comes around.', 15)).toEqual(jasmine.objectContaining({
+            word: ':man:',
+            realLength: 6
+        }));
+        expect($service.getWord('When the :man: comes around.', 14)).toEqual(jasmine.objectContaining({
+            word: ':man:',
+            realLength: 5
+        }));
     });
 
     it('parse string (with emoji (2 chars))', () => {
-        expect($service.getWord('this 😄 is a :smile: face', 19)).toEqual(':smile:');
+        expect($service.getWord('this 😄 is a :smile: face', 19)).toEqual(jasmine.objectContaining({
+            word: ':smile:',
+            realLength: 7
+        }));
     });
 
     it('parse string (additional separators)', () => {
-        expect($service.getWord('When the spider:man: comes around.', 20, [':'])).toEqual(':man:');
+        expect($service.getWord('When the spider:man: comes around.', 20, [':'])).toEqual(jasmine.objectContaining({
+            word: ':man:',
+            realLength: 5
+        }));
     });
 });