Merge changes from topic "ts-repo-commands"

* changes:
  Convert files to typescript
  Rename files to preserve history
diff --git a/Documentation/concept-changes.txt b/Documentation/concept-changes.txt
index 762fb43..6de787c 100644
--- a/Documentation/concept-changes.txt
+++ b/Documentation/concept-changes.txt
@@ -14,7 +14,7 @@
 
 * Current and previous patch sets
 * <<Change properties>>, such as owner, project, and target branch
-* link:CONCEPT-comments.html[Comments]
+* Comments
 * Votes on link:config-labels.html[Review Labels]
 * The <<change-id>>
 
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index a773276..b4ae469 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -379,13 +379,13 @@
 notifications of these events by implementing the corresponding
 listeners.
 
-* `com.google.gerrit.common.EventListener`:
+* `com.google.gerrit.server.events.EventListener`:
 +
 Allows to listen to events without user visibility restrictions. These
 are the same link:cmd-stream-events.html#events[events] that are also streamed by
 the link:cmd-stream-events.html[gerrit stream-events] command.
 
-* `com.google.gerrit.common.UserScopedEventListener`:
+* `com.google.gerrit.server.events.UserScopedEventListener`:
 +
 Allows to listen to events visible to the specified user. These are the
 same link:cmd-stream-events.html#events[events] that are also streamed
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 2504419..ce08a86 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
@@ -2138,7 +2138,8 @@
     }
 
     this._updateCheckTimerHandle = this.async(() => {
-      fetchChangeUpdates(this._change, this.$.restAPI).then(result => {
+      const change = this._change;
+      fetchChangeUpdates(change, this.$.restAPI).then(result => {
         let toastMessage = null;
         if (!result.isLatest) {
           toastMessage = ReloadToastMessage.NEWER_REVISION;
@@ -2152,7 +2153,12 @@
           toastMessage = ReloadToastMessage.NEW_MESSAGE;
         }
 
-        if (!toastMessage) {
+        // We have to make sure that the update is still relevant for the user.
+        // Since starting to fetch the change update the user may have sent a
+        // reply, or the change might have been reloaded, or it could be in the
+        // process of being reloaded.
+        const changeWasReloaded = change !== this._change;
+        if (!toastMessage || this._loading || changeWasReloaded) {
           this._startUpdateCheckTimer();
           return;
         }
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
index 3d530b5..179caaa 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
@@ -1971,7 +1971,7 @@
         assert.isFalse(getChangeDetailStub.called);
       });
 
-      test('_startUpdateCheckTimer up-to-date', () => {
+      test('_startUpdateCheckTimer up-to-date', async () => {
         const getChangeDetailStub =
             sinon.stub(element.$.restAPI, 'getChangeDetail')
                 .callsFake(() => Promise.resolve(generateChange({
@@ -1981,8 +1981,9 @@
                 })));
 
         element._serverConfig = {change: {update_delay: 12345}};
+        await flush();
 
-        assert.isTrue(element._startUpdateCheckTimer.called);
+        assert.equal(element._startUpdateCheckTimer.callCount, 2);
         assert.isTrue(getChangeDetailStub.called);
         assert.equal(element.async.lastCall.args[1], 12345 * 1000);
       });
@@ -2001,6 +2002,24 @@
           done();
         });
         element._serverConfig = {change: {update_delay: 12345}};
+
+        assert.equal(element._startUpdateCheckTimer.callCount, 1);
+      });
+
+      test('_startUpdateCheckTimer respects _loading', async () => {
+        sinon.stub(element.$.restAPI, 'getChangeDetail')
+            .callsFake(() => Promise.resolve(generateChange({
+              // new patchset was uploaded
+              revisionsCount: 2,
+              messagesCount: 1,
+            })));
+
+        element._loading = true;
+        element._serverConfig = {change: {update_delay: 12345}};
+        await flush();
+
+        // No toast, instead a second call to _startUpdateCheckTimer().
+        assert.equal(element._startUpdateCheckTimer.callCount, 2);
       });
 
       test('_startUpdateCheckTimer new status shows an alert', done => {
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
index 162caa4..bd3c052 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
@@ -335,6 +335,7 @@
     el.show(text, actionText, actionCallback);
     this._alertElement = el;
     this.fire('iron-announce', {text}, {bubbles: true});
+    this.reporting.reportInteraction('show-alert', {text});
   }
 
   _hideAlert() {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-side-by-side.ts b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-side-by-side.ts
index 6810683..7b0caf2 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-side-by-side.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-side-by-side.ts
@@ -41,6 +41,9 @@
     if (group.dueToRebase) {
       sectionEl.classList.add('dueToRebase');
     }
+    if (group.dueToMove) {
+      sectionEl.classList.add('dueToMove');
+    }
     if (group.ignoredWhitespaceOnly) {
       sectionEl.classList.add('ignoredWhitespaceOnly');
     }
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified.ts b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified.ts
index 6760514..2eb5bf9e 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified.ts
@@ -40,6 +40,9 @@
     if (group.dueToRebase) {
       sectionEl.classList.add('dueToRebase');
     }
+    if (group.dueToMove) {
+      sectionEl.classList.add('dueToMove');
+    }
     if (group.ignoredWhitespaceOnly) {
       sectionEl.classList.add('ignoredWhitespaceOnly');
     }
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js
index 5240296..3eba4e1 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js
@@ -133,6 +133,12 @@
       assert.isTrue(sectionEl.classList.contains('dueToRebase'));
     });
 
+    test('creates the section with class if dueToMove', () => {
+      group.dueToMove = true;
+      const sectionEl = diffBuilder.buildSectionElement(group);
+      assert.isTrue(sectionEl.classList.contains('dueToMove'));
+    });
+
     test('creates first the removed and then the added rows', () => {
       const sectionEl = diffBuilder.buildSectionElement(group);
       const rowEls = sectionEl.querySelectorAll('.diff-row');
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts
index b521661..a85af34 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts
@@ -359,6 +359,7 @@
     const group = new GrDiffGroup(type, lines);
     group.keyLocation = !!chunk.keyLocation;
     group.dueToRebase = !!chunk.due_to_rebase;
+    group.dueToMove = !!chunk.due_to_move;
     group.ignoredWhitespaceOnly = !!chunk.common;
     return group;
   }
@@ -676,6 +677,9 @@
       if (chunk.due_to_rebase) {
         subChunk.due_to_rebase = true;
       }
+      if (chunk.due_to_move) {
+        subChunk.due_to_move = true;
+      }
       return subChunk;
     });
   }
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js
index c1c344f..3a074bb 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js
@@ -875,6 +875,16 @@
             }
           });
 
