Display mention syntax in publisher instead of username

This commit is contained in:
Steffen van Bergerem 2017-01-30 12:50:03 +01:00
parent 408645cccc
commit b3c412d38f
No known key found for this signature in database
GPG key ID: 315C9787D548DC6B
2 changed files with 39 additions and 51 deletions

View file

@ -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("<strong><span><%= name %></span></strong>")
},
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 <strong><span>user1</span></strong>" 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;
}

View file

@ -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 <strong><span>user1</span></strong>\ntext after");
.toBe("@user1 Text before @{user1@pod.tld}\ntext after");
});
it("properly escapes the user input", function() {
this.view.inputBox.val("<img src=\"/default.png\"> @user1 Text before \u200Buser1\ntext after");
this.view.inputBox.val("<img src=\"/default.png\"> @user1 Text before @{user1@pod.tld}\ntext after");
this.view.updateMessageTexts();
expect(this.view.mentionsBox.find(".mentions").html())
.toBe("&lt;img src=\"/default.png\"&gt; @user1 Text before <strong><span>user1</span></strong>\ntext after");
.toBe("&lt;img src=\"/default.png\"&gt; @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}");
});
});