Merge "Fix highlight on multi-line range comments"
diff --git a/package.json b/package.json
index d051c41..329e3cb 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,8 @@
   },
   "scripts": {
     "clean": "git clean -fdx && bazel clean --expunge",
+    "compile:local": "tsc --project ./polygerrit-ui/app/tsconfig.json",
+    "compile:watch": "npm run compile:local -- --preserveWatchOutput --watch",
     "start": "polygerrit-ui/run-server.sh",
     "test": "./polygerrit-ui/app/run_test.sh",
     "safe_bazelisk": "if which bazelisk >/dev/null; then bazel_bin=bazelisk; else bazel_bin=bazel; fi && $bazel_bin",
diff --git a/polygerrit-ui/README.md b/polygerrit-ui/README.md
index ce274f2..3a66e97 100644
--- a/polygerrit-ui/README.md
+++ b/polygerrit-ui/README.md
@@ -4,7 +4,7 @@
 contains several typescript files and uses typescript compiler. This is a
 preparation for the upcoming migration to typescript and we actively working on
 it. We want to avoid massive typescript-related changes until the preparation
-work is done. Thanks for your understanding!    
+work is done. Thanks for your understanding!
 
 
 Follow the
@@ -93,7 +93,7 @@
 manually. For example, if IntelliJ IDEA shows
 `Cannot find parent 'tsconfig.json'` error, you can try to setup typescript
 options `--project polygerrit-ui/app/tsconfig.json` in the IDE settings.
-  
+
 
 ## Serving files locally
 
@@ -171,29 +171,58 @@
 For daily development you typically only want to run and debug individual tests.
 There are several ways to run tests.
 
-* Run all tests in headless mode:
+* Run all tests in headless mode (exactly like CI does):
 ```sh
 npm run test
 ```
+This command uses bazel rules for running frontend tests. Bazel fetches
+all nessecary dependencies and runs all required rules.
 
 * Run all tests in debug mode (the command opens Chrome browser with
 the default Karma page; you should click the "Debug" button to start testing):
 ```sh
+# The following command doesn't compile code before tests
 npm run test:debug
 ```
 
 * Run a single test file:
 ```
-# Headless mode
+# Headless mode (doesn't compile code before run)
 npm run test:single async-foreach-behavior_test.js
-# Debug mode
+
+# Debug mode (doesn't compile code before run)
+npm run test:debug async-foreach-behavior_test.js
+```
+
+Commands `test:debug` and `test:single` assumes that compiled code is located
+in the `./ts-out/polygerrit-ui/app` directory. It's up to you how to achieve it.
+For example, the following options are possible:
+* You can configure IDE for recompiling source code on changes
+* You can use `compile:local` command for running compiler once and
+`compile:watch` for running compiler in watch mode (`compile:...` places
+compile code exactly in the `./ts-out/polygerrit-ui/app` directory)
+
+```sh
+# Compile frontend once and run tests from a file:
+npm run compile:local && npm run test:single async-foreach-behavior_test.js
+
+# Watch mode:
+## Terminal 1:
+npm run compile:watch
+## Terminal 2:
 npm run test:debug async-foreach-behavior_test.js
 ```
 
 * You can run tests in IDE. :
   - [IntelliJ: running unit tests on Karma](https://www.jetbrains.com/help/idea/running-unit-tests-on-karma.html#ws_karma_running)
   - You should configure IDE to compile typescript before running tests.
-    
+
+**NOTE**: Bazel plugin for IntelliJ has a bug - it recompiles typescript
+project only if .ts and/or .d.ts files have been changed. If only .js files
+were changed, the plugin doesn't run compiler. As a workaround, setup
+"Run npm script 'compile:local" action instead of the "Compile Typescript" in
+the "Before launch" section for IntelliJ. This is a temporary problem until
+typescript migration is complete.
 
 ## Style guide
 
diff --git a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js
index 2db1c09..b525a82 100644
--- a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js
+++ b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js
@@ -577,6 +577,7 @@
         detail: {
           event: e,
           goKey: this._inGoKeyMode(),
+          vKey: this._inVKeyMode(),
         },
         composed: true, bubbles: true,
       }));
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 ad72ee1..d3cdfbe 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
@@ -563,8 +563,9 @@
       this.$.cursor.moveToNextCommentThread();
     } else {
       if (this.modifierPressed(e)) { return; }
+      // navigate to next file if key is not being held down
       this.$.cursor.moveToNextChunk(/* opt_clipToTop = */false,
-          /* opt_navigateToNextFile = */true);
+          /* opt_navigateToNextFile = */!e.detail.keyboardEvent.repeat);
     }
   }
 
diff --git a/polygerrit-ui/app/elements/gr-app-element.js b/polygerrit-ui/app/elements/gr-app-element.js
index a01e8a4..db098c5 100644
--- a/polygerrit-ui/app/elements/gr-app-element.js
+++ b/polygerrit-ui/app/elements/gr-app-element.js
@@ -421,10 +421,11 @@
   }
 
   _handleShortcutTriggered(event) {
-    const {event: e, goKey} = event.detail;
+    const {event: e, goKey, vKey} = event.detail;
     // eg: {key: "k:keydown", ..., from: "gr-diff-view"}
     let key = `${e.key}:${e.type}`;
     if (goKey) key = 'g+' + key;
+    if (vKey) key = 'v+' + key;
     if (e.shiftKey) key = 'shift+' + key;
     if (e.ctrlKey) key = 'ctrl+' + key;
     if (e.metaKey) key = 'meta+' + key;