Remove old unified diff screen

The functionality of skipping deleted or uncommented files when
navigating using the prev / next links will be implemented in a
following change. Note that the diff preferences dialog box currently
doesn't render these settings.

Change-Id: If7549cdd986a5e5dd26b1cbc4b4cfdb7ca48f880
This commit is contained in:
David Ostrovsky
2015-10-04 15:19:43 +02:00
committed by Michael Zhou
parent 7a9dca2b33
commit ff4ee1a494
81 changed files with 6 additions and 6970 deletions

View File

@@ -1,33 +0,0 @@
// Copyright (C) 2008 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.common.data;
import com.google.gerrit.common.audit.Audit;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.RemoteJsonService;
import com.google.gwtjsonrpc.common.RpcImpl;
import com.google.gwtjsonrpc.common.RpcImpl.Version;
@RpcImpl(version = Version.V2_0)
public interface ChangeDetailService extends RemoteJsonService {
@Audit
void patchSetDetail(PatchSet.Id key, AsyncCallback<PatchSetDetail> callback);
@Audit
void patchSetDetail2(PatchSet.Id baseId, PatchSet.Id key,
DiffPreferencesInfo diffPrefs, AsyncCallback<PatchSetDetail> callback);
}

View File

@@ -1,31 +0,0 @@
// Copyright (C) 2008 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.common.data;
import com.google.gerrit.common.audit.Audit;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.RemoteJsonService;
import com.google.gwtjsonrpc.common.RpcImpl;
import com.google.gwtjsonrpc.common.RpcImpl.Version;
@RpcImpl(version = Version.V2_0)
public interface PatchDetailService extends RemoteJsonService {
@Audit
void patchScript(Patch.Key key, PatchSet.Id a, PatchSet.Id b,
DiffPreferencesInfo diffPrefs, AsyncCallback<PatchScript> callback);
}

View File

@@ -1,64 +0,0 @@
// Copyright (C) 2008 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.common.data;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
import java.util.List;
public class PatchSetDetail {
protected PatchSet patchSet;
protected PatchSetInfo info;
protected List<Patch> patches;
protected Project.NameKey project;
public PatchSetDetail() {
}
public PatchSet getPatchSet() {
return patchSet;
}
public void setPatchSet(final PatchSet ps) {
patchSet = ps;
}
public PatchSetInfo getInfo() {
return info;
}
public void setInfo(final PatchSetInfo i) {
info = i;
}
public List<Patch> getPatches() {
return patches;
}
public void setPatches(final List<Patch> p) {
patches = p;
}
public Project.NameKey getProject() {
return project;
}
public void setProject(final Project.NameKey p) {
project = p;
}
}

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.extensions.client;
public enum GerritTopMenu {
ALL, MY, DIFFERENCES, PROJECTS, PEOPLE, PLUGINS, DOCUMENTATION;
ALL, MY, PROJECTS, PEOPLE, PLUGINS, DOCUMENTATION;
public final String menuName;

View File

@@ -88,7 +88,6 @@ import com.google.gerrit.client.documentation.DocScreen;
import com.google.gerrit.client.editor.EditScreen;
import com.google.gerrit.client.groups.GroupApi;
import com.google.gerrit.client.groups.GroupInfo;
import com.google.gerrit.client.patches.UnifiedPatchScreen;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.Screen;
@@ -481,8 +480,6 @@ public class Dispatcher {
codemirror(token, baseId, id, side, line, false);
} else if ("unified".equals(panel)) {
unified(token, baseId, id, side, line);
} else if ("unified1".equals(panel)) {
unified1(token, baseId, id);
} else if ("edit".equals(panel)) {
codemirror(token, null, id, side, line, true);
} else {
@@ -505,18 +502,6 @@ public class Dispatcher {
});
}
private static void unified1(final String token,
final PatchSet.Id baseId,
final Patch.Key id) {
GWT.runAsync(new AsyncSplit(token) {
@Override
public void onSuccess() {
UnifiedPatchScreen.TopView top = Gerrit.getPatchScreenTopView();
Gerrit.display(token, new UnifiedPatchScreen(id, top, baseId));
}
});
}
private static void codemirror(final String token, final PatchSet.Id baseId,
final Patch.Key id, final DisplaySide side, final int line,
final boolean edit) {

View File

@@ -37,7 +37,6 @@ import com.google.gerrit.client.info.ServerInfo;
import com.google.gerrit.client.info.TopMenu;
import com.google.gerrit.client.info.TopMenuItem;
import com.google.gerrit.client.info.TopMenuList;
import com.google.gerrit.client.patches.UnifiedPatchScreen;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
@@ -56,7 +55,6 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -138,7 +136,6 @@ public class Gerrit implements EntryPoint {
private static SearchPanel searchPanel;
private static final Dispatcher dispatcher = new Dispatcher();
private static ViewSite<Screen> body;
private static UnifiedPatchScreen patchScreen;
private static String lastChangeListToken;
private static String lastViewToken;
@@ -152,13 +149,6 @@ public class Gerrit implements EntryPoint {
Window.Location.reload();
}
public static UnifiedPatchScreen.TopView getPatchScreenTopView() {
if (patchScreen == null) {
return null;
}
return patchScreen.getTopView();
}
public static void displayLastChangeList() {
if (lastChangeListToken != null) {
display(lastChangeListToken);
@@ -214,26 +204,6 @@ public class Gerrit implements EntryPoint {
}
}
/**
* Update any top level menus which can vary based on the view which was
* loaded.
* @param view the loaded view.
*/
public static void updateMenus(Screen view) {
LinkMenuBar diffBar = menuBars.get(GerritTopMenu.DIFFERENCES.menuName);
if (view instanceof UnifiedPatchScreen) {
patchScreen = (UnifiedPatchScreen) view;
menuLeft.setVisible(diffBar, true);
menuLeft.selectTab(menuLeft.getWidgetIndex(diffBar));
} else {
if (patchScreen != null && menuLeft.getSelectedWidget() == diffBar) {
menuLeft.selectTab(isSignedIn() ? 1 : 0);
}
patchScreen = null;
menuLeft.setVisible(diffBar, false);
}
}
public static void selectMenu(LinkMenuBar bar) {
menuLeft.selectTab(menuLeft.getWidgetIndex(bar));
}
@@ -718,15 +688,6 @@ public class Gerrit implements EntryPoint {
menuLeft.selectTab(0);
}
patchScreen = null;
LinkMenuBar diffBar = new LinkMenuBar();
menuBars.put(GerritTopMenu.DIFFERENCES.menuName, diffBar);
menuLeft.addInvisible(diffBar, C.menuDiff());
addDiffLink(diffBar, C.menuDiffCommit(), UnifiedPatchScreen.TopView.COMMIT);
addDiffLink(diffBar, C.menuDiffPreferences(), UnifiedPatchScreen.TopView.PREFERENCES);
addDiffLink(diffBar, C.menuDiffPatchSets(), UnifiedPatchScreen.TopView.PATCH_SETS);
addDiffLink(diffBar, C.menuDiffFiles(), UnifiedPatchScreen.TopView.FILES);
final LinkMenuBar projectsBar = new LinkMenuBar();
menuBars.put(GerritTopMenu.PROJECTS.menuName, projectsBar);
addLink(projectsBar, C.menuProjectsList(), PageLinks.ADMIN_PROJECTS);
@@ -1018,19 +979,6 @@ public class Gerrit implements EntryPoint {
m.insertItem(new LinkMenuItem(text, historyToken), beforeIndex);
}
private static void addDiffLink(final LinkMenuBar m, final String text,
final UnifiedPatchScreen.TopView tv) {
m.addItem(new LinkMenuItem(text, "") {
@Override
public void go() {
if (patchScreen != null) {
patchScreen.setTopView(tv);
}
AnchorElement.as(getElement()).blur();
}
});
}
private static LinkMenuItem addProjectLink(LinkMenuBar m, TopMenuItem item) {
LinkMenuItem i = new ProjectLinkMenuItem(item.getName(), item.getUrl()) {
@Override

View File

@@ -111,9 +111,6 @@ public interface ChangeConstants extends Constants {
String reviewed();
String submitFailed();
String diffAllSideBySide();
String diffAllUnified();
String votable();
String pushCertMissing();

View File

@@ -94,9 +94,6 @@ nextPatchLinkIcon = &#x21e8;
reviewed = Reviewed
submitFailed = Submit Failed
diffAllSideBySide = All Side-by-Side
diffAllUnified = All Unified
votable = Votable:
pushCertMissing = This patch set was created without a push certificate

View File

@@ -477,8 +477,8 @@ abstract class DiffScreen extends Screen {
new NoOpKeyCommand(0, 'j', PatchUtil.C.lineNext()),
new NoOpKeyCommand(0, 'k', PatchUtil.C.linePrev()));
keysNavigation.add(
new NoOpKeyCommand(0, 'n', PatchUtil.C.chunkNext2()),
new NoOpKeyCommand(0, 'p', PatchUtil.C.chunkPrev2()));
new NoOpKeyCommand(0, 'n', PatchUtil.C.chunkNext()),
new NoOpKeyCommand(0, 'p', PatchUtil.C.chunkPrev()));
keysNavigation.add(
new NoOpKeyCommand(KeyCommand.M_SHIFT, 'n', PatchUtil.C.commentNext()),
new NoOpKeyCommand(KeyCommand.M_SHIFT, 'p', PatchUtil.C.commentPrev()));

View File

@@ -1,970 +0,0 @@
// Copyright (C) 2008 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.patches;
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.CommentPanel;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.client.ui.NeedsSignInKeyCommand;
import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.prettify.client.ClientSideFormatter;
import com.google.gerrit.prettify.client.PrettyFormatter;
import com.google.gerrit.prettify.client.SparseHtmlFile;
import com.google.gerrit.prettify.common.SparseFileContent;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Focusable;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import com.google.gwtorm.client.KeyUtil;
import org.eclipse.jgit.diff.Edit;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
abstract class AbstractPatchContentTable extends NavigationTable<Object>
implements CommentEditorContainer, FocusHandler, BlurHandler {
public static final int R_HEAD = 0;
static final short FILE_SIDE_A = (short) 0;
static final short FILE_SIDE_B = (short) 1;
protected PatchTable fileList;
protected AccountInfoCache accountCache = AccountInfoCache.empty();
protected Patch.Key patchKey;
protected PatchSet.Id idSideA;
protected PatchSet.Id idSideB;
protected boolean onlyOneHunk;
protected PatchSetSelectBox headerSideA;
protected PatchSetSelectBox headerSideB;
protected Image iconA;
protected Image iconB;
private final KeyCommandSet keysComment;
private HandlerRegistration regComment;
private final KeyCommandSet keysOpenByEnter;
private HandlerRegistration regOpenByEnter;
private CommentLinkProcessor commentLinkProcessor;
boolean isDisplayBinary;
protected AbstractPatchContentTable() {
keysNavigation.add(new PrevKeyCommand(0, 'k', PatchUtil.C.linePrev()));
keysNavigation.add(new NextKeyCommand(0, 'j', PatchUtil.C.lineNext()));
keysNavigation.add(new PrevChunkKeyCmd(0, 'p', PatchUtil.C.chunkPrev()));
keysNavigation.add(new NextChunkKeyCmd(0, 'n', PatchUtil.C.chunkNext()));
keysNavigation.add(new PrevCommentCmd(0, 'P', PatchUtil.C.commentPrev()));
keysNavigation.add(new NextCommentCmd(0, 'N', PatchUtil.C.commentNext()));
keysAction.add(new OpenKeyCommand(0, 'o', PatchUtil.C.expandComment()));
keysOpenByEnter = new KeyCommandSet(Gerrit.C.sectionNavigation());
keysOpenByEnter.add(new OpenKeyCommand(0, KeyCodes.KEY_ENTER, PatchUtil.C.expandComment()));
if (Gerrit.isSignedIn()) {
keysAction.add(new InsertCommentCommand(0, 'c', PatchUtil.C
.commentInsert()));
// See CommentEditorPanel
//
keysComment = new KeyCommandSet(PatchUtil.C.commentEditorSet());
keysComment.add(new NoOpKeyCommand(KeyCommand.M_CTRL, 's', PatchUtil.C
.commentSaveDraft()));
keysComment.add(new NoOpKeyCommand(0, KeyCodes.KEY_ESCAPE, PatchUtil.C
.commentCancelEdit()));
} else {
keysComment = null;
}
table.setStyleName(Gerrit.RESOURCES.css().patchContentTable());
}
abstract void createFileCommentEditorOnSideA();
abstract void createFileCommentEditorOnSideB();
protected void initHeaders(PatchScript script, PatchSetDetail detail) {
headerSideA = new PatchSetSelectBox(PatchSetSelectBox.Side.A);
headerSideA.display(detail, script, patchKey, idSideA, idSideB);
headerSideA.addDoubleClickHandler(new DoubleClickHandler() {
@Override
public void onDoubleClick(DoubleClickEvent event) {
if (headerSideA.isFileOrCommitMessage()) {
createFileCommentEditorOnSideA();
}
}
});
headerSideB = new PatchSetSelectBox(PatchSetSelectBox.Side.B);
headerSideB.display(detail, script, patchKey, idSideA, idSideB);
headerSideB.addDoubleClickHandler(new DoubleClickHandler() {
@Override
public void onDoubleClick(DoubleClickEvent event) {
if (headerSideB.isFileOrCommitMessage()) {
createFileCommentEditorOnSideB();
}
}
});
// Prepare icons.
iconA = new Image(Gerrit.RESOURCES.addFileComment());
iconA.setTitle(PatchUtil.C.addFileCommentToolTip());
iconA.addStyleName(Gerrit.RESOURCES.css().link());
iconA.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
createFileCommentEditorOnSideA();
}
});
iconB = new Image(Gerrit.RESOURCES.addFileComment());
iconB.setTitle(PatchUtil.C.addFileCommentToolTip());
iconB.addStyleName(Gerrit.RESOURCES.css().link());
iconB.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
createFileCommentEditorOnSideB();
}
});
}
@Override
public void notifyDraftDelta(final int delta) {
if (fileList != null) {
fileList.notifyDraftDelta(patchKey, delta);
}
Widget p = getParent();
while (p != null) {
if (p instanceof CommentEditorContainer) {
((CommentEditorContainer) p).notifyDraftDelta(delta);
break;
}
p = p.getParent();
}
}
@Override
public void remove(CommentEditorPanel panel) {
final int nRows = table.getRowCount();
for (int row = 0; row < nRows; row++) {
final int nCells = table.getCellCount(row);
for (int cell = 0; cell < nCells; cell++) {
if (table.getWidget(row, cell) == panel) {
destroyEditor(row, cell);
Widget p = table;
while (p != null) {
if (p instanceof Focusable) {
((Focusable) p).setFocus(true);
break;
}
p = p.getParent();
}
if (table.getCellFormatter().getStyleName(row - 1, cell)
.contains(Gerrit.RESOURCES.css().commentHolder())) {
table.getCellFormatter().addStyleName(row - 1, cell,
Gerrit.RESOURCES.css().commentPanelLast());
}
return;
}
}
}
}
@Override
public void setRegisterKeys(final boolean on) {
super.setRegisterKeys(on);
if (on && keysComment != null && regComment == null) {
regComment = GlobalKey.add(this, keysComment);
} else if (!on && regComment != null) {
regComment.removeHandler();
regComment = null;
}
if (on && keysOpenByEnter != null && regOpenByEnter == null) {
regOpenByEnter = GlobalKey.add(this, keysOpenByEnter);
} else if (!on && regOpenByEnter != null) {
regOpenByEnter.removeHandler();
regOpenByEnter = null;
}
}
public void display(final Patch.Key k, final PatchSet.Id a,
final PatchSet.Id b, final PatchScript s, final PatchSetDetail d) {
patchKey = k;
idSideA = a;
idSideB = b;
render(s, d);
}
void setCommentLinkProcessor(CommentLinkProcessor commentLinkProcessor) {
this.commentLinkProcessor = commentLinkProcessor;
}
protected boolean hasDifferences(PatchScript script) {
return hasEdits(script) || hasMeta(script) || hasComments(script);
}
public boolean isPureMetaChange(PatchScript script) {
return !hasEdits(script) && hasMeta(script);
}
// True if there are differences between the two patch sets
private boolean hasEdits(PatchScript script) {
for (Edit e : script.getEdits()) {
if (e.getType() != Edit.Type.EMPTY) {
return true;
}
}
return false;
}
// True if one of the two patch sets has comments
private boolean hasComments(PatchScript script) {
return !script.getCommentDetail().getCommentsA().isEmpty()
|| !script.getCommentDetail().getCommentsB().isEmpty();
}
// True if this change is a mode change or a pure rename/copy
private boolean hasMeta(PatchScript script) {
return !script.getPatchHeader().isEmpty();
}
protected void appendNoDifferences(SafeHtmlBuilder m) {
m.openTr();
m.openTd();
m.setAttribute("colspan", 5);
m.openDiv();
m.addStyleName(Gerrit.RESOURCES.css().patchNoDifference());
m.append(PatchUtil.C.noDifference());
m.closeDiv();
m.closeTd();
m.closeTr();
}
protected SparseHtmlFile getSparseHtmlFileA(PatchScript s) {
DiffPreferencesInfo dp = s.getDiffPrefs();
dp.showWhitespaceErrors = false;
PrettyFormatter f = ClientSideFormatter.FACTORY.get();
f.setDiffPrefs(dp);
f.setFileName(s.getA().getPath());
f.setEditFilter(PrettyFormatter.A);
f.setEditList(s.getEdits());
f.format(s.getA());
return f;
}
protected SparseHtmlFile getSparseHtmlFileB(PatchScript s) {
DiffPreferencesInfo dp = s.getDiffPrefs();
SparseFileContent b = s.getB();
PrettyFormatter f = ClientSideFormatter.FACTORY.get();
f.setDiffPrefs(dp);
f.setFileName(b.getPath());
f.setEditFilter(PrettyFormatter.B);
f.setEditList(s.getEdits());
if (s.getA().isWholeFile() && !b.isWholeFile()) {
b = b.apply(s.getA(), s.getEdits());
}
f.format(b);
return f;
}
protected String getUrlA() {
final String rawBase = GWT.getHostPageBaseURL() + "cat/";
final String url;
if (idSideA == null) {
url = rawBase + KeyUtil.encode(patchKey.toString()) + "^1";
} else {
Patch.Key k = new Patch.Key(idSideA, patchKey.get());
url = rawBase + KeyUtil.encode(k.toString()) + "^0";
}
return url;
}
protected String getUrlB() {
final String rawBase = GWT.getHostPageBaseURL() + "cat/";
return rawBase + KeyUtil.encode(patchKey.toString()) + "^0";
}
protected abstract void render(PatchScript script, final PatchSetDetail detail);
protected abstract void onInsertComment(PatchLine pl);
public abstract void display(CommentDetail comments, boolean expandComments);
@Override
protected Object getRowItemKey(final Object item) {
return null;
}
protected void initScript(final PatchScript script) {
if (script.getEdits().size() == 1) {
final SparseFileContent a = script.getA();
final SparseFileContent b = script.getB();
onlyOneHunk = a.size() == 0 || b.size() == 0;
} else {
onlyOneHunk = false;
}
}
private boolean isChunk(final int row) {
final Object o = getRowItem(row);
if (!onlyOneHunk && o instanceof PatchLine) {
final PatchLine pl = (PatchLine) o;
switch (pl.getType()) {
case DELETE:
case INSERT:
case REPLACE:
return true;
case CONTEXT:
break;
}
} else if (o instanceof CommentList) {
return true;
}
return false;
}
private int findChunkStart(int row) {
while (0 <= row && isChunk(row)) {
row--;
}
return row + 1;
}
private int findChunkEnd(int row) {
final int max = table.getRowCount();
while (row < max && isChunk(row)) {
row++;
}
return row - 1;
}
private static int oneBefore(final int begin) {
return 1 <= begin ? begin - 1 : begin;
}
private int oneAfter(final int end) {
return end + 1 < table.getRowCount() ? end + 1 : end;
}
private void moveToPrevChunk(int row) {
while (0 <= row && isChunk(row)) {
row--;
}
for (; 0 <= row; row--) {
if (isChunk(row)) {
final int start = findChunkStart(row);
movePointerTo(start, false);
scrollIntoView(oneBefore(start), oneAfter(row));
return;
}
}
// No prior hunk found? Try to hit the first line in the file.
//
for (row = 0; row < table.getRowCount(); row++) {
if (getRowItem(row) != null) {
movePointerTo(row);
break;
}
}
}
private void moveToNextChunk(int row) {
final int max = table.getRowCount();
while (row < max && isChunk(row)) {
row++;
}
for (; row < max; row++) {
if (isChunk(row)) {
movePointerTo(row, false);
scrollIntoView(oneBefore(row), oneAfter(findChunkEnd(row)));
return;
}
}
// No next hunk found? Try to hit the last line in the file.
//
for (row = max - 1; row >= 0; row--) {
if (getRowItem(row) != null) {
movePointerTo(row);
break;
}
}
}
private void moveToPrevComment(int row) {
while (0 <= row && isComment(row)) {
row--;
}
for (; 0 <= row; row--) {
if (isComment(row)) {
movePointerTo(row, false);
scrollIntoView(oneBefore(row), oneAfter(row));
return;
}
}
// No prior comment found? Try to hit the first line in the file.
//
for (row = 0; row < table.getRowCount(); row++) {
if (getRowItem(row) != null) {
movePointerTo(row);
break;
}
}
}
private void moveToNextComment(int row) {
final int max = table.getRowCount();
while (row < max && isComment(row)) {
row++;
}
for (; row < max; row++) {
if (isComment(row)) {
movePointerTo(row, false);
scrollIntoView(oneBefore(row), oneAfter(row));
return;
}
}
// No next comment found? Try to hit the last line in the file.
//
for (row = max - 1; row >= 0; row--) {
if (getRowItem(row) != null) {
movePointerTo(row);
break;
}
}
}
private boolean isComment(int row) {
return getRowItem(row) instanceof CommentList;
}
/**
* Invokes createCommentEditor() with an empty string as value for the comment
* parent UUID. This method is invoked by callers that want to create an
* editor for a comment that is not a reply.
*/
protected void createCommentEditor(final int suggestRow, final int column,
final int line, final short file) {
if (Gerrit.isSignedIn()) {
if (R_HEAD <= line) {
final Patch.Key parentKey;
final short side;
switch (file) {
case 0:
if (idSideA == null) {
parentKey = new Patch.Key(idSideB, patchKey.get());
side = (short) 0;
} else {
parentKey = new Patch.Key(idSideA, patchKey.get());
side = (short) 1;
}
break;
case 1:
parentKey = new Patch.Key(idSideB, patchKey.get());
side = (short) 1;
break;
default:
throw new RuntimeException("unexpected file id " + file);
}
final PatchLineComment newComment = new PatchLineComment(
new PatchLineComment.Key(parentKey, null), line,
Gerrit.getUserAccount().getId(), null,
new Timestamp(System.currentTimeMillis()));
newComment.setSide(side);
newComment.setMessage("");
findOrCreateCommentEditor(suggestRow, column, newComment, true)
.setFocus(true);
}
} else {
Gerrit.doSignIn(History.getToken());
}
}
/**
* Update cursor after selecting a comment.
*
* @param newComment comment that was selected.
*/
protected void updateCursor(final PatchLineComment newComment) {
}
abstract void insertFileCommentRow(final int row);
private CommentEditorPanel findOrCreateCommentEditor(final int suggestRow,
final int column, final PatchLineComment newComment, final boolean create) {
int row = suggestRow;
int[] spans = new int[column + 1];
FIND_ROW: while (row < table.getRowCount()) {
int col = 0;
for (int cell = 0; row < table.getRowCount()
&& cell < table.getCellCount(row); cell++) {
while (col < column && 0 < spans[col]) {
spans[col++]--;
}
spans[col] = table.getFlexCellFormatter().getRowSpan(row, cell);
if (col == column) {
final Widget w = table.getWidget(row, cell);
if (w instanceof CommentEditorPanel
&& ((CommentEditorPanel) w).getComment().getKey().getParentKey()
.equals(newComment.getKey().getParentKey())) {
// Don't insert two editors on the same position, it doesn't make
// any sense to the user.
//
return ((CommentEditorPanel) w);
} else if (w instanceof CommentPanel) {
if (newComment != null && newComment.getParentUuid() != null) {
// If we are a reply, we were given the exact row to insert
// ourselves at. We should be before this panel so break.
//
break FIND_ROW;
}
row++;
cell--;
} else {
break FIND_ROW;
}
}
}
}
if (newComment == null || !create) {
return null;
}
final CommentEditorPanel ed =
new CommentEditorPanel(newComment, commentLinkProcessor);
ed.addFocusHandler(this);
ed.addBlurHandler(this);
boolean isCommentRow = false;
boolean needInsert = false;
if (row < table.getRowCount()) {
for (int cell = 0; cell < table.getCellCount(row); cell++) {
final Widget w = table.getWidget(row, cell);
if (w instanceof CommentEditorPanel || w instanceof CommentPanel) {
if (column == cell) {
needInsert = true;
}
isCommentRow = true;
}
}
}
if (needInsert || !isCommentRow) {
if (newComment.getLine() == R_HEAD) {
insertFileCommentRow(row);
} else {
insertRow(row);
}
styleCommentRow(row);
}
table.setWidget(row, column, ed);
styleLastCommentCell(row, column);
int span = 1;
for (int r = row + 1; r < table.getRowCount(); r++) {
boolean hasComment = false;
for (int c = 0; c < table.getCellCount(r); c++) {
final Widget w = table.getWidget(r, c);
if (w instanceof CommentPanel || w instanceof CommentEditorPanel) {
if (c != column) {
hasComment = true;
break;
}
}
}
if (hasComment) {
table.removeCell(r, column);
span++;
} else {
break;
}
}
if (span > 1) {
table.getFlexCellFormatter().setRowSpan(row, column, span);
}
for (int r = row - 1; r > 0; r--) {
if (getRowItem(r) instanceof CommentList) {
continue;
} else if (getRowItem(r) != null) {
movePointerTo(r);
break;
}
}
updateCursor(newComment);
return ed;
}
protected void insertRow(final int row) {
table.insertRow(row);
table.getCellFormatter().setStyleName(row, 0,
Gerrit.RESOURCES.css().iconCell());
}
@Override
protected void onOpenRow(final int row) {
final Object item = getRowItem(row);
if (item instanceof CommentList) {
for (final CommentPanel p : ((CommentList) item).panels) {
p.setOpen(!p.isOpen());
}
}
}
public void setAccountInfoCache(final AccountInfoCache aic) {
assert aic != null;
accountCache = aic;
}
private void destroyEditor(final int row, final int col) {
table.clearCell(row, col);
final int span = table.getFlexCellFormatter().getRowSpan(row, col);
boolean removeRow = true;
final int nCells = table.getCellCount(row);
for (int cell = 0; cell < nCells; cell++) {
if (table.getWidget(row, cell) != null) {
removeRow = false;
break;
}
}
if (removeRow) {
destroyCommentRow(row);
} else {
destroyComment(row, col, span);
}
}
protected void destroyCommentRow(int row) {
for (int r = row - 1; 0 <= r; r--) {
boolean data = false;
for (int c = 0; c < table.getCellCount(r); c++) {
data |= table.getWidget(r, c) != null;
final int s = table.getFlexCellFormatter().getRowSpan(r, c) - 1;
if (r + s == row) {
table.getFlexCellFormatter().setRowSpan(r, c, s);
}
}
if (!data) {
break;
}
}
table.removeRow(row);
}
private void destroyComment(int row, int col, int span) {
table.getFlexCellFormatter().setStyleName(//
row, col, Gerrit.RESOURCES.css().diffText());
if (span != 1) {
table.getFlexCellFormatter().setRowSpan(row, col, 1);
for (int r = row + 1; r < row + span; r++) {
table.insertCell(r, col);
table.getFlexCellFormatter().setStyleName(//
r, col, Gerrit.RESOURCES.css().diffText());
}
}
}
protected void bindComment(final int row, final int col,
final PatchLineComment line, boolean expandComment) {
if (line.getStatus() == PatchLineComment.Status.DRAFT) {
final CommentEditorPanel plc =
new CommentEditorPanel(line, commentLinkProcessor);
plc.addFocusHandler(this);
plc.addBlurHandler(this);
table.setWidget(row, col, plc);
styleLastCommentCell(row, col);
} else {
final AccountInfo author = FormatUtil.asInfo(accountCache.get(line.getAuthor()));
final PublishedCommentPanel panel =
new PublishedCommentPanel(author, line);
panel.setOpen(expandComment);
panel.addFocusHandler(this);
panel.addBlurHandler(this);
table.setWidget(row, col, panel);
styleLastCommentCell(row, col);
CommentList l = (CommentList) getRowItem(row);
if (l == null) {
l = new CommentList();
setRowItem(row, l);
}
l.comments.add(line);
l.panels.add(panel);
}
styleCommentRow(row);
}
@Override
public void onFocus(FocusEvent event) {
// when the comment panel gets focused (actually when a button inside the
// comment panel gets focused) we have to unregister the key binding for
// ENTER that expands/collapses the comment panel, if we don't do this the
// focused button in the comment panel cannot be triggered by pressing ENTER
// since ENTER would then be already consumed by this key binding
if (regOpenByEnter != null) {
regOpenByEnter.removeHandler();
regOpenByEnter = null;
}
}
@Override
public void onBlur(BlurEvent event) {
// when the comment panel gets blurred (actually when a button inside the
// comment panel gets blurred) we have to re-register the key binding for
// ENTER that expands/collapses the comment panel
if (keysOpenByEnter != null && regOpenByEnter == null) {
regOpenByEnter = GlobalKey.add(this, keysOpenByEnter);
}
}
private void styleCommentRow(final int row) {
final CellFormatter fmt = table.getCellFormatter();
final Element iconCell = fmt.getElement(row, 0);
UIObject.setStyleName(DOM.getParent(iconCell), Gerrit.RESOURCES.css()
.commentHolder(), true);
}
private void styleLastCommentCell(final int row, final int col) {
final CellFormatter fmt = table.getCellFormatter();
fmt.removeStyleName(row - 1, col, //
Gerrit.RESOURCES.css().commentPanelLast());
fmt.setStyleName(row, col, Gerrit.RESOURCES.css().commentHolder());
fmt.addStyleName(row, col, Gerrit.RESOURCES.css().commentPanelLast());
if (!fmt.getStyleName(row, col - 1).contains(Gerrit.RESOURCES.css().commentHolder())) {
fmt.addStyleName(row, col, Gerrit.RESOURCES.css().commentHolderLeftmost());
}
}
protected static class CommentList {
final List<PatchLineComment> comments = new ArrayList<>();
final List<PublishedCommentPanel> panels = new ArrayList<>();
}
public static class NoOpKeyCommand extends NeedsSignInKeyCommand {
public NoOpKeyCommand(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
}
}
public class InsertCommentCommand extends NeedsSignInKeyCommand {
public InsertCommentCommand(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
ensurePointerVisible();
for (int row = getCurrentRow(); 0 <= row; row--) {
final Object item = getRowItem(row);
if (item instanceof PatchLine) {
onInsertComment((PatchLine) item);
return;
} else if (item instanceof CommentList) {
continue;
} else {
return;
}
}
}
}
public class PrevChunkKeyCmd extends KeyCommand {
public PrevChunkKeyCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
ensurePointerVisible();
moveToPrevChunk(getCurrentRow());
}
}
public class NextChunkKeyCmd extends KeyCommand {
public NextChunkKeyCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
ensurePointerVisible();
moveToNextChunk(getCurrentRow());
}
}
public class PrevCommentCmd extends KeyCommand {
public PrevCommentCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
ensurePointerVisible();
moveToPrevComment(getCurrentRow());
}
}
public class NextCommentCmd extends KeyCommand {
public NextCommentCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
ensurePointerVisible();
moveToNextComment(getCurrentRow());
}
}
private class PublishedCommentPanel extends CommentPanel implements
ClickHandler {
final PatchLineComment comment;
final Button reply;
final Button replyDone;
PublishedCommentPanel(final AccountInfo author, final PatchLineComment c) {
super(author, c.getWrittenOn(), c.getMessage(), commentLinkProcessor);
this.comment = c;
reply = new Button(PatchUtil.C.buttonReply());
reply.addClickHandler(this);
addButton(reply);
replyDone = new Button(PatchUtil.C.buttonReplyDone());
replyDone.addClickHandler(this);
addButton(replyDone);
}
@Override
public void onClick(final ClickEvent event) {
if (Gerrit.isSignedIn()) {
if (reply == event.getSource()) {
createReplyEditor();
} else if (replyDone == event.getSource()) {
cannedReply(PatchUtil.C.cannedReplyDone());
}
} else {
Gerrit.doSignIn(History.getToken());
}
}
private void createReplyEditor() {
final PatchLineComment newComment = newComment();
newComment.setMessage("");
findOrCreateEditor(newComment, true).setFocus(true);
}
private void cannedReply(String message) {
final PatchLineComment newComment = newComment();
newComment.setMessage(message);
CommentEditorPanel p = findOrCreateEditor(newComment, false);
if (p == null) {
enableButtons(false);
final PatchSet.Id psId = newComment.getKey().getParentKey().getParentKey();
CommentInfo in = CommentEditorPanel.toInput(newComment);
CommentApi.createDraft(psId, in,
new GerritCallback<CommentInfo>() {
@Override
public void onSuccess(CommentInfo result) {
enableButtons(true);
notifyDraftDelta(1);
findOrCreateEditor(CommentEditorPanel.toComment(
psId, newComment.getKey().getParentKey().get(), result),
true).setOpen(false);
}
@Override
public void onFailure(Throwable caught) {
enableButtons(true);
super.onFailure(caught);
}
});
} else {
if (!p.isOpen()) {
p.setOpen(true);
}
p.setFocus(true);
}
}
private CommentEditorPanel findOrCreateEditor(
PatchLineComment newComment, boolean create) {
int row = rowOf(getElement());
int column = columnOf(getElement());
return findOrCreateCommentEditor(row + 1, column, newComment, create);
}
private PatchLineComment newComment() {
PatchLineComment newComment =
new PatchLineComment(new PatchLineComment.Key(comment.getKey()
.getParentKey(), null), comment.getLine(), Gerrit
.getUserAccount().getId(), comment.getKey().get(),
new Timestamp(System.currentTimeMillis()));
newComment.setSide(comment.getSide());
return newComment;
}
}
}