+      test('_breakdownChunk keeps due_to_move for broken down additions',
+          () => {
+            sinon.spy(element, '_breakdown');
+            const chunk = {b: ['blah', 'blah', 'blah'], due_to_move: true};
+            const result = element._breakdownChunk(chunk);
+            for (const subResult of result) {
+              assert.isTrue(subResult.due_to_move);
+            }
+          });
+
       test('_breakdown common case', () => {
         const array = 'Lorem ipsum dolor sit amet, suspendisse inceptos'
             .split(' ');
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index 90acad3..8d57085 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -1210,9 +1210,10 @@
 
   _onLineSelected(e, detail) {
     if (!this._change) { return; }
-    const cursorAddress = this.$.cursor.getAddress();
-    const number = cursorAddress ? cursorAddress.number : undefined;
-    const leftSide = cursorAddress ? cursorAddress.leftSide : undefined;
+    const number = detail.number;
+    // for on-comment-anchor-tap side can be PARENT/REVISIONS
+    // for on-line-selected side can be LEFT/RIGHT
+    const leftSide = detail.side === 'LEFT' || detail.side === 'PARENT';
     const url = GerritNav.getUrlForDiffById(this._changeNum,
         this._change.project, this._path, this._patchRange.patchNum,
         this._patchRange.basePatchNum, number, leftSide);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
index 8b5a972..62963c8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
@@ -1272,20 +1272,6 @@
       assert.isTrue(getUrlStub.called);
     });
 
-    test('_onLineSelected w/o line address', () => {
-      const getUrlStub = sinon.stub(GerritNav, 'getUrlForDiffById');
-      sinon.stub(history, 'replaceState');
-      sinon.stub(element.$.cursor, 'moveToLineNumber');
-      sinon.stub(element.$.cursor, 'getAddress').returns(null);
-      element._changeNum = 321;
-      element._change = {_number: 321, project: 'foo/bar'};
-      element._patchRange = {basePatchNum: '3', patchNum: '5'};
-      element._onLineSelected({}, {number: 123, side: 'right'});
-      assert.isTrue(getUrlStub.calledOnce);
-      assert.isUndefined(getUrlStub.lastCall.args[5]);
-      assert.isUndefined(getUrlStub.lastCall.args[6]);
-    });
-
     test('_getDiffViewMode', () => {
       // No user prefs or change view state set.
       assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group.ts b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group.ts
index d500ea5..9f5cdf3 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group.ts
@@ -189,6 +189,8 @@
 
   dueToRebase = false;
 
+  dueToMove = false;
+
   /**
    * True means all changes in this line are whitespace changes that should
    * not be highlighted as changed as per the user settings.
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts
index f18af23..f9656b8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_html.ts
@@ -177,6 +177,14 @@
       background-color: var(--light-remove-add-highlight-color);
     }
 
+    /* dueToMove */
+    .dueToMove .content.add .contentText {
+      background-color: var(--light-moved-add-highlight-color);
+    }
+    .dueToMove .content.remove .contentText {
+      background-color: var(--light-remove-add-highlight-color);
+    }
+
     /* ignoredWhitespaceOnly */
     .ignoredWhitespaceOnly .content.add .contentText .intraline,
     .delta.total.ignoredWhitespaceOnly .content.add .contentText,
diff --git a/polygerrit-ui/app/styles/themes/app-theme.ts b/polygerrit-ui/app/styles/themes/app-theme.ts
index 2706b22..835ef0a 100644
--- a/polygerrit-ui/app/styles/themes/app-theme.ts
+++ b/polygerrit-ui/app/styles/themes/app-theme.ts
@@ -167,6 +167,7 @@
     --diff-trailing-whitespace-indicator: #ff9ad2;
     --light-add-highlight-color: #d8fed8;
     --light-rebased-add-highlight-color: #eef;
+    --light-moved-add-highlight-color: #eef;
     --light-remove-add-highlight-color: #fff8dc;
     --light-remove-highlight-color: #ffebee;
     --coverage-covered: #e0f2f1;
diff --git a/polygerrit-ui/app/styles/themes/dark-theme.ts b/polygerrit-ui/app/styles/themes/dark-theme.ts
index 2fa66f0..3032984 100644
--- a/polygerrit-ui/app/styles/themes/dark-theme.ts
+++ b/polygerrit-ui/app/styles/themes/dark-theme.ts
@@ -117,6 +117,7 @@
       --diff-trailing-whitespace-indicator: #ff9ad2;
       --light-add-highlight-color: #0f401f;
       --light-rebased-add-highlight-color: #487165;
+      --light-moved-add-highlight-color: #487165;
       --light-remove-add-highlight-color: #2f3f2f;
       --light-remove-highlight-color: #320404;
       --coverage-covered: #112826;
diff --git a/polygerrit-ui/app/types/common.ts b/polygerrit-ui/app/types/common.ts
index 0c4bc8b..cc74ef1 100644
--- a/polygerrit-ui/app/types/common.ts
+++ b/polygerrit-ui/app/types/common.ts
@@ -1123,6 +1123,7 @@
   edit_a?: number[][];
   edit_b?: number[][];
   due_to_rebase?: boolean;
+  due_to_move?: boolean;
   skip?: string;
   common?: string;
   keyLocation?: boolean;