| // 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.gerrit.client.Gerrit; |
| import com.google.gerrit.client.diff.DisplaySide; |
| import com.google.gerrit.client.rpc.CallbackGroup; |
| import com.google.gwt.core.client.JavaScriptObject; |
| import com.google.gwt.dom.client.Element; |
| import com.google.gwt.dom.client.NativeEvent; |
| import com.google.gwt.resources.client.CssResource; |
| import com.google.gwt.user.client.Window; |
| import com.google.gwt.user.client.rpc.AsyncCallback; |
| import net.codemirror.lib.TextMarker.FromTo; |
| |
| /** |
| * Glue to connect CodeMirror to be callable from GWT. |
| * |
| * @see <a href="http://codemirror.net/doc/manual.html#api">CodeMirror API</a> |
| */ |
| public class CodeMirror extends JavaScriptObject { |
| public static void preload() { |
| initLibrary(CallbackGroup.<Void>emptyCallback()); |
| } |
| |
| public static void initLibrary(AsyncCallback<Void> cb) { |
| Loader.initLibrary(cb); |
| } |
| |
| interface Style extends CssResource { |
| String activeLine(); |
| |
| String showTabs(); |
| |
| String margin(); |
| } |
| |
| static Style style() { |
| return Lib.I.style(); |
| } |
| |
| public static CodeMirror create(Element p, Configuration cfg) { |
| CodeMirror cm = newCM(p, cfg); |
| Extras.attach(cm); |
| return cm; |
| } |
| |
| private static native CodeMirror newCM(Element p, Configuration cfg) /*-{ |
| return $wnd.CodeMirror(p, cfg); |
| }-*/; |
| |
| public final native void setOption(String option, boolean value) /*-{ |
| this.setOption(option, value) |
| }-*/; |
| |
| public final native void setOption(String option, double value) /*-{ |
| this.setOption(option, value) |
| }-*/; |
| |
| public final native void setOption(String option, String value) /*-{ |
| this.setOption(option, value) |
| }-*/; |
| |
| public final native void setOption(String option, JavaScriptObject val) /*-{ |
| this.setOption(option, val) |
| }-*/; |
| |
| public final native String getStringOption(String o) /*-{ return this.getOption(o) }-*/; |
| |
| public final native String getValue() /*-{ return this.getValue() }-*/; |
| |
| public final native void setValue(String v) /*-{ this.setValue(v) }-*/; |
| |
| public final native int changeGeneration(boolean closeEvent) |
| /*-{ return this.changeGeneration(closeEvent) }-*/ ; |
| |
| public final native boolean isClean(int generation) /*-{ return this.isClean(generation) }-*/; |
| |
| public final native void setWidth(double w) /*-{ this.setSize(w, null) }-*/; |
| |
| public final native void setHeight(double h) /*-{ this.setSize(null, h) }-*/; |
| |
| public final int getHeight() { |
| return getWrapperElement().getClientHeight(); |
| } |
| |
| public final void adjustHeight(int localHeader) { |
| int rest = Gerrit.getHeaderFooterHeight() + localHeader + 5; // Estimate |
| setHeight(Window.getClientHeight() - rest); |
| } |
| |
| public final native String getLine(int n) /*-{ return this.getLine(n) }-*/; |
| |
| public final native double barHeight() /*-{ return this.display.barHeight }-*/; |
| |
| public final native double barWidth() /*-{ return this.display.barWidth }-*/; |
| |
| public final native int lastLine() /*-{ return this.lastLine() }-*/; |
| |
| public final native void refresh() /*-{ this.refresh() }-*/; |
| |
| public final native TextMarker markText(Pos from, Pos to, Configuration options) /*-{ |
| return this.markText(from, to, options) |
| }-*/; |
| |
| public enum LineClassWhere { |
| TEXT { |
| @Override |
| String value() { |
| return "text"; |
| } |
| }, |
| BACKGROUND { |
| @Override |
| String value() { |
| return "background"; |
| } |
| }, |
| WRAP { |
| @Override |
| String value() { |
| return "wrap"; |
| } |
| }; |
| |
| abstract String value(); |
| } |
| |
| public final void addLineClass(int line, LineClassWhere where, String className) { |
| addLineClassNative(line, where.value(), className); |
| } |
| |
| private native void addLineClassNative(int line, String where, String lineClass) /*-{ |
| this.addLineClass(line, where, lineClass) |
| }-*/; |
| |
| public final void addLineClass(LineHandle line, LineClassWhere where, String className) { |
| addLineClassNative(line, where.value(), className); |
| } |
| |
| private native void addLineClassNative(LineHandle line, String where, String lineClass) /*-{ |
| this.addLineClass(line, where, lineClass) |
| }-*/; |
| |
| public final void removeLineClass(int line, LineClassWhere where, String className) { |
| removeLineClassNative(line, where.value(), className); |
| } |
| |
| private native void removeLineClassNative(int line, String where, String lineClass) /*-{ |
| this.removeLineClass(line, where, lineClass) |
| }-*/; |
| |
| public final void removeLineClass(LineHandle line, LineClassWhere where, String className) { |
| removeLineClassNative(line, where.value(), className); |
| } |
| |
| private native void removeLineClassNative(LineHandle line, String where, String lineClass) /*-{ |
| this.removeLineClass(line, where, lineClass) |
| }-*/; |
| |
| public final native void addWidget(Pos pos, Element node) /*-{ |
| this.addWidget(pos, node, false) |
| }-*/; |
| |
| public final native LineWidget addLineWidget(int line, Element node, Configuration options) /*-{ |
| return this.addLineWidget(line, node, options) |
| }-*/; |
| |
| public final native int lineAtHeight(double height) /*-{ |
| return this.lineAtHeight(height) |
| }-*/; |
| |
| public final native int lineAtHeight(double height, String mode) /*-{ |
| return this.lineAtHeight(height, mode) |
| }-*/; |
| |
| public final native double heightAtLine(int line) /*-{ |
| return this.heightAtLine(line) |
| }-*/; |
| |
| public final native double heightAtLine(int line, String mode) /*-{ |
| return this.heightAtLine(line, mode) |
| }-*/; |
| |
| public final native Rect charCoords(Pos pos, String mode) /*-{ |
| return this.charCoords(pos, mode) |
| }-*/; |
| |
| public final native CodeMirrorDoc getDoc() /*-{ |
| return this.getDoc() |
| }-*/; |
| |
| public final native void scrollTo(double x, double y) /*-{ |
| this.scrollTo(x, y) |
| }-*/; |
| |
| public final native void scrollToY(double y) /*-{ |
| this.scrollTo(null, y) |
| }-*/; |
| |
| 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, 0)); |
| } |
| |
| public final native ScrollInfo getScrollInfo() /*-{ |
| return this.getScrollInfo() |
| }-*/; |
| |
| public final native Viewport getViewport() /*-{ |
| return this.getViewport() |
| }-*/; |
| |
| public final native void operation(Runnable thunk) /*-{ |
| this.operation(function() { |
| thunk.@java.lang.Runnable::run()(); |
| }) |
| }-*/; |
| |
| public final native void off(String event, RegisteredHandler h) /*-{ |
| this.off(event, h) |
| }-*/; |
| |
| public final native RegisteredHandler on(String event, Runnable thunk) /*-{ |
| var h = $entry(function() { thunk.@java.lang.Runnable::run()() }); |
| this.on(event, h); |
| return h; |
| }-*/; |
| |
| public final native void on(String event, EventHandler handler) /*-{ |
| this.on(event, $entry(function(cm, e) { |
| handler.@net.codemirror.lib.CodeMirror.EventHandler::handle( |
| Lnet/codemirror/lib/CodeMirror; |
| Lcom/google/gwt/dom/client/NativeEvent;)(cm, e); |
| })) |
| }-*/; |
| |
| public final native void on(String event, RenderLineHandler handler) /*-{ |
| this.on(event, $entry(function(cm, h, e) { |
| handler.@net.codemirror.lib.CodeMirror.RenderLineHandler::handle( |
| Lnet/codemirror/lib/CodeMirror; |
| Lnet/codemirror/lib/CodeMirror$LineHandle; |
| Lcom/google/gwt/dom/client/Element;)(cm, h, e); |
| })) |
| }-*/; |
| |
| public final native void on(String event, GutterClickHandler handler) /*-{ |
| this.on(event, $entry(function(cm, l, g, e) { |
| handler.@net.codemirror.lib.CodeMirror.GutterClickHandler::handle( |
| Lnet/codemirror/lib/CodeMirror; |
| I |
| Ljava/lang/String; |
| Lcom/google/gwt/dom/client/NativeEvent;)(cm, l, g, e); |
| })) |
| }-*/; |
| |
| public final native void on(String event, BeforeSelectionChangeHandler handler) /*-{ |
| this.on(event, $entry(function(cm, o) { |
| var e = o.ranges[o.ranges.length-1]; |
| handler.@net.codemirror.lib.CodeMirror.BeforeSelectionChangeHandler::handle( |
| Lnet/codemirror/lib/CodeMirror; |
| Lnet/codemirror/lib/Pos; |
| Lnet/codemirror/lib/Pos;)(cm, e.anchor, e.head); |
| })) |
| }-*/; |
| |
| public final native void on(ChangesHandler handler) /*-{ |
| this.on('changes', $entry(function(cm, o) { |
| handler.@net.codemirror.lib.CodeMirror.ChangesHandler::handle( |
| Lnet/codemirror/lib/CodeMirror;)(cm); |
| })) |
| }-*/; |
| |
| public final native void setCursor(Pos p) /*-{ this.setCursor(p) }-*/; |
| |
| public final native Pos getCursor() /*-{ return this.getCursor() }-*/; |
| |
| public final native Pos getCursor(String start) /*-{ |
| return this.getCursor(start) |
| }-*/; |
| |
| public final FromTo getSelectedRange() { |
| return FromTo.create(getCursor("start"), getCursor("end")); |
| } |
| |
| public final native void setSelection(Pos p) /*-{ this.setSelection(p) }-*/; |
| |
| public final native void setSelection(Pos anchor, Pos head) /*-{ |
| this.setSelection(anchor, head) |
| }-*/; |
| |
| public final native boolean somethingSelected() /*-{ |
| return this.somethingSelected() |
| }-*/; |
| |
| public final native void addKeyMap(KeyMap map) /*-{ this.addKeyMap(map) }-*/; |
| |
| public final native void removeKeyMap(KeyMap map) /*-{ this.removeKeyMap(map) }-*/; |
| |
| public final native LineHandle getLineHandle(int line) /*-{ |
| return this.getLineHandle(line) |
| }-*/; |
| |
| public final native LineHandle getLineHandleVisualStart(int line) /*-{ |
| return this.getLineHandleVisualStart(line) |
| }-*/; |
| |
| public final native int getLineNumber(LineHandle handle) /*-{ |
| return this.getLineNumber(handle) |
| }-*/; |
| |
| public final native void focus() /*-{ |
| this.focus() |
| }-*/; |
| |
| public final native Element getWrapperElement() /*-{ |
| return this.getWrapperElement() |
| }-*/; |
| |
| public final native Element getGutterElement() /*-{ |
| return this.getGutterElement() |
| }-*/; |
| |
| public final native Element sizer() /*-{ |
| return this.display.sizer |
| }-*/; |
| |
| public final native Element mover() /*-{ |
| return this.display.mover |
| }-*/; |
| |
| public final native Element measure() /*-{ |
| return this.display.measure |
| }-*/; |
| |
| public final native Element scrollbarV() /*-{ |
| return this.display.scrollbars.vert.node; |
| }-*/; |
| |
| public final native void execCommand(String cmd) /*-{ |
| this.execCommand(cmd) |
| }-*/; |
| |
| public static final native KeyMap getKeyMap(String name) /*-{ |
| return $wnd.CodeMirror.keyMap[name]; |
| }-*/; |
| |
| public static final native void addKeyMap(String name, KeyMap km) /*-{ |
| $wnd.CodeMirror.keyMap[name] = km |
| }-*/; |
| |
| public static final native void normalizeKeyMap(KeyMap km) /*-{ |
| $wnd.CodeMirror.normalizeKeyMap(km); |
| }-*/; |
| |
| public static final native void addCommand(String name, CommandRunner runner) /*-{ |
| $wnd.CodeMirror.commands[name] = function(cm) { |
| runner.@net.codemirror.lib.CodeMirror.CommandRunner::run( |
| Lnet/codemirror/lib/CodeMirror;)(cm); |
| }; |
| }-*/; |
| |
| public final native Vim vim() /*-{ |
| return this; |
| }-*/; |
| |
| public final DisplaySide side() { |
| return extras().side(); |
| } |
| |
| public final Extras extras() { |
| return Extras.get(this); |
| } |
| |
| public final native LineHandle setGutterMarker(int line, String gutterId, Element value) /*-{ |
| return this.setGutterMarker(line, gutterId, value); |
| }-*/; |
| |
| public final native LineHandle setGutterMarker( |
| LineHandle line, String gutterId, Element value) /*-{ |
| return this.setGutterMarker(line, gutterId, value); |
| }-*/; |
| |
| public final native boolean hasSearchHighlight() /*-{ |
| return this.state.search && !!this.state.search.query; |
| }-*/; |
| |
| protected CodeMirror() {} |
| |
| public static class Viewport extends JavaScriptObject { |
| public final native int from() /*-{ return this.from }-*/; |
| |
| public final native int to() /*-{ return this.to }-*/; |
| |
| public final boolean contains(int line) { |
| return from() <= line && line < to(); |
| } |
| |
| protected Viewport() {} |
| } |
| |
| public static class LineHandle extends JavaScriptObject { |
| protected LineHandle() {} |
| } |
| |
| public static class RegisteredHandler extends JavaScriptObject { |
| protected RegisteredHandler() {} |
| } |
| |
| public interface EventHandler { |
| void handle(CodeMirror instance, NativeEvent event); |
| } |
| |
| public interface RenderLineHandler { |
| void handle(CodeMirror instance, LineHandle handle, Element element); |
| } |
| |
| public interface GutterClickHandler { |
| void handle(CodeMirror instance, int line, String gutter, NativeEvent clickEvent); |
| } |
| |
| public interface BeforeSelectionChangeHandler { |
| void handle(CodeMirror instance, Pos anchor, Pos head); |
| } |
| |
| public interface ChangesHandler { |
| void handle(CodeMirror instance); |
| } |
| |
| public interface CommandRunner { |
| void run(CodeMirror instance); |
| } |
| } |