View File

@@ -1,21 +0,0 @@
// Copyright (C) 2010 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.patches;
public interface CommentEditorContainer {
void notifyDraftDelta(int delta);
void remove(CommentEditorPanel panel);
}

View File

@@ -1,371 +0,0 @@
// Copyright (C) 2008 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.patches;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.change.LocalComments;
import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.CommentPanel;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.NpTextArea;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.VoidResult;
import java.sql.Timestamp;
public class CommentEditorPanel extends CommentPanel implements ClickHandler,
DoubleClickHandler {
private static final int INITIAL_COLS = 60;
private static final int INITIAL_LINES = 5;
private static final int MAX_LINES = 30;
private static final AsyncCallback<VoidResult> NULL_CALLBACK =
new AsyncCallback<VoidResult>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(VoidResult result) {
}
};
private PatchLineComment comment;
private final NpTextArea text;
private final Button edit;
private final Button save;
private final Button cancel;
private final Button discard;
private final Timer expandTimer;
public CommentEditorPanel(final PatchLineComment plc,
final CommentLinkProcessor commentLinkProcessor) {
super(commentLinkProcessor);
comment = plc;
addStyleName(Gerrit.RESOURCES.css().commentEditorPanel());
setAuthorNameText(Gerrit.getUserAccount(), PatchUtil.C.draft());
setMessageText(plc.getMessage());
addDoubleClickHandler(this);
expandTimer = new Timer() {
@Override
public void run() {
expandText();
}
};
text = new NpTextArea();
text.setText(comment.getMessage());
text.setCharacterWidth(INITIAL_COLS);
text.setVisibleLines(INITIAL_LINES);
text.setSpellCheck(true);
text.addKeyDownHandler(new KeyDownHandler() {
@Override
public void onKeyDown(final KeyDownEvent event) {
if ((event.isControlKeyDown() || event.isMetaKeyDown())
&& !event.isAltKeyDown() && !event.isShiftKeyDown()) {
switch (event.getNativeKeyCode()) {
case 's':
case 'S':
event.preventDefault();
onSave(NULL_CALLBACK);
return;
}
}
expandTimer.schedule(250);
}
});
addContent(text);
edit = new Button();
edit.setText(PatchUtil.C.buttonEdit());
edit.addClickHandler(this);
addButton(edit);
save = new Button();
save.setText(PatchUtil.C.buttonSave());
save.addClickHandler(this);
addButton(save);
cancel = new Button();
cancel.setText(PatchUtil.C.buttonCancel());
cancel.addClickHandler(this);
addButton(cancel);
discard = new Button();
discard.setText(PatchUtil.C.buttonDiscard());
discard.addClickHandler(this);
addButton(discard);
setOpen(true);
if (isNew()) {
edit();
} else {
render();
}
}
private void expandText() {
final double cols = text.getCharacterWidth();
int rows = 2;
for (final String line : text.getText().split("\n")) {
rows += Math.ceil((1.0 + line.length()) / cols);
}
rows = Math.max(INITIAL_LINES, Math.min(rows, MAX_LINES));
if (text.getVisibleLines() != rows) {
text.setVisibleLines(rows);
}
}
private void edit() {
if (!isOpen()) {
setOpen(true);
}
text.setText(comment.getMessage());
expandText();
stateEdit(true);
text.setFocus(true);
}
private void render() {
final Timestamp on = comment.getWrittenOn();
setDateText(PatchUtil.M.draftSaved(new java.util.Date(on.getTime())));
setMessageText(comment.getMessage());
stateEdit(false);
}
private void stateEdit(final boolean inEdit) {
expandTimer.cancel();
setMessageTextVisible(!inEdit);
edit.setVisible(!inEdit);
if (inEdit) {
text.setVisible(true);
} else {
text.setFocus(false);
text.setVisible(false);
}
save.setVisible(inEdit);
cancel.setVisible(inEdit && !isNew());
discard.setVisible(inEdit);
}
void setFocus(final boolean take) {
if (take && !isOpen()) {
setOpen(true);
}
if (text.isVisible()) {
text.setFocus(take);
} else if (take) {
edit();
}
}
boolean isNew() {
return comment.getKey().get() == null;
}
public PatchLineComment getComment() {
return comment;
}
@Override
public void onDoubleClick(final DoubleClickEvent event) {
edit();
}
@Override
public void onClick(final ClickEvent event) {
final Widget sender = (Widget) event.getSource();
if (sender == edit) {
edit();
} else if (sender == save) {
onSave(NULL_CALLBACK);
} else if (sender == cancel) {
render();
} else if (sender == discard) {
onDiscard();
}
}
public void saveDraft(AsyncCallback<VoidResult> onSave) {
if (isOpen() && text.isVisible()) {
onSave(onSave);
} else {
onSave.onSuccess(VoidResult.INSTANCE);
}
}
private void onSave(final AsyncCallback<VoidResult> onSave) {
expandTimer.cancel();
final String txt = text.getText().trim();
if ("".equals(txt)) {
return;
}
comment.setMessage(txt);
text.setFocus(false);
text.setReadOnly(true);
save.setEnabled(false);
cancel.setEnabled(false);
discard.setEnabled(false);
final PatchSet.Id psId = comment.getKey().getParentKey().getParentKey();
final LocalComments lc = new LocalComments(psId);
final boolean wasNew = isNew();
GerritCallback<CommentInfo> cb = new GerritCallback<CommentInfo>() {
@Override
public void onSuccess(CommentInfo result) {
notifyDraftDelta(wasNew ? 1 : 0);
comment = toComment(psId, comment.getKey().getParentKey().get(), result);
text.setReadOnly(false);
save.setEnabled(true);
cancel.setEnabled(true);
discard.setEnabled(true);
render();
onSave.onSuccess(VoidResult.INSTANCE);
}
@Override
public void onFailure(final Throwable caught) {
text.setReadOnly(false);
text.setFocus(true);
save.setEnabled(true);
cancel.setEnabled(true);
discard.setEnabled(true);
lc.setInlineComment(toInput(comment));
super.onFailure(caught);
onSave.onFailure(caught);
}
};
CommentInfo input = toInput(comment);
if (wasNew) {
CommentApi.createDraft(psId, input, cb);
} else {
CommentApi.updateDraft(psId, input.id(), input, cb);
}
}
private void notifyDraftDelta(final int delta) {
CommentEditorContainer c = getContainer();
if (c != null) {
c.notifyDraftDelta(delta);
}
}
private void onDiscard() {
expandTimer.cancel();
if (isNew()) {
text.setFocus(false);
removeUI();
return;
}
text.setFocus(false);
text.setReadOnly(true);
save.setEnabled(false);
cancel.setEnabled(false);
discard.setEnabled(false);
CommentApi.deleteDraft(
comment.getKey().getParentKey().getParentKey(),
comment.getKey().get(),
new GerritCallback<JavaScriptObject>() {
@Override
public void onSuccess(JavaScriptObject result) {
notifyDraftDelta(-1);
removeUI();
}
@Override
public void onFailure(final Throwable caught) {
text.setReadOnly(false);
text.setFocus(true);
save.setEnabled(true);
cancel.setEnabled(true);
discard.setEnabled(true);
super.onFailure(caught);
}
});
}
private void removeUI() {
CommentEditorContainer c = getContainer();
if (c != null) {
c.remove(this);
}
}
private CommentEditorContainer getContainer() {
Widget p = getParent();
while (p != null) {
if (p instanceof CommentEditorContainer) {
return (CommentEditorContainer) p;
}
p = p.getParent();
}
return null;
}
public static CommentInfo toInput(PatchLineComment c) {
CommentInfo i = CommentInfo.createObject().cast();
i.id(c.getKey().get());
i.path(c.getKey().getParentKey().get());
i.side(c.getSide() == 0 ? Side.PARENT : Side.REVISION);
if (c.getLine() > 0) {
i.line(c.getLine());
}
i.inReplyTo(c.getParentUuid());
i.message(c.getMessage());
return i;
}
public static PatchLineComment toComment(PatchSet.Id ps,
String path,
CommentInfo i) {
PatchLineComment p = new PatchLineComment(
new PatchLineComment.Key(
new Patch.Key(ps, path),
i.id()),
i.line(),
Gerrit.getUserAccount().getId(),
i.inReplyTo(),
i.updated());
p.setMessage(i.message());
p.setSide((short) (i.side() == Side.PARENT ? 0 : 1));
return p;
}
}

View File

@@ -1,117 +0,0 @@
// Copyright (C) 2010 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.patches;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.StarredChanges;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.ui.ChangeLink;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.PreElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwtexpui.clippy.client.CopyableLabel;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
class CommitMessageBlock extends Composite {
interface Binder extends UiBinder<HTMLPanel, CommitMessageBlock> {}
private static final Binder uiBinder = GWT.create(Binder.class);
private KeyCommandSet keysAction;
@UiField
SimplePanel starPanel;
@UiField
FlowPanel permalinkPanel;
@UiField
PreElement commitSummaryPre;
@UiField
PreElement commitBodyPre;
CommitMessageBlock() {
initWidget(uiBinder.createAndBindUi(this));
}
CommitMessageBlock(KeyCommandSet keysAction) {
this.keysAction = keysAction;
initWidget(uiBinder.createAndBindUi(this));
}
void display(String commitMessage,
CommentLinkProcessor commentLinkProcessor) {
display(null, null, null, commitMessage, commentLinkProcessor);
}
void display(final PatchSet.Id patchSetId, final String revision,
Boolean starred, final String commitMessage,
CommentLinkProcessor commentLinkProcessor) {
starPanel.clear();
if (patchSetId != null && starred != null && Gerrit.isSignedIn()) {
Change.Id changeId = patchSetId.getParentKey();
StarredChanges.Icon star = StarredChanges.createIcon(changeId, starred);
star.setStyleName(Gerrit.RESOURCES.css().changeScreenStarIcon());
starPanel.add(star);
if (keysAction != null) {
keysAction.add(StarredChanges.newKeyCommand(star));
}
}
permalinkPanel.clear();
if (patchSetId != null && revision != null) {
final Change.Id changeId = patchSetId.getParentKey();
permalinkPanel.add(new ChangeLink(Util.C.changePermalink(), changeId));
permalinkPanel.add(new CopyableLabel(ChangeLink.permalink(changeId),
false));
}
String[] splitCommitMessage = commitMessage.split("\n", 2);
String commitSummary = splitCommitMessage[0];
String commitBody = "";
if (splitCommitMessage.length > 1) {
commitBody = splitCommitMessage[1];
}
// Linkify commit summary
SafeHtml commitSummaryLinkified = new SafeHtmlBuilder().append(commitSummary);
commitSummaryLinkified = commitSummaryLinkified.linkify();
commitSummaryLinkified = commentLinkProcessor.apply(commitSummaryLinkified);
commitSummaryPre.setInnerHTML(commitSummaryLinkified.asString());
// Hide commit body if there is no body
if (commitBody.trim().isEmpty()) {
commitBodyPre.getStyle().setDisplay(Display.NONE);
} else {
// Linkify commit body
SafeHtml commitBodyLinkified = new SafeHtmlBuilder().append(commitBody);
commitBodyLinkified = commitBodyLinkified.linkify();
commitBodyLinkified = commentLinkProcessor.apply(commitBodyLinkified);
commitBodyLinkified = commitBodyLinkified.replaceAll("\n\n", "<p></p>");
commitBodyLinkified = commitBodyLinkified.replaceAll("\n", "<br />");
commitBodyPre.setInnerHTML(commitBodyLinkified.asString());
}
}
}

View File

@@ -1,102 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2012 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.
-->
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='res' type='com.google.gerrit.client.GerritResources'/>
<ui:style gss='false'>
@eval selectionColor com.google.gerrit.client.Gerrit.getTheme().selectionColor;
@eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
@eval backgroundColor com.google.gerrit.client.Gerrit.getTheme().backgroundColor;
.commitMessageTable {
border-collapse: separate;
border-spacing: 0;
margin-bottom: 10px;
}
.header {
background-color: trimColor;
white-space: nowrap;
color: textColor;
font-size: 10pt;
font-style: italic;
padding: 2px 6px 1px;
}
.contents {
border-bottom: 1px solid trimColor;
border-left: 1px solid trimColor;
border-right: 1px solid trimColor;
padding: 5px;
}
.contents span {
font-weight: bold;
}
.contents pre {
margin: 0;
}
.commitSummary {
font-weight: bold;
}
.commitBody p {
padding-top: 0px;
}
.starPanel {
float: left;
}
.boxTitle {
float: left;
margin-right: 10px;
}
.permalinkPanel {
float: right;
}
.permalinkPanel a {
float: left;
}
.permalinkPanel div {
display: inline;
}
</ui:style>
<g:HTMLPanel>
<table class='{style.commitMessageTable}'>
<tr><td class='{style.header}'>
<g:SimplePanel styleName='{style.starPanel}' ui:field='starPanel'></g:SimplePanel>
<div class='{style.boxTitle}'>Commit Message</div>
<g:FlowPanel styleName='{style.permalinkPanel}' ui:field='permalinkPanel'></g:FlowPanel>
</td></tr>
<tr><td class='{style.contents}'>
<pre class='{style.commitSummary} {res.css.changeScreenDescription}' ui:field='commitSummaryPre'/>
<pre class='{style.commitBody} {res.css.changeScreenDescription}' ui:field='commitBodyPre'/>
</td></tr>
</table>
</g:HTMLPanel>
</ui:UiBinder>

