Merge "Remove target=_self from commentlinks"
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index 28ecc97..10a2ff3 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -1728,6 +1728,10 @@
Retrieves the external ids of a user account.
+Only external ids belonging to the caller may be requested. Users that have
+link:access-control.html#capability_modifyAccount[Modify Account] can request
+external ids that belong to other accounts.
+
.Request
----
GET /a/accounts/self/external.ids HTTP/1.0
@@ -1761,7 +1765,9 @@
Delete a list of external ids for a user account. The target external ids must
be provided as a list in the request body.
-Only external ids belonging to the caller may be deleted.
+Only external ids belonging to the caller may be deleted. Users that have
+link:access-control.html#capability_modifyAccount[Modify Account] can delete
+external ids that belong to other accounts.
.Request
----
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 3b243b0..59af694 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -6266,7 +6266,7 @@
|`tag` |optional, drafts only|
Value of the `tag` field. Only allowed on link:#create-draft[draft comment] +
inputs; for published comments, use the `tag` field in +
-link#review-input[ReviewInput]. Votes/comments that contain `tag` with
+link:#review-input[ReviewInput]. Votes/comments that contain `tag` with
'autogenerated:' prefix can be filtered out in the web UI.
|`unresolved` |optional|
Whether or not the comment must be addressed by the user. This value will
diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
index 43470af..b6375c8 100644
--- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
+++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
@@ -186,12 +186,6 @@
if (urlParameterMap.containsKey("ce")) {
data.put("polyfillCE", "true");
}
- if (urlParameterMap.containsKey("sd")) {
- data.put("polyfillSD", "true");
- }
- if (urlParameterMap.containsKey("sc")) {
- data.put("polyfillSC", "true");
- }
if (urlParameterMap.containsKey("gf")) {
data.put("useGoogleFonts", "true");
}
diff --git a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index b32da89..89ebdc1 100644
--- a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -328,10 +328,10 @@
try (TraceContext traceContext = enableTracing(req, res)) {
List<IdString> path = splitPath(req);
- RequestInfo requestInfo = createRequestInfo(traceContext, requestUri(req), path);
- globals.requestListeners.runEach(l -> l.onRequest(requestInfo));
-
try (PerThreadCache ignored = PerThreadCache.create()) {
+ RequestInfo requestInfo = createRequestInfo(traceContext, requestUri(req), path);
+ globals.requestListeners.runEach(l -> l.onRequest(requestInfo));
+
// It's important that the PerformanceLogContext is closed before the response is sent to
// the client. Only this way it is ensured that the invocation of the PerformanceLogger
// plugins happens before the client sees the response. This is needed for being able to
@@ -1702,9 +1702,9 @@
if (rootCollection instanceof ProjectsCollection) {
requestInfo.project(Project.nameKey(resourceId));
} else if (rootCollection instanceof ChangesCollection) {
- ChangeNotes changeNotes = globals.changeFinder.findOne(resourceId);
- if (changeNotes != null) {
- requestInfo.project(changeNotes.getProjectName());
+ Optional<ChangeNotes> changeNotes = globals.changeFinder.findOne(resourceId);
+ if (changeNotes.isPresent()) {
+ requestInfo.project(changeNotes.get().getProjectName());
}
}
return requestInfo.build();
diff --git a/java/com/google/gerrit/server/account/CreateGroupArgs.java b/java/com/google/gerrit/server/account/CreateGroupArgs.java
index 2a764cc..ba58c3f 100644
--- a/java/com/google/gerrit/server/account/CreateGroupArgs.java
+++ b/java/com/google/gerrit/server/account/CreateGroupArgs.java
@@ -35,10 +35,6 @@
}
public void setGroupName(String n) {
- groupName = n != null ? AccountGroup.nameKey(n) : null;
- }
-
- public void setGroupName(AccountGroup.NameKey n) {
- groupName = n;
+ groupName = n != null ? AccountGroup.nameKey(n.trim()) : null;
}
}
diff --git a/java/com/google/gerrit/server/change/ChangeFinder.java b/java/com/google/gerrit/server/change/ChangeFinder.java
index da3650d..f2b6dd6 100644
--- a/java/com/google/gerrit/server/change/ChangeFinder.java
+++ b/java/com/google/gerrit/server/change/ChangeFinder.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
+import com.google.common.flogger.FluentLogger;
import com.google.common.primitives.Ints;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
@@ -54,6 +55,8 @@
@Singleton
public class ChangeFinder {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
private static final String CACHE_NAME = "changeid_project";
public static Module module() {
@@ -108,12 +111,12 @@
this.allowedIdTypes = ImmutableSet.copyOf(configuredChangeIdTypes);
}
- public ChangeNotes findOne(String id) {
+ public Optional<ChangeNotes> findOne(String id) {
List<ChangeNotes> ctls = find(id);
if (ctls.size() != 1) {
- return null;
+ return Optional.empty();
}
- return ctls.get(0);
+ return Optional.of(ctls.get(0));
}
/**
@@ -211,12 +214,12 @@
}
}
- public ChangeNotes findOne(Change.Id id) {
+ public Optional<ChangeNotes> findOne(Change.Id id) {
List<ChangeNotes> notes = find(id);
if (notes.size() != 1) {
- throw new NoSuchChangeException(id);
+ return Optional.empty();
}
- return notes.get(0);
+ return Optional.of(notes.get(0));
}
public List<ChangeNotes> find(Change.Id id) {
@@ -239,7 +242,11 @@
List<ChangeNotes> notes = new ArrayList<>(cds.size());
if (!indexConfig.separateChangeSubIndexes()) {
for (ChangeData cd : cds) {
- notes.add(cd.notes());
+ try {
+ notes.add(cd.notes());
+ } catch (NoSuchChangeException e) {
+ logger.atWarning().log("Change %s seen in index, but missing in NoteDb", e.getMessage());
+ }
}
return notes;
}
@@ -253,7 +260,11 @@
Set<Change.Id> seen = Sets.newHashSetWithExpectedSize(cds.size());
for (ChangeData cd : cds) {
if (seen.add(cd.getId())) {
- notes.add(cd.notes());
+ try {
+ notes.add(cd.notes());
+ } catch (NoSuchChangeException e) {
+ logger.atWarning().log("Change %s seen in index, but missing in NoteDb", e.getMessage());
+ }
}
}
return notes;
diff --git a/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java b/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java
index 42a8310..4a95b2e 100644
--- a/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/account/AccountQueryBuilder.java
@@ -41,6 +41,7 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
+import java.util.Optional;
/** Parses a query string meant to be applied to account objects. */
public class AccountQueryBuilder extends QueryBuilder<AccountState, AccountQueryBuilder> {
@@ -115,20 +116,23 @@
@Operator
public Predicate<AccountState> cansee(String change)
throws QueryParseException, PermissionBackendException {
- ChangeNotes changeNotes = args.changeFinder.findOne(change);
- if (changeNotes == null) {
+ Optional<ChangeNotes> changeNotes = args.changeFinder.findOne(change);
+ if (!changeNotes.isPresent()) {
throw error(String.format("change %s not found", change));
}
try {
- args.permissionBackend.user(args.getUser()).change(changeNotes).check(ChangePermission.READ);
+ args.permissionBackend
+ .user(args.getUser())
+ .change(changeNotes.get())
+ .check(ChangePermission.READ);
} catch (AuthException e) {
String msg = String.format("change %s not found", change);
logger.atSevere().withCause(e).log(msg);
throw error(msg);
}
- return AccountPredicates.cansee(args, changeNotes);
+ return AccountPredicates.cansee(args, changeNotes.get());
}
@Operator
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index f8610db..7401657 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -703,7 +703,7 @@
}
@Operator
- public Predicate<ChangeData> branch(String name) {
+ public Predicate<ChangeData> branch(String name) throws QueryParseException {
if (name.startsWith("^")) {
return ref("^" + RefNames.fullName(name.substring(1)));
}
@@ -732,7 +732,7 @@
}
@Operator
- public Predicate<ChangeData> ref(String ref) {
+ public Predicate<ChangeData> ref(String ref) throws QueryParseException {
if (ref.startsWith("^")) {
return new RegexRefPredicate(ref);
}
diff --git a/java/com/google/gerrit/server/query/change/RegexRefPredicate.java b/java/com/google/gerrit/server/query/change/RegexRefPredicate.java
index 6d404b4..b2dba72 100644
--- a/java/com/google/gerrit/server/query/change/RegexRefPredicate.java
+++ b/java/com/google/gerrit/server/query/change/RegexRefPredicate.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.query.change;
import com.google.gerrit.entities.Change;
+import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.index.change.ChangeField;
import dk.brics.automaton.RegExp;
import dk.brics.automaton.RunAutomaton;
@@ -22,7 +23,7 @@
public class RegexRefPredicate extends ChangeRegexPredicate {
protected final RunAutomaton pattern;
- public RegexRefPredicate(String re) {
+ public RegexRefPredicate(String re) throws QueryParseException {
super(ChangeField.REF, re);
if (re.startsWith("^")) {
@@ -33,7 +34,11 @@
re = re.substring(0, re.length() - 1);
}
- this.pattern = new RunAutomaton(new RegExp(re).toAutomaton());
+ try {
+ this.pattern = new RunAutomaton(new RegExp(re).toAutomaton());
+ } catch (IllegalArgumentException e) {
+ throw new QueryParseException(String.format("invalid regular expression: %s", re), e);
+ }
}
@Override
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
index 80f0bb1..445a5d6 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
@@ -73,7 +73,7 @@
public Response<?> apply(AccountResource resource, List<String> extIds)
throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException {
if (!self.get().hasSameAccountId(resource.getUser())) {
- permissionBackend.currentUser().check(GlobalPermission.ACCESS_DATABASE);
+ permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
}
if (extIds == null || extIds.isEmpty()) {
diff --git a/java/com/google/gerrit/server/restapi/account/GetExternalIds.java b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
index c5b4454..a3c48b9 100644
--- a/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
@@ -67,7 +67,7 @@
public Response<List<AccountExternalIdInfo>> apply(AccountResource resource)
throws RestApiException, IOException, PermissionBackendException {
if (!self.get().hasSameAccountId(resource.getUser())) {
- permissionBackend.currentUser().check(GlobalPermission.ACCESS_DATABASE);
+ permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
}
Collection<ExternalId> ids = externalIds.byAccount(resource.getUser().getAccountId());
diff --git a/java/com/google/gerrit/sshd/commands/PatchSetParser.java b/java/com/google/gerrit/sshd/commands/PatchSetParser.java
index f804c2d..4ebf15e 100644
--- a/java/com/google/gerrit/sshd/commands/PatchSetParser.java
+++ b/java/com/google/gerrit/sshd/commands/PatchSetParser.java
@@ -22,7 +22,6 @@
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.change.ChangeFinder;
import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
@@ -32,6 +31,7 @@
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
@Singleton
public class PatchSetParser {
@@ -126,12 +126,11 @@
if (projectState != null) {
return notesFactory.create(projectState.getNameKey(), changeId);
}
- try {
- ChangeNotes notes = changeFinder.findOne(changeId);
- return notesFactory.create(notes.getProjectName(), changeId);
- } catch (NoSuchChangeException e) {
- throw error("\"" + changeId + "\" no such change", e);
+ Optional<ChangeNotes> notes = changeFinder.findOne(changeId);
+ if (!notes.isPresent()) {
+ throw error("\"" + changeId + "\" no such change");
}
+ return notesFactory.create(notes.get().getProjectName(), changeId);
}
private static boolean inProject(Change change, ProjectState projectState) {
diff --git a/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java
index bf5acee..52bff58 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/QueryChangeIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import static javax.servlet.http.HttpServletResponse.SC_OK;
@@ -31,6 +32,7 @@
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.server.restapi.change.QueryChanges;
import com.google.inject.Inject;
@@ -225,6 +227,26 @@
assertThat(queryChanges.apply(TopLevelResource.INSTANCE).statusCode()).isEqualTo(SC_OK);
}
+ @Test
+ public void defaultQueryCannotBeParsedDueToInvalidRegEx() throws Exception {
+ QueryChanges queryChanges = queryChangesProvider.get();
+ queryChanges.addQuery("^[A");
+ BadRequestException e =
+ assertThrows(
+ BadRequestException.class, () -> queryChanges.apply(TopLevelResource.INSTANCE));
+ assertThat(e).hasMessageThat().contains("no viable alternative at character '['");
+ }
+
+ @Test
+ public void defaultQueryWithInvalidQuotedRegEx() throws Exception {
+ QueryChanges queryChanges = queryChangesProvider.get();
+ queryChanges.addQuery("\"^[A\"");
+ BadRequestException e =
+ assertThrows(
+ BadRequestException.class, () -> queryChanges.apply(TopLevelResource.INSTANCE));
+ assertThat(e).hasMessageThat().isEqualTo("invalid regular expression: [A");
+ }
+
private static void assertNoChangeHasMoreChangesSet(List<ChangeInfo> results) {
for (ChangeInfo info : results) {
assertThat(info._moreChanges).isNull();
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
index 17a0ea6..30eaf22 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
@@ -363,6 +363,13 @@
}
@Test
+ public void createGroupNameIsTrimmed() throws Exception {
+ String newGroupName = name("newGroup");
+ GroupInfo g = gApi.groups().create(" " + newGroupName + " ").get();
+ assertGroupInfo(group(newGroupName), g);
+ }
+
+ @Test
public void createDuplicateInternalGroupCaseSensitiveName_Conflict() throws Exception {
String dupGroupName = name("dupGroup");
gApi.groups().create(dupGroupName);
@@ -1349,17 +1356,6 @@
}
@Test
- public void groupNamesWithLeadingAndTrailingWhitespace() throws Exception {
- for (String leading : ImmutableList.of("", " ", " ")) {
- for (String trailing : ImmutableList.of("", " ", " ")) {
- String name = leading + name("group") + trailing;
- GroupInfo g = gApi.groups().create(name).get();
- assertThat(g.name).isEqualTo(name);
- }
- }
- }
-
- @Test
@Sandboxed
public void groupsOfUserCanBeListedInSlaveMode() throws Exception {
GroupInput groupInput = new GroupInput();
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java b/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
index 6e16435..53e871f 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
@@ -132,14 +132,14 @@
AuthException thrown =
assertThrows(
AuthException.class, () -> gApi.accounts().id(admin.id().get()).getExternalIds());
- assertThat(thrown).hasMessageThat().contains("access database not permitted");
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
- public void getExternalIdsOfOtherUserWithAccessDatabase() throws Exception {
+ public void getExternalIdsOfOtherUserWithModifyAccount() throws Exception {
projectOperations
.allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
.update();
Collection<ExternalId> expectedIds = getAccountState(admin.id()).externalIds();
@@ -193,7 +193,7 @@
gApi.accounts()
.id(admin.id().get())
.deleteExternalIds(extIds.stream().map(e -> e.identity).collect(toList())));
- assertThat(thrown).hasMessageThat().contains("access database not permitted");
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
@@ -213,10 +213,10 @@
}
@Test
- public void deleteExternalIdsOfOtherUserWithAccessDatabase() throws Exception {
+ public void deleteExternalIdsOfOtherUserWithModifyAccount() throws Exception {
projectOperations
.allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
.update();
List<AccountExternalIdInfo> externalIds = gApi.accounts().self().getExternalIds();
@@ -464,7 +464,7 @@
public void readExternalIdsWhenInvalidExternalIdsExist() throws Exception {
projectOperations
.allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
.update();
requestScopeOperations.resetCurrentApiUser();
diff --git a/plugins/replication b/plugins/replication
index 8be6db9..718d621 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 8be6db961b2c6c3a32e0b3db2f04475ca2c4c520
+Subproject commit 718d6210721cbfc38bbac6a3d976636fe17e4b72
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index 51fabe8..ff6a093 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -255,6 +255,9 @@
gr-messages-list {
display: block;
}
+ gr-thread-list {
+ min-height: 250px;
+ }
#includedInOverlay {
width: 65em;
}
@@ -617,7 +620,7 @@
change="[[_change]]"
change-num="[[_changeNum]]"
logged-in="[[_loggedIn]]"
- comment-tab="[[_currentView]]"
+ tab="[[_findings_tab_name]]"
hide-toggle-buttons
on-thread-list-modified="_handleReloadDiffComments"></gr-thread-list>
</template>
@@ -672,7 +675,6 @@
threads="[[_commentThreads]]"
change="[[_change]]"
change-num="[[_changeNum]]"
- comment-tab="[[_currentView]]"
logged-in="[[_loggedIn]]"
only-show-robot-comments-with-human-reply
on-thread-list-modified="_handleReloadDiffComments"></gr-thread-list>
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
index 8fc61b7..53e852f 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
@@ -36,6 +36,7 @@
<link rel="import" href="../../shared/gr-select/gr-select.html">
<link rel="import" href="../../shared/gr-count-string-formatter/gr-count-string-formatter.html">
<link rel="import" href="../../shared/gr-tooltip-content/gr-tooltip-content.html">
+<link rel="import" href="../../shared/gr-copy-clipboard/gr-copy-clipboard.html">
<link rel="import" href="../gr-file-list-constants.html">
<dom-module id="gr-file-list">
@@ -115,14 +116,10 @@
.path {
cursor: pointer;
flex: 1;
- text-decoration: none;
/* Wrap it into multiple lines if too long. */
white-space: normal;
word-break: break-word;
}
- .path:hover :first-child {
- text-decoration: underline;
- }
.oldPath {
color: var(--deemphasized-text-color);
}
@@ -245,6 +242,26 @@
display: inline-block;
margin: -2px 0;
padding: var(--spacing-s) 0;
+ text-decoration: none;
+ }
+ .pathLink:hover {
+ text-decoration: underline;
+ }
+
+ /** copy on file path **/
+ .pathLink gr-copy-clipboard,
+ .oldPath gr-copy-clipboard {
+ display: inline-block;
+ visibility: hidden;
+ vertical-align: bottom;
+ text-decoration: none;
+ --gr-button: {
+ padding: 0px;
+ }
+ }
+ .pathLink:hover gr-copy-clipboard,
+ .oldPath:hover gr-copy-clipboard {
+ visibility: visible;
}
/** small screen breakpoint: 768px */
@@ -273,7 +290,7 @@
}
.expanded .fullFileName,
.truncatedFileName {
- display: block;
+ display: inline;
}
.expanded .truncatedFileName,
.fullFileName {
@@ -330,11 +347,18 @@
class="truncatedFileName">
[[computeTruncatedPath(file.__path)]]
</span>
+ <gr-copy-clipboard
+ hide-input
+ text="[[file.__path]]"></gr-copy-clipboard>
</a>
- <div class="oldPath" hidden$="[[!file.old_path]]" hidden
- title$="[[file.old_path]]">
- [[file.old_path]]
- </div>
+ <template is="dom-if" if="[[file.old_path]]">
+ <div class="oldPath" title$="[[file.old_path]]">
+ [[file.old_path]]
+ <gr-copy-clipboard
+ hide-input
+ text="[[file.old_path]]"></gr-copy-clipboard>
+ </div>
+ </template>
</span>
<div class="comments desktop">
<span class="drafts">
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.html b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
index b807b37..f7ef7e6 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
@@ -36,7 +36,6 @@
</style>
<style include="shared-styles">
:host {
- border-bottom: 1px solid var(--border-color);
display: block;
position: relative;
cursor: pointer;
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
index 6154ca5..60ec6b0 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
@@ -64,6 +64,9 @@
align-items: center;
display: flex;
}
+ gr-message:not(:last-of-type) {
+ border-bottom: 1px solid var(--border-color);
+ }
gr-message:nth-child(2n) {
background-color: var(--background-color-secondary);
}
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
index eacc0d0..f04a39a 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
@@ -25,7 +25,6 @@
<style include="shared-styles">
#threads {
display: block;
- min-height: 20rem;
padding: var(--spacing-l);
}
gr-comment-thread {
@@ -76,7 +75,7 @@
</template>
<div id="threads">
<template is="dom-if" if="[[!threads.length]]">
- [[_computeNoThreadsMessage(commentTab)]]
+ [[_computeNoThreadsMessage(tab)]]
</template>
<template
is="dom-repeat"
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.js b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.js
index d8c7b61..e99367e 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.js
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.js
@@ -27,12 +27,7 @@
+ 'for this change.';
const NO_ROBOT_COMMENTS_THREADS_MESSAGE = 'There are no findings for this ' +
'patchset.';
-
- const CommentTabs = {
- CHANGE_LOG: 0,
- COMMENT_THREADS: 1,
- ROBOT_COMMENTS: 2,
- };
+ const FINDINGS_TAB_NAME = '__gerrit_internal_findings';
class GrThreadList extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
@@ -73,7 +68,10 @@
type: Boolean,
value: false,
},
- commentTab: Number,
+ tab: {
+ type: String,
+ value: '',
+ },
};
}
@@ -83,8 +81,8 @@
return loggedIn ? 'show' : '';
}
- _computeNoThreadsMessage(commentTab) {
- if (commentTab === CommentTabs.ROBOT_COMMENTS) {
+ _computeNoThreadsMessage(tab) {
+ if (tab === FINDINGS_TAB_NAME) {
return NO_ROBOT_COMMENTS_THREADS_MESSAGE;
}
return NO_THREADS_MESSAGE;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
index 5797ff7..18ffc0e 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
@@ -325,6 +325,7 @@
</div>
<div>
<a
+ tabIndex="-1"
on-click="_onRespectfulReadMoreClick"
href="https://testing.googleblog.com/2019/11/code-health-respectful-reviews-useful.html"
target="_blank">
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.js b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.js
index 2ce03e3..9be6852 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.js
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.js
@@ -53,7 +53,10 @@
Polymer.dom(e).rootTarget.select();
}
- _copyToClipboard() {
+ _copyToClipboard(e) {
+ e.preventDefault();
+ e.stopPropagation();
+
if (this.hideInput) {
this.$.input.style.display = 'block';
}
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
index 55eb198..05014f1 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
@@ -90,5 +90,16 @@
flushAsynchronousOperations();
assert.equal(getComputedStyle(element.$.input).display, 'none');
});
+
+ test('stop events propagation', () => {
+ const divParent = document.createElement('div');
+ divParent.appendChild(element);
+ const clickStub = sinon.stub();
+ divParent.addEventListener('click', clickStub);
+ element.stopPropagation = true;
+ const copyBtn = element.shadowRoot.querySelector('.copyToClipboard');
+ MockInteractions.tap(copyBtn);
+ assert.isFalse(clickStub.called);
+ });
});
</script>
diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
index dbb47a3..212f504 100644
--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
+++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
@@ -25,8 +25,6 @@
{@param? faviconPath: ?}
{@param? versionInfo: ?}
{@param? polyfillCE: ?}
- {@param? polyfillSD: ?}
- {@param? polyfillSC: ?}
{@param? useGoogleFonts: ?}
{@param? changeRequestsPath: ?}
{@param? defaultChangeDetailHex: ?}
@@ -62,8 +60,6 @@
{if $staticResourcePath != ''}window.STATIC_RESOURCE_PATH = '{$staticResourcePath}';{/if}
{if $assetsPath}window.ASSETS_PATH = '{$assetsPath}';{/if}
{if $polyfillCE}if (window.customElements) window.customElements.forcePolyfill = true;{/if}
- {if $polyfillSD}{literal}ShadyDOM = { force: true };{/literal}{/if}
- {if $polyfillSC}{literal}ShadyCSS = { shimcssproperties: true};{/literal}{/if}
{if $gerritInitialData}
// INITIAL_DATA is a string that represents a JSON map. It's inlined here so that we can
// spare calls to the API when starting up the app.