Fix R= issue in commit message

There was an issue when R=example@email.com went through link parsing
and the R= was considered to be part of the email address. Technically,
it is a valid email address, but with this change, we assume that
whenever a capital R= is in a linked text area, it indicates reviewers.

This is achieved by adding a zero width space after the '=' in the
change view prior to linkification. The linkify library correctly parses
the email without including R=.

Bug: Issue 5101
Change-Id: I1cca3b30e9cf503f2c2035768e7500bbc8081223
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 53119c3..bc3b91e 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -16,6 +16,7 @@
 
   // Maximum length for patch set descriptions.
   var PATCH_DESC_MAX_LENGTH = 500;
+  var REVIEWERS_REGEX = /^R=/gm;
 
   Polymer({
     is: 'gr-change-view',
@@ -178,7 +179,7 @@
         this.$.commitMessageEditor.disabled = false;
         if (!resp.ok) { return; }
 
-        this._latestCommitMessage = message;
+        this._latestCommitMessage = this._prepareCommitMsgForLinkify(message);
         this._editingCommitMessage = false;
         this._reloadWindow();
       }.bind(this)).catch(function(err) {
@@ -759,6 +760,12 @@
       return revisionActions;
     },
 
+    _prepareCommitMsgForLinkify: function(msg) {
+      // This is a zero-with space. It is added to prevent the linkify library
+      // from including R= as part of the email address.
+      return msg.replace(REVIEWERS_REGEX, 'R=\u200B');
+    },
+
     _getChangeDetail: function() {
       return this.$.restAPI.getChangeDetail(this._changeNum,
           this._handleGetChangeDetailError.bind(this)).then(
@@ -771,7 +778,8 @@
                 var latestRevisionSha = this._getLatestRevisionSHA(change);
                 var currentRevision = change.revisions[latestRevisionSha];
                 if (currentRevision.commit && currentRevision.commit.message) {
-                  this._latestCommitMessage = currentRevision.commit.message;
+                  this._latestCommitMessage = this._prepareCommitMsgForLinkify(
+                      currentRevision.commit.message);
                 } else {
                   this._latestCommitMessage = null;
                 }
@@ -802,7 +810,8 @@
       return this.$.restAPI.getChangeCommitInfo(this._changeNum,
           this._computeLatestPatchNum(this._allPatchSets)).then(
               function(commitInfo) {
-                this._latestCommitMessage = commitInfo.message;
+                this._latestCommitMessage =
+                    this._prepareCommitMsgForLinkify(commitInfo.message);
               }.bind(this));
     },
 
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index ac07952..0f13b29 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -164,6 +164,16 @@
           'Add a patch set description');
     });
 
+    test('_prepareCommitMsgForLinkify', function() {
+      var commitMessage = 'R=test@google.com';
+      var result = element._prepareCommitMsgForLinkify(commitMessage);
+      assert.equal(result, 'R=\u200Btest@google.com');
+
+      commitMessage = 'R=test@google.com\nR=test@google.com';
+      var result = element._prepareCommitMsgForLinkify(commitMessage);
+      assert.equal(result, 'R=\u200Btest@google.com\nR=\u200Btest@google.com');
+    }),
+
     test('_handleDescriptionChanged', function() {
       var putDescStub = sandbox.stub(element.$.restAPI, 'setDescription')
           .returns(Promise.resolve({ok: true}));
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
index 90b09ab..e33eb24 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
@@ -175,6 +175,12 @@
       assert.equal(element.$.output.innerHTML, 'foo:baz');
     });
 
+    test('R=email labels link correctly', function() {
+      element.content = 'R=\u200Btest@google.com';
+      assert.equal(element.$.output.textContent, 'R=\u200Btest@google.com');
+      assert.equal(element.$.output.innerHTML.match(/(R=\u200B<a)/g).length, 1);
+    });
+
     test('overlapping links', function() {
       element.config = {
         b1: {