View File

@@ -1,155 +0,0 @@
// Copyright (C) 2009 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.patches;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.ui.FancyFlexTable;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.RadioButton;
import java.util.ArrayList;
import java.util.List;
/**
* A table used to specify which two patch sets should be diff'ed.
*/
class HistoryTable extends FancyFlexTable<Patch> {
private final UnifiedPatchScreen screen;
final List<HistoryRadio> all = new ArrayList<>();
HistoryTable(final UnifiedPatchScreen parent) {
setStyleName(Gerrit.RESOURCES.css().patchHistoryTable());
screen = parent;
table.setWidth("auto");
table.addStyleName(Gerrit.RESOURCES.css().changeTable());
}
void onClick(final HistoryRadio b) {
PatchSet.Id sideA = screen.idSideA;
PatchSet.Id sideB = screen.idSideB;
switch (b.file) {
case 0:
sideA = b.patchSetId;
break;
case 1:
sideB = b.patchSetId;
break;
default:
return;
}
enableAll(false);
Patch.Key k = new Patch.Key(sideB, screen.getPatchKey().get());
Gerrit.display(Dispatcher.toUnified(sideA, k));
}
void enableAll(final boolean on) {
for (final HistoryRadio a : all) {
a.setEnabled(on);
}
}
void display(final List<Patch> result) {
all.clear();
final FlexCellFormatter fmt = table.getFlexCellFormatter();
table.setText(0, 0, PatchUtil.C.patchHeaderPatchSet());
fmt.setStyleName(0, 0, Gerrit.RESOURCES.css().dataHeader());
table.setText(1, 0, PatchUtil.C.patchHeaderOld());
fmt.setStyleName(1, 0, Gerrit.RESOURCES.css().dataHeader());
table.setText(2, 0, PatchUtil.C.patchHeaderNew());
fmt.setStyleName(2, 0, Gerrit.RESOURCES.css().dataHeader());
table.setText(3, 0, Util.C.patchTableColumnComments());
fmt.setStyleName(3, 0, Gerrit.RESOURCES.css().dataHeader());
if (screen.getPatchSetDetail().getInfo().getParents().size() > 1) {
table.setText(0, 1, PatchUtil.C.patchBaseAutoMerge());
} else {
table.setText(0, 1, PatchUtil.C.patchBase());
}
fmt.setStyleName(0, 1, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().topMostCell());
fmt.setStyleName(1, 1, Gerrit.RESOURCES.css().dataCell());
fmt.setStyleName(2, 1, Gerrit.RESOURCES.css().dataCell());
fmt.setStyleName(3, 1, Gerrit.RESOURCES.css().dataCell());
installRadio(1, 1, null, screen.idSideA, 0);
int col=2;
for (final Patch k : result) {
final PatchSet.Id psId = k.getKey().getParentKey();
table.setText(0, col, String.valueOf(psId.get()));
fmt.setStyleName(0, col, Gerrit.RESOURCES.css().patchHistoryTablePatchSetHeader());
fmt.addStyleName(0, col, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(0, col, Gerrit.RESOURCES.css().topMostCell());
installRadio(1, col, psId, screen.idSideA, 0);
installRadio(2, col, psId, screen.idSideB, 1);
fmt.setStyleName(3, col, Gerrit.RESOURCES.css().dataCell());
if (k.getCommentCount() > 0) {
table.setText(3, col, Integer.toString(k.getCommentCount()));
}
col++;
}
}
private void installRadio(final int row, final int col, final PatchSet.Id psId,
final PatchSet.Id cur, final int file) {
final HistoryRadio b = new HistoryRadio(psId, file);
b.setValue(eq(cur, psId));
table.setWidget(row, col, b);
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.setHorizontalAlignment(row, col, HasHorizontalAlignment.ALIGN_CENTER);
fmt.setStyleName(row, col, Gerrit.RESOURCES.css().dataCell());
all.add(b);
}
private boolean eq(final PatchSet.Id cur, final PatchSet.Id psid) {
if (cur == null && psid == null) {
return true;
}
return psid != null && psid.equals(cur);
}
private class HistoryRadio extends RadioButton {
final PatchSet.Id patchSetId;
final int file;
HistoryRadio(final PatchSet.Id ps, final int f) {
super(String.valueOf(f));
sinkEvents(Event.ONCLICK);
patchSetId = ps;
file = f;
}
@Override
public void onBrowserEvent(final Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONCLICK:
onClick(this);
break;
default:
super.onBrowserEvent(event);
}
}
}
}

View File

@@ -1,135 +0,0 @@
// Copyright (C) 2010 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.patches;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.info.WebLinkInfo;
import com.google.gerrit.client.ui.ChangeLink;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import java.util.List;
class NavLinks extends Composite {
public enum Nav {
PREV (0, '[', PatchUtil.C.previousFileHelp(), 0),
NEXT (4, ']', PatchUtil.C.nextFileHelp(), 1);
public int col; // Table Cell column to display link in
public int key; // key code shortcut to activate link
public String help; // help string for '?' popup
public int cmd; // index into cmds array
Nav(int c, int k, String h, int i) {
this.col = c;
this.key = k;
this.help = h;
this.cmd = i;
}
}
private final PatchSet.Id patchSetId;
private final KeyCommandSet keys;
private final Grid table;
private KeyCommand[] cmds = new KeyCommand[2];
NavLinks(KeyCommandSet kcs, PatchSet.Id forPatch) {
patchSetId = forPatch;
keys = kcs;
table = new Grid(1, 5);
initWidget(table);
final CellFormatter fmt = table.getCellFormatter();
table.setStyleName(Gerrit.RESOURCES.css().sideBySideScreenLinkTable());
fmt.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_LEFT);
fmt.setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_CENTER);
fmt.setHorizontalAlignment(0, 2, HasHorizontalAlignment.ALIGN_RIGHT);
fmt.setHorizontalAlignment(0, 3, HasHorizontalAlignment.ALIGN_RIGHT);
fmt.setHorizontalAlignment(0, 4, HasHorizontalAlignment.ALIGN_RIGHT);
final ChangeLink up = new ChangeLink("", patchSetId);
SafeHtml.set(up, SafeHtml.asis(Util.C.upToChangeIconLink()));
table.setWidget(0, 1, up);
}
void display(int patchIndex, PatchTable fileList,
List<InlineHyperlink> links, List<WebLinkInfo> webLinks) {
if (fileList != null) {
Label fileCountLabel =
new Label(Gerrit.M.fileCount(patchIndex + 1, fileList.size()));
fileCountLabel.setStyleName(Gerrit.RESOURCES.css().nowrap());
table.setWidget(0, 3, fileCountLabel);
setupNav(Nav.PREV, fileList.getPreviousPatchLink(patchIndex));
setupNav(Nav.NEXT, fileList.getNextPatchLink(patchIndex));
} else {
setupNav(Nav.PREV, null);
setupNav(Nav.NEXT, null);
}
FlowPanel linkPanel = new FlowPanel();
linkPanel.setStyleName(Gerrit.RESOURCES.css().linkPanel());
for (InlineHyperlink link : links) {
linkPanel.add(link);
}
for (WebLinkInfo webLink : webLinks) {
linkPanel.add(webLink.toAnchor());
}
table.setWidget(0, 2, linkPanel);
}
protected void setupNav(final Nav nav, final InlineHyperlink link) {
/* setup the cells */
if (link != null) {
link.addStyleName(Gerrit.RESOURCES.css().nowrap());
table.setWidget(0, nav.col, link);
} else {
table.clearCell(0, nav.col);
}
/* setup the keys */
if (keys != null) {
if (cmds[nav.cmd] != null) {
keys.remove(cmds[nav.cmd]);
}
if (link != null) {
cmds[nav.cmd] = new KeyCommand(0, nav.key, nav.help) {
@Override
public void onKeyPress(KeyPressEvent event) {
link.go();
}
};
} else {
cmds[nav.cmd] = new UpToChangeCommand(patchSetId, 0, nav.key);
}
keys.add(cmds[nav.cmd]);
}
}
}

View File

@@ -1,119 +0,0 @@
// Copyright (C) 2009 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.patches;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.reviewdb.client.Patch;
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.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.globalkey.client.HidePopupPanelCommand;
class PatchBrowserPopup extends DialogBox implements
PositionCallback, ResizeHandler {
private final Patch.Key callerKey;
private final PatchTable fileList;
private final ScrollPanel sp;
private HandlerRegistration regWindowResize;
PatchBrowserPopup(final Patch.Key pk, final PatchTable fl) {
super(true/* autohide */, false/* modal */);
callerKey = pk;
fileList = fl;
sp = new ScrollPanel(fileList);
final FlowPanel body = new FlowPanel();
body.setStyleName(Gerrit.RESOURCES.css().patchBrowserPopupBody());
body.add(sp);
setText(Util.M.patchSetHeader(callerKey.getParentKey().get()));
setWidget(body);
addStyleName(Gerrit.RESOURCES.css().patchBrowserPopup());
}
@Override
public void setPosition(final int myWidth, int myHeight) {
final int dLeft = (Window.getClientWidth() - myWidth) >> 1;
final int cHeight = Window.getClientHeight();
final int cHeight2 = 2 * cHeight / 3;
final int sLeft = Window.getScrollLeft();
final int sTop = Window.getScrollTop();
if (myHeight > cHeight2) {
sp.setHeight((cHeight2 - 50) + "px");
myHeight = getOffsetHeight();
}
setPopupPosition(sLeft + dLeft, (sTop + cHeight) - (myHeight + 10));
}
@Override
public void onResize(final ResizeEvent event) {
sp.setWidth((Window.getClientWidth() - 60) + "px");
setPosition(getOffsetWidth(), getOffsetHeight());
}
@Override
public void hide() {
if (regWindowResize != null) {
regWindowResize.removeHandler();
regWindowResize = null;
}
super.hide();
}
@Override
public void show() {
super.show();
if (regWindowResize == null) {
regWindowResize = Window.addResizeHandler(this);
}
GlobalKey.dialog(this);
GlobalKey.addApplication(this, new HidePopupPanelCommand(0, 'f', this));
if (!fileList.isLoaded()) {
fileList.onTableLoaded(new Command() {
@Override
public void execute() {
sp.setHeight("");
setPosition(getOffsetWidth(), getOffsetHeight());
fileList.setRegisterKeys(true);
fileList.movePointerTo(callerKey);
}
});
}
}
public void open() {
if (!fileList.isLoaded()) {
sp.setHeight("22px");
}
sp.setWidth((Window.getClientWidth() - 60) + "px");
setPopupPositionAndShow(this);
if (fileList.isLoaded()) {
fileList.setRegisterKeys(true);
fileList.movePointerTo(callerKey);
}
}
}

View File

@@ -17,49 +17,25 @@ package com.google.gerrit.client.patches;
import com.google.gwt.i18n.client.Constants;
public interface PatchConstants extends Constants {
String draft();
String buttonReply();
String buttonEdit();
String buttonSave();
String buttonCancel();
String buttonDiscard();
String noDifference();
String patchBase();
String patchBaseAutoMerge();
String patchHeaderPatchSet();
String patchHeaderOld();
String patchHeaderNew();
String patchSet();
String patchHistoryTitle();
String disabledOnLargeFiles();
String intralineFailure();
String intralineTimeout();
String illegalNumberOfColumns();
String upToChange();
String openReply();
String linePrev();
String lineNext();
String chunkPrev();
String chunkNext();
String chunkPrev2();
String chunkNext2();
String commentPrev();
String commentNext();
String focusSideA();
String focusSideB();
String fileList();
String expandComment();
String expandAllCommentsOnCurrentLine();
String toggleSideA();
String toggleIntraline();
String showPreferences();
String openEditScreen();
String toggleReviewed();
String markAsReviewedAndGoToNext();
@@ -76,22 +52,12 @@ public interface PatchConstants extends Constants {
String previousFileHelp();
String nextFileHelp();
String reviewedAnd();
String next();
String download();
String edit();
String addFileCommentToolTip();
String addFileCommentByDoubleClick();
String buttonReplyDone();
String cannedReplyDone();
String fileTypeSymlink();
String fileTypeGitlink();
String patchSkipRegionStart();
String patchSkipRegionEnd();
String sideBySideDiff();
String unifiedDiff();
}

View File

@@ -1,46 +1,24 @@
draft = (Draft)
buttonReply = Reply ...
buttonReplyDone = Reply 'Done'
cannedReplyDone = Done
buttonEdit = Edit
buttonSave = Save
buttonCancel = Cancel
buttonDiscard = Discard
noDifference = No Differences
patchBase = Base
patchBaseAutoMerge = Auto Merge
patchHeaderPatchSet = Patch Set
patchHeaderOld = Old Version
patchHeaderNew = New Version
patchHistoryTitle = Patch History
patchSet = Patch Set
disabledOnLargeFiles = Disabled on very large source files.
intralineFailure = Intraline difference not available due to server error.
intralineTimeout = Intraline difference not available due to timeout.
illegalNumberOfColumns = The number of columns cannot be zero or negative
upToChange = Up to change
openReply = Reply and score
linePrev = Previous line
lineNext = Next line
chunkPrev = Previous diff chunk or comment
chunkNext = Next diff chunk or comment
chunkPrev2 = Previous diff chunk
chunkNext2 = Next diff chunk or search result
chunkPrev = Previous diff chunk
chunkNext = Next diff chunk or search result
commentPrev = Previous comment
commentNext = Next comment
focusSideA = Focus left side
focusSideB = Focus right side
fileList = Browse files in patch set
expandComment = Expand or collapse comment
expandAllCommentsOnCurrentLine = Expand or collapse all comments on current line
toggleSideA = Toggle left side
toggleIntraline = Toggle intraline difference
showPreferences = Show diff preferences
openEditScreen = Edit file in browser
toggleReviewed = Toggle the reviewed flag
markAsReviewedAndGoToNext = Mark patch as reviewed and go to next unreviewed patch
@@ -57,18 +35,9 @@ whitespaceIGNORE_ALL=All
previousFileHelp = Previous file
nextFileHelp = Next file
reviewedAnd = Reviewed &
next = next
download = Download
edit = Edit
addFileCommentToolTip = Click to add file comment
addFileCommentByDoubleClick = Double click to add file comment
fileTypeSymlink = Type: Symbolic Link
fileTypeGitlink = Type: Git Commit in Subproject
patchSkipRegionStart = ... skipped
patchSkipRegionEnd = common lines ...
sideBySideDiff = Side-by-side diff
unifiedDiff = Unified diff

View File

@@ -1,43 +0,0 @@
// Copyright (C) 2008 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.patches;
class PatchLine {
static enum Type {
DELETE, INSERT, REPLACE, CONTEXT
}
private PatchLine.Type type;
private int lineA;
private int lineB;
PatchLine(final PatchLine.Type t, final int a, final int b) {
type = t;
lineA = a;
lineB = b;
}
PatchLine.Type getType() {
return type;
}
int getLineA() {
return lineA;
}
int getLineB() {
return lineB;
}
}

View File

@@ -16,12 +16,9 @@ package com.google.gerrit.client.patches;
import com.google.gwt.i18n.client.Messages;
import java.util.Date;
public interface PatchMessages extends Messages {
String expandBefore(int cnt);
String expandAfter(int cnt);
String draftSaved(Date when);
String patchSkipRegion(String lineNumber);
String fileNameWithShortcutKey(String file, String key);
}

View File

@@ -1,5 +1,4 @@
expandBefore = +{0}&#x21e7;
expandAfter = +{0}&#x21e9;
draftSaved = Draft saved at {0,time,short}
patchSkipRegion = ... skipped {0} common lines ...
fileNameWithShortcutKey = {0} (Shortcut: {1})

View File

@@ -1,3 +1,4 @@
expandBefore = +{0}&#x21e7;
expandAfter = +{0}&#x21e9;
patchSkipRegion = ... skipped {0} common lines ...
fileNameWithShortcutKey = {0} (Shortcut: {1})

View File

@@ -1,347 +0,0 @@
// Copyright (C) 2010 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.patches;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.Util;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
import com.google.gerrit.client.ui.NpIntTextBox;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.OptionElement;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
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.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtjsonrpc.common.VoidResult;
public class PatchScriptSettingsPanel extends Composite {
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
interface MyUiBinder extends UiBinder<Widget, PatchScriptSettingsPanel> {
}
private final ListenableAccountDiffPreference listenablePrefs;
private boolean enableIntralineDifference = true;
private boolean enableSmallFileFeatures = true;
@UiField
ListBox ignoreWhitespace;
@UiField
NpIntTextBox tabWidth;
@UiField
NpIntTextBox colWidth;
@UiField
CheckBox syntaxHighlighting;
@UiField
CheckBox intralineDifference;
@UiField
ListBox context;
@UiField
CheckBox whitespaceErrors;
@UiField
CheckBox showLineEndings;
@UiField
CheckBox showTabs;
@UiField
CheckBox manualReview;
@UiField
CheckBox skipDeleted;
@UiField
CheckBox skipUncommented;
@UiField
CheckBox expandAllComments;
@UiField
CheckBox retainHeader;
@UiField
Button update;
@UiField
Button save;
/**
* Counts +1 for every setEnabled(true) and -1 for every setEnabled(false)
*
* The purpose is to prevent enabling widgets too early. It might happen that
* setEnabled(false) is called from this class and from an event handler
* of ValueChangeEvent in another class. The first setEnabled(true) would then
* enable widgets too early i.e. before the second setEnabled(true) is called.
*
* With this counter the setEnabled(true) will enable widgets only when
* setEnabledCounter == 0. Until it is less than zero setEnabled(true) will
* not enable the widgets.
*/
private int setEnabledCounter;
public PatchScriptSettingsPanel(ListenableAccountDiffPreference prefs) {
listenablePrefs = prefs;
initWidget(uiBinder.createAndBindUi(this));
initIgnoreWhitespace(ignoreWhitespace);
initContext(context);
if (!Gerrit.isSignedIn()) {
save.setVisible(false);
}
KeyPressHandler onEnter = new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
save();
}
}
};
tabWidth.addKeyPressHandler(onEnter);
colWidth.addKeyPressHandler(onEnter);
display();
}
public void setEnabled(final boolean on) {
if (on) {
setEnabledCounter++;
} else {
setEnabledCounter--;
}
if (on && setEnabledCounter == 0 || !on) {
for (Widget w : (HasWidgets) getWidget()) {
if (w instanceof FocusWidget) {
((FocusWidget) w).setEnabled(on);
}
}
toggleEnabledStatus(on);
}
}
public void setEnableSmallFileFeatures(final boolean on) {
enableSmallFileFeatures = on;
if (enableSmallFileFeatures) {
syntaxHighlighting.setValue(getValue().syntaxHighlighting);
} else {
syntaxHighlighting.setValue(false);
}
NodeList<OptionElement> options =
context.getElement().<SelectElement>cast().getOptions();
// WHOLE_FILE_CONTEXT is the last option in the list.
int lastIndex = options.getLength() - 1;
OptionElement currOption = options.getItem(lastIndex);
if (enableSmallFileFeatures) {
currOption.setDisabled(false);
} else {
currOption.setDisabled(true);
if (context.getSelectedIndex() == lastIndex) {
// Select the next longest context from WHOLE_FILE_CONTEXT
context.setSelectedIndex(lastIndex - 1);
}
}
toggleEnabledStatus(save.isEnabled());
}
public void setEnableIntralineDifference(final boolean on) {
enableIntralineDifference = on;
if (enableIntralineDifference) {
intralineDifference.setValue(getValue().intralineDifference);
} else {
intralineDifference.setValue(false);
}
toggleEnabledStatus(save.isEnabled());
}
private void toggleEnabledStatus(final boolean on) {
intralineDifference.setEnabled(on & enableIntralineDifference);
syntaxHighlighting.setEnabled(on & enableSmallFileFeatures);
final String title =
enableSmallFileFeatures ? null : PatchUtil.C.disabledOnLargeFiles();
syntaxHighlighting.setTitle(title);
}
public DiffPreferencesInfo getValue() {
return listenablePrefs.get();
}
public void setValue(final DiffPreferencesInfo dp) {
listenablePrefs.set(dp);
display();
}
protected void display() {
final DiffPreferencesInfo dp = getValue();
setIgnoreWhitespace(dp.ignoreWhitespace);
if (enableSmallFileFeatures) {
syntaxHighlighting.setValue(dp.syntaxHighlighting);
} else {
syntaxHighlighting.setValue(false);
}
setContext(dp.context);
tabWidth.setIntValue(dp.tabSize);
colWidth.setIntValue(dp.lineLength);
intralineDifference.setValue(dp.intralineDifference);
whitespaceErrors.setValue(dp.showWhitespaceErrors);
showLineEndings.setValue(dp.showLineEndings);
showTabs.setValue(dp.showTabs);
skipDeleted.setValue(dp.skipDeleted);
skipUncommented.setValue(dp.skipUncommented);
expandAllComments.setValue(dp.expandAllComments);
retainHeader.setValue(dp.retainHeader);
manualReview.setValue(dp.manualReview);
}
@UiHandler("update")
void onUpdate(@SuppressWarnings("unused") ClickEvent event) {
update();
}
@UiHandler("save")
void onSave(@SuppressWarnings("unused") ClickEvent event) {
save();
}
private void update() {
if (colWidth.getIntValue() <= 0) {
new ErrorDialog(PatchUtil.C.illegalNumberOfColumns()).center();
return;
}
DiffPreferencesInfo dp = getValue();
dp.ignoreWhitespace = getIgnoreWhitespace();
dp.context = getContext();
dp.tabSize = tabWidth.getIntValue();
dp.lineLength = colWidth.getIntValue();
dp.syntaxHighlighting = syntaxHighlighting.getValue();
dp.intralineDifference = intralineDifference.getValue();
dp.showWhitespaceErrors = whitespaceErrors.getValue();
dp.showLineEndings = showLineEndings.getValue();
dp.showTabs = showTabs.getValue();
dp.skipDeleted = skipDeleted.getValue();
dp.skipUncommented = skipUncommented.getValue();
dp.expandAllComments = expandAllComments.getValue();
dp.retainHeader = retainHeader.getValue();
dp.manualReview = manualReview.getValue();
listenablePrefs.set(dp);
}
private void save() {
update();
if (Gerrit.isSignedIn()) {
persistDiffPreferences();
}
}
private void persistDiffPreferences() {
setEnabled(false);
listenablePrefs.save(new GerritCallback<VoidResult>() {
@Override
public void onSuccess(VoidResult result) {
setEnabled(true);
}
@Override
public void onFailure(Throwable caught) {
setEnabled(true);
}
});
}
private void initIgnoreWhitespace(ListBox ws) {
ws.addItem(PatchUtil.C.whitespaceIGNORE_NONE(), //
Whitespace.IGNORE_NONE.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_TRAILING(), //
Whitespace.IGNORE_TRAILING.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_LEADING_AND_TRAILING(), //
Whitespace.IGNORE_LEADING_AND_TRAILING.name());
ws.addItem(PatchUtil.C.whitespaceIGNORE_ALL(), //
Whitespace.IGNORE_ALL.name());
}
private void initContext(ListBox context) {
for (final short v : DiffPreferencesInfo.CONTEXT_CHOICES) {
final String label;
if (v == DiffPreferencesInfo.WHOLE_FILE_CONTEXT) {
label = Util.C.contextWholeFile();
} else {
label = Util.M.lines(v);
}
context.addItem(label, String.valueOf(v));
}
}
private Whitespace getIgnoreWhitespace() {
final int sel = ignoreWhitespace.getSelectedIndex();
if (0 <= sel) {
return Whitespace.valueOf(ignoreWhitespace.getValue(sel));
}
return getValue().ignoreWhitespace;
}
private void setIgnoreWhitespace(Whitespace s) {
for (int i = 0; i < ignoreWhitespace.getItemCount(); i++) {
if (ignoreWhitespace.getValue(i).equals(s.name())) {
ignoreWhitespace.setSelectedIndex(i);
return;
}
}
ignoreWhitespace.setSelectedIndex(0);
}
private int getContext() {
final int sel = context.getSelectedIndex();
if (0 <= sel) {
return Short.parseShort(context.getValue(sel));
}
return getValue().context;
}
private void setContext(int ctx) {
String v = String.valueOf(ctx);
for (int i = 0; i < context.getItemCount(); i++) {
if (context.getValue(i).equals(v)) {
context.setSelectedIndex(i);
return;
}
}
context.setSelectedIndex(0);
}
}

