Pass line number in EditScreen URL tokens

The line number should be part of the token, not a static field.
This allows the line to survive through a sign-in redirect.

Refactor the scroll-to-line feature from SideBySide into a common
Java based utility method on the CodeMirror instance. There is no
reason for this to be in pure JavaScript.

Change-Id: I2f1655e5a7c52bc27cc3a987e44210833d8b68bd
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
index 3e812bd..7bfde74 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
@@ -125,7 +125,11 @@
   }
 
   public static String toEditScreen(PatchSet.Id revision, String fileName) {
-    return toPatch("edit", null, revision, fileName, null, 0);
+    return toEditScreen(revision, fileName, 0);
+  }
+
+  public static String toEditScreen(PatchSet.Id revision, String fileName, int line) {
+    return toPatch("edit", null, revision, fileName, null, line);
   }
 
   private static String toPatch(String type, PatchSet.Id diffBase,
@@ -638,7 +642,7 @@
       @Override
       public void onSuccess() {
         Gerrit.display(token, edit
-            ? new EditScreen(id)
+            ? new EditScreen(id, line)
             : new SideBySide(baseId, id.getParentKey(), id.get(), side, line));
       }
     });
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PublishedBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PublishedBox.java
index 24b880c..7d71564 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PublishedBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PublishedBox.java
@@ -21,7 +21,6 @@
 import com.google.gerrit.client.changes.CommentApi;
 import com.google.gerrit.client.changes.CommentInfo;
 import com.google.gerrit.client.changes.Util;
-import com.google.gerrit.client.editor.EditScreen;
 import com.google.gerrit.client.patches.PatchUtil;
 import com.google.gerrit.client.rpc.GerritCallback;
 import com.google.gerrit.client.ui.CommentLinkProcessor;
@@ -160,12 +159,11 @@
   @UiHandler("edit")
   void onEdit(ClickEvent e) {
     e.stopPropagation();
-    EditScreen.scrollToLine(comment.line());
-    String token = Dispatcher.toEditScreen(psId, comment.path());
+    String t = Dispatcher.toEditScreen(psId, comment.path(), comment.line());
     if (!Gerrit.isSignedIn()) {
-      Gerrit.doSignIn(token);
+      Gerrit.doSignIn(t);
     } else {
-      Gerrit.display(token);
+      Gerrit.display(t);
     }
   }
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java
index 682fdc4..fca7b1e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java
@@ -30,7 +30,6 @@
 import com.google.gerrit.client.changes.ChangeList;
 import com.google.gerrit.client.diff.DiffInfo.FileMeta;
 import com.google.gerrit.client.diff.LineMapper.LineOnOtherInfo;
-import com.google.gerrit.client.editor.EditScreen;
 import com.google.gerrit.client.patches.PatchUtil;
 import com.google.gerrit.client.projects.ConfigInfoCache;
 import com.google.gerrit.client.rpc.CallbackGroup;
@@ -308,13 +307,8 @@
       }
     }
     if (startSide != null && startLine > 0) {
-      int line = startLine - 1;
       CodeMirror cm = getCmFromSide(startSide);
-      int height = cm.getHeight();
-      if (cm.lineAtHeight(height - 20) < line) {
-        cm.scrollToY(cm.heightAtLine(line, "local") - 0.5 * height);
-      }
-      cm.setCursor(Pos.create(line));
+      cm.scrollToLine(startLine - 1);
       cm.focus();
     } else {
       cmA.setCursor(Pos.create(0));
@@ -919,8 +913,7 @@
       public void run() {
         LineHandle handle = cm.extras().activeLine();
         int line = cm.getLineNumber(handle) + 1;
-        EditScreen.scrollToLine(line);
-        String token = Dispatcher.toEditScreen(revision, path);
+        String token = Dispatcher.toEditScreen(revision, path, line);
         if (!Gerrit.isSignedIn()) {
           Gerrit.doSignIn(token);
         } else {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java
index eba4a35..498301a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java
@@ -71,9 +71,9 @@
   interface Binder extends UiBinder<HTMLPanel, EditScreen> {}
   private static final Binder uiBinder = GWT.create(Binder.class);
 
-  private static int scrollToLine;
   private final PatchSet.Id revision;
   private final String path;
+  private final int startLine;
   private DiffPreferences prefs;
   private CodeMirror cm;
   private HttpResponse<NativeString> content;
@@ -92,9 +92,10 @@
   private HandlerRegistration closeHandler;
   private int generation;
 
-  public EditScreen(Patch.Key patch) {
+  public EditScreen(Patch.Key patch, int startLine) {
     this.revision = patch.getParentKey();
     this.path = patch.get();
+    this.startLine = startLine;
     prefs = DiffPreferences.create(Gerrit.getAccountDiffPreference());
     add(uiBinder.createAndBindUi(this));
     addDomHandler(GlobalKey.STOP_PROPAGATION, KeyPressEvent.getType());
@@ -219,9 +220,9 @@
         Patch.COMMIT_MSG.equals(path) ? 72 : prefs.lineLength());
     cm.refresh();
     cm.focus();
-    if (scrollToLine != 0) {
-      cm.scrollToLine(scrollToLine);
-      scrollToLine = 0;
+
+    if (startLine > 0) {
+      cm.scrollToLine(startLine);
     }
     updateActiveLine();
   }
@@ -347,8 +348,4 @@
   private void injectMode(String type, AsyncCallback<Void> cb) {
     new ModeInjector().add(type).inject(cb);
   }
-
-  public static void scrollToLine(int line) {
-    scrollToLine = line;
-  }
 }
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
index 3373395..fc21532 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
@@ -199,13 +199,13 @@
     this.scrollTo(null, y)
   }-*/;
 
-  public final native void scrollToLine(int line) /*-{
-    line = line - 1;
-    this.setCursor({line:line,ch:0});
-    var myHeight = this.getScrollInfo().clientHeight;
-    var coords = this.charCoords({line: line, ch: 0}, "local");
-    this.scrollTo(null, (coords.top + coords.bottom - myHeight) / 2);
-  }-*/;
+  public final void scrollToLine(int line) {
+    int height = getHeight();
+    if (lineAtHeight(height - 20) < line) {
+      scrollToY(heightAtLine(line, "local") - 0.5 * height);
+    }
+    setCursor(Pos.create(line));
+  }
 
   public final native ScrollInfo getScrollInfo() /*-{
     return this.getScrollInfo()