Add ",codemirror" view of a file

To support development of an alternative view of files using
CodeMirror any patch can now be viewed using CodeMirror by
replacing ",unified" in the URL with ",codemirror".

This is currently fairly boring. I did just enough glue to
initialize the CodeMirror object, supply it with file data,
attach it to the DOM, and let it render. There are no modes
loaded so there is currently no syntax highlighting or any
other fancy features.

The intent of this new screen is to allow development in-tree.
If this ever becomes fully functional it will replace current
views by updating the Dispatcher. If it fails we will just rip
the code out and try something else.

Change-Id: I0a187b4ff2e273b803500af97d2bb1772f166daf
This commit is contained in:
Shawn Pearce
2013-05-20 23:08:50 -07:00
parent 99ca234e1c
commit 75110c1628
5 changed files with 181 additions and 3 deletions

View File

@@ -69,6 +69,7 @@ import com.google.gerrit.client.changes.PublishCommentScreen;
import com.google.gerrit.client.changes.QueryScreen;
import com.google.gerrit.client.dashboards.DashboardInfo;
import com.google.gerrit.client.dashboards.DashboardList;
import com.google.gerrit.client.diff.CodeMirrorDemo;
import com.google.gerrit.client.groups.GroupApi;
import com.google.gerrit.client.groups.GroupInfo;
import com.google.gerrit.client.patches.PatchScreen;
@@ -567,6 +568,8 @@ public class Dispatcher {
top, //
baseId //
);
} else if ("codemirror".equals(panel)) {
return new CodeMirrorDemo(baseId, id.getParentKey(), id.get());
}
}

View File

@@ -0,0 +1,111 @@
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.client.diff;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import net.codemirror.lib.CodeMirror;
import net.codemirror.lib.Configuration;
public class CodeMirrorDemo extends Screen {
private static final int HEADER_FOOTER = 60 + 15 * 2 + 38;
private final PatchSet.Id base;
private final PatchSet.Id revision;
private final String path;
private FlowPanel editorContainer;
private CodeMirror cm;
private HandlerRegistration resizeHandler;
public CodeMirrorDemo(
PatchSet.Id base,
PatchSet.Id revision,
String path) {
this.base = base;
this.revision = revision;
this.path = path;
}
@Override
protected void onInitUI() {
super.onInitUI();
add(editorContainer = new FlowPanel());
}
@Override
protected void onLoad() {
super.onLoad();
DiffApi.diff(revision, path)
.base(base)
.wholeFile()
.ignoreWhitespace(DiffApi.IgnoreWhitespace.NONE)
.get(new ScreenLoadCallback<DiffInfo>(this) {
@Override
protected void preDisplay(DiffInfo diff) {
display(diff);
}
});
}
@Override
public void onShowView() {
super.onShowView();
cm.refresh();
}
@Override
protected void onUnload() {
super.onUnload();
if (resizeHandler != null) {
resizeHandler.removeHandler();
resizeHandler = null;
}
if (cm != null) {
cm.getWrapperElement().removeFromParent();
cm = null;
}
}
private void display(DiffInfo diff) {
Configuration cfg = Configuration.create()
.set("readOnly", true)
.set("lineNumbers", true)
.set("tabSize", 2)
.set("value", diff.text_b());
if (diff.meta_b() != null && diff.meta_b().content_type() != null) {
cfg.set("mode", diff.meta_b().content_type());
}
cm = CodeMirror.create(editorContainer.getElement(), cfg);
cm.setWidth("100%");
cm.setHeight(Window.getClientHeight() - HEADER_FOOTER);
resizeHandler = Window.addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
cm.setHeight(event.getHeight() - HEADER_FOOTER);
cm.refresh();
}
});
}
}

View File

@@ -37,7 +37,9 @@ public class DiffApi {
}
public DiffApi base(PatchSet.Id id) {
call.addParameter("base", id.get());
if (id != null) {
call.addParameter("base", id.get());
}
return this;
}

View File

@@ -14,7 +14,9 @@
package net.codemirror.lib;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.ScriptElement;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.resources.client.ExternalTextResource;
@@ -26,7 +28,26 @@ import com.google.gwt.safehtml.shared.SafeUri;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CodeMirror {
/**
* Glue to connect CodeMirror to be callable from GWT.
*
* @link http://codemirror.net/doc/manual.html#api
*/
public class CodeMirror extends JavaScriptObject {
public static native CodeMirror create(Element parent, Configuration cfg) /*-{
return $wnd.CodeMirror(parent, cfg);
}-*/;
public final native void setValue(String v) /*-{ this.setValue(v); }-*/;
public final native void setWidth(int w) /*-{ this.setSize(w, null); }-*/;
public final native void setWidth(String w) /*-{ this.setSize(w, null); }-*/;
public final native void setHeight(int h) /*-{ this.setSize(null, h); }-*/;
public final native void setHeight(String h) /*-{ this.setSize(null, h); }-*/;
public final native void refresh() /*-{ this.refresh(); }-*/;
public final native Element getWrapperElement() /*-{ return this.getWrapperElement(); }-*/;
public static void install() {
asyncInjectCss(Lib.I.css());
asyncInjectScript(Lib.I.js().getSafeUri());
@@ -63,6 +84,6 @@ public class CodeMirror {
log.log(Level.SEVERE, "Cannot fetch CSS", e);
}
private CodeMirror() {
protected CodeMirror() {
}
}

View File

@@ -0,0 +1,41 @@
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package net.codemirror.lib;
import com.google.gwt.core.client.JavaScriptObject;
/**
* Simple map-like structure to pass configuration to CodeMirror.
*
* @link http://codemirror.net/doc/manual.html#config
* @see CodeMirror#create(com.google.gwt.dom.client.Element, Configuration)
*/
public class Configuration extends JavaScriptObject {
public static Configuration create() {
return createObject().cast();
}
public final native Configuration set(String name, String val)
/*-{ this[name] = val; return this; }-*/;
public final native Configuration set(String name, int val)
/*-{ this[name] = val; return this; }-*/;
public final native Configuration set(String name, boolean val)
/*-{ this[name] = val; return this; }-*/;
protected Configuration() {
}
}