View File

@@ -1,209 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 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.
-->
<ui:UiBinder
xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:my='urn:import:com.google.gerrit.client.ui'
ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat'
ui:generateKeys='com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator'
ui:generateLocales='default,en'
>
<ui:style gss='false'>
@external .gwt-TextBox;
@external .gwt-ListBox;
@def fontSize 8pt;
.controls {
border: none;
border-collapse: separate;
border-spacing: 0;
}
.controls td {
font-size: fontSize;
padding: 0;
white-space: nowrap;
}
.controls .gwt-TextBox {
font-size: fontSize;
padding: 0;
text-align: right;
}
.controls .gwt-ListBox {
font-size: fontSize;
padding: 0;
margin-right: 1em;
}
.updateButton {
margin-left: 1em;
margin-right: 1em;
font-size: fontSize;
}
</ui:style>
<g:HTMLPanel>
<table class='{style.controls}'>
<tr valign='top'>
<ui:msg>
<td align='right'>Ignore Whitespace:</td>
<td align='right'>
<g:ListBox
ui:field='ignoreWhitespace'
visibleItemCount='1'
tabIndex='1'/>
</td>
</ui:msg>
<td align='right'>
<ui:msg>Tab Width:
<my:NpIntTextBox
ui:field='tabWidth'
width='2em'
visibleLength='2'
maxLength='2'
tabIndex='3'/>
</ui:msg>
</td>
<td rowspan='2'>
<g:CheckBox
ui:field='syntaxHighlighting'
text='Syntax Coloring'
tabIndex='5'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='intralineDifference'
text='Intraline Difference'
tabIndex='6'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td rowspan='2'>
<g:CheckBox
ui:field='whitespaceErrors'
text='Whitespace Errors'
tabIndex='7'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='showLineEndings'
text='Show Line Endings'
tabIndex='8'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td rowspan='2'>
<g:CheckBox
ui:field='showTabs'
text='Show Tabs'
tabIndex='9'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='expandAllComments'
text='Expand All Comments'
tabIndex='10'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td rowspan='2'>
<g:CheckBox
ui:field='retainHeader'
text='Retain Header On File Switch'
tabIndex='11'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='skipUncommented'
text='Skip Uncommented Files'
tabIndex='12'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td valign='bottom' rowspan='2'>
<g:CheckBox
ui:field='skipDeleted'
text='Skip Deleted Files'
tabIndex='13'>
<ui:attribute name='text'/>
</g:CheckBox>
<br/>
<g:CheckBox
ui:field='manualReview'
text='Manual Review'
tabIndex='14'>
<ui:attribute name='text'/>
</g:CheckBox>
</td>
<td rowspan='2'>
<br/>
<g:Button
ui:field='update'
text='Update'
styleName='{style.updateButton}'
tabIndex='15'>
<ui:attribute name='text'/>
</g:Button>
<g:Button
ui:field='save'
text='Save'
styleName='{style.updateButton}'
tabIndex='16'>
<ui:attribute name='text'/>
</g:Button>
</td>
</tr>
<tr valign='top'>
<ui:msg>
<td align='right'>Context:</td>
<td align='right'>
<g:ListBox
ui:field='context'
visibleItemCount='1'
tabIndex='2'/>
</td>
</ui:msg>
<td align='right'>
<ui:msg>Columns:
<my:NpIntTextBox
ui:field='colWidth'
width='2.5em'
visibleLength='3'
maxLength='3'
tabIndex='4'/>
</ui:msg>
</td>
</tr>
</table>
</g:HTMLPanel>
</ui:UiBinder>

View File

@@ -1,188 +0,0 @@
// Copyright (C) 2012 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.patches;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchSetDetail;
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.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
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.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwtorm.client.KeyUtil;
import java.util.HashMap;
import java.util.Map;
public class PatchSetSelectBox extends Composite {
interface Binder extends UiBinder<HTMLPanel, PatchSetSelectBox> {}
private static final Binder uiBinder = GWT.create(Binder.class);
interface BoxStyle extends CssResource {
String selected();
String hidden();
String sideMarker();
String patchSetLabel();
}
public enum Side {
A, B
}
PatchScript script;
Patch.Key patchKey;
PatchSet.Id idSideA;
PatchSet.Id idSideB;
PatchSet.Id idActive;
Side side;
Map<Integer, Anchor> links;
private Label patchSet;
@UiField
HTMLPanel linkPanel;
@UiField
BoxStyle style;
public PatchSetSelectBox(Side side) {
this.side = side;
initWidget(uiBinder.createAndBindUi(this));
}
public void display(final PatchSetDetail detail, final PatchScript script,
Patch.Key key, PatchSet.Id idSideA, PatchSet.Id idSideB) {
this.script = script;
this.patchKey = key;
this.idSideA = idSideA;
this.idSideB = idSideB;
this.idActive = (side == Side.A) ? idSideA : idSideB;
this.links = new HashMap<>();
linkPanel.clear();
if (isFileOrCommitMessage()) {
linkPanel.setTitle(PatchUtil.C.addFileCommentByDoubleClick());
}
patchSet = new Label(PatchUtil.C.patchSet());
patchSet.addStyleName(style.patchSetLabel());
linkPanel.add(patchSet);
Label sideMarker = new Label((side == Side.A) ? "(-)" : "(+)");
sideMarker.addStyleName(style.sideMarker());
linkPanel.add(sideMarker);
Anchor baseLink;
if (detail.getInfo().getParents().size() > 1) {
baseLink = createLink(PatchUtil.C.patchBaseAutoMerge(), null);
} else {
baseLink = createLink(PatchUtil.C.patchBase(), null);
}
links.put(0, baseLink);
linkPanel.add(baseLink);
if (side == Side.B) {
links.get(0).setStyleName(style.hidden());
}
for (Patch patch : script.getHistory()) {
PatchSet.Id psId = patch.getKey().getParentKey();
Anchor anchor = createLink(psId.getId(), psId);
links.put(psId.get(), anchor);
linkPanel.add(anchor);
}
if (idActive == null && side == Side.A) {
links.get(0).setStyleName(style.selected());
} else if (idActive != null) {
links.get(idActive.get()).setStyleName(style.selected());
}
Anchor downloadLink = createDownloadLink();
if (downloadLink != null) {
linkPanel.add(downloadLink);
}
}
public void addDoubleClickHandler(DoubleClickHandler handler) {
linkPanel.sinkEvents(Event.ONDBLCLICK);
linkPanel.addHandler(handler, DoubleClickEvent.getType());
patchSet.addDoubleClickHandler(handler);
}
private Anchor createLink(String label, final PatchSet.Id id) {
final Anchor anchor = new Anchor(label);
anchor.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (side == Side.A) {
idSideA = id;
} else {
idSideB = id;
}
Patch.Key keySideB = new Patch.Key(idSideB, patchKey.get());
Gerrit.display(Dispatcher.toUnified(idSideA, keySideB));
}
});
return anchor;
}
public boolean isFileOrCommitMessage() {
return !((side == Side.A && 0 >= script.getA().size()) || //
(side == Side.B && 0 >= script.getB().size()));
}
private Anchor createDownloadLink() {
boolean isCommitMessage = Patch.COMMIT_MSG.equals(script.getNewName());
if (isCommitMessage || //
(side == Side.A && 0 >= script.getA().size()) || //
(side == Side.B && 0 >= script.getB().size())) {
return null;
}
Patch.Key key = (idActive == null) ? //
patchKey : (new Patch.Key(idActive, patchKey.get()));
String sideURL = (idActive == null) ? "1" : "0";
final String base = GWT.getHostPageBaseURL() + "cat/";
Image image = new Image(Gerrit.RESOURCES.downloadIcon());
final Anchor anchor = new Anchor();
anchor.setHref(base + KeyUtil.encode(key.toString()) + "^" + sideURL);
anchor.setTitle(PatchUtil.C.download());
DOM.insertBefore(anchor.getElement(), image.getElement(),
DOM.getFirstChild(anchor.getElement()));
return anchor;
}
}

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2012 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.
-->
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='res' type='com.google.gerrit.client.GerritResources'/>
<ui:style gss='false' type='com.google.gerrit.client.patches.PatchSetSelectBox.BoxStyle'>
@eval selectionColor com.google.gerrit.client.Gerrit.getTheme().selectionColor;
@eval backgroundColor com.google.gerrit.client.Gerrit.getTheme().backgroundColor;
.linkPanel {
font-size: 12px;
white-space: normal;
}
.linkPanel > div {
padding-left: 3px;
padding-right: 3px;
vertical-align: middle;
display: inline-block;
}
.patchSetLabel {
font-weight: bold;
}
.sideMarker {
font-family: monospace;
}
.linkPanel > a {
padding-left: 3px;
padding-right: 3px;
text-decoration: none;
vertical-align: middle;
display: inline-block;
}
.selected {
font-weight: bold;
background-color: selectionColor;
}
.hidden {
visibility: hidden;
}
</ui:style>
<g:HTMLPanel>
<g:HTMLPanel styleName='{style.linkPanel}' ui:field='linkPanel'/>
</g:HTMLPanel>
</ui:UiBinder>

View File

@@ -1,901 +0,0 @@
// Copyright (C) 2008 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.patches;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.client.ui.PatchLink;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.Patch.PatchType;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.progress.client.ProgressBar;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class PatchTable extends Composite {
interface PatchValidator {
/**
* @param patch
* @return true if patch is valid.
*/
boolean isValid(Patch patch);
}
final PatchValidator PREFERENCE_VALIDATOR =
new PatchValidator() {
@Override
public boolean isValid(Patch patch) {
return !((listenablePrefs.get().skipDeleted
&& patch.getChangeType().equals(ChangeType.DELETED))
|| (listenablePrefs.get().skipUncommented
&& patch.getCommentCount() == 0));
}
};
private final FlowPanel myBody;
private PatchSetDetail detail;
private Command onLoadCommand;
private MyTable myTable;
private String savePointerId;
private PatchSet.Id base;
private List<Patch> patchList;
private Map<Patch.Key, Integer> patchMap;
private ListenableAccountDiffPreference listenablePrefs;
private List<ClickHandler> clickHandlers;
private boolean active;
private boolean registerKeys;
PatchTable(ListenableAccountDiffPreference prefs) {
listenablePrefs = prefs;
myBody = new FlowPanel();
initWidget(myBody);
}
PatchTable() {
this(new ListenableAccountDiffPreference());
}
int indexOf(Patch.Key patch) {
Integer i = patchMap().get(patch);
return i != null ? i : -1;
}
int size() {
return patchMap.size();
}
private Map<Patch.Key, Integer> patchMap() {
if (patchMap == null) {
patchMap = new HashMap<>();
for (int i = 0; i < patchList.size(); i++) {
patchMap.put(patchList.get(i).getKey(), i);
}
}
return patchMap;
}
void display(PatchSet.Id base, PatchSetDetail detail) {
this.base = base;
this.detail = detail;
this.patchList = detail.getPatches();
this.patchMap = null;
myTable = null;
final DisplayCommand cmd = new DisplayCommand(patchList, base);
if (cmd.execute()) {
cmd.initMeter();
Scheduler.get().scheduleIncremental(cmd);
} else {
cmd.showTable();
}
}
PatchSet.Id getBase() {
return base;
}
void setSavePointerId(final String id) {
savePointerId = id;
}
boolean isLoaded() {
return myTable != null;
}
void onTableLoaded(final Command cmd) {
if (myTable != null) {
cmd.execute();
} else {
onLoadCommand = cmd;
}
}
void addClickHandler(final ClickHandler clickHandler) {
if (myTable != null) {
myTable.addClickHandler(clickHandler);
} else {
if (clickHandlers == null) {
clickHandlers = new ArrayList<>(2);
}
clickHandlers.add(clickHandler);
}
}
void setRegisterKeys(final boolean on) {
registerKeys = on;
if (myTable != null) {
myTable.setRegisterKeys(on);
}
}
void movePointerTo(final Patch.Key k) {
if (myTable != null) {
myTable.movePointerTo(k);
}
}
void setActive(boolean active) {
this.active = active;
if (myTable != null) {
myTable.setActive(active);
}
}
void notifyDraftDelta(final Patch.Key k, final int delta) {
if (myTable != null) {
myTable.notifyDraftDelta(k, delta);
}
}
private void setMyTable(MyTable table) {
myBody.clear();
myBody.add(table);
myTable = table;
if (clickHandlers != null) {
for (ClickHandler ch : clickHandlers) {
myTable.addClickHandler(ch);
}
clickHandlers = null;
}
if (active) {
myTable.setActive(true);
active = false;
}
if (registerKeys) {
myTable.setRegisterKeys(registerKeys);
registerKeys = false;
}
myTable.finishDisplay();
}
/**
* @return a link to the previous file in this patch set, or null.
*/
InlineHyperlink getPreviousPatchLink(int index) {
int previousPatchIndex = getPreviousPatch(index, PREFERENCE_VALIDATOR);
if (previousPatchIndex < 0) {
return null;
}
return createLink(previousPatchIndex,
SafeHtml.asis(Util.C.prevPatchLinkIcon()), null);
}
/**
* @return a link to the next file in this patch set, or null.
*/
InlineHyperlink getNextPatchLink(int index) {
int nextPatchIndex = getNextPatch(index, false, PREFERENCE_VALIDATOR);
if (nextPatchIndex < 0) {
return null;
}
return createLink(nextPatchIndex, null,
SafeHtml.asis(Util.C.nextPatchLinkIcon()));
}
/**
* @return a link to the the given patch.
* @param index The patch to link to
* @param before A string to display at the beginning of the href text
* @param after A string to display at the end of the href text
*/
PatchLink createLink(int index, SafeHtml before, SafeHtml after) {
Patch patch = patchList.get(index);
Patch.Key thisKey = patch.getKey();
PatchLink link;
if (isUnifiedPatchLink(patch)) {
link = new PatchLink.Unified("", base, thisKey);
} else {
link = new PatchLink.SideBySide("", base, thisKey);
}
SafeHtmlBuilder text = new SafeHtmlBuilder();
text.append(before);
text.append(getFileNameOnly(patch));
text.append(after);
SafeHtml.set(link, text);
return link;
}
private static boolean isUnifiedPatchLink(final Patch patch) {
return (patch.getPatchType().equals(PatchType.BINARY)
|| (Gerrit.isSignedIn()
&& Gerrit.getUserPreferences().diffView()
.equals(DiffView.UNIFIED_DIFF)));
}
private static String getFileNameOnly(Patch patch) {
// Note: use '/' here and not File.pathSeparator since git paths
// are always separated by /
//
String fileName = getDisplayFileName(patch);
int s = fileName.lastIndexOf('/');
if (s >= 0) {
fileName = fileName.substring(s + 1);
}
return fileName;
}
static String getDisplayFileName(Patch patch) {
return getDisplayFileName(patch.getKey());
}
static String getDisplayFileName(Patch.Key patchKey) {
if (Patch.COMMIT_MSG.equals(patchKey.get())) {
return Util.C.commitMessage();
}
return patchKey.get();
}
/**
* Update the reviewed status for the given patch.
*/
void updateReviewedStatus(Patch.Key patchKey, boolean reviewed) {
if (myTable != null) {
myTable.updateReviewedStatus(patchKey, reviewed);
}
}
ListenableAccountDiffPreference getPreferences() {
return listenablePrefs;
}
private class MyTable extends NavigationTable<Patch> {
private static final int C_PATH = 2;
private static final int C_DRAFT = 3;
private static final int C_SIZE = 4;
private static final int C_SIDEBYSIDE = 5;
private int activeRow = -1;
MyTable() {
keysNavigation.add(new PrevKeyCommand(0, 'k', Util.C.patchTablePrev()));
keysNavigation.add(new NextKeyCommand(0, 'j', Util.C.patchTableNext()));
keysNavigation.add(new OpenKeyCommand(0, 'o', Util.C.patchTableOpenDiff()));
keysNavigation.add(new OpenKeyCommand(0, KeyCodes.KEY_ENTER, Util.C
.patchTableOpenDiff()));
keysNavigation.add(new OpenUnifiedDiffKeyCommand(0, 'O', Util.C
.patchTableOpenUnifiedDiff()));
table.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
final Cell cell = table.getCellForEvent(event);
if (cell != null && cell.getRowIndex() > 0) {
movePointerTo(cell.getRowIndex());
}
}
});
setSavePointerId(PatchTable.this.savePointerId);
}
public void addClickHandler(final ClickHandler clickHandler) {
table.addClickHandler(clickHandler);
}
void updateReviewedStatus(final Patch.Key patchKey, boolean reviewed) {
int idx = patchMap().get(patchKey);
if (0 <= idx) {
Patch patch = patchList.get(idx);
if (patch.isReviewedByCurrentUser() != reviewed) {
int row = idx + 1;
int col = C_SIDEBYSIDE + 2;
if (patch.getPatchType() == Patch.PatchType.BINARY) {
col = C_SIDEBYSIDE + 3;
}
if (reviewed) {
table.setWidget(row, col, new Image(Gerrit.RESOURCES.greenCheck()));
} else {
table.clearCell(row, col);
}
patch.setReviewedByCurrentUser(reviewed);
}
}
}
void notifyDraftDelta(final Patch.Key key, final int delta) {
int idx = patchMap().get(key);
if (0 <= idx) {
Patch p = patchList.get(idx);
p.setDraftCount(p.getDraftCount() + delta);
SafeHtmlBuilder m = new SafeHtmlBuilder();
appendCommentCount(m, p);
SafeHtml.set(table, idx + 1, C_DRAFT, m);
}
}
@Override
public void resetHtml(final SafeHtml html) {
super.resetHtml(html);
}
@Override
public void movePointerTo(Object oldId) {
super.movePointerTo(oldId);
}
/** Activates / Deactivates the key navigation and the highlighting of the current row for this table */
void setActive(boolean active) {
if (active) {
if(activeRow > 0 && getCurrentRow() != activeRow) {
super.movePointerTo(activeRow);
activeRow = -1;
}
} else {
if(getCurrentRow() > 0) {
activeRow = getCurrentRow();
super.movePointerTo(-1);
}
}
setRegisterKeys(active);
}
void initializeRow(int row) {
Patch patch = PatchTable.this.patchList.get(row - 1);
setRowItem(row, patch);
Widget nameCol = new PatchLink.SideBySide(getDisplayFileName(patch), base,
patch.getKey());
if (patch.getSourceFileName() != null) {
final String text;
if (patch.getChangeType() == Patch.ChangeType.RENAMED) {
text = Util.M.renamedFrom(patch.getSourceFileName());
} else if (patch.getChangeType() == Patch.ChangeType.COPIED) {
text = Util.M.copiedFrom(patch.getSourceFileName());
} else {
text = Util.M.otherFrom(patch.getSourceFileName());
}
final Label line = new Label(text);
line.setStyleName(Gerrit.RESOURCES.css().sourceFilePath());
final FlowPanel cell = new FlowPanel();
cell.add(nameCol);
cell.add(line);
nameCol = cell;
}
table.setWidget(row, C_PATH, nameCol);
int C_UNIFIED = C_SIDEBYSIDE + 1;
PatchLink sideBySide = new PatchLink.SideBySide(
Util.C.patchTableDiffSideBySide(), base, patch.getKey());
sideBySide.setStyleName("gwt-Anchor");
PatchLink unified = new PatchLink.Unified(Util.C.patchTableDiffUnified(),
base, patch.getKey());
unified.setStyleName("gwt-Anchor");
table.setWidget(row, C_SIDEBYSIDE, sideBySide);
table.setWidget(row, C_UNIFIED, unified);
}
void initializeLastRow(int row) {
Anchor sideBySide = new Anchor(Util.C.diffAllSideBySide());
sideBySide.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
for (Patch p : detail.getPatches()) {
openWindow(Dispatcher.toSideBySide(base, p.getKey()));
}
}
});
table.setWidget(row, C_SIDEBYSIDE - 2, sideBySide);
int C_UNIFIED = C_SIDEBYSIDE - 2 + 1;
Anchor unified = new Anchor(Util.C.diffAllUnified());
unified.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
for (Patch p : detail.getPatches()) {
openWindow(Dispatcher.toUnified(base, p.getKey()));
}
}
});
table.setWidget(row, C_UNIFIED, unified);
}
private void openWindow(String token) {
String url = Window.Location.getPath() + "#" + token;
Window.open(url, "_blank", null);
}
void appendHeader(final SafeHtmlBuilder m) {
m.openTr();
// Cursor
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().iconHeader());
m.addStyleName(Gerrit.RESOURCES.css().leftMostCell());
m.nbsp();
m.closeTd();
// Mode
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().iconHeader());
m.nbsp();
m.closeTd();
// "File path"
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
m.append(Util.C.patchTableColumnName());
m.closeTd();
// "Comments"
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
m.append(Util.C.patchTableColumnComments());
m.closeTd();
// "Size"
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
m.append(Util.C.patchTableColumnSize());
m.closeTd();
// "Diff"
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().dataHeader());
m.setAttribute("colspan", 3);
m.append(Util.C.patchTableColumnDiff());
m.closeTd();
// "Reviewed"
if (Gerrit.isSignedIn()) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().iconHeader());
m.addStyleName(Gerrit.RESOURCES.css().dataHeader());
m.append(Util.C.reviewed());
m.closeTd();
}
m.closeTr();
}
void appendRow(final SafeHtmlBuilder m, final Patch p,
final boolean isReverseDiff) {
m.openTr();
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().iconCell());
m.addStyleName(Gerrit.RESOURCES.css().leftMostCell());
m.nbsp();
m.closeTd();
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().changeTypeCell());
if (isReverseDiff) {
m.addStyleName(Gerrit.RESOURCES.css().patchCellReverseDiff());
}
if (Patch.COMMIT_MSG.equals(p.getFileName())) {
m.nbsp();
} else {
m.append(p.getChangeType().getCode());
}
m.closeTd();
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().dataCell());
m.addStyleName(Gerrit.RESOURCES.css().filePathCell());
m.closeTd();
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().dataCell());
m.addStyleName(Gerrit.RESOURCES.css().commentCell());
appendCommentCount(m, p);
m.closeTd();
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().dataCell());
m.addStyleName(Gerrit.RESOURCES.css().patchSizeCell());
if (isReverseDiff) {
m.addStyleName(Gerrit.RESOURCES.css().patchCellReverseDiff());
}
appendSize(m, p);
m.closeTd();
// Diff
openlink(m, 2);
m.closeTd();
openlink(m, 1);
m.closeTd();
// Green check mark if the user is logged in and they reviewed that file
if (Gerrit.isSignedIn()) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().dataCell());
if (p.isReviewedByCurrentUser()) {
m.openDiv();
m.setStyleName(Gerrit.RESOURCES.css().greenCheckClass());
m.closeSelf();
}
m.closeTd();
}
m.closeTr();
}
void appendLastRow(final SafeHtmlBuilder m, int ins, int dels,
final boolean isReverseDiff) {
m.openTr();
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().iconCell());
m.addStyleName(Gerrit.RESOURCES.css().noborder());
m.nbsp();
m.closeTd();
m.openTd();
m.setAttribute("colspan", C_SIZE - 1);
m.closeTd();
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().dataCell());
m.addStyleName(Gerrit.RESOURCES.css().patchSizeCell());
m.addStyleName(Gerrit.RESOURCES.css().leftMostCell());
if (isReverseDiff) {
m.addStyleName(Gerrit.RESOURCES.css().patchCellReverseDiff());
}
m.append(Util.M.patchTableSize_Modify(ins, dels));
m.closeTd();
openlink(m, 2);
m.closeTd();
openlink(m, 1);
m.closeTd();
m.closeTr();
}
void appendCommentCount(final SafeHtmlBuilder m, final Patch p) {
if (p.getCommentCount() > 0) {
m.append(Util.M.patchTableComments(p.getCommentCount()));
}
if (p.getDraftCount() > 0) {
if (p.getCommentCount() > 0) {
m.append(", ");
}
m.openSpan();
m.setStyleName(Gerrit.RESOURCES.css().drafts());
m.append(Util.M.patchTableDrafts(p.getDraftCount()));
m.closeSpan();
}
}
void appendSize(final SafeHtmlBuilder m, final Patch p) {
if (Patch.COMMIT_MSG.equals(p.getFileName())) {
m.nbsp();
return;
}
if (p.getPatchType() == PatchType.UNIFIED) {
int ins = p.getInsertions();
int dels = p.getDeletions();
switch (p.getChangeType()) {
case ADDED:
m.append(Util.M.patchTableSize_Lines(ins));
break;
case DELETED:
m.nbsp();
break;
case MODIFIED:
case COPIED:
case RENAMED:
m.append(Util.M.patchTableSize_Modify(ins, dels));
break;
case REWRITE:
break;
}
} else {
m.nbsp();
}
}
private void openlink(final SafeHtmlBuilder m, final int colspan) {
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().dataCell());
m.addStyleName(Gerrit.RESOURCES.css().diffLinkCell());
m.setAttribute("colspan", colspan);
}
@Override
protected Object getRowItemKey(final Patch item) {
return item.getKey();
}
@Override
protected void onOpenRow(final int row) {
Widget link = table.getWidget(row, C_PATH);
if (link instanceof FlowPanel) {
link = ((FlowPanel) link).getWidget(0);
}
if (link instanceof InlineHyperlink) {
((InlineHyperlink) link).go();
}
}
private final class OpenUnifiedDiffKeyCommand extends KeyCommand {
public OpenUnifiedDiffKeyCommand(int mask, char key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(KeyPressEvent event) {
Widget link = table.getWidget(getCurrentRow(), C_PATH);
if (link instanceof FlowPanel) {
link = ((FlowPanel) link).getWidget(0);
}
if (link instanceof PatchLink.Unified) {
((InlineHyperlink) link).go();
} else {
link = table.getWidget(getCurrentRow(), C_SIDEBYSIDE + 1);
if (link instanceof PatchLink.Unified) {
((InlineHyperlink) link).go();
}
}
}
}
}
private final class DisplayCommand implements RepeatingCommand {
private final MyTable table;
private final List<Patch> list;
private boolean attached;
private SafeHtmlBuilder nc = new SafeHtmlBuilder();
private int stage = 0;
private int row;
private double start;
private ProgressBar meter;
private int insertions;
private int deletions;
private final PatchSet.Id psIdToCompareWith;
private DisplayCommand(final List<Patch> list, final PatchSet.Id psIdToCompareWith) {
this.table = new MyTable();
this.list = list;
this.psIdToCompareWith = psIdToCompareWith;
}
/**
* Add the files contained in the list of patches to the table, one per row.
*/
@Override
@SuppressWarnings("fallthrough")
public boolean execute() {
final boolean attachedNow = isAttached();
if (!attached && attachedNow) {
// Remember that we have been attached at least once. If
// later we find we aren't attached we should stop running.
//
attached = true;
} else if (attached && !attachedNow) {
// If the user navigated away, we aren't in the DOM anymore.
// Don't continue to render.
//
return false;
}
boolean isReverseDiff = false;
if (psIdToCompareWith != null
&& list.get(0).getKey().getParentKey().get() < psIdToCompareWith.get()) {
isReverseDiff = true;
}
start = System.currentTimeMillis();
switch (stage) {
case 0:
if (row == 0) {
table.appendHeader(nc);
table.appendRow(nc, list.get(row++), isReverseDiff);
}
while (row < list.size()) {
Patch p = list.get(row);
insertions += p.getInsertions();
deletions += p.getDeletions();
table.appendRow(nc, p, isReverseDiff);
if ((++row % 10) == 0 && longRunning()) {
updateMeter();
return true;
}
}
table.appendLastRow(nc, insertions, deletions, isReverseDiff);
table.resetHtml(nc);
table.initializeLastRow(row + 1);
nc = null;
stage = 1;
row = 0;
case 1:
while (row < list.size()) {
table.initializeRow(row + 1);
if ((++row % 50) == 0 && longRunning()) {
updateMeter();
return true;
}
}
updateMeter();
showTable();
}
return false;
}
void showTable() {
setMyTable(table);
if (PatchTable.this.onLoadCommand != null) {
PatchTable.this.onLoadCommand.execute();
PatchTable.this.onLoadCommand = null;
}
}
void initMeter() {
if (meter == null) {
meter = new ProgressBar(Util.M.loadingPatchSet(detail.getPatchSet().getId().get()));
PatchTable.this.myBody.clear();
PatchTable.this.myBody.add(meter);
}
updateMeter();
}
void updateMeter() {
if (meter != null) {
final int n = list.size();
meter.setValue(((100 * (stage * n + row)) / (2 * n)));
}
}
private boolean longRunning() {
return System.currentTimeMillis() - start > 200;
}
}
/**
* Gets the next patch
*
* @param currentIndex
* @param validators
* @param loopAround loops back around to the front and traverses if this is
* true
* @return index of next valid patch, or -1 if no valid patches
*/
int getNextPatch(int currentIndex, boolean loopAround,
PatchValidator... validators) {
return getNextPatchHelper(currentIndex, loopAround, detail.getPatches()
.size(), validators);
}
/**
* Helper function for getNextPatch
*
* @param currentIndex
* @param validators
* @param loopAround
* @param maxIndex will only traverse up to this index
* @return index of next valid patch, or -1 if no valid patches
*/
private int getNextPatchHelper(int currentIndex, boolean loopAround,
int maxIndex, PatchValidator... validators) {
for (int i = currentIndex + 1; i < maxIndex; i++) {
Patch patch = detail.getPatches().get(i);
if (patch != null && patchIsValid(patch, validators)) {
return i;
}
}
if (loopAround) {
return getNextPatchHelper(-1, false, currentIndex, validators);
}
return -1;
}
/**
* @return the index to the previous patch
*/
int getPreviousPatch(int currentIndex, PatchValidator... validators) {
for (int i = currentIndex - 1; i >= 0; i--) {
Patch patch = detail.getPatches().get(i);
if (patch != null && patchIsValid(patch, validators)) {
return i;
}
}
return -1;
}
/**
* Helper function that returns whether a patch is valid or not
*
* @param patch
* @param validators
* @return whether the patch is valid based on the validators
*/
private boolean patchIsValid(Patch patch, PatchValidator... validators) {
for (PatchValidator v : validators) {
if (!v.isValid(patch)) {
return false;
}
}
return true;
}
}

