From b3c412d38f106891b66fd0d1fc09ea1cb6467280 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 30 Jan 2017 12:50:03 +0100 Subject: [PATCH] Display mention syntax in publisher instead of username --- .../app/views/publisher/mention_view.js | 42 ++++------------ .../app/views/publisher_mention_view_spec.js | 48 +++++++++++-------- 2 files changed, 39 insertions(+), 51 deletions(-) diff --git a/app/assets/javascripts/app/views/publisher/mention_view.js b/app/assets/javascripts/app/views/publisher/mention_view.js index f732c0247..0641e2fcc 100644 --- a/app/assets/javascripts/app/views/publisher/mention_view.js +++ b/app/assets/javascripts/app/views/publisher/mention_view.js @@ -2,13 +2,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({ triggerChar: "@", - invisibleChar: "\u200B", // zero width space mentionRegex: /@([^@\s]+)$/, - - templates: { - mentionItemSyntax: _.template("@{<%= handle %>}"), - mentionItemHighlight: _.template("<%= name %>") - }, + mentionSyntaxTemplate: function(person) { return "@{" + person.handle + "}"; }, events: { "keydown #status_message_fake_text": "onInputBoxKeyDown", @@ -55,8 +50,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({ cleanMentionedPeople: function() { var inputText = this.inputBox.val(); this.mentionedPeople = this.mentionedPeople.filter(function(person) { - return person.name && inputText.indexOf(person.name) > -1; - }); + return person.handle && inputText.indexOf(this.mentionSyntaxTemplate(person)) > -1; + }.bind(this)); this.ignoreDiasporaIds = this.mentionedPeople.map(function(person) { return person.handle; }); }, @@ -70,39 +65,22 @@ app.views.PublisherMention = app.views.SearchBase.extend({ this.addPersonToMentions(person); this.closeSuggestions(); - messageText = messageText.substring(0, triggerCharPosition) + - this.invisibleChar + person.name + messageText.substring(caretPosition); + var mentionText = this.mentionSyntaxTemplate(person); + + messageText = messageText.substring(0, triggerCharPosition) + mentionText + messageText.substring(caretPosition); this.inputBox.val(messageText); this.updateMessageTexts(); this.inputBox.focus(); - var newCaretPosition = triggerCharPosition + person.name.length + 1; + var newCaretPosition = triggerCharPosition + mentionText.length; this.inputBox[0].setSelectionRange(newCaretPosition, newCaretPosition); }, - /** - * Replaces every combination of this.invisibleChar + mention.name by the - * correct syntax for both hidden text and visible one. - * - * For instance, the text "Hello \u200Buser1" will be tranformed to - * "Hello @{user1 ; user1@pod.tld}" in the hidden element and - * "Hello user1" in the element visible to the user. - */ updateMessageTexts: function() { - var fakeMessageText = this.inputBox.val(), - mentionBoxText = _.escape(fakeMessageText), - messageText = fakeMessageText; - - this.mentionedPeople.forEach(function(person) { - var mentionName = this.invisibleChar + person.name; - messageText = messageText.replace(mentionName, this.templates.mentionItemSyntax(person)); - var textHighlight = this.templates.mentionItemHighlight({name: _.escape(person.name)}); - mentionBoxText = mentionBoxText.replace(mentionName, textHighlight); - }, this); - + var messageText = this.inputBox.val(); this.inputBox.data("messageText", messageText); - this.mentionsBox.find(".mentions").html(mentionBoxText); + this.mentionsBox.find(".mentions").html(_.escape(messageText)); }, updateTypeaheadInput: function() { @@ -128,7 +106,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({ prefillMention: function(persons) { persons.forEach(function(person) { this.addPersonToMentions(person); - var text = this.invisibleChar + person.name; + var text = this.mentionSyntaxTemplate(person); if(this.inputBox.val().length !== 0) { text = this.inputBox.val() + " " + text; } diff --git a/spec/javascripts/app/views/publisher_mention_view_spec.js b/spec/javascripts/app/views/publisher_mention_view_spec.js index c95a3247a..54e72ad90 100644 --- a/spec/javascripts/app/views/publisher_mention_view_spec.js +++ b/spec/javascripts/app/views/publisher_mention_view_spec.js @@ -7,7 +7,6 @@ describe("app.views.PublisherMention", function() { it("initializes object properties", function() { this.view = new app.views.PublisherMention({ el: "#publisher" }); expect(this.view.mentionedPeople).toEqual([]); - expect(this.view.invisibleChar).toBe("\u200B"); expect(this.view.triggerChar).toBe("@"); }); @@ -29,6 +28,17 @@ describe("app.views.PublisherMention", function() { }); }); + describe("mentionSyntaxTemplate", function() { + beforeEach(function() { + this.view = new app.views.PublisherMention({el: "#publisher"}); + this.person = {handle: "alice@pod.tld", name: "Alice Awesome"}; + }); + + it("returns the correct mention syntax", function() { + expect(this.view.mentionSyntaxTemplate(this.person)).toBe("@{alice@pod.tld}"); + }); + }); + describe("bindTypeaheadEvents", function() { beforeEach(function() { this.view = new app.views.PublisherMention({ el: "#publisher" }); @@ -92,30 +102,30 @@ describe("app.views.PublisherMention", function() { }); it("removes person from mentioned people if not mentioned anymore", function() { - this.view.addPersonToMentions({name: "user1", handle: "user1@pod.tld"}); + this.view.addPersonToMentions({name: "User Name", handle: "user1@pod.tld"}); expect(this.view.mentionedPeople.length).toBe(1); this.view.cleanMentionedPeople(); expect(this.view.mentionedPeople.length).toBe(0); }); it("removes person from ignored people if not mentioned anymore", function() { - this.view.addPersonToMentions({name: "user1", handle: "user1@pod.tld"}); + this.view.addPersonToMentions({name: "User Name", handle: "user1@pod.tld"}); expect(this.view.ignoreDiasporaIds.length).toBe(1); this.view.cleanMentionedPeople(); expect(this.view.ignoreDiasporaIds.length).toBe(0); }); it("keeps mentioned persons", function() { - this.view.addPersonToMentions({name: "user1", handle: "user1@pod.tld"}); - this.view.inputBox.val("user1"); + this.view.addPersonToMentions({name: "User Name", handle: "user1@pod.tld"}); + this.view.inputBox.val("@{user1@pod.tld}"); expect(this.view.mentionedPeople.length).toBe(1); this.view.cleanMentionedPeople(); expect(this.view.mentionedPeople.length).toBe(1); }); it("keeps mentioned persons for ignored diaspora ids", function() { - this.view.addPersonToMentions({name: "user1", handle: "user1@pod.tld"}); - this.view.inputBox.val("user1"); + this.view.addPersonToMentions({name: "User Name", handle: "user1@pod.tld"}); + this.view.inputBox.val("@{user1@pod.tld}"); expect(this.view.ignoreDiasporaIds.length).toBe(1); this.view.cleanMentionedPeople(); expect(this.view.ignoreDiasporaIds.length).toBe(1); @@ -151,20 +161,20 @@ describe("app.views.PublisherMention", function() { it("correctly formats the text", function() { this.view.onSuggestionSelection({name: "user1337", handle: "user1@pod.tld"}); - expect(this.view.inputBox.val()).toBe("@user1337 Text before \u200Buser1337 text after"); + expect(this.view.inputBox.val()).toBe("@user1337 Text before @{user1@pod.tld} text after"); }); it("replaces the correct mention", function() { this.view.inputBox.val("@user1337 123 user2 @user2 456 @user3 789"); this.view.inputBox[0].setSelectionRange(26, 26); this.view.onSuggestionSelection({name: "user23", handle: "user2@pod.tld"}); - expect(this.view.inputBox.val()).toBe("@user1337 123 user2 \u200Buser23 456 @user3 789"); + expect(this.view.inputBox.val()).toBe("@user1337 123 user2 @{user2@pod.tld} 456 @user3 789"); this.view.inputBox[0].setSelectionRange(9, 9); this.view.onSuggestionSelection({name: "user1337", handle: "user1@pod.tld"}); - expect(this.view.inputBox.val()).toBe("\u200Buser1337 123 user2 \u200Buser23 456 @user3 789"); - this.view.inputBox[0].setSelectionRange(38, 38); + expect(this.view.inputBox.val()).toBe("@{user1@pod.tld} 123 user2 @{user2@pod.tld} 456 @user3 789"); + this.view.inputBox[0].setSelectionRange(54, 54); this.view.onSuggestionSelection({name: "user32", handle: "user3@pod.tld"}); - expect(this.view.inputBox.val()).toBe("\u200Buser1337 123 user2 \u200Buser23 456 \u200Buser32 789"); + expect(this.view.inputBox.val()).toBe("@{user1@pod.tld} 123 user2 @{user2@pod.tld} 456 @{user3@pod.tld} 789"); }); it("calls updateMessageTexts", function() { @@ -175,7 +185,7 @@ describe("app.views.PublisherMention", function() { it("places the caret at the right position", function() { this.view.onSuggestionSelection({"name": "user1WithLongName", "handle": "user1@pod.tld"}); - var expectedCaretPosition = ("@user1337 Text before \u200Buser1WithLongName").length; + var expectedCaretPosition = ("@user1337 Text before @{user1@pod.tld}").length; expect(this.view.inputBox[0].selectionStart).toBe(expectedCaretPosition); }); }); @@ -183,7 +193,7 @@ describe("app.views.PublisherMention", function() { describe("updateMessageTexts", function() { beforeEach(function() { this.view = new app.views.PublisherMention({ el: "#publisher" }); - this.view.inputBox.val("@user1 Text before \u200Buser1\ntext after"); + this.view.inputBox.val("@user1 Text before @{user1@pod.tld}\ntext after"); this.view.mentionedPeople.push({"name": "user1", "handle": "user1@pod.tld"}); }); @@ -195,14 +205,14 @@ describe("app.views.PublisherMention", function() { it("formats overlay text to HTML", function() { this.view.updateMessageTexts(); expect(this.view.mentionsBox.find(".mentions").html()) - .toBe("@user1 Text before user1\ntext after"); + .toBe("@user1 Text before @{user1@pod.tld}\ntext after"); }); it("properly escapes the user input", function() { - this.view.inputBox.val(" @user1 Text before \u200Buser1\ntext after"); + this.view.inputBox.val(" @user1 Text before @{user1@pod.tld}\ntext after"); this.view.updateMessageTexts(); expect(this.view.mentionsBox.find(".mentions").html()) - .toBe("<img src=\"/default.png\"> @user1 Text before user1\ntext after"); + .toBe("<img src=\"/default.png\"> @user1 Text before @{user1@pod.tld}\ntext after"); }); }); @@ -264,7 +274,7 @@ describe("app.views.PublisherMention", function() { this.view.prefillMention([{"name": "user1", "handle": "user1@pod.tld"}]); expect(this.view.addPersonToMentions).toHaveBeenCalledWith({"name": "user1", "handle": "user1@pod.tld"}); expect(this.view.updateMessageTexts).toHaveBeenCalled(); - expect(this.view.inputBox.val()).toBe("\u200Buser1"); + expect(this.view.inputBox.val()).toBe("@{user1@pod.tld}"); }); it("prefills multiple mentions", function() { @@ -276,7 +286,7 @@ describe("app.views.PublisherMention", function() { expect(this.view.addPersonToMentions).toHaveBeenCalledWith({"name": "user1", "handle": "user1@pod.tld"}); expect(this.view.addPersonToMentions).toHaveBeenCalledWith({"name": "user2", "handle": "user2@pod.tld"}); expect(this.view.updateMessageTexts).toHaveBeenCalled(); - expect(this.view.inputBox.val()).toBe("\u200Buser1 \u200Buser2"); + expect(this.view.inputBox.val()).toBe("@{user1@pod.tld} @{user2@pod.tld}"); }); });