Merge changes from topic 'inline-4'
* changes: Inline Edit: Bind Ctrl/Cmd-S to save Inline Edit: Confirm discard of edits Inline Edit: Honor diff preferences like SideBySide2 Refactor common SideBySide2 CSS for CodeMirror Inline Edit: Set content during editor creation Inline Edit: Correctly handle browser resizing
This commit is contained in:
@@ -147,7 +147,7 @@ class ChunkManager {
|
||||
|
||||
void adjustPadding() {
|
||||
if (paddingDivs != null) {
|
||||
double h = host.getLineHeightPx();
|
||||
double h = cmB.extras().lineHeightPx();
|
||||
for (Element div : paddingDivs) {
|
||||
int lines = div.getPropertyInt(DATA_LINES);
|
||||
div.getStyle().setHeight(lines * h, Unit.PX);
|
||||
@@ -291,7 +291,9 @@ class ChunkManager {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int line = cm.hasActiveLine() ? cm.getLineNumber(cm.activeLine()) : 0;
|
||||
int line = cm.extras().hasActiveLine()
|
||||
? cm.getLineNumber(cm.extras().activeLine())
|
||||
: 0;
|
||||
int res = Collections.binarySearch(
|
||||
chunks,
|
||||
new DiffChunkInfo(cm.side(), line, 0, false),
|
||||
|
@@ -91,8 +91,8 @@ class CommentManager {
|
||||
// It is only necessary to search one side to find a comment
|
||||
// on either side of the editor pair.
|
||||
SortedMap<Integer, CommentGroup> map = map(src.side());
|
||||
int line = src.hasActiveLine()
|
||||
? src.getLineNumber(src.activeLine()) + 1
|
||||
int line = src.extras().hasActiveLine()
|
||||
? src.getLineNumber(src.extras().activeLine()) + 1
|
||||
: 0;
|
||||
if (dir == Direction.NEXT) {
|
||||
map = map.tailMap(line + 1);
|
||||
@@ -295,9 +295,9 @@ class CommentManager {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (cm.hasActiveLine()) {
|
||||
if (cm.extras().hasActiveLine()) {
|
||||
CommentGroup w = map(cm.side()).get(
|
||||
cm.getLineNumber(cm.activeLine()) + 1);
|
||||
cm.getLineNumber(cm.extras().activeLine()) + 1);
|
||||
if (w != null) {
|
||||
w.openCloseLast();
|
||||
}
|
||||
@@ -310,9 +310,9 @@ class CommentManager {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (cm.hasActiveLine()) {
|
||||
if (cm.extras().hasActiveLine()) {
|
||||
CommentGroup w = map(cm.side()).get(
|
||||
cm.getLineNumber(cm.activeLine()) + 1);
|
||||
cm.getLineNumber(cm.extras().activeLine()) + 1);
|
||||
if (w != null) {
|
||||
w.openCloseAll();
|
||||
}
|
||||
@@ -327,8 +327,8 @@ class CommentManager {
|
||||
@Override
|
||||
public void run() {
|
||||
String token = host.getToken();
|
||||
if (cm.hasActiveLine()) {
|
||||
LineHandle handle = cm.activeLine();
|
||||
if (cm.extras().hasActiveLine()) {
|
||||
LineHandle handle = cm.extras().activeLine();
|
||||
int line = cm.getLineNumber(handle) + 1;
|
||||
token += "@" + (cm.side() == DisplaySide.A ? "a" : "") + line;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ class CommentManager {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (cm.hasActiveLine()) {
|
||||
if (cm.extras().hasActiveLine()) {
|
||||
newDraft(cm);
|
||||
}
|
||||
}
|
||||
@@ -348,7 +348,7 @@ class CommentManager {
|
||||
}
|
||||
|
||||
private void newDraft(CodeMirror cm) {
|
||||
int line = cm.getLineNumber(cm.activeLine()) + 1;
|
||||
int line = cm.getLineNumber(cm.extras().activeLine()) + 1;
|
||||
if (cm.somethingSelected()) {
|
||||
FromTo fromTo = cm.getSelectedRange();
|
||||
Pos end = fromTo.to();
|
||||
|
@@ -48,14 +48,11 @@ class DiffTable extends Composite {
|
||||
String dark();
|
||||
String diff();
|
||||
String noIntraline();
|
||||
String activeLine();
|
||||
String range();
|
||||
String rangeHighlight();
|
||||
String showTabs();
|
||||
String showLineNumbers();
|
||||
String hideA();
|
||||
String hideB();
|
||||
String columnMargin();
|
||||
String padding();
|
||||
}
|
||||
|
||||
|
@@ -18,12 +18,11 @@ limitations under the License.
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui'
|
||||
xmlns:d='urn:import:com.google.gerrit.client.diff'>
|
||||
<ui:style type='com.google.gerrit.client.diff.DiffTable.DiffTableStyle'>
|
||||
@external .CodeMirror, .CodeMirror-lines, .CodeMirror-selectedtext;
|
||||
@external .CodeMirror, .CodeMirror-selectedtext;
|
||||
@external .CodeMirror-linenumber;
|
||||
@external .CodeMirror-overlayscroll-vertical, .CodeMirror-scroll;
|
||||
@external .CodeMirror-dialog-bottom;
|
||||
@external .cm-animate-fat-cursor, .CodeMirror-cursor;
|
||||
@external .cm-searching, .cm-trailingspace, .cm-tab;
|
||||
|
||||
.fullscreen {
|
||||
background-color: #f7f7f7;
|
||||
@@ -39,13 +38,10 @@ limitations under the License.
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.difftable .CodeMirror-lines { padding: 0; }
|
||||
.difftable .CodeMirror pre {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border-right: 0;
|
||||
width: auto;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/* Preserve space for underscores. If this changes
|
||||
@@ -106,23 +102,12 @@ limitations under the License.
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.activeLine .CodeMirror-linenumber {
|
||||
background-color: #bcf !important;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.range {
|
||||
background-color: #ffd500 !important;
|
||||
}
|
||||
.rangeHighlight {
|
||||
background-color: #ffff00 !important;
|
||||
}
|
||||
.cm-searching {
|
||||
background-color: #ffa !important;
|
||||
}
|
||||
.cm-trailingspace {
|
||||
background-color: red !important;
|
||||
}
|
||||
.difftable .CodeMirror-selectedtext {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
@@ -154,24 +139,10 @@ limitations under the License.
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
}
|
||||
.showTabs .cm-tab:before {
|
||||
position: absolute;
|
||||
content: "\00bb";
|
||||
color: #f00;
|
||||
}
|
||||
.showLineNumbers .padding {
|
||||
margin-left: 21px;
|
||||
border-left: 2px solid #d64040;
|
||||
}
|
||||
.columnMargin {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
border-right: 1px dashed #ffa500;
|
||||
z-index: 2;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.diff_header {
|
||||
font-size: 12px;
|
||||
|
@@ -13,26 +13,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@external .CodeMirror;
|
||||
@external .CodeMirror-overlayscroll-horizontal;
|
||||
@external .CodeMirror-overlayscroll-vertical;
|
||||
|
||||
.CodeMirror-overlayscroll-horizontal div {
|
||||
min-width: 25px;
|
||||
}
|
||||
.CodeMirror-overlayscroll-vertical div {
|
||||
min-height: 25px;
|
||||
}
|
||||
|
||||
.CodeMirror .CodeMirror-overlayscroll-vertical {
|
||||
z-index: inherit;
|
||||
}
|
||||
.CodeMirror .CodeMirror-overlayscroll-horizontal div,
|
||||
.CodeMirror .CodeMirror-overlayscroll-vertical div {
|
||||
background-color: rgba(128, 128, 128, 0.50);
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
.comment, .draft, .insert, .delete, .edit {
|
||||
min-height: 5px;
|
||||
position: absolute;
|
||||
|
@@ -48,7 +48,6 @@ import com.google.gwt.core.client.Scheduler.RepeatingCommand;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.event.dom.client.FocusEvent;
|
||||
import com.google.gwt.event.dom.client.FocusHandler;
|
||||
import com.google.gwt.event.dom.client.KeyCodes;
|
||||
@@ -58,7 +57,6 @@ import com.google.gwt.event.logical.shared.ResizeHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -71,7 +69,6 @@ import com.google.gwtexpui.globalkey.client.ShowHelpCommand;
|
||||
import net.codemirror.lib.CodeMirror;
|
||||
import net.codemirror.lib.CodeMirror.BeforeSelectionChangeHandler;
|
||||
import net.codemirror.lib.CodeMirror.GutterClickHandler;
|
||||
import net.codemirror.lib.CodeMirror.LineClassWhere;
|
||||
import net.codemirror.lib.CodeMirror.LineHandle;
|
||||
import net.codemirror.lib.Configuration;
|
||||
import net.codemirror.lib.KeyMap;
|
||||
@@ -120,10 +117,6 @@ public class SideBySide2 extends Screen {
|
||||
|
||||
private CodeMirror cmA;
|
||||
private CodeMirror cmB;
|
||||
private Element columnMarginA;
|
||||
private Element columnMarginB;
|
||||
private double charWidthPx;
|
||||
private double lineHeightPx;
|
||||
|
||||
private HandlerRegistration resizeHandler;
|
||||
private ScrollSynchronizer scrollSynchronizer;
|
||||
@@ -268,12 +261,10 @@ public class SideBySide2 extends Screen {
|
||||
}
|
||||
});
|
||||
|
||||
final int height = getCodeMirrorHeight();
|
||||
operation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cmA.setHeight(height);
|
||||
cmB.setHeight(height);
|
||||
resizeCodeMirror();
|
||||
chunkManager.adjustPadding();
|
||||
cmA.refresh();
|
||||
cmB.refresh();
|
||||
@@ -297,6 +288,7 @@ public class SideBySide2 extends Screen {
|
||||
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);
|
||||
}
|
||||
@@ -549,24 +541,21 @@ public class SideBySide2 extends Screen {
|
||||
|
||||
private void display(final CommentsCollections comments) {
|
||||
setThemeStyles(prefs.theme().isDark());
|
||||
setShowTabs(prefs.showTabs());
|
||||
setShowIntraline(prefs.intralineDifference());
|
||||
if (prefs.showLineNumbers()) {
|
||||
diffTable.addStyleName(DiffTable.style.showLineNumbers());
|
||||
}
|
||||
|
||||
cmA = newCM(diff.meta_a(), diff.text_a(), diffTable.cmA).side(DisplaySide.A);
|
||||
cmB = newCM(diff.meta_b(), diff.text_b(), diffTable.cmB).side(DisplaySide.B);
|
||||
cmA = newCM(diff.meta_a(), diff.text_a(), diffTable.cmA);
|
||||
cmB = newCM(diff.meta_b(), diff.text_b(), diffTable.cmB);
|
||||
|
||||
cmA.extras().side(DisplaySide.A);
|
||||
cmB.extras().side(DisplaySide.B);
|
||||
setShowTabs(prefs.showTabs());
|
||||
|
||||
chunkManager = new ChunkManager(this, cmA, cmB, diffTable.scrollbar);
|
||||
skipManager = new SkipManager(this, commentManager);
|
||||
|
||||
columnMarginA = DOM.createDiv();
|
||||
columnMarginB = DOM.createDiv();
|
||||
columnMarginA.setClassName(DiffTable.style.columnMargin());
|
||||
columnMarginB.setClassName(DiffTable.style.columnMargin());
|
||||
cmA.mover().appendChild(columnMarginA);
|
||||
cmB.mover().appendChild(columnMarginB);
|
||||
|
||||
if (prefs.renderEntireFile() && !canEnableRenderEntireFile(prefs)) {
|
||||
// CodeMirror is too slow to layout an entire huge file.
|
||||
prefs.renderEntireFile(false);
|
||||
@@ -679,61 +668,14 @@ public class SideBySide2 extends Screen {
|
||||
}
|
||||
}
|
||||
|
||||
void setShowTabs(boolean b) {
|
||||
if (b) {
|
||||
diffTable.addStyleName(DiffTable.style.showTabs());
|
||||
} else {
|
||||
diffTable.removeStyleName(DiffTable.style.showTabs());
|
||||
}
|
||||
void setShowTabs(boolean show) {
|
||||
cmA.extras().showTabs(show);
|
||||
cmB.extras().showTabs(show);
|
||||
}
|
||||
|
||||
void setLineLength(int columns) {
|
||||
double w = columns * getCharWidthPx();
|
||||
columnMarginA.getStyle().setMarginLeft(w, Style.Unit.PX);
|
||||
columnMarginB.getStyle().setMarginLeft(w, Style.Unit.PX);
|
||||
}
|
||||
|
||||
double getLineHeightPx() {
|
||||
if (lineHeightPx <= 1) {
|
||||
Element p = DOM.createDiv();
|
||||
int lines = 1;
|
||||
for (int i = 0; i < lines; i++) {
|
||||
Element e = DOM.createDiv();
|
||||
p.appendChild(e);
|
||||
|
||||
Element pre = DOM.createElement("pre");
|
||||
pre.setInnerText("gqyŚŻŹŃ");
|
||||
e.appendChild(pre);
|
||||
}
|
||||
|
||||
cmB.measure().appendChild(p);
|
||||
lineHeightPx = ((double) p.getOffsetHeight()) / lines;
|
||||
p.removeFromParent();
|
||||
}
|
||||
return lineHeightPx;
|
||||
}
|
||||
|
||||
private double getCharWidthPx() {
|
||||
if (charWidthPx <= 1) {
|
||||
int len = 100;
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < len; i++) {
|
||||
s.append('m');
|
||||
}
|
||||
Element e = DOM.createSpan();
|
||||
e.getStyle().setDisplay(Style.Display.INLINE_BLOCK);
|
||||
e.setInnerText(s.toString());
|
||||
|
||||
cmA.measure().appendChild(e);
|
||||
double a = ((double) e.getOffsetWidth()) / len;
|
||||
e.removeFromParent();
|
||||
|
||||
cmB.measure().appendChild(e);
|
||||
double b = ((double) e.getOffsetWidth()) / len;
|
||||
e.removeFromParent();
|
||||
charWidthPx = Math.max(a, b);
|
||||
}
|
||||
return charWidthPx;
|
||||
cmA.extras().lineLength(columns);
|
||||
cmB.extras().lineLength(columns);
|
||||
}
|
||||
|
||||
void setShowLineNumbers(boolean b) {
|
||||
@@ -815,15 +757,6 @@ public class SideBySide2 extends Screen {
|
||||
return chunkManager.getLineMapper().lineOnOther(side, line);
|
||||
}
|
||||
|
||||
private void clearActiveLine(CodeMirror cm) {
|
||||
if (cm.hasActiveLine()) {
|
||||
LineHandle activeLine = cm.activeLine();
|
||||
cm.removeLineClass(activeLine,
|
||||
LineClassWhere.WRAP, DiffTable.style.activeLine());
|
||||
cm.activeLine(null);
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable updateActiveLine(final CodeMirror cm) {
|
||||
final CodeMirror other = otherCm(cm);
|
||||
return new Runnable() {
|
||||
@@ -842,22 +775,16 @@ public class SideBySide2 extends Screen {
|
||||
public void run() {
|
||||
LineHandle handle =
|
||||
cm.getLineHandleVisualStart(cm.getCursor("end").line());
|
||||
if (cm.hasActiveLine() && cm.activeLine().equals(handle)) {
|
||||
if (!cm.extras().activeLine(handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearActiveLine(cm);
|
||||
clearActiveLine(other);
|
||||
cm.activeLine(handle);
|
||||
cm.addLineClass(
|
||||
handle, LineClassWhere.WRAP, DiffTable.style.activeLine());
|
||||
LineOnOtherInfo info =
|
||||
lineOnOther(cm.side(), cm.getLineNumber(handle));
|
||||
if (info.isAligned()) {
|
||||
LineHandle oLineHandle = other.getLineHandle(info.getLine());
|
||||
other.activeLine(oLineHandle);
|
||||
other.addLineClass(oLineHandle, LineClassWhere.WRAP,
|
||||
DiffTable.style.activeLine());
|
||||
other.extras().activeLine(other.getLineHandle(info.getLine()));
|
||||
} else {
|
||||
other.extras().clearActiveLine();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -877,8 +804,8 @@ public class SideBySide2 extends Screen {
|
||||
&& !clickEvent.getAltKey()
|
||||
&& !clickEvent.getCtrlKey()
|
||||
&& !clickEvent.getShiftKey()) {
|
||||
if (!(cm.hasActiveLine() &&
|
||||
cm.getLineNumber(cm.activeLine()) == line)) {
|
||||
if (!(cm.extras().hasActiveLine() &&
|
||||
cm.getLineNumber(cm.extras().activeLine()) == line)) {
|
||||
cm.setCursor(Pos.create(line));
|
||||
}
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@@ -928,10 +855,10 @@ public class SideBySide2 extends Screen {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (cmSrc.hasActiveLine()) {
|
||||
if (cmSrc.extras().hasActiveLine()) {
|
||||
cmDst.setCursor(Pos.create(lineOnOther(
|
||||
sideSrc,
|
||||
cmSrc.getLineNumber(cmSrc.activeLine())).getLine()));
|
||||
cmSrc.getLineNumber(cmSrc.extras().activeLine())).getLine()));
|
||||
}
|
||||
cmDst.focus();
|
||||
}
|
||||
@@ -977,17 +904,9 @@ public class SideBySide2 extends Screen {
|
||||
}
|
||||
|
||||
void resizeCodeMirror() {
|
||||
int height = getCodeMirrorHeight();
|
||||
cmA.setHeight(height);
|
||||
cmB.setHeight(height);
|
||||
}
|
||||
|
||||
private int getCodeMirrorHeight() {
|
||||
int rest = Gerrit.getHeaderFooterHeight()
|
||||
+ header.getOffsetHeight()
|
||||
+ diffTable.getHeaderHeight()
|
||||
+ 5; // Estimate
|
||||
return Window.getClientHeight() - rest;
|
||||
int hdr = header.getOffsetHeight() + diffTable.getHeaderHeight();
|
||||
cmA.adjustHeight(hdr);
|
||||
cmB.adjustHeight(hdr);
|
||||
}
|
||||
|
||||
void syncScroll(DisplaySide masterSide) {
|
||||
|
@@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2015 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.editor;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.i18n.client.Constants;
|
||||
|
||||
interface EditConstants extends Constants {
|
||||
static final EditConstants I = GWT.create(EditConstants.class);
|
||||
|
||||
String closeUnsavedChanges();
|
||||
String cancelUnsavedChanges();
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
closeUnsavedChanges = Unsaved changes were made to this file.
|
||||
|
||||
cancelUnsavedChanges = Unsaved changes were made to this file.\n\
|
||||
\n\
|
||||
Discard unsaved changes?
|
@@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.client.editor;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.JumpKeys;
|
||||
import com.google.gerrit.client.VoidResult;
|
||||
import com.google.gerrit.client.account.DiffPreferences;
|
||||
import com.google.gerrit.client.changes.ChangeApi;
|
||||
@@ -30,13 +31,20 @@ import com.google.gerrit.common.PageLinks;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.KeyPressEvent;
|
||||
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.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.Window.ClosingEvent;
|
||||
import com.google.gwt.user.client.Window.ClosingHandler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
@@ -44,9 +52,13 @@ import com.google.gwtexpui.globalkey.client.GlobalKey;
|
||||
import com.google.gwtexpui.safehtml.client.SafeHtml;
|
||||
|
||||
import net.codemirror.lib.CodeMirror;
|
||||
import net.codemirror.lib.CodeMirror.ChangesHandler;
|
||||
import net.codemirror.lib.Configuration;
|
||||
import net.codemirror.lib.KeyMap;
|
||||
import net.codemirror.lib.Pos;
|
||||
import net.codemirror.mode.ModeInfo;
|
||||
import net.codemirror.mode.ModeInjector;
|
||||
import net.codemirror.theme.ThemeLoader;
|
||||
|
||||
public class EditScreen extends Screen {
|
||||
interface Binder extends UiBinder<HTMLPanel, EditScreen> {}
|
||||
@@ -58,12 +70,17 @@ public class EditScreen extends Screen {
|
||||
private CodeMirror cm;
|
||||
private String type;
|
||||
|
||||
@UiField Element header;
|
||||
@UiField Element project;
|
||||
@UiField Element filePath;
|
||||
@UiField Button cancel;
|
||||
@UiField Button close;
|
||||
@UiField Button save;
|
||||
@UiField Element editor;
|
||||
|
||||
private HandlerRegistration resizeHandler;
|
||||
private HandlerRegistration closeHandler;
|
||||
private int generation;
|
||||
|
||||
public EditScreen(Patch.Key patch) {
|
||||
this.revision = patch.getParentKey();
|
||||
this.path = patch.get();
|
||||
@@ -84,9 +101,22 @@ public class EditScreen extends Screen {
|
||||
super.onLoad();
|
||||
|
||||
CallbackGroup cmGroup = new CallbackGroup();
|
||||
CodeMirror.initLibrary(cmGroup.<Void> addEmpty());
|
||||
CallbackGroup group = new CallbackGroup();
|
||||
if (!Patch.COMMIT_MSG.equals(path)) {
|
||||
final CallbackGroup group = new CallbackGroup();
|
||||
CodeMirror.initLibrary(cmGroup.add(new AsyncCallback<Void>() {
|
||||
final AsyncCallback<Void> themeCallback = group.addEmpty();
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
// Load theme after CM library to ensure theme can override CSS.
|
||||
ThemeLoader.loadTheme(prefs.theme(), themeCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
}
|
||||
}));
|
||||
|
||||
if (prefs.syntaxHighlighting() && !Patch.COMMIT_MSG.equals(path)) {
|
||||
final AsyncCallback<Void> modeInjectorCb = group.addEmpty();
|
||||
ChangeFileApi.getContentType(revision, path,
|
||||
cmGroup.add(new GerritCallback<String>() {
|
||||
@@ -121,60 +151,151 @@ public class EditScreen extends Screen {
|
||||
@Override
|
||||
public void onShowView() {
|
||||
super.onShowView();
|
||||
Window.enableScrolling(false);
|
||||
JumpKeys.enable(false);
|
||||
if (prefs.hideTopMenu()) {
|
||||
Gerrit.setHeaderVisible(false);
|
||||
}
|
||||
int rest = Gerrit.getHeaderFooterHeight()
|
||||
+ 30; // Estimate
|
||||
cm.setHeight(Window.getClientHeight() - rest);
|
||||
resizeHandler = Window.addResizeHandler(new ResizeHandler() {
|
||||
@Override
|
||||
public void onResize(ResizeEvent event) {
|
||||
cm.adjustHeight(header.getOffsetHeight());
|
||||
}
|
||||
});
|
||||
closeHandler = Window.addWindowClosingHandler(new ClosingHandler() {
|
||||
@Override
|
||||
public void onWindowClosing(ClosingEvent event) {
|
||||
if (!cm.isClean(generation)) {
|
||||
event.setMessage(EditConstants.I.closeUnsavedChanges());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
generation = cm.changeGeneration(true);
|
||||
save.setEnabled(false);
|
||||
cm.on(new ChangesHandler() {
|
||||
@Override
|
||||
public void handle(CodeMirror cm) {
|
||||
save.setEnabled(!cm.isClean(generation));
|
||||
}
|
||||
});
|
||||
|
||||
cm.adjustHeight(header.getOffsetHeight());
|
||||
cm.on("cursorActivity", updateCursorPosition());
|
||||
cm.extras().showTabs(prefs.showTabs());
|
||||
cm.extras().lineLength(prefs.lineLength());
|
||||
cm.refresh();
|
||||
cm.focus();
|
||||
updateActiveLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnload() {
|
||||
super.onUnload();
|
||||
if (cm != null) {
|
||||
cm.getWrapperElement().removeFromParent();
|
||||
}
|
||||
if (resizeHandler != null) {
|
||||
resizeHandler.removeHandler();
|
||||
}
|
||||
if (closeHandler != null) {
|
||||
closeHandler.removeHandler();
|
||||
}
|
||||
Window.enableScrolling(true);
|
||||
Gerrit.setHeaderVisible(true);
|
||||
JumpKeys.enable(true);
|
||||
}
|
||||
|
||||
@UiHandler("save")
|
||||
void onSave(@SuppressWarnings("unused") ClickEvent e) {
|
||||
ChangeFileApi.putContentOrMessage(revision, path, cm.getValue(),
|
||||
new GerritCallback<VoidResult>() {
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
Gerrit.display(PageLinks.toChangeInEditMode(
|
||||
revision.getParentKey()));
|
||||
}
|
||||
});
|
||||
save().run();
|
||||
}
|
||||
|
||||
@UiHandler("cancel")
|
||||
void onCancel(@SuppressWarnings("unused") ClickEvent e) {
|
||||
@UiHandler("close")
|
||||
void onClose(@SuppressWarnings("unused") ClickEvent e) {
|
||||
if (cm.isClean(generation)
|
||||
|| Window.confirm(EditConstants.I.cancelUnsavedChanges())) {
|
||||
upToChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void upToChange() {
|
||||
Gerrit.display(PageLinks.toChangeInEditMode(revision.getParentKey()));
|
||||
}
|
||||
|
||||
private void initEditor(String content) {
|
||||
cm = CodeMirror.create(editor, getConfig());
|
||||
cm.setValue(content);
|
||||
ModeInfo mode = prefs.syntaxHighlighting()
|
||||
? ModeInfo.findMode(type, path)
|
||||
: null;
|
||||
cm = CodeMirror.create(editor, Configuration.create()
|
||||
.set("value", content)
|
||||
.set("readOnly", false)
|
||||
.set("cursorBlinkRate", 0)
|
||||
.set("cursorHeight", 0.85)
|
||||
.set("lineNumbers", true)
|
||||
.set("tabSize", prefs.tabSize())
|
||||
.set("lineWrapping", false)
|
||||
.set("scrollbarStyle", "overlay")
|
||||
.set("styleSelectedText", true)
|
||||
.set("showTrailingSpace", true)
|
||||
.set("keyMap", "default")
|
||||
.set("theme", prefs.theme().name().toLowerCase())
|
||||
.set("mode", mode != null ? mode.mode() : null));
|
||||
cm.addKeyMap(KeyMap.create()
|
||||
.on("Cmd-S", save())
|
||||
.on("Ctrl-S", save()));
|
||||
}
|
||||
|
||||
private Runnable updateCursorPosition() {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// The rendering of active lines has to be deferred. Reflow
|
||||
// caused by adding and removing styles chokes Firefox when arrow
|
||||
// key (or j/k) is held down. Performance on Chrome is fine
|
||||
// without the deferral.
|
||||
//
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
cm.operation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateActiveLine();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void updateActiveLine() {
|
||||
Pos p = cm.getCursor("end");
|
||||
cm.extras().activeLine(cm.getLineHandleVisualStart(p.line()));
|
||||
}
|
||||
|
||||
private Runnable save() {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!cm.isClean(generation)) {
|
||||
String text = cm.getValue();
|
||||
final int g = cm.changeGeneration(false);
|
||||
ChangeFileApi.putContentOrMessage(revision, path, text,
|
||||
new GerritCallback<VoidResult>() {
|
||||
@Override
|
||||
public void onSuccess(VoidResult result) {
|
||||
generation = g;
|
||||
save.setEnabled(!cm.isClean(g));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void injectMode(String type, AsyncCallback<Void> cb) {
|
||||
new ModeInjector().add(type).inject(cb);
|
||||
}
|
||||
|
||||
private Configuration getConfig() {
|
||||
// TODO(davido): Retrieve user preferences from AllUsers repository
|
||||
return Configuration.create()
|
||||
.set("readOnly", false)
|
||||
.set("cursorBlinkRate", 0)
|
||||
.set("cursorHeight", 0.85)
|
||||
.set("lineNumbers", true)
|
||||
.set("tabSize", 4)
|
||||
.set("lineWrapping", false)
|
||||
.set("styleSelectedText", true)
|
||||
.set("showTrailingSpace", true)
|
||||
.set("keyMap", "default")
|
||||
.set("mode", type);
|
||||
}
|
||||
}
|
||||
|
@@ -31,7 +31,9 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.headerButtons button:disabled {
|
||||
background-color: #999;
|
||||
background-color: #ddd;
|
||||
font-weight: normal;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.headerButtons button {
|
||||
@@ -62,13 +64,13 @@ limitations under the License.
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<div class='{style.headerLine}'>
|
||||
<div class='{style.headerLine}' ui:field='header'>
|
||||
<div class='{style.headerButtons}'>
|
||||
<g:Button ui:field='cancel'
|
||||
<g:Button ui:field='close'
|
||||
styleName=''
|
||||
title='Cancel'>
|
||||
title='Close file and return to change'>
|
||||
<ui:attribute name='title'/>
|
||||
<div><ui:msg>Cancel</ui:msg></div>
|
||||
<div><ui:msg>Close</ui:msg></div>
|
||||
</g:Button>
|
||||
<g:Button ui:field='save'
|
||||
styleName='{style.save}'
|
||||
|
@@ -14,11 +14,14 @@
|
||||
|
||||
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;
|
||||
@@ -37,7 +40,23 @@ public class CodeMirror extends JavaScriptObject {
|
||||
Loader.initLibrary(cb);
|
||||
}
|
||||
|
||||
public static native CodeMirror create(Element p, Configuration cfg) /*-{
|
||||
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);
|
||||
}-*/;
|
||||
|
||||
@@ -62,10 +81,25 @@ public class CodeMirror extends JavaScriptObject {
|
||||
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 setWidth(String w) /*-{ this.setSize(w, null) }-*/;
|
||||
public final native void setHeight(double h) /*-{ this.setSize(null, h) }-*/;
|
||||
public final native void setHeight(String 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 }-*/;
|
||||
@@ -226,6 +260,13 @@ public class CodeMirror extends JavaScriptObject {
|
||||
}))
|
||||
}-*/;
|
||||
|
||||
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) /*-{
|
||||
@@ -245,18 +286,6 @@ public class CodeMirror extends JavaScriptObject {
|
||||
return this.somethingSelected()
|
||||
}-*/;
|
||||
|
||||
public final native boolean hasActiveLine() /*-{
|
||||
return !!this.state.activeLine
|
||||
}-*/;
|
||||
|
||||
public final native LineHandle activeLine() /*-{
|
||||
return this.state.activeLine
|
||||
}-*/;
|
||||
|
||||
public final native void activeLine(LineHandle line) /*-{
|
||||
this.state.activeLine = line
|
||||
}-*/;
|
||||
|
||||
public final native void addKeyMap(KeyMap map) /*-{ this.addKeyMap(map) }-*/;
|
||||
public final native void removeKeyMap(KeyMap map) /*-{ this.removeKeyMap(map) }-*/;
|
||||
|
||||
@@ -321,11 +350,13 @@ public class CodeMirror extends JavaScriptObject {
|
||||
return this;
|
||||
}-*/;
|
||||
|
||||
public final native DisplaySide side() /*-{ return this._sbs2_side }-*/;
|
||||
public final native CodeMirror side(DisplaySide side) /*-{
|
||||
this._sbs2_side = side;
|
||||
return this;
|
||||
}-*/;
|
||||
public final DisplaySide side() {
|
||||
return extras().side();
|
||||
}
|
||||
|
||||
public final Extras extras() {
|
||||
return Extras.get(this);
|
||||
}
|
||||
|
||||
protected CodeMirror() {
|
||||
}
|
||||
@@ -367,4 +398,8 @@ public class CodeMirror extends JavaScriptObject {
|
||||
public interface BeforeSelectionChangeHandler {
|
||||
public void handle(CodeMirror instance, Pos anchor, Pos head);
|
||||
}
|
||||
|
||||
public interface ChangesHandler {
|
||||
public void handle(CodeMirror instance);
|
||||
}
|
||||
}
|
||||
|
143
gerrit-gwtui/src/main/java/net/codemirror/lib/Extras.java
vendored
Normal file
143
gerrit-gwtui/src/main/java/net/codemirror/lib/Extras.java
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright (C) 2015 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 static com.google.gwt.dom.client.Style.Display.INLINE_BLOCK;
|
||||
import static com.google.gwt.dom.client.Style.Unit.PX;
|
||||
import static net.codemirror.lib.CodeMirror.style;
|
||||
import static net.codemirror.lib.CodeMirror.LineClassWhere.WRAP;
|
||||
|
||||
import com.google.gerrit.client.diff.DisplaySide;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
|
||||
import net.codemirror.lib.CodeMirror.LineHandle;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/** Additional features added to CodeMirror by Gerrit Code Review. */
|
||||
public class Extras {
|
||||
static final native Extras get(CodeMirror c) /*-{ return c.gerritExtras }-*/;
|
||||
private static final native void set(CodeMirror c, Extras e)
|
||||
/*-{ c.gerritExtras = e }-*/;
|
||||
|
||||
static void attach(CodeMirror c) {
|
||||
set(c, new Extras(c));
|
||||
}
|
||||
|
||||
private final CodeMirror cm;
|
||||
private Element margin;
|
||||
private DisplaySide side;
|
||||
private double charWidthPx;
|
||||
private double lineHeightPx;
|
||||
private LineHandle activeLine;
|
||||
|
||||
private Extras(CodeMirror cm) {
|
||||
this.cm = cm;
|
||||
}
|
||||
|
||||
public DisplaySide side() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void side(DisplaySide s) {
|
||||
side = s;
|
||||
}
|
||||
|
||||
public double charWidthPx() {
|
||||
if (charWidthPx <= 1) {
|
||||
int len = 100;
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < len; i++) {
|
||||
s.append('m');
|
||||
}
|
||||
|
||||
Element e = DOM.createSpan();
|
||||
e.getStyle().setDisplay(INLINE_BLOCK);
|
||||
e.setInnerText(s.toString());
|
||||
|
||||
cm.measure().appendChild(e);
|
||||
charWidthPx = ((double) e.getOffsetWidth()) / len;
|
||||
e.removeFromParent();
|
||||
}
|
||||
return charWidthPx;
|
||||
}
|
||||
|
||||
public double lineHeightPx() {
|
||||
if (lineHeightPx <= 1) {
|
||||
Element p = DOM.createDiv();
|
||||
int lines = 1;
|
||||
for (int i = 0; i < lines; i++) {
|
||||
Element e = DOM.createDiv();
|
||||
p.appendChild(e);
|
||||
|
||||
Element pre = DOM.createElement("pre");
|
||||
pre.setInnerText("gqyŚŻŹŃ");
|
||||
e.appendChild(pre);
|
||||
}
|
||||
|
||||
cm.measure().appendChild(p);
|
||||
lineHeightPx = ((double) p.getOffsetHeight()) / lines;
|
||||
p.removeFromParent();
|
||||
}
|
||||
return lineHeightPx;
|
||||
}
|
||||
|
||||
public void lineLength(int columns) {
|
||||
if (margin == null) {
|
||||
margin = DOM.createDiv();
|
||||
margin.setClassName(style().margin());
|
||||
cm.mover().appendChild(margin);
|
||||
}
|
||||
margin.getStyle().setMarginLeft(columns * charWidthPx(), PX);
|
||||
}
|
||||
|
||||
public void showTabs(boolean show) {
|
||||
Element e = cm.getWrapperElement();
|
||||
if (show) {
|
||||
e.addClassName(style().showTabs());
|
||||
} else {
|
||||
e.removeClassName(style().showTabs());
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean hasActiveLine() {
|
||||
return activeLine != null;
|
||||
}
|
||||
|
||||
public final LineHandle activeLine() {
|
||||
return activeLine;
|
||||
}
|
||||
|
||||
public final boolean activeLine(LineHandle line) {
|
||||
if (Objects.equals(activeLine, line)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (activeLine != null) {
|
||||
cm.removeLineClass(activeLine, WRAP, style().activeLine());
|
||||
}
|
||||
activeLine = line;
|
||||
cm.addLineClass(activeLine, WRAP, style().activeLine());
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void clearActiveLine() {
|
||||
if (activeLine != null) {
|
||||
cm.removeLineClass(activeLine, WRAP, style().activeLine());
|
||||
activeLine = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -29,4 +29,7 @@ interface Lib extends ClientBundle {
|
||||
@Source("cm.js")
|
||||
@DoNotEmbed
|
||||
DataResource js();
|
||||
|
||||
@Source("style.css")
|
||||
CodeMirror.Style style();
|
||||
}
|
||||
|
@@ -56,6 +56,7 @@ public class Loader {
|
||||
@Override
|
||||
public void onSuccess(TextResource resource) {
|
||||
StyleInjector.inject(resource.getText());
|
||||
Lib.I.style().ensureInjected();
|
||||
cb.onSuccess(null);
|
||||
}
|
||||
|
||||
|
83
gerrit-gwtui/src/main/java/net/codemirror/lib/style.css
vendored
Normal file
83
gerrit-gwtui/src/main/java/net/codemirror/lib/style.css
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
@external .CodeMirror;
|
||||
@external .CodeMirror-lines;
|
||||
@external .CodeMirror-linenumber;
|
||||
@external .CodeMirror-overlayscroll-horizontal;
|
||||
@external .CodeMirror-overlayscroll-vertical;
|
||||
@external .cm-tab;
|
||||
@external .cm-searching;
|
||||
@external .cm-trailingspace;
|
||||
|
||||
/* Reduce margins around CodeMirror to save space. */
|
||||
.CodeMirror-lines {
|
||||
padding: 0;
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/* Minimum scrollbar bubble size even on large files. */
|
||||
.CodeMirror-overlayscroll-horizontal div {
|
||||
min-width: 25px;
|
||||
}
|
||||
.CodeMirror-overlayscroll-vertical div {
|
||||
min-height: 25px;
|
||||
}
|
||||
|
||||
/* Stack the scrollbar so annotations can receive clicks. */
|
||||
.CodeMirror-overlayscroll-vertical {
|
||||
z-index: inherit;
|
||||
}
|
||||
.CodeMirror-overlayscroll-horizontal div,
|
||||
.CodeMirror-overlayscroll-vertical div {
|
||||
background-color: rgba(128, 128, 128, 0.50);
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
/* Highlight current line number in the line gutter. */
|
||||
.activeLine .CodeMirror-linenumber {
|
||||
background-color: #bcf !important;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.showTabs .cm-tab:before {
|
||||
position: absolute;
|
||||
content: "\00bb";
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.cm-searching {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
.cm-trailingspace {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
/* Line length margin displayed at NN columns to provide
|
||||
* a visual guide for length of any single line of code.
|
||||
*/
|
||||
.margin {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
border-right: 1px dashed #ffa500;
|
||||
z-index: 2;
|
||||
cursor: text;
|
||||
}
|
Reference in New Issue
Block a user