View File

@@ -14,22 +14,9 @@
package com.google.gerrit.client.patches;
import com.google.gerrit.common.data.ChangeDetailService;
import com.google.gerrit.common.data.PatchDetailService;
import com.google.gwt.core.client.GWT;
import com.google.gwtjsonrpc.client.JsonUtil;
public class PatchUtil {
public static final PatchConstants C = GWT.create(PatchConstants.class);
public static final PatchMessages M = GWT.create(PatchMessages.class);
public static final ChangeDetailService CHANGE_SVC;
public static final PatchDetailService PATCH_SVC;
static {
CHANGE_SVC = GWT.create(ChangeDetailService.class);
JsonUtil.bind(CHANGE_SVC, "rpc/ChangeDetailService");
PATCH_SVC = GWT.create(PatchDetailService.class);
JsonUtil.bind(PATCH_SVC, "rpc/PatchDetailService");
}
}

View File

@@ -1,176 +0,0 @@
// Copyright (C) 2012 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.patches;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.patches.PatchTable.PatchValidator;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.client.ui.ChangeLink;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
class ReviewedPanels {
final FlowPanel top;
final FlowPanel bottom;
private Patch.Key patchKey;
private PatchTable fileList;
private InlineHyperlink reviewedLink;
private CheckBox checkBoxTop;
private CheckBox checkBoxBottom;
ReviewedPanels() {
this.top = new FlowPanel();
this.bottom = new FlowPanel();
this.bottom.setStyleName(Gerrit.RESOURCES.css().reviewedPanelBottom());
}
void populate(Patch.Key pk, PatchTable pt, int patchIndex) {
patchKey = pk;
fileList = pt;
reviewedLink = createReviewedLink(patchIndex);
top.clear();
checkBoxTop = createReviewedCheckbox();
top.add(checkBoxTop);
top.add(createReviewedAnchor());
bottom.clear();
checkBoxBottom = createReviewedCheckbox();
bottom.add(checkBoxBottom);
bottom.add(createReviewedAnchor());
}
private CheckBox createReviewedCheckbox() {
final CheckBox checkBox = new CheckBox(PatchUtil.C.reviewedAnd() + " ");
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
final boolean value = event.getValue();
setReviewedByCurrentUser(value);
if (checkBoxTop.getValue() != value) {
checkBoxTop.setValue(value);
}
if (checkBoxBottom.getValue() != value) {
checkBoxBottom.setValue(value);
}
}
});
return checkBox;
}
boolean getValue() {
return checkBoxTop.getValue();
}
void setValue(final boolean value) {
checkBoxTop.setValue(value);
checkBoxBottom.setValue(value);
}
void setReviewedByCurrentUser(boolean reviewed) {
PatchSet.Id ps = patchKey.getParentKey();
if (ps.get() != 0) {
if (fileList != null) {
fileList.updateReviewedStatus(patchKey, reviewed);
}
RestApi api = new RestApi("/changes/").id(ps.getParentKey().get())
.view("revisions").id(ps.get())
.view("files").id(patchKey.getFileName())
.view("reviewed");
AsyncCallback<VoidResult> cb = new AsyncCallback<VoidResult>() {
@Override
public void onFailure(Throwable arg0) {
// nop
}
@Override
public void onSuccess(VoidResult result) {
// nop
}
};
if (reviewed) {
api.put(cb);
} else {
api.delete(cb);
}
}
}
void go() {
if (reviewedLink != null) {
setReviewedByCurrentUser(true);
reviewedLink.go();
}
}
private InlineHyperlink createReviewedLink(final int patchIndex) {
final PatchValidator unreviewedValidator = new PatchValidator() {
@Override
public boolean isValid(Patch patch) {
return !patch.isReviewedByCurrentUser();
}
};
InlineHyperlink reviewedLink = new ChangeLink("", patchKey.getParentKey());
if (fileList != null) {
int nextUnreviewedPatchIndex =
fileList.getNextPatch(patchIndex, true, unreviewedValidator,
fileList.PREFERENCE_VALIDATOR);
if (nextUnreviewedPatchIndex > -1) {
// Create invisible patch link to change page
reviewedLink =
fileList.createLink(nextUnreviewedPatchIndex, null, null);
reviewedLink.setText("");
}
}
return reviewedLink;
}
private Anchor createReviewedAnchor() {
SafeHtmlBuilder text = new SafeHtmlBuilder();
text.append(PatchUtil.C.next());
text.append(SafeHtml.asis(Util.C.nextPatchLinkIcon()));
Anchor reviewedAnchor = new Anchor("");
SafeHtml.set(reviewedAnchor, text);
reviewedAnchor.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
setReviewedByCurrentUser(true);
reviewedLink.go();
}
});
return reviewedAnchor;
}
}

View File

@@ -1,643 +0,0 @@
// Copyright (C) 2008 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.patches;
import static com.google.gerrit.client.patches.PatchLine.Type.CONTEXT;
import static com.google.gerrit.client.patches.PatchLine.Type.DELETE;
import static com.google.gerrit.client.patches.PatchLine.Type.INSERT;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchScript.DisplayMethod;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.prettify.client.SparseHtmlFile;
import com.google.gerrit.prettify.common.EditList;
import com.google.gerrit.prettify.common.EditList.Hunk;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
public class UnifiedDiffTable extends AbstractPatchContentTable {
private static final int PC = 3;
private static final Comparator<PatchLineComment> BY_DATE =
new Comparator<PatchLineComment>() {
@Override
public int compare(final PatchLineComment o1, final PatchLineComment o2) {
return o1.getWrittenOn().compareTo(o2.getWrittenOn());
}
};
protected boolean isFileCommentBorderRowExist;
// Cursors.
protected int rowOfTableHeaderB;
protected int borderRowOfFileComment;
@Override
protected void onCellDoubleClick(final int row, final int column) {
if (column > C_ARROW && getRowItem(row) instanceof PatchLine) {
final PatchLine pl = (PatchLine) getRowItem(row);
switch (pl.getType()) {
case DELETE:
case CONTEXT:
createCommentEditor(row + 1, PC, pl.getLineA(), (short) 0);
break;
case INSERT:
createCommentEditor(row + 1, PC, pl.getLineB(), (short) 1);
break;
case REPLACE:
break;
}
}
}
@Override
protected void updateCursor(final PatchLineComment newComment) {
if (newComment.getLine() == R_HEAD) {
final PatchSet.Id psId =
newComment.getKey().getParentKey().getParentKey();
switch (newComment.getSide()) {
case FILE_SIDE_A:
if (idSideA == null && idSideB.equals(psId)) {
rowOfTableHeaderB++;
borderRowOfFileComment++;
return;
}
break;
case FILE_SIDE_B:
if (idSideA != null && idSideA.equals(psId)) {
rowOfTableHeaderB++;
borderRowOfFileComment++;
} else if (idSideB.equals(psId)) {
borderRowOfFileComment++;
}
}
}
}
@Override
protected void onCellSingleClick(Event event, int row, int column) {
super.onCellSingleClick(event, row, column);
if (column == 1 || column == 2) {
if (!"".equals(table.getText(row, column))) {
onCellDoubleClick(row, column);
}
}
}
@Override
protected void destroyCommentRow(final int row) {
super.destroyCommentRow(row);
if (this.rowOfTableHeaderB + 1 == row && row + 1 == borderRowOfFileComment) {
table.removeRow(row);
isFileCommentBorderRowExist = false;
}
}
@Override
public void remove(CommentEditorPanel panel) {
super.remove(panel);
if (panel.getComment().getLine() == AbstractPatchContentTable.R_HEAD) {
final PatchSet.Id psId =
panel.getComment().getKey().getParentKey().getParentKey();
switch (panel.getComment().getSide()) {
case FILE_SIDE_A:
if (idSideA == null && idSideB.equals(psId)) {
rowOfTableHeaderB--;
borderRowOfFileComment--;
return;
}
break;
case FILE_SIDE_B:
if (idSideA != null && idSideA.equals(psId)) {
rowOfTableHeaderB--;
borderRowOfFileComment--;
} else if (idSideB.equals(psId)) {
borderRowOfFileComment--;
}
}
}
}
@Override
protected void onInsertComment(final PatchLine pl) {
final int row = getCurrentRow();
switch (pl.getType()) {
case DELETE:
case CONTEXT:
createCommentEditor(row + 1, PC, pl.getLineA(), (short) 0);
break;
case INSERT:
createCommentEditor(row + 1, PC, pl.getLineB(), (short) 1);
break;
case REPLACE:
break;
}
}
private void appendImgTag(SafeHtmlBuilder nc, String url) {
nc.openElement("img");
nc.setAttribute("src", url);
nc.closeElement("img");
}
@Override
protected void createFileCommentEditorOnSideA() {
createCommentEditor(R_HEAD + 1, PC, R_HEAD, FILE_SIDE_A);
}
@Override
protected void createFileCommentEditorOnSideB() {
createCommentEditor(rowOfTableHeaderB + 1, PC, R_HEAD, FILE_SIDE_B);
createFileCommentBorderRow();
}
private void populateTableHeader(final PatchScript script,
final PatchSetDetail detail) {
initHeaders(script, detail);
table.setWidget(R_HEAD, PC, headerSideA);
table.setWidget(rowOfTableHeaderB, PC, headerSideB);
table.getFlexCellFormatter().addStyleName(R_HEAD, PC,
Gerrit.RESOURCES.css().unifiedTableHeader());
table.getFlexCellFormatter().addStyleName(rowOfTableHeaderB, PC,
Gerrit.RESOURCES.css().unifiedTableHeader());
// Add icons to lineNumber column header
if (headerSideA.isFileOrCommitMessage()) {
table.setWidget(R_HEAD, 1, iconA);
}
if (headerSideB.isFileOrCommitMessage()) {
table.setWidget(rowOfTableHeaderB, 2, iconB);
}
}
private void allocateTableHeader(SafeHtmlBuilder nc) {
rowOfTableHeaderB = 1;
borderRowOfFileComment = 2;
for (int i = R_HEAD; i < borderRowOfFileComment; i++) {
openTableHeaderLine(nc);
padLineNumberOnTableHeaderForSideA(nc);
padLineNumberOnTableHeaderForSideB(nc);
nc.openTd();
nc.setStyleName(Gerrit.RESOURCES.css().fileLine());
nc.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
nc.closeTd();
closeLine(nc);
}
}
@Override
protected void render(final PatchScript script, final PatchSetDetail detail) {
final SafeHtmlBuilder nc = new SafeHtmlBuilder();
allocateTableHeader(nc);
// Display the patch header
for (final String line : script.getPatchHeader()) {
appendFileHeader(nc, line);
}
final ArrayList<PatchLine> lines = new ArrayList<>();
if (hasDifferences(script)) {
if (script.getDisplayMethodA() == DisplayMethod.IMG
|| script.getDisplayMethodB() == DisplayMethod.IMG) {
appendImageDifferences(script, nc);
} else if (!isDisplayBinary) {
appendTextDifferences(script, nc, lines);
}
} else {
appendNoDifferences(nc);
}
resetHtml(nc);
populateTableHeader(script, detail);
if (hasDifferences(script)) {
initScript(script);
if (!isDisplayBinary) {
int row = script.getPatchHeader().size();
final CellFormatter fmt = table.getCellFormatter();
final Iterator<PatchLine> iLine = lines.iterator();
while (iLine.hasNext()) {
final PatchLine l = iLine.next();
final String n;
switch (l.getType()) {
case CONTEXT:
n = Gerrit.RESOURCES.css().diffTextCONTEXT();
break;
case DELETE:
n = Gerrit.RESOURCES.css().diffTextDELETE();
break;
case INSERT:
n = Gerrit.RESOURCES.css().diffTextINSERT();
break;
case REPLACE:
default:
continue;
}
while (!fmt.getStyleName(row, PC).contains(n)) {
row++;
}
setRowItem(row++, l);
}
}
}
}
private void appendImageLine(final SafeHtmlBuilder nc, final String url,
final boolean syntaxHighlighting, final boolean isInsert) {
nc.openTr();
nc.setAttribute("valign", "center");
nc.setAttribute("align", "center");
nc.openTd();
nc.setStyleName(Gerrit.RESOURCES.css().iconCell());
nc.closeTd();
padLineNumberForSideA(nc);
padLineNumberForSideB(nc);
nc.openTd();
nc.setStyleName(Gerrit.RESOURCES.css().fileLine());
if (isInsert) {
setStyleInsert(nc, syntaxHighlighting);
} else {
setStyleDelete(nc, syntaxHighlighting);
}
appendImgTag(nc, url);
nc.closeTd();
nc.closeTr();
}
private void appendImageDifferences(final PatchScript script,
final SafeHtmlBuilder nc) {
final boolean syntaxHighlighting =
script.getDiffPrefs().syntaxHighlighting;
if (script.getDisplayMethodA() == DisplayMethod.IMG) {
final String url = getUrlA();
appendImageLine(nc, url, syntaxHighlighting, false);
}
if (script.getDisplayMethodB() == DisplayMethod.IMG) {
final String url = getUrlB();
appendImageLine(nc, url, syntaxHighlighting, true);
}
}
private void appendTextDifferences(final PatchScript script,
final SafeHtmlBuilder nc, final ArrayList<PatchLine> lines) {
final SparseHtmlFile a = getSparseHtmlFileA(script);
final SparseHtmlFile b = getSparseHtmlFileB(script);
final boolean syntaxHighlighting =
script.getDiffPrefs().syntaxHighlighting;
for (final EditList.Hunk hunk : script.getHunks()) {
appendHunkHeader(nc, hunk);
while (hunk.next()) {
if (hunk.isContextLine()) {
openLine(nc);
appendLineNumberForSideA(nc, hunk.getCurA());
appendLineNumberForSideB(nc, hunk.getCurB());
appendLineText(nc, false, CONTEXT, a, hunk.getCurA());
closeLine(nc);
hunk.incBoth();
lines.add(new PatchLine(CONTEXT, hunk.getCurA(), hunk.getCurB()));
} else if (hunk.isDeletedA()) {
openLine(nc);
appendLineNumberForSideA(nc, hunk.getCurA());
padLineNumberForSideB(nc);
appendLineText(nc, syntaxHighlighting, DELETE, a, hunk.getCurA());
closeLine(nc);
hunk.incA();
lines.add(new PatchLine(DELETE, hunk.getCurA(), -1));
if (a.size() == hunk.getCurA()
&& script.getA().isMissingNewlineAtEnd()) {
appendNoLF(nc);
}
} else if (hunk.isInsertedB()) {
openLine(nc);
padLineNumberForSideA(nc);
appendLineNumberForSideB(nc, hunk.getCurB());
appendLineText(nc, syntaxHighlighting, INSERT, b, hunk.getCurB());
closeLine(nc);
hunk.incB();
lines.add(new PatchLine(INSERT, -1, hunk.getCurB()));
if (b.size() == hunk.getCurB()
&& script.getB().isMissingNewlineAtEnd()) {
appendNoLF(nc);
}
}
}
}
}
@Override
public void display(final CommentDetail cd, boolean expandComments) {
if (cd == null || cd.isEmpty()) {
return;
}
setAccountInfoCache(cd.getAccounts());
final ArrayList<PatchLineComment> all = new ArrayList<>();
for (int row = 0; row < table.getRowCount();) {
final List<PatchLineComment> fora;
final List<PatchLineComment> forb;
if (row == R_HEAD) {
fora = cd.getForA(R_HEAD);
forb = cd.getForB(R_HEAD);
row++;
if (!fora.isEmpty()) {
row = insert(fora, row);
}
rowOfTableHeaderB = row;
borderRowOfFileComment = row + 1;
if (!forb.isEmpty()) {
row++;// Skip the Header of sideB.
row = insert(forb, row);
borderRowOfFileComment = row;
createFileCommentBorderRow();
}
} else if (getRowItem(row) instanceof PatchLine) {
final PatchLine pLine = (PatchLine) getRowItem(row);
fora = cd.getForA(pLine.getLineA());
forb = cd.getForB(pLine.getLineB());
row++;
if (!fora.isEmpty() && !forb.isEmpty()) {
all.clear();
all.addAll(fora);
all.addAll(forb);
Collections.sort(all, BY_DATE);
row = insert(all, row);
} else if (!fora.isEmpty()) {
row = insert(fora, row);
} else if (!forb.isEmpty()) {
row = insert(forb, row);
}
} else {
row++;
continue;
}
}
}
private void defaultStyle(final int row, final CellFormatter fmt) {
fmt.addStyleName(row, PC - 2, Gerrit.RESOURCES.css().lineNumber());
fmt.addStyleName(row, PC - 2, Gerrit.RESOURCES.css().rightBorder());
fmt.addStyleName(row, PC - 1, Gerrit.RESOURCES.css().lineNumber());
fmt.addStyleName(row, PC, Gerrit.RESOURCES.css().diffText());
}
@Override
protected void insertRow(final int row) {
super.insertRow(row);
final CellFormatter fmt = table.getCellFormatter();
defaultStyle(row, fmt);
}
private int insert(final List<PatchLineComment> in, int row) {
for (Iterator<PatchLineComment> ci = in.iterator(); ci.hasNext();) {
final PatchLineComment c = ci.next();
if (c.getLine() == R_HEAD) {
insertFileCommentRow(row);
} else {
insertRow(row);
}
bindComment(row, PC, c, !ci.hasNext());
row++;
}
return row;
}
@Override
protected void insertFileCommentRow(final int row) {
table.insertRow(row);
final CellFormatter fmt = table.getCellFormatter();
fmt.addStyleName(row, C_ARROW, //
Gerrit.RESOURCES.css().iconCellOfFileCommentRow());
defaultStyle(row, fmt);
fmt.addStyleName(row, C_ARROW, //
Gerrit.RESOURCES.css().cellsNextToFileComment());
fmt.addStyleName(row, PC - 2, //
Gerrit.RESOURCES.css().cellsNextToFileComment());
fmt.addStyleName(row, PC - 1, //
Gerrit.RESOURCES.css().cellsNextToFileComment());
}
private void createFileCommentBorderRow() {
if (!isFileCommentBorderRowExist) {
isFileCommentBorderRowExist = true;
table.insertRow(borderRowOfFileComment);
final CellFormatter fmt = table.getCellFormatter();
fmt.addStyleName(borderRowOfFileComment, C_ARROW, //
Gerrit.RESOURCES.css().iconCellOfFileCommentRow());
defaultStyle(borderRowOfFileComment, fmt);
final Element iconCell =
fmt.getElement(borderRowOfFileComment, C_ARROW);
UIObject.setStyleName(DOM.getParent(iconCell), //
Gerrit.RESOURCES.css().fileCommentBorder(), true);
}
}
private void appendFileHeader(final SafeHtmlBuilder m, final String line) {
openLine(m);
padLineNumberForSideA(m);
padLineNumberForSideB(m);
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().fileLine());
m.addStyleName(Gerrit.RESOURCES.css().diffText());
m.addStyleName(Gerrit.RESOURCES.css().diffTextFileHeader());
m.append(line);
m.closeTd();
closeLine(m);
}
private void appendHunkHeader(final SafeHtmlBuilder m, final Hunk hunk) {
openLine(m);
padLineNumberForSideA(m);
padLineNumberForSideB(m);
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().fileLine());
m.addStyleName(Gerrit.RESOURCES.css().diffText());
m.addStyleName(Gerrit.RESOURCES.css().diffTextHunkHeader());
m.append("@@ -");
appendRange(m, hunk.getCurA() + 1, hunk.getEndA() - hunk.getCurA());
m.append(" +");
appendRange(m, hunk.getCurB() + 1, hunk.getEndB() - hunk.getCurB());
m.append(" @@");
m.closeTd();
closeLine(m);
}
private void appendRange(final SafeHtmlBuilder m, final int begin,
final int cnt) {
switch (cnt) {
case 0:
m.append(begin - 1);
m.append(",0");
break;
case 1:
m.append(begin);
break;
default:
m.append(begin);
m.append(',');
m.append(cnt);
break;
}
}
private void setStyleDelete(final SafeHtmlBuilder m,
boolean syntaxHighlighting) {
m.addStyleName(Gerrit.RESOURCES.css().diffTextDELETE());
if (syntaxHighlighting) {
m.addStyleName(Gerrit.RESOURCES.css().fileLineDELETE());
}
}
private void setStyleInsert(final SafeHtmlBuilder m,
boolean syntaxHighlighting) {
m.addStyleName(Gerrit.RESOURCES.css().diffTextINSERT());
if (syntaxHighlighting) {
m.addStyleName(Gerrit.RESOURCES.css().fileLineINSERT());
}
}
private void appendLineText(final SafeHtmlBuilder m,
boolean syntaxHighlighting, final PatchLine.Type type,
final SparseHtmlFile src, final int i) {
final SafeHtml text = src.getSafeHtmlLine(i);
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().fileLine());
m.addStyleName(Gerrit.RESOURCES.css().diffText());
switch (type) {
case CONTEXT:
m.addStyleName(Gerrit.RESOURCES.css().diffTextCONTEXT());
m.nbsp();
m.append(text);
break;
case DELETE:
setStyleDelete(m, syntaxHighlighting);
m.append("-");
m.append(text);
break;
case INSERT:
setStyleInsert(m, syntaxHighlighting);
m.append("+");
m.append(text);
break;
case REPLACE:
break;
}
m.closeTd();
}
private void appendNoLF(final SafeHtmlBuilder m) {
openLine(m);
padLineNumberForSideA(m);
padLineNumberForSideB(m);
m.openTd();
m.addStyleName(Gerrit.RESOURCES.css().diffText());
m.addStyleName(Gerrit.RESOURCES.css().diffTextNoLF());
m.append("\\ No newline at end of file");
m.closeTd();
closeLine(m);
}
private void openLine(final SafeHtmlBuilder m) {
m.openTr();
m.setAttribute("valign", "top");
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().iconCell());
m.closeTd();
}
private void openTableHeaderLine(final SafeHtmlBuilder m) {
m.openTr();
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().iconCell());
m.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
m.closeTd();
}
private void closeLine(final SafeHtmlBuilder m) {
m.closeTr();
}
private void padLineNumberForSideB(final SafeHtmlBuilder m) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
m.closeTd();
}
private void padLineNumberForSideA(final SafeHtmlBuilder m) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
m.addStyleName(Gerrit.RESOURCES.css().rightBorder());
m.closeTd();
}
private void appendLineNumberForSideB(final SafeHtmlBuilder m, final int idx) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
m.append(SafeHtml.asis("<a href=\"javascript:void(0)\">"+ (idx + 1) + "</a>"));
m.closeTd();
}
private void appendLineNumberForSideA(final SafeHtmlBuilder m, final int idx) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
m.addStyleName(Gerrit.RESOURCES.css().rightBorder());
m.append(SafeHtml.asis("<a href=\"javascript:void(0)\">"+ (idx + 1) + "</a>"));
m.closeTd();
}
private void padLineNumberOnTableHeaderForSideB(final SafeHtmlBuilder m) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
m.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
m.closeTd();
}
private void padLineNumberOnTableHeaderForSideA(final SafeHtmlBuilder m) {
m.openTd();
m.setStyleName(Gerrit.RESOURCES.css().lineNumber());
m.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
m.addStyleName(Gerrit.RESOURCES.css().rightBorder());
m.closeTd();
}
}

