Add functionalities to CommentBox and fix various styles
- Added expandText() to DraftBox. - Fixed CommentBox styles to make it look better. Added box-shadow. - Adjusted CodeMirror's line height to avoid cutting off the bottom of text. - Added refocusing on CM after clicking on CommentBoxes and SkipBars. - Prevented feedback loop in synced scrolling. - Fixed a bug in skip calculation. Change-Id: I7cbe644f3a890cb6e62a5d83942a93411ea5550f
This commit is contained in:
@@ -226,10 +226,12 @@ public class CodeMirrorDemo extends Screen {
|
||||
|
||||
private void registerCmEvents(CodeMirror cm) {
|
||||
cm.on("cursorActivity", updateActiveLine(cm));
|
||||
cm.on("scroll", doScroll(otherCM(cm)));
|
||||
cm.on("scroll", doScroll(cm));
|
||||
/**
|
||||
* TODO: Trying to prevent right click from updating the cursor.
|
||||
* Doesn't seem to work for now.
|
||||
* Trying to prevent right click from updating the cursor.
|
||||
*
|
||||
* TODO: Change to listen on "contextmenu" instead. Latest CM has
|
||||
* provided a patch that will hopefully make this work.
|
||||
*/
|
||||
cm.on("mousedown", ignoreRightClick());
|
||||
cm.addKeyMap(KeyMap.create().on("'u'", upToChange()));
|
||||
@@ -238,7 +240,10 @@ public class CodeMirrorDemo extends Screen {
|
||||
if (Gerrit.isSignedIn()) {
|
||||
cm.addKeyMap(KeyMap.create().on("'c'", insertNewDraft(cm)));
|
||||
}
|
||||
// TODO: Examine if a better way exists.
|
||||
/**
|
||||
* TODO: Maybe remove this after updating CM to HEAD. The latest VIM mode
|
||||
* doesn't enter INSERT mode when document is read only.
|
||||
*/
|
||||
for (String c : new String[]{"A", "C", "D", "I", "O", "P", "R", "S", "U",
|
||||
"X", "Y", "~"}) {
|
||||
CodeMirror.disableUnwantedKey("vim", c);
|
||||
@@ -328,6 +333,7 @@ public class CodeMirrorDemo extends Screen {
|
||||
.set("lineNumbers", true)
|
||||
.set("tabSize", 2)
|
||||
.set("mode", getContentType(meta))
|
||||
.set("lineWrapping", true)
|
||||
.set("styleSelectedText", true)
|
||||
.set("showTrailingSpace", true)
|
||||
.set("keyMap", "vim")
|
||||
@@ -422,20 +428,20 @@ public class CodeMirrorDemo extends Screen {
|
||||
return box;
|
||||
}
|
||||
|
||||
CommentBox addCommentBox(CommentInfo info, final CommentBox box) {
|
||||
CommentBox addCommentBox(CommentInfo info, CommentBox box) {
|
||||
diffTable.add(box);
|
||||
Side mySide = info.side();
|
||||
CodeMirror cm = mySide == Side.PARENT ? cmA : cmB;
|
||||
CodeMirror other = otherCM(cm);
|
||||
CodeMirror other = otherCm(cm);
|
||||
int line = info.line() - 1; // CommentInfo is 1-based, but CM is 0-based
|
||||
LineHandle handle = cm.getLineHandle(line);
|
||||
PaddingManager manager;
|
||||
if (linePaddingManagerMap.containsKey(handle)) {
|
||||
manager = linePaddingManagerMap.get(handle);
|
||||
} else {
|
||||
// Estimated height at 21px, fixed by deferring after display
|
||||
// Estimated height at 28px, fixed by deferring after display
|
||||
manager = new PaddingManager(
|
||||
addPaddingWidget(cm, DiffTable.style.padding(), line, 21, Unit.PX, 0));
|
||||
addPaddingWidget(cm, DiffTable.style.padding(), line, 28, Unit.PX, 0));
|
||||
linePaddingManagerMap.put(handle, manager);
|
||||
}
|
||||
int lineToPad = mapper.lineOnOther(mySide, line).getLine();
|
||||
@@ -444,7 +450,7 @@ public class CodeMirrorDemo extends Screen {
|
||||
PaddingManager.link(manager, linePaddingManagerMap.get(otherHandle));
|
||||
} else {
|
||||
PaddingManager otherManager = new PaddingManager(
|
||||
addPaddingWidget(other, DiffTable.style.padding(), lineToPad, 21, Unit.PX, 0));
|
||||
addPaddingWidget(other, DiffTable.style.padding(), lineToPad, 28, Unit.PX, 0));
|
||||
linePaddingManagerMap.put(otherHandle, otherManager);
|
||||
PaddingManager.link(manager, otherManager);
|
||||
}
|
||||
@@ -484,13 +490,14 @@ public class CodeMirrorDemo extends Screen {
|
||||
private void renderPublished() {
|
||||
List<CommentInfo> sorted = sortComment(published);
|
||||
for (CommentInfo info : sorted) {
|
||||
final PublishedBox box =
|
||||
new PublishedBox(this, revision, info, commentLinkProcessor);
|
||||
CodeMirror cm = getCmFromSide(info.side());
|
||||
PublishedBox box =
|
||||
new PublishedBox(this, cm, revision, info, commentLinkProcessor);
|
||||
box.setOpen(false);
|
||||
initialBoxes.add(box);
|
||||
publishedMap.put(info.id(), box);
|
||||
int line = info.line() - 1;
|
||||
LineHandle handle = getCmFromSide(info.side()).getLineHandle(line);
|
||||
LineHandle handle = cm.getLineHandle(line);
|
||||
lineLastPublishedBoxMap.put(handle, box);
|
||||
lineActiveBoxMap.put(handle, box);
|
||||
addCommentBox(info, box);
|
||||
@@ -500,7 +507,7 @@ public class CodeMirrorDemo extends Screen {
|
||||
private void renderDrafts() {
|
||||
List<CommentInfo> sorted = sortComment(drafts);
|
||||
for (CommentInfo info : sorted) {
|
||||
final DraftBox box =
|
||||
DraftBox box =
|
||||
new DraftBox(this, getCmFromSide(info.side()), revision, info,
|
||||
commentLinkProcessor, false, false);
|
||||
box.setOpen(false);
|
||||
@@ -529,7 +536,7 @@ public class CodeMirrorDemo extends Screen {
|
||||
int boxLine = info.line();
|
||||
int deltaBefore = boxLine - startLine;
|
||||
int deltaAfter = startLine + skip.getSize() - boxLine;
|
||||
if (deltaBefore < 0 || deltaAfter < 0) {
|
||||
if (deltaBefore < -context || deltaAfter < -context) {
|
||||
temp.add(skip);
|
||||
} else if (deltaBefore > context && deltaAfter > context) {
|
||||
SkippedLine before = new SkippedLine(
|
||||
@@ -584,7 +591,7 @@ public class CodeMirrorDemo extends Screen {
|
||||
return bar;
|
||||
}
|
||||
|
||||
private CodeMirror otherCM(CodeMirror me) {
|
||||
private CodeMirror otherCm(CodeMirror me) {
|
||||
return me == cmA ? cmB : cmA;
|
||||
}
|
||||
|
||||
@@ -633,11 +640,11 @@ public class CodeMirrorDemo extends Screen {
|
||||
private void insertEmptyLines(CodeMirror cm, int nextLine, int cnt) {
|
||||
// -1 to compensate for the line we went past when this method is called.
|
||||
addPaddingWidget(cm, DiffTable.style.padding(), nextLine - 1,
|
||||
cnt, Unit.EM, null);
|
||||
1.1 * cnt, Unit.EM, null);
|
||||
}
|
||||
|
||||
private LineWidgetElementPair addPaddingWidget(CodeMirror cm, String style,
|
||||
int line, int height, Unit unit, Integer index) {
|
||||
int line, double height, Unit unit, Integer index) {
|
||||
Element div = DOM.createDiv();
|
||||
div.setClassName(style);
|
||||
div.getStyle().setHeight(height, unit);
|
||||
@@ -652,16 +659,23 @@ public class CodeMirrorDemo extends Screen {
|
||||
}
|
||||
|
||||
private Runnable doScroll(final CodeMirror cm) {
|
||||
final CodeMirror other = otherCM(cm);
|
||||
final CodeMirror other = otherCm(cm);
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
cm.scrollToY(other.getScrollInfo().getTop());
|
||||
// Prevent feedback loop, Chrome seems fine but Firefox chokes.
|
||||
double now = (double) System.currentTimeMillis();
|
||||
if (cm.getScrollSetBy() == other && cm.getScrollSetAt() + 50 > now) {
|
||||
return;
|
||||
}
|
||||
other.scrollToY(cm.getScrollInfo().getTop());
|
||||
other.setScrollSetBy(cm);
|
||||
other.setScrollSetAt(now);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Runnable updateActiveLine(final CodeMirror cm) {
|
||||
final CodeMirror other = otherCM(cm);
|
||||
final CodeMirror other = otherCm(cm);
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
if (cm.hasActiveLine()) {
|
||||
@@ -793,7 +807,7 @@ public class CodeMirrorDemo extends Screen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyPress(final KeyPressEvent event) {
|
||||
public void onKeyPress(KeyPressEvent event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -30,6 +32,7 @@ import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwtexpui.safehtml.client.SafeHtml;
|
||||
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
|
||||
|
||||
import net.codemirror.lib.CodeMirror;
|
||||
import net.codemirror.lib.LineWidget;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
@@ -48,6 +51,9 @@ abstract class CommentBox extends Composite {
|
||||
private CodeMirrorDemo diffView;
|
||||
private boolean draft;
|
||||
private LineWidget selfWidget;
|
||||
private CodeMirror cm;
|
||||
private HandlerRegistration regClick;
|
||||
private ClickHandler clickFocusHandler;
|
||||
|
||||
@UiField(provided=true)
|
||||
CommentBoxHeader header;
|
||||
@@ -60,24 +66,27 @@ abstract class CommentBox extends Composite {
|
||||
|
||||
CommentBox(
|
||||
CodeMirrorDemo host,
|
||||
CodeMirror cmInstance,
|
||||
UiBinder<? extends Widget, CommentBox> binder,
|
||||
PatchSet.Id id, CommentInfo info, CommentLinkProcessor linkProcessor,
|
||||
boolean isDraft) {
|
||||
diffView = host;
|
||||
cm = cmInstance;
|
||||
commentLinkProcessor = linkProcessor;
|
||||
original = info;
|
||||
patchSetId = id;
|
||||
draft = isDraft;
|
||||
header = new CommentBoxHeader(info.author(), info.updated(), isDraft);
|
||||
initWidget(binder.createAndBindUi(this));
|
||||
setMessageText(info.message());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
|
||||
clickFocusHandler = new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
cm.focus();
|
||||
}
|
||||
};
|
||||
enableClickFocusHandler();
|
||||
res.style().ensureInjected();
|
||||
setMessageText(info.message());
|
||||
}
|
||||
|
||||
void resizePaddingWidget() {
|
||||
@@ -160,8 +169,26 @@ abstract class CommentBox extends Composite {
|
||||
return selfWidget;
|
||||
}
|
||||
|
||||
CodeMirror getCm() {
|
||||
return cm;
|
||||
}
|
||||
|
||||
@UiHandler("header")
|
||||
void onHeaderClick(ClickEvent e) {
|
||||
setOpen(!isOpen());
|
||||
cm.focus();
|
||||
}
|
||||
|
||||
void enableClickFocusHandler() {
|
||||
if (regClick == null) {
|
||||
regClick = addDomHandler(clickFocusHandler, ClickEvent.getType());
|
||||
}
|
||||
}
|
||||
|
||||
void disableClickFocusHandler() {
|
||||
if (regClick != null) {
|
||||
regClick.removeHandler();
|
||||
regClick = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,17 +55,23 @@ class CommentBoxHeader extends Composite implements HasClickHandlers {
|
||||
Element date;
|
||||
|
||||
CommentBoxHeader(AccountInfo author, Timestamp when, boolean isDraft) {
|
||||
// TODO: Set avatar's display to none if we get a 404.
|
||||
avatar = author == null ? new AvatarImage() : new AvatarImage(author, 26);
|
||||
if (author != null) {
|
||||
avatar = new AvatarImage(author, 26);
|
||||
avatar.setSize("", "");
|
||||
} else {
|
||||
avatar = new AvatarImage();
|
||||
}
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
this.draft = isDraft;
|
||||
draft = isDraft;
|
||||
if (when != null) {
|
||||
setDate(when);
|
||||
}
|
||||
if (isDraft) {
|
||||
name.setInnerText("(Draft)");
|
||||
name.setInnerText(PatchUtil.C.draft());
|
||||
} else {
|
||||
name.setInnerText(FormatUtil.name(author));
|
||||
name.setTitle(FormatUtil.nameEmail(author));
|
||||
date.setTitle(FormatUtil.mediumFormat(when));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ limitations under the License.
|
||||
<table class='{res.style.table}'>
|
||||
<tr>
|
||||
<td><c:AvatarImage ui:field='avatar' /></td>
|
||||
<td ui:field='name'></td>
|
||||
<td ui:field='name' class='{res.style.name}'></td>
|
||||
<td class='{res.style.summary}'>
|
||||
<div ui:field='summary' class='{res.style.summaryText}'></div>
|
||||
</td>
|
||||
|
||||
@@ -29,10 +29,12 @@ interface CommentBoxResources extends ClientBundle {
|
||||
String close();
|
||||
String commentBox();
|
||||
String table();
|
||||
String name();
|
||||
String summary();
|
||||
String summaryText();
|
||||
String date();
|
||||
String contentPanel();
|
||||
String message();
|
||||
String button();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
.commentBox {
|
||||
background-color: #e5ecf9;
|
||||
border: 1px solid black;
|
||||
-webkit-box-shadow: 3px 3px 3px #888888;
|
||||
-moz-box-shadow: 3px 3px 3px #888888;
|
||||
box-shadow: 3px 3px 3px #888888;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 5px;
|
||||
overflow: visible;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.table {
|
||||
@@ -9,6 +17,11 @@
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.name {
|
||||
width: 20%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.summary {
|
||||
width: 60%;
|
||||
}
|
||||
@@ -18,7 +31,7 @@
|
||||
height: 1em;
|
||||
max-width: 80%;
|
||||
overflow: hidden;
|
||||
padding-bottom: 1px;
|
||||
padding-bottom: 2px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -37,5 +50,11 @@
|
||||
}
|
||||
|
||||
.message {
|
||||
margin: 5px;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-left: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ limitations under the License.
|
||||
@external .cm-searching, .cm-trailingspace;
|
||||
.difftable .CodeMirror pre {
|
||||
padding: 0;
|
||||
padding-bottom: 0.1em;
|
||||
overflow: hidden;
|
||||
}
|
||||
.table {
|
||||
@@ -60,7 +61,7 @@ limitations under the License.
|
||||
}
|
||||
.activeLine .CodeMirror-linenumber,
|
||||
.activeLine .diff, .activeLine .intralineBg {
|
||||
background-color: #E0FFFF;
|
||||
background-color: #E0FFFF !important;
|
||||
}
|
||||
.activeLineBg {
|
||||
background-color: #E0FFFF !important;
|
||||
@@ -74,11 +75,14 @@ limitations under the License.
|
||||
.CodeMirror-selectedtext {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
.difftable .CodeMirror-linenumber {
|
||||
height: 1.1em;
|
||||
}
|
||||
.hideNumber .CodeMirror-linenumber {
|
||||
color: transparent;
|
||||
background-color: #def;
|
||||
width: 23px !important;
|
||||
height: 16px;
|
||||
height: 1.3em;
|
||||
}
|
||||
.difftable .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
|
||||
opacity: 0.8;
|
||||
|
||||
@@ -24,16 +24,15 @@ import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.DoubleClickEvent;
|
||||
import com.google.gwt.event.dom.client.DoubleClickHandler;
|
||||
import com.google.gwt.event.dom.client.KeyCodes;
|
||||
import com.google.gwt.event.dom.client.KeyDownEvent;
|
||||
import com.google.gwt.event.dom.client.MouseMoveEvent;
|
||||
import com.google.gwt.event.dom.client.MouseMoveHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
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.Timer;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwtexpui.globalkey.client.NpTextArea;
|
||||
@@ -70,10 +69,13 @@ class DraftBox extends CommentBox {
|
||||
@UiField
|
||||
Button discard;
|
||||
|
||||
private HandlerRegistration messageClick;
|
||||
private static final int INITIAL_COLS = 60;
|
||||
private static final int INITIAL_LINES = 5;
|
||||
private static final int MAX_LINES = 30;
|
||||
|
||||
private boolean isNew;
|
||||
private PublishedBox replyToBox;
|
||||
private CodeMirror cm;
|
||||
private Timer expandTimer;
|
||||
|
||||
DraftBox(
|
||||
CodeMirrorDemo host,
|
||||
@@ -81,46 +83,46 @@ class DraftBox extends CommentBox {
|
||||
PatchSet.Id id,
|
||||
CommentInfo info,
|
||||
CommentLinkProcessor linkProcessor,
|
||||
boolean isNew,
|
||||
boolean isNewDraft,
|
||||
boolean saveOnInit) {
|
||||
super(host, uiBinder, id, info, linkProcessor, true);
|
||||
super(host, cm, uiBinder, id, info, linkProcessor, true);
|
||||
|
||||
this.cm = cm;
|
||||
this.isNew = isNew;
|
||||
editArea.setText(contentPanelMessage.getText());
|
||||
isNew = isNewDraft;
|
||||
editArea.setText(info.message());
|
||||
editArea.setCharacterWidth(INITIAL_COLS);
|
||||
editArea.setVisibleLines(INITIAL_LINES);
|
||||
editArea.setSpellCheck(true);
|
||||
if (saveOnInit) {
|
||||
onSave(null);
|
||||
}
|
||||
if (isNew) {
|
||||
addStyleName(draftStyle.newDraft());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
|
||||
messageClick = contentPanelMessage.addDoubleClickHandler(
|
||||
new DoubleClickHandler() {
|
||||
expandTimer = new Timer() {
|
||||
@Override
|
||||
public void onDoubleClick(DoubleClickEvent arg0) {
|
||||
setEdit(true);
|
||||
public void run() {
|
||||
expandText();
|
||||
}
|
||||
});
|
||||
};
|
||||
addDomHandler(new MouseMoveHandler() {
|
||||
@Override
|
||||
public void onMouseMove(MouseMoveEvent arg0) {
|
||||
public void onMouseMove(MouseMoveEvent event) {
|
||||
resizePaddingWidget();
|
||||
}
|
||||
}, MouseMoveEvent.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnload() {
|
||||
super.onUnload();
|
||||
|
||||
messageClick.removeHandler();
|
||||
messageClick = null;
|
||||
private void expandText() {
|
||||
double cols = editArea.getCharacterWidth();
|
||||
int rows = 2;
|
||||
for (String line : editArea.getText().split("\n")) {
|
||||
rows += Math.ceil((1.0 + line.length()) / cols);
|
||||
}
|
||||
rows = Math.max(INITIAL_LINES, Math.min(rows, MAX_LINES));
|
||||
if (editArea.getVisibleLines() != rows) {
|
||||
editArea.setVisibleLines(rows);
|
||||
}
|
||||
resizePaddingWidget();
|
||||
}
|
||||
|
||||
void setEdit(boolean edit) {
|
||||
@@ -128,11 +130,15 @@ class DraftBox extends CommentBox {
|
||||
setOpen(true);
|
||||
removeStyleName(draftStyle.view());
|
||||
addStyleName(draftStyle.edit());
|
||||
editArea.setText(contentPanelMessage.getText());
|
||||
editArea.setText(getOriginal().message());
|
||||
expandText();
|
||||
editArea.setFocus(true);
|
||||
disableClickFocusHandler();
|
||||
} else {
|
||||
expandTimer.cancel();
|
||||
removeStyleName(draftStyle.edit());
|
||||
addStyleName(draftStyle.view());
|
||||
enableClickFocusHandler();
|
||||
}
|
||||
resizePaddingWidget();
|
||||
}
|
||||
@@ -142,6 +148,7 @@ class DraftBox extends CommentBox {
|
||||
}
|
||||
|
||||
private void removeUI() {
|
||||
expandTimer.cancel();
|
||||
if (replyToBox != null) {
|
||||
replyToBox.unregisterReplyBox();
|
||||
}
|
||||
@@ -152,7 +159,12 @@ class DraftBox extends CommentBox {
|
||||
PaddingManager manager = getPaddingManager();
|
||||
manager.remove(this);
|
||||
manager.resizePaddingWidget();
|
||||
cm.focus();
|
||||
getCm().focus();
|
||||
}
|
||||
|
||||
@UiHandler("contentPanelMessage")
|
||||
void onDoubleClick(DoubleClickEvent e) {
|
||||
setEdit(true);
|
||||
}
|
||||
|
||||
@UiHandler("edit")
|
||||
@@ -187,13 +199,13 @@ class DraftBox extends CommentBox {
|
||||
} else {
|
||||
CommentApi.updateDraft(getPatchSetId(), original.id(), input, cb);
|
||||
}
|
||||
cm.focus();
|
||||
getCm().focus();
|
||||
}
|
||||
|
||||
@UiHandler("cancel")
|
||||
void onCancel(ClickEvent e) {
|
||||
setEdit(false);
|
||||
cm.focus();
|
||||
getCm().focus();
|
||||
}
|
||||
|
||||
@UiHandler("discard")
|
||||
@@ -213,10 +225,17 @@ class DraftBox extends CommentBox {
|
||||
|
||||
@UiHandler("editArea")
|
||||
void onCtrlS(KeyDownEvent e) {
|
||||
if (e.isControlKeyDown() && e.getNativeKeyCode() == 83) {
|
||||
onSave(null);
|
||||
e.preventDefault();
|
||||
if ((e.isControlKeyDown() || e.isMetaKeyDown())
|
||||
&& !e.isAltKeyDown() && !e.isShiftKeyDown()) {
|
||||
switch (e.getNativeKeyCode()) {
|
||||
case 's':
|
||||
case 'S':
|
||||
e.preventDefault();
|
||||
onSave(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
expandTimer.schedule(250);
|
||||
}
|
||||
|
||||
/** TODO: Unused now. Re-enable this after implementing auto-save */
|
||||
|
||||
@@ -23,6 +23,10 @@ limitations under the License.
|
||||
.edit .messagePanel {
|
||||
display: none;
|
||||
}
|
||||
textarea.editArea {
|
||||
margin-left: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.view .editArea {
|
||||
display: none;
|
||||
}
|
||||
@@ -30,27 +34,27 @@ limitations under the License.
|
||||
display: none;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel styleName='{res.style.commentBox}'>
|
||||
<g:HTMLPanel addStyleNames='{res.style.commentBox}'>
|
||||
<d:CommentBoxHeader ui:field='header' />
|
||||
<div class='{res.style.contentPanel}'>
|
||||
<c:NpTextArea ui:field='editArea' styleName='{draftStyle.editArea}'/>
|
||||
<div>
|
||||
<g:Button ui:field='save' styleName='{draftStyle.editArea}'>
|
||||
<c:NpTextArea ui:field='editArea' addStyleNames='{draftStyle.editArea}'/>
|
||||
<div class='{res.style.button}'>
|
||||
<g:Button ui:field='save' addStyleNames='{draftStyle.editArea}'>
|
||||
<ui:msg>Save</ui:msg>
|
||||
</g:Button>
|
||||
<g:Button ui:field='cancel'
|
||||
styleName='{draftStyle.editArea} {draftStyle.cancel}'>
|
||||
addStyleNames='{draftStyle.editArea} {draftStyle.cancel}'>
|
||||
<ui:msg>Cancel</ui:msg>
|
||||
</g:Button>
|
||||
<g:Button ui:field='discard' styleName='{draftStyle.editArea}'>
|
||||
<g:Button ui:field='discard' addStyleNames='{draftStyle.editArea}'>
|
||||
<ui:msg>Discard</ui:msg>
|
||||
</g:Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class='{res.style.contentPanel}'>
|
||||
<g:HTML ui:field='contentPanelMessage'
|
||||
styleName='{res.style.message} {draftStyle.messagePanel}'></g:HTML>
|
||||
<g:Button ui:field='edit' styleName='{draftStyle.messagePanel}'>
|
||||
addStyleNames='{res.style.message} {draftStyle.messagePanel}'></g:HTML>
|
||||
<g:Button ui:field='edit' addStyleNames='{draftStyle.messagePanel} {res.style.button}'>
|
||||
<ui:msg>Edit</ui:msg>
|
||||
</g:Button>
|
||||
</div>
|
||||
|
||||
@@ -58,7 +58,7 @@ class PaddingManager {
|
||||
private int getMyTotalHeight() {
|
||||
int total = 0;
|
||||
for (CommentBox box : comments) {
|
||||
total += box.getOffsetHeight();
|
||||
total += box.getOffsetHeight() + 5; // 5px for shadow margin
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
|
||||
import net.codemirror.lib.CodeMirror;
|
||||
|
||||
/** An HtmlPanel for displaying a published comment */
|
||||
class PublishedBox extends CommentBox {
|
||||
interface Binder extends UiBinder<HTMLPanel, PublishedBox> {}
|
||||
@@ -31,9 +33,13 @@ class PublishedBox extends CommentBox {
|
||||
|
||||
private DraftBox replyBox;
|
||||
|
||||
PublishedBox(CodeMirrorDemo host, PatchSet.Id id, CommentInfo info,
|
||||
PublishedBox(
|
||||
CodeMirrorDemo host,
|
||||
CodeMirror cm,
|
||||
PatchSet.Id id,
|
||||
CommentInfo info,
|
||||
CommentLinkProcessor linkProcessor) {
|
||||
super(host, uiBinder, id, info, linkProcessor, false);
|
||||
super(host, cm, uiBinder, id, info, linkProcessor, false);
|
||||
}
|
||||
|
||||
void registerReplyBox(DraftBox box) {
|
||||
|
||||
@@ -18,11 +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:with field='res' type='com.google.gerrit.client.diff.CommentBoxResources' />
|
||||
<g:HTMLPanel styleName='{res.style.commentBox}'>
|
||||
<g:HTMLPanel addStyleNames='{res.style.commentBox}'>
|
||||
<d:CommentBoxHeader ui:field='header' />
|
||||
<g:HTMLPanel styleName='{res.style.contentPanel}'>
|
||||
<g:HTML ui:field='contentPanelMessage' styleName='{res.style.message}'></g:HTML>
|
||||
<div>
|
||||
<g:HTMLPanel addStyleNames='{res.style.contentPanel}'>
|
||||
<g:HTML ui:field='contentPanelMessage' addStyleNames='{res.style.message}'></g:HTML>
|
||||
<div class='{res.style.button}'>
|
||||
<g:Button ui:field='reply'><ui:msg>Reply ...</ui:msg></g:Button>
|
||||
<g:Button ui:field='replyDone'><ui:msg>Reply 'Done'</ui:msg></g:Button>
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.google.gerrit.client.diff;
|
||||
import com.google.gerrit.client.patches.PatchUtil;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -65,12 +66,18 @@ class SkipBar extends Composite {
|
||||
private CodeMirror cm;
|
||||
private int numSkipLines;
|
||||
|
||||
SkipBar(CodeMirror cm) {
|
||||
this.cm = cm;
|
||||
SkipBar(CodeMirror cmInstance) {
|
||||
cm = cmInstance;
|
||||
skipNum = new Anchor(true);
|
||||
upArrow = new Anchor(true);
|
||||
downArrow = new Anchor(true);
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
addDomHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
cm.focus();
|
||||
}
|
||||
}, ClickEvent.getType());
|
||||
}
|
||||
|
||||
void setWidget(LineWidget widget) {
|
||||
|
||||
@@ -19,6 +19,8 @@ limitations under the License.
|
||||
<ui:style type='com.google.gerrit.client.diff.SkipBar.SkipBarStyle'>
|
||||
.skipBar {
|
||||
background-color: #def;
|
||||
height: 1.3em;
|
||||
overflow: hidden;
|
||||
}
|
||||
.text {
|
||||
display: table;
|
||||
@@ -38,16 +40,16 @@ limitations under the License.
|
||||
display: none;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel styleName='{style.skipBar}'>
|
||||
<g:HTMLPanel addStyleNames='{style.skipBar}'>
|
||||
<div class='{style.text}'>
|
||||
<ui:msg>
|
||||
<g:Anchor ui:field='upArrow' styleName='{style.anchor}'>
|
||||
<g:Anchor ui:field='upArrow' addStyleNames='{style.anchor}'>
|
||||
</g:Anchor>
|
||||
<span>... skipped </span>
|
||||
<g:Anchor ui:field='skipNum' styleName='{style.anchor}'>
|
||||
<span><ui:msg>... skipped </ui:msg></span>
|
||||
<g:Anchor ui:field='skipNum' addStyleNames='{style.anchor}'>
|
||||
</g:Anchor>
|
||||
<span> common lines ...</span>
|
||||
<g:Anchor ui:field='downArrow' styleName='{style.anchor}'>
|
||||
<span><ui:msg> common lines ...</ui:msg></span>
|
||||
<g:Anchor ui:field='downArrow' addStyleNames='{style.anchor}'>
|
||||
</g:Anchor>
|
||||
</ui:msg>
|
||||
</div>
|
||||
|
||||
@@ -128,12 +128,29 @@ public class CodeMirror extends JavaScriptObject {
|
||||
return this.getScrollInfo();
|
||||
}-*/;
|
||||
|
||||
public final native CodeMirror getScrollSetBy() /*-{
|
||||
return this.state.scrollSetBy;
|
||||
}-*/;
|
||||
|
||||
public final native void setScrollSetBy(CodeMirror cm) /*-{
|
||||
this.state.scrollSetBy = cm;
|
||||
}-*/;
|
||||
|
||||
public final native double getScrollSetAt() /*-{
|
||||
return this.state.scrollSetAt;
|
||||
}-*/;
|
||||
|
||||
public final native void setScrollSetAt(double when) /*-{
|
||||
this.state.scrollSetAt = when;
|
||||
}-*/;
|
||||
|
||||
public final native void on(String event, Runnable thunk) /*-{
|
||||
this.on(event, $entry(function() {
|
||||
thunk.@java.lang.Runnable::run()();
|
||||
}));
|
||||
}-*/;
|
||||
|
||||
/** TODO: Break this line after updating GWT */
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user