View File

@@ -1,564 +0,0 @@
// Copyright (C) 2008 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.patches;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.RpcStatus;
import com.google.gerrit.client.diff.DiffApi;
import com.google.gerrit.client.diff.DiffInfo;
import com.google.gerrit.client.info.WebLinkInfo;
import com.google.gerrit.client.projects.ConfigInfoCache;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.prettify.client.ClientSideFormatter;
import com.google.gerrit.prettify.client.PrettyFactory;
import com.google.gerrit.reviewdb.client.Patch;
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.KeyPressEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
import java.util.Collections;
import java.util.List;
public class UnifiedPatchScreen extends Screen implements
CommentEditorContainer {
static final PrettyFactory PRETTY = ClientSideFormatter.FACTORY;
static final short LARGE_FILE_CONTEXT = 100;
/**
* What should be displayed in the top of the screen
*/
public static enum TopView {
MAIN, COMMIT, PREFERENCES, PATCH_SETS, FILES
}
protected final Patch.Key patchKey;
protected PatchSetDetail patchSetDetail;
protected PatchTable fileList;
protected PatchSet.Id idSideA;
protected PatchSet.Id idSideB;
protected PatchScriptSettingsPanel settingsPanel;
protected TopView topView;
protected CommentLinkProcessor commentLinkProcessor;
private ReviewedPanels reviewedPanels;
private HistoryTable historyTable;
private FlowPanel topPanel;
private FlowPanel contentPanel;
private UnifiedDiffTable contentTable;
private CommitMessageBlock commitMessageBlock;
private NavLinks topNav;
private NavLinks bottomNav;
private int rpcSequence;
private PatchScript lastScript;
/** The index of the file we are currently looking at among the fileList */
private int patchIndex;
private ListenableAccountDiffPreference prefs;
private HandlerRegistration prefsHandler;
/** Keys that cause an action on this screen */
private KeyCommandSet keysNavigation;
private KeyCommandSet keysAction;
private HandlerRegistration regNavigation;
private HandlerRegistration regAction;
private boolean intralineFailure;
private boolean intralineTimeout;
public UnifiedPatchScreen(Patch.Key id, TopView top, PatchSet.Id baseId) {
patchKey = id;
topView = top;
idSideA = baseId; // null here means we're diff'ing from the Base
idSideB = id.getParentKey();
prefs = fileList != null
? fileList.getPreferences()
: new ListenableAccountDiffPreference();
if (Gerrit.isSignedIn()) {
prefs.reset();
}
reviewedPanels = new ReviewedPanels();
settingsPanel = new PatchScriptSettingsPanel(prefs);
}
@Override
public void notifyDraftDelta(int delta) {
lastScript = null;
}
@Override
public void remove(CommentEditorPanel panel) {
lastScript = null;
}
private void update(DiffPreferencesInfo dp) {
// Did the user just turn on auto-review?
if (!reviewedPanels.getValue() && prefs.getOld().manualReview
&& !dp.manualReview) {
reviewedPanels.setValue(true);
reviewedPanels.setReviewedByCurrentUser(true);
}
if (lastScript != null && canReuse(dp, lastScript)) {
lastScript.setDiffPrefs(dp);
RpcStatus.INSTANCE.onRpcStart(null);
settingsPanel.setEnabled(false);
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
try {
onResult(lastScript, false /* not the first time */);
} finally {
RpcStatus.INSTANCE.onRpcComplete(null);
}
}
});
} else {
refresh(false);
}
}
private boolean canReuse(DiffPreferencesInfo dp, PatchScript last) {
if (last.getDiffPrefs().ignoreWhitespace != dp.ignoreWhitespace) {
// Whitespace ignore setting requires server computation.
return false;
}
final int ctx = dp.context;
if (ctx == DiffPreferencesInfo.WHOLE_FILE_CONTEXT
&& !last.getA().isWholeFile()) {
// We don't have the entire file here, so we can't render it.
return false;
}
if (last.getDiffPrefs().context < ctx && !last.getA().isWholeFile()) {
// We don't have sufficient context.
return false;
}
if (dp.syntaxHighlighting && !last.getA().isWholeFile()) {
// We need the whole file to syntax highlight accurately.
return false;
}
return true;
}
@Override
protected void onInitUI() {
super.onInitUI();
if (Gerrit.isSignedIn()) {
setTitleFarEast(reviewedPanels.top);
}
keysNavigation = new KeyCommandSet(Gerrit.C.sectionNavigation());
keysNavigation.add(new UpToChangeCommand(patchKey.getParentKey(), 0, 'u'));
keysNavigation.add(new FileListCmd(0, 'f', PatchUtil.C.fileList()));
if (Gerrit.isSignedIn()) {
keysAction = new KeyCommandSet(Gerrit.C.sectionActions());
keysAction
.add(new ToggleReviewedCmd(0, 'm', PatchUtil.C.toggleReviewed()));
keysAction.add(new MarkAsReviewedAndGoToNextCmd(0, 'M', PatchUtil.C
.markAsReviewedAndGoToNext()));
}
historyTable = new HistoryTable(this);
commitMessageBlock = new CommitMessageBlock();
topPanel = new FlowPanel();
add(topPanel);
contentTable = new UnifiedDiffTable();
contentTable.fileList = fileList;
topNav = new NavLinks(keysNavigation, patchKey.getParentKey());
bottomNav = new NavLinks(null, patchKey.getParentKey());
add(topNav);
contentPanel = new FlowPanel();
contentPanel.setStyleName(Gerrit.RESOURCES.css().unifiedTable());
contentPanel.add(contentTable);
add(contentPanel);
add(bottomNav);
if (Gerrit.isSignedIn()) {
add(reviewedPanels.bottom);
}
if (fileList != null) {
displayNav();
}
}
private void displayNav() {
DiffApi.diff(idSideB, patchKey.getFileName())
.base(idSideA)
.webLinksOnly()
.get(new GerritCallback<DiffInfo>() {
@Override
public void onSuccess(DiffInfo diffInfo) {
topNav.display(patchIndex, fileList,
getLinks(), getWebLinks(diffInfo));
bottomNav.display(patchIndex, fileList,
getLinks(), getWebLinks(diffInfo));
}
});
}
private List<InlineHyperlink> getLinks() {
InlineHyperlink toSideBySideDiffLink = new InlineHyperlink();
toSideBySideDiffLink.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.sideBySideDiff()));
toSideBySideDiffLink.setTargetHistoryToken(getSideBySideDiffUrl());
toSideBySideDiffLink.setTitle(PatchUtil.C.sideBySideDiff());
return Collections.singletonList(toSideBySideDiffLink);
}
private List<WebLinkInfo> getWebLinks(DiffInfo diffInfo) {
return diffInfo.unifiedWebLinks();
}
private String getSideBySideDiffUrl() {
return Dispatcher.toPatch("sidebyside", idSideA,
new Patch.Key(idSideB, patchKey.getFileName()));
}
@Override
protected void onLoad() {
super.onLoad();
if (patchSetDetail == null) {
PatchUtil.CHANGE_SVC.patchSetDetail(idSideB,
new GerritCallback<PatchSetDetail>() {
@Override
public void onSuccess(PatchSetDetail result) {
patchSetDetail = result;
if (fileList == null) {
fileList = new PatchTable(prefs);
fileList.display(idSideA, result);
patchIndex = fileList.indexOf(patchKey);
}
refresh(true);
}
});
} else {
refresh(true);
}
}
@Override
protected void onUnload() {
if (prefsHandler != null) {
prefsHandler.removeHandler();
prefsHandler = null;
}
if (regNavigation != null) {
regNavigation.removeHandler();
regNavigation = null;
}
if (regAction != null) {
regAction.removeHandler();
regAction = null;
}
super.onUnload();
}
@Override
public void registerKeys() {
super.registerKeys();
contentTable.setRegisterKeys(contentTable.isVisible());
if (regNavigation != null) {
regNavigation.removeHandler();
regNavigation = null;
}
regNavigation = GlobalKey.add(this, keysNavigation);
if (regAction != null) {
regAction.removeHandler();
regAction = null;
}
if (keysAction != null) {
regAction = GlobalKey.add(this, keysAction);
}
}
public PatchSet.Id getSideA() {
return idSideA;
}
public Patch.Key getPatchKey() {
return patchKey;
}
public int getPatchIndex() {
return patchIndex;
}
public PatchSetDetail getPatchSetDetail() {
return patchSetDetail;
}
public PatchTable getFileList() {
return fileList;
}
public TopView getTopView() {
return topView;
}
protected void refresh(final boolean isFirst) {
final int rpcseq = ++rpcSequence;
lastScript = null;
settingsPanel.setEnabled(false);
reviewedPanels.populate(patchKey, fileList, patchIndex);
if (isFirst && fileList != null && fileList.isLoaded()) {
fileList.movePointerTo(patchKey);
}
CallbackGroup cb = new CallbackGroup();
ConfigInfoCache.get(patchSetDetail.getProject(),
cb.add(new AsyncCallback<ConfigInfoCache.Entry>() {
@Override
public void onSuccess(ConfigInfoCache.Entry result) {
commentLinkProcessor = result.getCommentLinkProcessor();
contentTable.setCommentLinkProcessor(commentLinkProcessor);
setTheme(result.getTheme());
}
@Override
public void onFailure(Throwable caught) {
// Handled by ScreenLoadCallback.onFailure.
}
}));
PatchUtil.PATCH_SVC.patchScript(patchKey, idSideA, idSideB,
settingsPanel.getValue(), cb.addFinal(
new ScreenLoadCallback<PatchScript>(this) {
@Override
protected void preDisplay(final PatchScript result) {
if (rpcSequence == rpcseq) {
onResult(result, isFirst);
}
}
@Override
public void onFailure(final Throwable caught) {
if (rpcSequence == rpcseq) {
settingsPanel.setEnabled(true);
super.onFailure(caught);
}
}
}));
}
private void onResult(final PatchScript script, final boolean isFirst) {
final String path = PatchTable.getDisplayFileName(patchKey);
String fileName = path;
final int last = fileName.lastIndexOf('/');
if (last >= 0) {
fileName = fileName.substring(last + 1);
}
setWindowTitle(fileName);
setPageTitle(path);
if (idSideB.equals(patchSetDetail.getPatchSet().getId())) {
commitMessageBlock.setVisible(true);
commitMessageBlock.display(patchSetDetail.getInfo().getMessage(),
commentLinkProcessor);
} else {
commitMessageBlock.setVisible(false);
PatchUtil.CHANGE_SVC.patchSetDetail(idSideB,
new GerritCallback<PatchSetDetail>() {
@Override
public void onSuccess(PatchSetDetail result) {
commitMessageBlock.setVisible(true);
commitMessageBlock.display(result.getInfo().getMessage(),
commentLinkProcessor);
}
});
}
historyTable.display(script.getHistory());
for (Patch p : patchSetDetail.getPatches()) {
if (p.getKey().equals(patchKey)) {
if (p.getPatchType().equals(Patch.PatchType.BINARY)) {
contentTable.isDisplayBinary = true;
}
break;
}
}
if (script.isHugeFile()) {
DiffPreferencesInfo dp = script.getDiffPrefs();
int context = dp.context;
if (context == DiffPreferencesInfo.WHOLE_FILE_CONTEXT) {
context = Short.MAX_VALUE;
} else if (context > Short.MAX_VALUE) {
context = Short.MAX_VALUE;
}
dp.context = Math.min(context, LARGE_FILE_CONTEXT);
dp.syntaxHighlighting = false;
script.setDiffPrefs(dp);
}
contentTable.display(patchKey, idSideA, idSideB, script, patchSetDetail);
contentTable.display(script.getCommentDetail(), script.isExpandAllComments());
contentTable.finishDisplay();
contentTable.setRegisterKeys(isCurrentView());
settingsPanel.setEnableSmallFileFeatures(!script.isHugeFile());
settingsPanel.setEnableIntralineDifference(script.hasIntralineDifference());
settingsPanel.setEnabled(true);
lastScript = script;
if (fileList != null) {
displayNav();
}
if (Gerrit.isSignedIn()) {
boolean isReviewed = false;
if (isFirst && !prefs.get().manualReview) {
isReviewed = true;
reviewedPanels.setReviewedByCurrentUser(isReviewed);
} else {
for (Patch p : patchSetDetail.getPatches()) {
if (p.getKey().equals(patchKey)) {
isReviewed = p.isReviewedByCurrentUser();
break;
}
}
}
reviewedPanels.setValue(isReviewed);
}
intralineFailure = isFirst && script.hasIntralineFailure();
intralineTimeout = isFirst && script.hasIntralineTimeout();
}
@Override
public void onShowView() {
super.onShowView();
if (prefsHandler == null) {
prefsHandler = prefs.addValueChangeHandler(
new ValueChangeHandler<DiffPreferencesInfo>() {
@Override
public void onValueChange(ValueChangeEvent<DiffPreferencesInfo> event) {
update(event.getValue());
}
});
}
if (intralineFailure) {
intralineFailure = false;
new ErrorDialog(PatchUtil.C.intralineFailure()).show();
} else if (intralineTimeout) {
intralineTimeout = false;
new ErrorDialog(PatchUtil.C.intralineTimeout()).setText(
Gerrit.C.warnTitle()).show();
}
if (topView != null && prefs.get().retainHeader) {
setTopView(topView);
}
}
public void setTopView(TopView tv) {
topView = tv;
topPanel.clear();
switch(tv) {
case COMMIT: topPanel.add(commitMessageBlock);
break;
case PREFERENCES: topPanel.add(settingsPanel);
break;
case PATCH_SETS: topPanel.add(historyTable);
break;
case FILES: topPanel.add(fileList);
break;
case MAIN:
break;
}
}
public class FileListCmd extends KeyCommand {
public FileListCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
if (fileList == null || fileList.isAttached()) {
final PatchSet.Id psid = patchKey.getParentKey();
fileList = new PatchTable(prefs);
fileList.setSavePointerId("PatchTable " + psid);
PatchUtil.CHANGE_SVC.patchSetDetail(psid,
new GerritCallback<PatchSetDetail>() {
@Override
public void onSuccess(final PatchSetDetail result) {
fileList.display(idSideA, result);
}
});
}
final PatchBrowserPopup p = new PatchBrowserPopup(patchKey, fileList);
p.open();
}
}
public class ToggleReviewedCmd extends KeyCommand {
public ToggleReviewedCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
final boolean isReviewed = !reviewedPanels.getValue();
reviewedPanels.setValue(isReviewed);
reviewedPanels.setReviewedByCurrentUser(isReviewed);
}
}
public class MarkAsReviewedAndGoToNextCmd extends KeyCommand {
public MarkAsReviewedAndGoToNextCmd(int mask, int key, String help) {
super(mask, key, help);
}
@Override
public void onKeyPress(final KeyPressEvent event) {
reviewedPanels.go();
}
}
}

View File

@@ -1,35 +0,0 @@
// Copyright (C) 2010 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.patches;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwtexpui.globalkey.client.KeyCommand;
class UpToChangeCommand extends KeyCommand {
private final PatchSet.Id patchSetId;
UpToChangeCommand(PatchSet.Id patchSetId, int mask, int key) {
super(mask, key, PatchUtil.C.upToChange());
this.patchSetId = patchSetId;
}
@Override
public void onKeyPress(final KeyPressEvent event) {
Gerrit.display(PageLinks.toChange(patchSetId));
}
}

View File

@@ -17,7 +17,6 @@ package com.google.gerrit.client.ui;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
public class ChangeLink extends InlineHyperlink {
@@ -26,19 +25,11 @@ public class ChangeLink extends InlineHyperlink {
}
protected Change.Id cid;
protected PatchSet.Id psid;
public ChangeLink(final String text, final Change.Id c) {
super(text, PageLinks.toChange(c));
getElement().setPropertyString("href", permalink(c));
cid = c;
psid = null;
}
public ChangeLink(final String text, final PatchSet.Id ps) {
super(text, PageLinks.toChange(ps));
cid = ps.getParentKey();
psid = ps;
}
@Override

View File

@@ -184,7 +184,6 @@ public abstract class Screen extends View {
if (windowTitle != null) {
Gerrit.setWindowTitle(this, windowTitle);
}
Gerrit.updateMenus(this);
Gerrit.EVENT_BUS.fireEvent(new ScreenLoadEvent(this));
Gerrit.setQueryString(null);
registerKeys();

View File

@@ -15,8 +15,6 @@
package com.google.gerrit.httpd.rpc;
import com.google.gerrit.httpd.rpc.account.AccountModule;
import com.google.gerrit.httpd.rpc.changedetail.ChangeModule;
import com.google.gerrit.httpd.rpc.patch.PatchModule;
import com.google.gerrit.httpd.rpc.project.ProjectModule;
/** Registers servlets to answer RPCs from client UI. */
@@ -30,8 +28,6 @@ public class UiRpcModule extends RpcServletModule {
rpc(SystemInfoServiceImpl.class);
install(new AccountModule());
install(new ChangeModule());
install(new PatchModule());
install(new ProjectModule());
}
}

View File

@@ -1,44 +0,0 @@
// Copyright (C) 2008 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.httpd.rpc.changedetail;
import com.google.gerrit.common.data.ChangeDetailService;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.inject.Inject;
class ChangeDetailServiceImpl implements ChangeDetailService {
private final PatchSetDetailFactory.Factory patchSetDetail;
@Inject
ChangeDetailServiceImpl(
final PatchSetDetailFactory.Factory patchSetDetail) {
this.patchSetDetail = patchSetDetail;
}
@Override
public void patchSetDetail(PatchSet.Id id,
AsyncCallback<PatchSetDetail> callback) {
patchSetDetail2(null, id, null, callback);
}
@Override
public void patchSetDetail2(PatchSet.Id baseId, PatchSet.Id id,
DiffPreferencesInfo diffPrefs, AsyncCallback<PatchSetDetail> callback) {
patchSetDetail.create(baseId, id, diffPrefs).to(callback);
}
}

View File

@@ -1,36 +0,0 @@
// Copyright (C) 2009 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.httpd.rpc.changedetail;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.httpd.rpc.RpcServletModule;
import com.google.gerrit.httpd.rpc.UiRpcModule;
public class ChangeModule extends RpcServletModule {
public ChangeModule() {
super(UiRpcModule.PREFIX);
}
@Override
protected void configureServlets() {
install(new FactoryModule() {
@Override
protected void configure() {
factory(PatchSetDetailFactory.Factory.class);
}
});
rpc(ChangeDetailServiceImpl.class);
}
}

View File

@@ -1,234 +0,0 @@
// Copyright (C) 2008 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.httpd.rpc.changedetail;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Optional;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountPatchReview;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchLineCommentsUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListKey;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.lib.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** Creates a {@link PatchSetDetail} from a {@link PatchSet}. */
class PatchSetDetailFactory extends Handler<PatchSetDetail> {
private static final Logger log =
LoggerFactory.getLogger(PatchSetDetailFactory.class);
interface Factory {
PatchSetDetailFactory create(
@Assisted("psIdBase") @Nullable PatchSet.Id psIdBase,
@Assisted("psIdNew") PatchSet.Id psIdNew,
@Nullable DiffPreferencesInfo diffPrefs);
}
private final PatchSetInfoFactory infoFactory;
private final ReviewDb db;
private final PatchListCache patchListCache;
private final Provider<CurrentUser> userProvider;
private final ChangeControl.GenericFactory changeControlFactory;
private final PatchLineCommentsUtil plcUtil;
private final PatchSetUtil psUtil;
private final ChangeEditUtil editUtil;
private Project.NameKey project;
private final PatchSet.Id psIdBase;
private final PatchSet.Id psIdNew;
private final DiffPreferencesInfo diffPrefs;
private ObjectId oldId;
private ObjectId newId;
private PatchSetDetail detail;
ChangeControl control;
PatchSet patchSet;
@Inject
PatchSetDetailFactory(final PatchSetInfoFactory psif, final ReviewDb db,
final PatchListCache patchListCache,
final Provider<CurrentUser> userProvider,
final ChangeControl.GenericFactory changeControlFactory,
final PatchLineCommentsUtil plcUtil,
final PatchSetUtil psUtil,
ChangeEditUtil editUtil,
@Assisted("psIdBase") @Nullable final PatchSet.Id psIdBase,
@Assisted("psIdNew") final PatchSet.Id psIdNew,
@Assisted @Nullable final DiffPreferencesInfo diffPrefs) {
this.infoFactory = psif;
this.db = db;
this.patchListCache = patchListCache;
this.userProvider = userProvider;
this.changeControlFactory = changeControlFactory;
this.plcUtil = plcUtil;
this.psUtil = psUtil;
this.editUtil = editUtil;
this.psIdBase = psIdBase;
this.psIdNew = psIdNew;
if (psIdBase != null && psIdNew != null) {
checkArgument(psIdBase.getParentKey().equals(psIdNew.getParentKey()),
"cannot compare PatchSets from different changes: %s and %s",
psIdBase, psIdNew);
}
this.diffPrefs = diffPrefs;
}
@Override
public PatchSetDetail call() throws OrmException, NoSuchEntityException,
PatchSetInfoNotAvailableException, NoSuchChangeException, AuthException,
IOException {
Optional<ChangeEdit> edit = null;
ChangeNotes notes;
if (control == null || patchSet == null) {
control = changeControlFactory.validateFor(db, psIdNew.getParentKey(),
userProvider.get());
notes = control.getNotes();
if (psIdNew.get() == 0) {
edit = editUtil.byChange(control.getChange());
if (edit.isPresent()) {
patchSet = edit.get().getBasePatchSet();
}
} else {
patchSet = psUtil.get(db, notes, psIdNew);
}
if (patchSet == null) {
throw new NoSuchEntityException();
}
} else {
notes = control.getNotes();
}
project = control.getProject().getNameKey();
final PatchList list;
try {
if (psIdBase != null) {
oldId = toObjectId(psUtil.get(db, notes, psIdBase));
if (edit != null && edit.isPresent()) {
newId = edit.get().getEditCommit().toObjectId();
} else {
newId = toObjectId(patchSet);
}
list = listFor(keyFor(diffPrefs.ignoreWhitespace));
} else { // OK, means use base to compare
list = patchListCache.get(control.getChange(), patchSet);
}
} catch (PatchListNotAvailableException e) {
throw new NoSuchEntityException();
}
final List<Patch> patches = list.toPatchList(patchSet.getId());
final Map<Patch.Key, Patch> byKey = new HashMap<>();
for (final Patch p : patches) {
byKey.put(p.getKey(), p);
}
if (edit == null) {
for (PatchLineComment c : plcUtil.publishedByPatchSet(db, notes, psIdNew)) {
final Patch p = byKey.get(c.getKey().getParentKey());
if (p != null) {
p.setCommentCount(p.getCommentCount() + 1);
}
}
}
detail = new PatchSetDetail();
detail.setPatchSet(patchSet);
detail.setProject(project);
detail.setInfo(infoFactory.get(db, notes, patchSet.getId()));
detail.setPatches(patches);
final CurrentUser user = control.getUser();
if (user.isIdentifiedUser() && edit == null) {
// If we are signed in, compute the number of draft comments by the
// current user on each of these patch files. This way they can more
// quickly locate where they have pending drafts, and review them.
//
final Account.Id me = user.getAccountId();
for (PatchLineComment c
: plcUtil.draftByPatchSetAuthor(db, psIdNew, me, notes)) {
final Patch p = byKey.get(c.getKey().getParentKey());
if (p != null) {
p.setDraftCount(p.getDraftCount() + 1);
}
}
for (AccountPatchReview r : db.accountPatchReviews().byReviewer(me, psIdNew)) {
final Patch p = byKey.get(r.getKey().getPatchKey());
if (p != null) {
p.setReviewedByCurrentUser(true);
}
}
}
return detail;
}
private ObjectId toObjectId(PatchSet ps) throws NoSuchEntityException {
try {
return ObjectId.fromString(ps.getRevision().get());
} catch (IllegalArgumentException e) {
log.error("Patch set " + ps.getId() + " has invalid revision");
throw new NoSuchEntityException();
}
}
private PatchListKey keyFor(Whitespace whitespace) {
return new PatchListKey(oldId, newId, whitespace);
}
private PatchList listFor(PatchListKey key)
throws PatchListNotAvailableException {
return patchListCache.get(key, project);
}
}

View File

@@ -1,69 +0,0 @@
// Copyright (C) 2008 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.httpd.rpc.patch;
import com.google.gerrit.common.data.PatchDetailService;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.patch.PatchScriptFactory;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Provider;
class PatchDetailServiceImpl extends BaseServiceImplementation implements
PatchDetailService {
private final PatchScriptFactory.Factory patchScriptFactoryFactory;
private final ChangeControl.GenericFactory changeControlFactory;
@Inject
PatchDetailServiceImpl(final Provider<ReviewDb> schema,
final Provider<CurrentUser> currentUser,
final PatchScriptFactory.Factory patchScriptFactoryFactory,
final ChangeControl.GenericFactory changeControlFactory) {
super(schema, currentUser);
this.patchScriptFactoryFactory = patchScriptFactoryFactory;
this.changeControlFactory = changeControlFactory;
}
@Override
public void patchScript(final Patch.Key patchKey, final PatchSet.Id psa,
final PatchSet.Id psb, final DiffPreferencesInfo dp,
final AsyncCallback<PatchScript> callback) {
if (psb == null) {
callback.onFailure(new NoSuchEntityException());
return;
}
new Handler<PatchScript>() {
@Override
public PatchScript call() throws Exception {
ChangeControl control = changeControlFactory.validateFor(
getDb(), patchKey.getParentKey().getParentKey(),
getUser());
return patchScriptFactoryFactory.create(
control, patchKey.getFileName(), psa, psb, dp).call();
}
}.to(callback);
}
}

View File

@@ -1,29 +0,0 @@
// Copyright (C) 2009 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.httpd.rpc.patch;
import com.google.gerrit.httpd.rpc.RpcServletModule;
import com.google.gerrit.httpd.rpc.UiRpcModule;
public class PatchModule extends RpcServletModule {
public PatchModule() {
super(UiRpcModule.PREFIX);
}
@Override
protected void configureServlets() {
rpc(PatchDetailServiceImpl.class);
}
}

View File

@@ -3,15 +3,10 @@ SRC = 'src/main/java/com/google/gerrit/prettify/'
gwt_module(
name = 'client',
srcs = glob([
SRC + 'client/**/*.java',
SRC + 'common/**/*.java',
]),
gwt_xml = SRC + 'PrettyFormatter.gwt.xml',
resources = glob([
'src/main/java/com/google/gerrit/prettify/client/*.properties',
]),
deps = [
':google-code-prettify',
'//gerrit-gwtexpui:SafeHtml',
],
exported_deps = [
@@ -26,16 +21,6 @@ gwt_module(
visibility = ['PUBLIC'],
)
java_library(
name = 'google-code-prettify',
resources = glob([
'src/main/resources/com/google/gerrit/prettify/client/**/*',
]),
deps = [
'//lib:LICENSE-Apache2.0',
],
)
java_library(
name = 'server',
srcs = glob([SRC + 'common/**/*.java']),

View File

@@ -24,5 +24,4 @@
<inherits name='com.google.gwt.resources.Resources'/>
<inherits name='com.google.gwtexpui.safehtml.SafeHtml'/>
<source path='common' />
<source path='client' />
</module>

View File

@@ -1,80 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.ui.RootPanel;
/** Evaluates prettify using the host browser's JavaScript engine. */
public class ClientSideFormatter extends PrettyFormatter {
public static final PrettyFactory FACTORY = new PrettyFactory() {
@Override
public PrettyFormatter get() {
return new ClientSideFormatter();
}
};
private static final PrivateScopeImpl prettify;
static {
Resources.I.prettify_css().ensureInjected();
Resources.I.gerrit_css().ensureInjected();
prettify = GWT.create(PrivateScopeImpl.class);
RootPanel.get().add(prettify);
prettify.compile(Resources.I.core());
prettify.compile(Resources.I.lang_apollo());
prettify.compile(Resources.I.lang_basic());
prettify.compile(Resources.I.lang_clj());
prettify.compile(Resources.I.lang_css());
prettify.compile(Resources.I.lang_dart());
prettify.compile(Resources.I.lang_erlang());
prettify.compile(Resources.I.lang_go());
prettify.compile(Resources.I.lang_hs());
prettify.compile(Resources.I.lang_lisp());
prettify.compile(Resources.I.lang_llvm());
prettify.compile(Resources.I.lang_lua());
prettify.compile(Resources.I.lang_matlab());
prettify.compile(Resources.I.lang_ml());
prettify.compile(Resources.I.lang_mumps());
prettify.compile(Resources.I.lang_n());
prettify.compile(Resources.I.lang_pascal());
prettify.compile(Resources.I.lang_proto());
prettify.compile(Resources.I.lang_r());
prettify.compile(Resources.I.lang_rd());
prettify.compile(Resources.I.lang_scala());
prettify.compile(Resources.I.lang_sql());
prettify.compile(Resources.I.lang_tcl());
prettify.compile(Resources.I.lang_tex());
prettify.compile(Resources.I.lang_vb());
prettify.compile(Resources.I.lang_vhdl());
prettify.compile(Resources.I.lang_wiki());
prettify.compile(Resources.I.lang_xq());
prettify.compile(Resources.I.lang_yaml());
}
@Override
protected String prettify(String html, String type) {
return go(prettify.getContext(), html, type);
}
private static native String go(JavaScriptObject ctx, String srcText,
String srcType)
/*-{
return ctx.prettyPrintOne(srcText, srcType);
}-*/;
}

View File

@@ -1,27 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.Constants;
public interface PrettifyConstants extends Constants {
static final PrettifyConstants C = GWT.create(PrettifyConstants.class);
String wseTabAfterSpace();
String wseTrailingSpace();
String wseBareCR();
String leCR();
}

View File

@@ -1,4 +0,0 @@
wseTabAfterSpace=Whitespace error: Tab after space
wseTrailingSpace=Whitespace error: Trailing space at end of line
wseBareCR=CR without LF
leCR=Carriage Return

View File

@@ -1,20 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
/** Creates a new PrettyFormatter instance for one formatting run. */
public interface PrettyFactory {
PrettyFormatter get();
}

View File

@@ -1,561 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.prettify.common.SparseFileContent;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.ReplaceEdit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class PrettyFormatter implements SparseHtmlFile {
public abstract static class EditFilter {
abstract String getStyleName();
abstract int getBegin(Edit edit);
abstract int getEnd(Edit edit);
}
public static final EditFilter A = new EditFilter() {
@Override
String getStyleName() {
return "wdd";
}
@Override
int getBegin(Edit edit) {
return edit.getBeginA();
}
@Override
int getEnd(Edit edit) {
return edit.getEndA();
}
};
public static final EditFilter B = new EditFilter() {
@Override
String getStyleName() {
return "wdi";
}
@Override
int getBegin(Edit edit) {
return edit.getBeginB();
}
@Override
int getEnd(Edit edit) {
return edit.getEndB();
}
};
protected SparseFileContent content;
protected EditFilter side;
protected List<Edit> edits;
protected DiffPreferencesInfo diffPrefs;
protected String fileName;
protected Set<Integer> trailingEdits;
private int col;
private int lineIdx;
private Tag lastTag;
private StringBuilder buf;
@Override
public SafeHtml getSafeHtmlLine(int lineNo) {
return SafeHtml.asis(content.get(lineNo));
}
@Override
public int size() {
return content.size();
}
@Override
public boolean contains(int idx) {
return content.contains(idx);
}
@Override
public boolean hasTrailingEdit(int idx) {
return trailingEdits.contains(idx);
}
public void setEditFilter(EditFilter f) {
side = f;
}
public void setEditList(List<Edit> all) {
edits = all;
}
public void setDiffPrefs(DiffPreferencesInfo how) {
diffPrefs = how;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* Parse and format a complete source code file.
*
* @param src raw content of the file to format. The line strings will be HTML
* escaped before processing, so it must be the raw text.
*/
public void format(SparseFileContent src) {
content = new SparseFileContent();
content.setSize(src.size());
trailingEdits = new HashSet<>();
String html = toHTML(src);
html = expandTabs(html);
if (diffPrefs.syntaxHighlighting && getFileType() != null
&& src.isWholeFile()) {
// The prettify parsers don't like &#39; as an entity for the
// single quote character. Replace them all out so we don't
// confuse the parser.
//
html = html.replaceAll("&#39;", "'");
// If a line is modified at its end and the line ending is changed from
// '\n' to '\r\n' then the '\r' of the new line is part of the modified
// text. If intraline diffs are highlighted the modified text is
// surrounded by a 'span' tag. As result '\r' and '\n' of the new line get
// separated by '</span>'. For the prettify parser this now looks like two
// separate line endings. This messes up the line counting below.
// Drop any '\r' to avoid this problem.
html = html.replaceAll("\r</span>(<span class=\"wdc\">)?\n", "</span>$1\n");
html = html.replaceAll("(\r)?\n", " $1\n");
html = prettify(html, getFileType());
html = html.replaceAll(" (\r)?\n", "$1\n");
}
int pos = 0;
int textChunkStart = 0;
lastTag = Tag.NULL;
col = 0;
lineIdx = 0;
buf = new StringBuilder();
while (pos <= html.length()) {
int tagStart = html.indexOf('<', pos);
int lf = html.indexOf('\n', pos);
if (tagStart < 0 && lf < 0) {
// No more tags remaining. What's left is plain text.
//
assert lastTag == Tag.NULL;
pos = html.length();
if (textChunkStart < pos) {
htmlText(html.substring(textChunkStart, pos));
}
if (0 < buf.length()) {
content.addLine(src.mapIndexToLine(lineIdx), buf.toString());
}
break;
}
// Line end occurs before the next HTML tag. Break the line.
if (0 <= lf && (lf < tagStart || tagStart < 0)) {
if (textChunkStart < lf) {
lastTag.open(buf, html);
htmlText(html.substring(textChunkStart, lf));
}
pos = lf + 1;
textChunkStart = pos;
lastTag.close(buf, html);
content.addLine(src.mapIndexToLine(lineIdx++), buf.toString());
buf = new StringBuilder();
col = 0;
continue;
}
// Assume no attribute contains '>' and that all tags
// within the HTML will be well-formed.
//
int tagEnd = html.indexOf('>', tagStart);
assert tagStart < tagEnd;
pos = tagEnd + 1;
// Handle any text between the end of the last tag,
// and the start of this tag.
//
if (textChunkStart < tagStart) {
lastTag.open(buf, html);
htmlText(html.substring(textChunkStart, tagStart));
}
textChunkStart = pos;
if (html.charAt(tagStart + 1) == '/') {
lastTag = lastTag.pop(buf, html);
} else if (html.charAt(tagEnd - 1) != '/') {
lastTag = new Tag(lastTag, tagStart, tagEnd);
}
}
buf = null;
}
private void htmlText(String txt) {
int pos = 0;
while (pos < txt.length()) {
int start = txt.indexOf('&', pos);
if (start < 0) {
break;
}
cleanText(txt, pos, start);
pos = txt.indexOf(';', start + 1) + 1;
if (diffPrefs.lineLength <= col) {
buf.append("<br />");
col = 0;
}
buf.append(txt.substring(start, pos));
col++;
}
cleanText(txt, pos, txt.length());
}
private void cleanText(String txt, int pos, int end) {
while (pos < end) {
int free = diffPrefs.lineLength - col;
if (free <= 0) {
// The current line is full. Throw an explicit line break
// onto the end, and we'll continue on the next line.
//
buf.append("<br />");
col = 0;
free = diffPrefs.lineLength;
}
int n = Math.min(end - pos, free);
buf.append(txt.substring(pos, pos + n));
col += n;
pos += n;
}
}
/** Run the prettify engine over the text and return the result. */
protected abstract String prettify(String html, String type);
private static class Tag {
static final Tag NULL = new Tag(null, 0, 0) {
@Override
void open(StringBuilder buf, String html) {
}
@Override
void close(StringBuilder buf, String html) {
}
@Override
Tag pop(StringBuilder buf, String html) {
return this;
}
};
final Tag parent;
final int start;
final int end;
boolean open;
Tag(Tag p, int s, int e) {
parent = p;
start = s;
end = e;
}
void open(StringBuilder buf, String html) {
if (!open) {
parent.open(buf, html);
buf.append(html.substring(start, end + 1));
open = true;
}
}
void close(StringBuilder buf, String html) {
pop(buf, html);
parent.close(buf, html);
}
Tag pop(StringBuilder buf, String html) {
if (open) {
int sp = html.indexOf(' ', start + 1);
if (sp < 0 || end < sp) {
sp = end;
}
buf.append("</");
buf.append(html.substring(start + 1, sp));
buf.append('>');
open = false;
}
return parent;
}
}
private String toHTML(SparseFileContent src) {
SafeHtml html;
if (diffPrefs.intralineDifference) {
html = colorLineEdits(src);
} else {
SafeHtmlBuilder b = new SafeHtmlBuilder();
for (int index = src.first(); index < src.size(); index = src.next(index)) {
b.append(src.get(index));
b.append('\n');
}
html = b;
final String r = "<span class=\"wse\"" //
+ " title=\"" + PrettifyConstants.C.wseBareCR() + "\"" //
+ ">&nbsp;</span>$1";
html = html.replaceAll("\r([^\n])", r);
}
if (diffPrefs.showWhitespaceErrors) {
// We need to do whitespace errors before showing tabs, because
// these patterns rely on \t as a literal, before it expands.
//
html = showTabAfterSpace(html);
html = showTrailingWhitespace(html);
}
if (diffPrefs.showLineEndings){
html = showLineEndings(html);
}
if (diffPrefs.showTabs) {
String t = 1 < diffPrefs.tabSize ? "\t" : "";
html = html.replaceAll("\t", "<span class=\"vt\">\u00BB</span>" + t);
}
return html.asString();
}
private SafeHtml colorLineEdits(SparseFileContent src) {
// Make a copy of the edits with a sentinel that is after all lines
// in the source. That simplifies our loop below because we'll never
// run off the end of the edit list.
//
List<Edit> edits = new ArrayList<>(this.edits.size() + 1);
edits.addAll(this.edits);
edits.add(new Edit(src.size(), src.size()));
SafeHtmlBuilder buf = new SafeHtmlBuilder();
int curIdx = 0;
Edit curEdit = edits.get(curIdx);
ReplaceEdit lastReplace = null;
List<Edit> charEdits = null;
int lastPos = 0;
int lastIdx = 0;
for (int index = src.first(); index < src.size(); index = src.next(index)) {
int cmp = compare(index, curEdit);
while (0 < cmp) {
// The index is after the edit. Skip to the next edit.
//
curEdit = edits.get(curIdx++);
cmp = compare(index, curEdit);
}
if (cmp < 0) {
// index occurs before the edit. This is a line of context.
//
appendShowBareCR(buf, src.get(index), true);
buf.append('\n');
continue;
}
// index occurs within the edit. The line is a modification.
//
if (curEdit instanceof ReplaceEdit) {
if (lastReplace != curEdit) {
lastReplace = (ReplaceEdit) curEdit;
charEdits = lastReplace.getInternalEdits();
lastPos = 0;
lastIdx = 0;
}
String line = src.get(index) + "\n";
for (int c = 0; c < line.length();) {
if (charEdits == null || (charEdits.size() <= lastIdx)) {
appendShowBareCR(buf, line.substring(c), false);
break;
}
final Edit edit = charEdits.get(lastIdx);
final int b = side.getBegin(edit) - lastPos;
final int e = side.getEnd(edit) - lastPos;
if (c < b) {
// There is text at the start of this line that is common
// with the other side. Copy it with no style around it.
//
final int cmnLen = Math.min(b, line.length());
buf.openSpan();
buf.setStyleName("wdc");
appendShowBareCR(buf, line.substring(c, cmnLen), //
cmnLen == line.length() - 1);
buf.closeSpan();
c = cmnLen;
}
final int modLen = Math.min(e, line.length());
if (c < e && c < modLen) {
buf.openSpan();
buf.setStyleName(side.getStyleName());
appendShowBareCR(buf, line.substring(c, modLen), //
modLen == line.length() - 1);
buf.closeSpan();
if (modLen == line.length()) {
trailingEdits.add(index);
}
c = modLen;
}
if (e <= c) {
lastIdx++;
}
}
lastPos += line.length();
} else {
appendShowBareCR(buf, src.get(index), true);
buf.append('\n');
}
}
return buf;
}
private void appendShowBareCR(SafeHtmlBuilder buf, String src, boolean end) {
while (!src.isEmpty()) {
int cr = src.indexOf('\r');
if (cr < 0) {
buf.append(src);
return;
} else if (end) {
if (cr == src.length() - 1) {
buf.append(src.substring(0, cr + 1));
return;
}
} else if (cr == src.length() - 2 && src.charAt(cr + 1) == '\n') {
buf.append(src);
return;
}
buf.append(src.substring(0, cr));
buf.openSpan();
buf.setStyleName("wse");
buf.setAttribute("title", PrettifyConstants.C.wseBareCR());
buf.nbsp();
buf.closeSpan();
src = src.substring(cr + 1);
}
}
private int compare(int index, Edit edit) {
if (index < side.getBegin(edit)) {
return -1; // index occurs before the edit.
} else if (index < side.getEnd(edit)) {
return 0; // index occurs within the edit.
} else {
return 1; // index occurs after the edit.
}
}
private SafeHtml showTabAfterSpace(SafeHtml src) {
final String m = "( ( |<span[^>]*>|</span>)*\t)";
final String r = "<span class=\"wse\"" //
+ " title=\"" + PrettifyConstants.C.wseTabAfterSpace() + "\"" //
+ ">$1</span>";
src = src.replaceFirst("^" + m, r);
src = src.replaceAll("\n" + m, "\n" + r);
return src;
}
private SafeHtml showTrailingWhitespace(SafeHtml src) {
final String r = "<span class=\"wse\"" //
+ " title=\"" + PrettifyConstants.C.wseTrailingSpace() + "\"" //
+ ">$1</span>$2";
src = src.replaceAll("([ \t][ \t]*)(\r?(</span>)?\n)", r);
src = src.replaceFirst("([ \t][ \t]*)(\r?(</span>)?\n?)$", r);
return src;
}
private SafeHtml showLineEndings(SafeHtml src) {
final String r = "<span class=\"lecr\""
+ " title=\"" + PrettifyConstants.C.leCR() + "\"" //
+ ">\\\\r</span>";
src = src.replaceAll("\r", r);
return src;
}
private String expandTabs(String html) {
StringBuilder tmp = new StringBuilder();
int i = 0;
if (diffPrefs.showTabs) {
i = 1;
}
for (; i < diffPrefs.tabSize; i++) {
tmp.append("&nbsp;");
}
return html.replaceAll("\t", tmp.toString());
}
private String getFileType() {
String srcType = fileName;
if (srcType == null) {
return null;
}
int dot = srcType.lastIndexOf('.');
if (dot < 0) {
return null;
}
if (0 < dot) {
srcType = srcType.substring(dot + 1);
}
if ("txt".equalsIgnoreCase(srcType)) {
return null;
}
return srcType;
}
}

View File

@@ -1,67 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.resources.client.TextResource;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.NamedFrame;
/**
* Creates a private JavaScript environment, typically inside an IFrame.
* <p>
* Instances must be created through {@code GWT.create(PrivateScopeImpl.class)}.
* A scope must remain attached to the primary document for its entire life.
* Behavior is undefined if a scope is detached and attached again later. It is
* best to attach the scope with {@code RootPanel.get().add(scope)} as soon as
* it has been created.
*/
public class PrivateScopeImpl extends Composite {
private static int scopeId;
protected final String scopeName;
public PrivateScopeImpl() {
scopeName = nextScopeName();
NamedFrame frame = new NamedFrame(scopeName);
frame.setUrl("javascript:''");
initWidget(frame);
setVisible(false);
}
public void compile(TextResource js) {
eval(js.getText());
}
public void eval(String js) {
nativeEval(getContext(), js);
}
public JavaScriptObject getContext() {
return nativeGetContext(scopeName);
}
private static String nextScopeName() {
return "_PrivateScope" + (++scopeId);
}
private static native void nativeEval(JavaScriptObject ctx, String js)
/*-{ ctx.eval(js); }-*/;
private static native JavaScriptObject nativeGetContext(String scopeName)
/*-{ return $wnd[scopeName]; }-*/;
}

View File

@@ -1,46 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
import com.google.gwt.core.client.JavaScriptObject;
/** MSIE requires us to initialize the document before we can use it. */
public class PrivateScopeImplIE8 extends PrivateScopeImpl {
private JavaScriptObject context;
@Override
protected void onAttach() {
super.onAttach();
context = nativeInitContext(scopeName);
}
@Override
public JavaScriptObject getContext() {
return context;
}
private static native JavaScriptObject nativeInitContext(String scopeName)
/*-{
var fe = $wnd[scopeName];
fe.document.write(
'<script>'
+ 'parent._PrivateScopeNewChild = this;'
+ '</' + 'script>'
);
var ctx = $wnd._PrivateScopeNewChild;
$wnd._PrivateScopeNewChild = undefined;
return ctx;
}-*/;
}

View File

@@ -1,63 +0,0 @@
// Copyright (C) 2009 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.prettify.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.TextResource;
/** Loads the minimized form of prettify into the client. */
interface Resources extends ClientBundle {
static final Resources I = GWT.create(Resources.class);
@Source("prettify.css")
CssResource prettify_css();
@Source("gerrit.css")
CssResource gerrit_css();
@Source("prettify.js")
TextResource core();
@Source("lang-apollo.js") TextResource lang_apollo();
@Source("lang-basic.js") TextResource lang_basic();
@Source("lang-clj.js") TextResource lang_clj();
@Source("lang-css.js") TextResource lang_css();
@Source("lang-dart.js") TextResource lang_dart();
@Source("lang-erlang.js") TextResource lang_erlang();
@Source("lang-go.js") TextResource lang_go();
@Source("lang-hs.js") TextResource lang_hs();
@Source("lang-lisp.js") TextResource lang_lisp();
@Source("lang-llvm.js") TextResource lang_llvm();
@Source("lang-lua.js") TextResource lang_lua();
@Source("lang-matlab.js") TextResource lang_matlab();
@Source("lang-ml.js") TextResource lang_ml();
@Source("lang-mumps.js") TextResource lang_mumps();
@Source("lang-n.js") TextResource lang_n();
@Source("lang-pascal.js") TextResource lang_pascal();
@Source("lang-proto.js") TextResource lang_proto();
@Source("lang-r.js") TextResource lang_r();
@Source("lang-rd.js") TextResource lang_rd();
@Source("lang-scala.js") TextResource lang_scala();
@Source("lang-sql.js") TextResource lang_sql();
@Source("lang-tcl.js") TextResource lang_tcl();
@Source("lang-tex.js") TextResource lang_tex();
@Source("lang-vb.js") TextResource lang_vb();
@Source("lang-vhdl.js") TextResource lang_vhdl();
@Source("lang-wiki.js") TextResource lang_wiki();
@Source("lang-xq.js") TextResource lang_xq();
@Source("lang-yaml.js") TextResource lang_yaml();
}

View File

@@ -1,31 +0,0 @@
// Copyright (C) 2010 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.prettify.client;
import com.google.gwtexpui.safehtml.client.SafeHtml;
public interface SparseHtmlFile {
/** @return the line of formatted HTML. */
SafeHtml getSafeHtmlLine(int lineNo);
/** @return the number of lines in this sparse list. */
int size();
/** @return true if the line is valid in this sparse list. */
boolean contains(int idx);
/** @return true if this line ends in the middle of a character edit span. */
boolean hasTrailingEdit(int idx);
}

View File

@@ -1,98 +0,0 @@
/* Copyright (C) 2009 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 .wse;
@external .lecr;
@external .vt;
@external .wdd;
@external .wdi;
@external .str;
@external .kwd;
@external .com;
@external .typ;
@external .lit;
@external .pun;
@external .pln;
@external .tag;
@external .atn;
@external .atv;
@external .dec;
.wse {
background: red;
cursor: pointer;
}
.lecr {
border-bottom: #aaaaaa 1px dashed;
border-left: #aaaaaa 1px dashed;
padding-bottom: 0px;
margin: 0px 2px;
padding-left: 2px;
padding-right: 2px;
border-top: #aaaaaa 1px dashed;
border-right: #aaaaaa 1px dashed;
padding-top: 0px;
cursor: pointer;
}
.vt,
.vt .str,
.vt .kwd,
.vt .com,
.vt .typ,
.vt .lit,
.vt .pun,
.vt .pln,
.vt .tag,
.vt .atn,
.vt .atv,
.vt .dec {
color: red;
}
.wdd {
background: #FAA;
}
.wdi {
background: #9F9;
}
/* Use special rules for special styles contained within a whitespace
* error. For these we want the whitespace error to take precedence
* so we have to override the contained style.
*/
.wse .vt, .wdd .vt,
.wse .vt .pun, .wdd .vt .pun,
.wse .vt .str, .wdd .vt .str,
.wse .vt .kwd, .wdd .vt .kwd,
.wse .vt .com, .wdd .vt .com,
.wse .vt .typ, .wdd .vt .typ,
.wse .vt .lit, .wdd .vt .lit,
.wse .vt .pun, .wdd .vt .pun,
.wse .vt .pln, .wdd .vt .pln,
.wse .vt .tag, .wdd .vt .tag,
.wse .vt .atn, .wdd .vt .atn,
.wse .vt .atv, .wdd .vt .atv,
.wse .vt .dec, .wdd .vt .dec {
color: black;
}
.wse .wdd {
background: red;
}
.wse .wdi {
background: red;
}

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\n\r]*/,null,"#"],["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[ES]?BANK=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[!-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["apollo","agc","aea"]);

View File

@@ -1,3 +0,0 @@
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["str",/^"(?:[^\n\r"\\]|\\.)*(?:"|$)/,a,'"'],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["com",/^REM[^\n\r]*/,a],["kwd",/^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/,a],["pln",/^[a-z][^\W_]?(?:\$|%)?/i,a],["lit",/^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i,a,"0123456789"],["pun",
/^.[^\s\w"$%.]*/,a]]),["basic","cbm"]);

View File

@@ -1,18 +0,0 @@
/*
Copyright (C) 2011 Google Inc.
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.
*/
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a],
["typ",/^:[\dA-Za-z-]+/]]),["clj"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n\u000c"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]+)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],
["com",/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}\b/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);

View File

@@ -1,3 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"]],[["com",/^#!.*/],["kwd",/^\b(?:import|library|part of|part|as|show|hide)\b/i],["com",/^\/\/.*/],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["kwd",/^\b(?:class|interface)\b/i],["kwd",/^\b(?:assert|break|case|catch|continue|default|do|else|finally|for|if|in|is|new|return|super|switch|this|throw|try|while)\b/i],["kwd",/^\b(?:abstract|const|extends|factory|final|get|implements|native|operator|set|static|typedef|var)\b/i],
["typ",/^\b(?:bool|double|dynamic|int|num|object|string|void)\b/i],["kwd",/^\b(?:false|null|true)\b/i],["str",/^r?'''[\S\s]*?[^\\]'''/],["str",/^r?"""[\S\s]*?[^\\]"""/],["str",/^r?'('|[^\n\f\r]*?[^\\]')/],["str",/^r?"("|[^\n\f\r]*?[^\\]")/],["pln",/^[$_a-z]\w*/i],["pun",/^[!%&*+/:<-?^|~-]/],["lit",/^\b0x[\da-f]+/i],["lit",/^\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i],["lit",/^\b\.\d+(?:e[+-]?\d+)?/i],["pun",/^[(),.;[\]{}]/]]),
["dart"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["lit",/^[a-z]\w*/],["lit",/^'(?:[^\n\f\r'\\]|\\[^&])+'?/,null,"'"],["lit",/^\?[^\t\n ({]+/,null,"?"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\n]*/],["kwd",/^(?:module|attributes|do|let|in|letrec|apply|call|primop|case|of|end|when|fun|try|catch|receive|after|char|integer|float,atom,string,var)\b/],
["kwd",/^-[_a-z]+/],["typ",/^[A-Z_]\w*/],["pun",/^[,.;]/]]),["erlang","erl"]);

View File

@@ -1 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["pln",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])+(?:'|$)|`[^`]*(?:`|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\/\*[\S\s]*?\*\/)/],["pln",/^(?:[^"'/`]|\/(?![*/]))+/]]),["go"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/,
null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]);

View File

@@ -1,3 +0,0 @@
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a],
["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","lsp","scm","ss","rkt"]);

View File

@@ -1 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^!?"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["com",/^;[^\n\r]*/,null,";"]],[["pln",/^[!%@](?:[$\-.A-Z_a-z][\w$\-.]*|\d+)/],["kwd",/^[^\W\d]\w*/,null],["lit",/^\d+\.\d+/],["lit",/^(?:\d+|0[Xx][\dA-Fa-f]+)/],["pun",/^[(-*,:<->[\]{}]|\.\.\.$/]]),["llvm","ll"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\S\s]*?(?:]\1]|$)|[^\n\r]*)/],["str",/^\[(=*)\[[\S\s]*?(?:]\1]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],
["pln",/^[_a-z]\w*/i],["pun",/^[^\w\t\n\r \xa0][^\w\t\n\r "'+=\xa0-]*/]]),["lua"]);

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xa0]+(?:[$_a-z][\w']*|``[^\t\n\r`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])(?:'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\(\*[\S\s]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^(?:[_a-z][\w']*[!#?]?|``[^\t\n\r`]*(?:``|$))/i],["pun",/^[^\w\t\n\r "'\xa0]+/]]),["fs","ml"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"]|\\.)*"/,null,'"']],[["com",/^;[^\n\r]*/,null,";"],["dec",/^\$(?:d|device|ec|ecode|es|estack|et|etrap|h|horolog|i|io|j|job|k|key|p|principal|q|quit|st|stack|s|storage|sy|system|t|test|tl|tlevel|tr|trestart|x|y|z[a-z]*|a|ascii|c|char|d|data|e|extract|f|find|fn|fnumber|g|get|j|justify|l|length|na|name|o|order|p|piece|ql|qlength|qs|qsubscript|q|query|r|random|re|reverse|s|select|st|stack|t|text|tr|translate|nan)\b/i,
null],["kwd",/^(?:[^$]b|break|c|close|d|do|e|else|f|for|g|goto|h|halt|h|hang|i|if|j|job|k|kill|l|lock|m|merge|n|new|o|open|q|quit|r|read|s|set|tc|tcommit|tre|trestart|tro|trollback|ts|tstart|u|use|v|view|w|write|x|xecute)\b/i,null],["lit",/^[+-]?(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?/i],["pln",/^[a-z][^\W_]*/i],["pun",/^[^\w\t\n\r"$%;^\xa0]|_/]]),["mumps"]);

View File

@@ -1,4 +0,0 @@
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/,
a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/,
a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]);

View File

@@ -1,3 +0,0 @@
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["str",/^'(?:[^\n\r'\\]|\\.)*(?:'|$)/,a,"'"],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["com",/^\(\*[\S\s]*?(?:\*\)|$)|^{[\S\s]*?(?:}|$)/,a],["kwd",/^(?:absolute|and|array|asm|assembler|begin|case|const|constructor|destructor|div|do|downto|else|end|external|for|forward|function|goto|if|implementation|in|inline|interface|interrupt|label|mod|not|object|of|or|packed|procedure|program|record|repeat|set|shl|shr|then|to|type|unit|until|uses|var|virtual|while|with|xor)\b/i,a],
["lit",/^(?:true|false|self|nil)/i,a],["pln",/^[a-z][^\W_]*/i,a],["lit",/^(?:\$[\da-f]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)/i,a,"0123456789"],["pun",/^.[^\s\w$'./@]*/,a]]),["pascal"]);

View File

@@ -1 +0,0 @@
PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^'\\]|\\[\S\s])*(?:'|$)/,null,"'"]],[["com",/^#.*/],["kwd",/^(?:if|else|for|while|repeat|in|next|break|return|switch|function)(?![\w.])/],["lit",/^0[Xx][\dA-Fa-f]+([Pp]\d+)?[Li]?/],["lit",/^[+-]?(\d+(\.\d+)?|\.\d+)([Ee][+-]?\d+)?[Li]?/],["lit",/^(?:NULL|NA(?:_(?:integer|real|complex|character)_)?|Inf|TRUE|FALSE|NaN|\.\.(?:\.|\d+))(?![\w.])/],
["pun",/^(?:<<?-|->>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|[!*+/^]|%.*?%|[$=@~]|:{1,3}|[(),;?[\]{}])/],["pln",/^(?:[A-Za-z]+[\w.]*|\.[^\W\d][\w.]*)(?![\w.])/],["str",/^`.+`/]]),["r","s","R","S","Splus"]);

View File

@@ -1 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\n\r]*/,null,"%"]],[["lit",/^\\(?:cr|l?dots|R|tab)\b/],["kwd",/^\\[@-Za-z]+/],["kwd",/^#(?:ifn?def|endif)/],["pln",/^\\[{}]/],["pun",/^[()[\]{}]+/]]),["Rd","rd"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:""(?:""?(?!")|[^"\\]|\\.)*"{0,3}|(?:[^\n\r"\\]|\\.)*"?)/,null,'"'],["lit",/^`(?:[^\n\r\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&(--:-@[-^{-~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\n\r'\\]|\\(?:'|[^\n\r']+))'/],["lit",/^'[$A-Z_a-z][\w$]*(?![\w$'])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/],
["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:0(?:[0-7]+|x[\da-f]+)l?|(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:e[+-]?\d+)?f?|l?)|\\.\d+(?:e[+-]?\d+)?f?)/i],["typ",/^[$_]*[A-Z][\d$A-Z_]*[a-z][\w$]*/],["pln",/^[$A-Z_a-z][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\n\r]*|\/\*[\S\s]*?(?:\*\/|$))/],["kwd",/^(?:add|all|alter|and|any|apply|as|asc|authorization|backup|begin|between|break|browse|bulk|by|cascade|case|check|checkpoint|close|clustered|coalesce|collate|column|commit|compute|connect|constraint|contains|containstable|continue|convert|create|cross|current|current_date|current_time|current_timestamp|current_user|cursor|database|dbcc|deallocate|declare|default|delete|deny|desc|disk|distinct|distributed|double|drop|dummy|dump|else|end|errlvl|escape|except|exec|execute|exists|exit|fetch|file|fillfactor|following|for|foreign|freetext|freetexttable|from|full|function|goto|grant|group|having|holdlock|identity|identitycol|identity_insert|if|in|index|inner|insert|intersect|into|is|join|key|kill|left|like|lineno|load|match|matched|merge|natural|national|nocheck|nonclustered|nocycle|not|null|nullif|of|off|offsets|on|open|opendatasource|openquery|openrowset|openxml|option|or|order|outer|over|partition|percent|pivot|plan|preceding|precision|primary|print|proc|procedure|public|raiserror|read|readtext|reconfigure|references|replication|restore|restrict|return|revoke|right|rollback|rowcount|rowguidcol|rows?|rule|save|schema|select|session_user|set|setuser|shutdown|some|start|statistics|system_user|table|textsize|then|to|top|tran|transaction|trigger|truncate|tsequal|unbounded|union|unique|unpivot|update|updatetext|use|user|using|values|varying|view|waitfor|when|where|while|with|within|writetext|xml)(?=[^\w-]|$)/i,
null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^[_a-z][\w-]*/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'+\xa0-]*/]]),["sql"]);

View File

@@ -1,3 +0,0 @@
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["opn",/^{+/,a,"{"],["clo",/^}+/,a,"}"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:after|append|apply|array|break|case|catch|continue|error|eval|exec|exit|expr|for|foreach|if|incr|info|proc|return|set|switch|trace|uplevel|upvar|while)\b/,a],["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",
/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["tcl"]);

View File

@@ -1 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\n\r]*/,null,"%"]],[["kwd",/^\\[@-Za-z]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[()=[\]{}]+/]]),["latex","tex"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0\u2028\u2029]+/,null,"\t\n\r \u00a0\u2028\u2029"],["str",/^(?:["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})(?:["\u201c\u201d]c|$)|["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})*(?:["\u201c\u201d]|$))/i,null,'"\u201c\u201d'],["com",/^['\u2018\u2019](?:_(?:\r\n?|[^\r]?)|[^\n\r_\u2028\u2029])*/,null,"'\u2018\u2019"]],[["kwd",/^(?:addhandler|addressof|alias|and|andalso|ansi|as|assembly|auto|boolean|byref|byte|byval|call|case|catch|cbool|cbyte|cchar|cdate|cdbl|cdec|char|cint|class|clng|cobj|const|cshort|csng|cstr|ctype|date|decimal|declare|default|delegate|dim|directcast|do|double|each|else|elseif|end|endif|enum|erase|error|event|exit|finally|for|friend|function|get|gettype|gosub|goto|handles|if|implements|imports|in|inherits|integer|interface|is|let|lib|like|long|loop|me|mod|module|mustinherit|mustoverride|mybase|myclass|namespace|new|next|not|notinheritable|notoverridable|object|on|option|optional|or|orelse|overloads|overridable|overrides|paramarray|preserve|private|property|protected|public|raiseevent|readonly|redim|removehandler|resume|return|select|set|shadows|shared|short|single|static|step|stop|string|structure|sub|synclock|then|throw|to|try|typeof|unicode|until|variant|wend|when|while|with|withevents|writeonly|xor|endif|gosub|let|variant|wend)\b/i,
null],["com",/^rem\b.*/i],["lit",/^(?:true\b|false\b|nothing\b|\d+(?:e[+-]?\d+[dfr]?|[dfilrs])?|(?:&h[\da-f]+|&o[0-7]+)[ils]?|\d*\.\d+(?:e[+-]?\d+)?[dfr]?|#\s+(?:\d+[/-]\d+[/-]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:am|pm))?)?|\d+:\d+(?::\d+)?(\s*(?:am|pm))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*(?:\[[!#%&@]+])?|\[(?:[a-z]|_\w)\w*])/i],["pun",/^[^\w\t\n\r "'[\]\xa0\u2018\u2019\u201c\u201d\u2028\u2029]+/],["pun",/^(?:\[|])/]]),["vb","vbs"]);

View File

@@ -1,3 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"]],[["str",/^(?:[box]?"(?:[^"]|"")*"|'.')/i],["com",/^--[^\n\r]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i,
null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^'(?:active|ascending|base|delayed|driving|driving_value|event|high|image|instance_name|last_active|last_event|last_value|left|leftof|length|low|path_name|pos|pred|quiet|range|reverse_range|right|rightof|simple_name|stable|succ|transaction|val|value)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w.\\]+#(?:[+-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:e[+-]?\d+(?:_\d+)*)?)/i],
["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'\xa0-]*/]]),["vhdl","vhd"]);

View File

@@ -1,2 +0,0 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\d\t a-gi-z\xa0]+/,null,"\t \u00a0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[*=[\]^~]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^[A-Z][a-z][\da-z]+[A-Z][a-z][^\W_]+\b/],["lang-",/^{{{([\S\s]+?)}}}/],["lang-",/^`([^\n\r`]+)`/],["str",/^https?:\/\/[^\s#/?]*(?:\/[^\s#?]*)?(?:\?[^\s#]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\S\s])[^\n\r#*=A-[^`h{~]*/]]),["wiki"]);
PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"]);

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
var a=null;
PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]);