Merge "Fix more to support undefined behaviour"
diff --git a/Documentation/user-request-tracing.txt b/Documentation/user-request-tracing.txt
index 1123775..e684b85 100644
--- a/Documentation/user-request-tracing.txt
+++ b/Documentation/user-request-tracing.txt
@@ -87,8 +87,7 @@
`AutoRetry`. For each auto-retry that happened this should match 1 or 2
log entries:
-* one `ERROR` log entry with the exception that triggered the
- auto-retry
+* one `FINE` log entry with the exception that triggered the auto-retry
* one `FINE` log entry with the exception that happened on auto-retry
(if this log entry is not present the operation succeeded on
auto-retry)
diff --git a/Jenkinsfile b/Jenkinsfile
index 756c1d4..7417bb3 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -63,17 +63,15 @@
}
def getCheckResultFromBuild() {
- switch(build.result) {
- case 'SUCCESS':
- return "SUCCESSFUL"
- case 'NOT_BUILT':
- case 'ABORTED':
- return "NOT_STARTED"
- case 'FAILURE':
- case 'UNSTABLE':
- default:
- return "FAILED"
+ def resultString = build.result.toString()
+ if (resultString == 'SUCCESS') {
+ return "SUCCESSFUL"
+ } else if (resultString == 'NOT_BUILT' || resultString == 'ABORTED') {
+ return "NOT_STARTED"
}
+
+ // Remaining options: 'FAILURE' or 'UNSTABLE':
+ return "FAILED"
}
}
diff --git a/java/com/google/gerrit/acceptance/AccountIndexedCounter.java b/java/com/google/gerrit/acceptance/AccountIndexedCounter.java
new file mode 100644
index 0000000..88b97c7
--- /dev/null
+++ b/java/com/google/gerrit/acceptance/AccountIndexedCounter.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2020 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.acceptance;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.util.concurrent.AtomicLongMap;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.extensions.common.AccountInfo;
+import com.google.gerrit.extensions.events.AccountIndexedListener;
+
+/** Checks if an account is indexed the correct number of times. */
+public class AccountIndexedCounter implements AccountIndexedListener {
+ private final AtomicLongMap<Integer> countsByAccount = AtomicLongMap.create();
+
+ @Override
+ public void onAccountIndexed(int id) {
+ countsByAccount.incrementAndGet(id);
+ }
+
+ public void clear() {
+ countsByAccount.clear();
+ }
+
+ public void assertReindexOf(TestAccount testAccount) {
+ assertReindexOf(testAccount, 1);
+ }
+
+ public void assertReindexOf(AccountInfo accountInfo) {
+ assertReindexOf(Account.id(accountInfo._accountId), 1);
+ }
+
+ public void assertReindexOf(TestAccount testAccount, long expectedCount) {
+ assertThat(countsByAccount.asMap()).containsExactly(testAccount.id().get(), expectedCount);
+ clear();
+ }
+
+ public void assertReindexOf(Account.Id accountId, long expectedCount) {
+ assertThat(countsByAccount.asMap()).containsEntry(accountId.get(), expectedCount);
+ countsByAccount.remove(accountId.get());
+ }
+
+ public void assertNoReindex() {
+ assertThat(countsByAccount.asMap()).isEmpty();
+ }
+}
diff --git a/java/com/google/gerrit/server/git/PermissionAwareReadOnlyRefDatabase.java b/java/com/google/gerrit/server/git/PermissionAwareReadOnlyRefDatabase.java
index 060000a..8c9ebeb 100644
--- a/java/com/google/gerrit/server/git/PermissionAwareReadOnlyRefDatabase.java
+++ b/java/com/google/gerrit/server/git/PermissionAwareReadOnlyRefDatabase.java
@@ -23,7 +23,6 @@
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.inject.Inject;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
@@ -50,7 +49,6 @@
private final PermissionBackend.ForProject forProject;
- @Inject
PermissionAwareReadOnlyRefDatabase(
Repository delegateRepository, PermissionBackend.ForProject forProject) {
super(delegateRepository);
@@ -100,16 +98,14 @@
@SuppressWarnings("deprecation")
@Override
public Map<String, Ref> getRefs(String prefix) throws IOException {
- Map<String, Ref> refs = getDelegate().getRefDatabase().getRefs(prefix);
+ List<Ref> refs = getDelegate().getRefDatabase().getRefsByPrefix(prefix);
if (refs.isEmpty()) {
- return refs;
+ return Collections.emptyMap();
}
Collection<Ref> result;
try {
- // The security filtering assumes to receive the same refMap, independently from the ref
- // prefix offset
- result = forProject.filter(refs.values(), getDelegate(), RefFilterOptions.defaults());
+ result = forProject.filter(refs, getDelegate(), RefFilterOptions.defaults());
} catch (PermissionBackendException e) {
throw new IOException("");
}
diff --git a/java/com/google/gerrit/server/git/meta/VersionedMetaData.java b/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
index bcd3bea..66482a9 100644
--- a/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
+++ b/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
@@ -27,6 +27,7 @@
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import java.io.BufferedReader;
+import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
@@ -416,14 +417,7 @@
update.fireGitRefUpdatedEvent(ru);
return revision;
case LOCK_FAILURE:
- throw new LockFailureException(
- "Cannot update "
- + ru.getName()
- + " in "
- + db.getDirectory()
- + ": "
- + ru.getResult(),
- ru);
+ throw new LockFailureException(errorMsg(ru, db.getDirectory()), ru);
case FORCED:
case IO_FAILURE:
case NOT_ATTEMPTED:
@@ -434,19 +428,18 @@
case REJECTED_MISSING_OBJECT:
case REJECTED_OTHER_REASON:
default:
- throw new GitUpdateFailureException(
- "Cannot update "
- + ru.getName()
- + " in "
- + db.getDirectory()
- + ": "
- + ru.getResult(),
- ru);
+ throw new GitUpdateFailureException(errorMsg(ru, db.getDirectory()), ru);
}
}
};
}
+ private String errorMsg(RefUpdate ru, File location) {
+ return String.format(
+ "Cannot update %s in %s : %s (%s)",
+ ru.getName(), location, ru.getResult(), ru.getRefLogMessage());
+ }
+
protected DirCache readTree(RevTree tree)
throws IOException, MissingObjectException, IncorrectObjectTypeException {
DirCache dc = DirCache.newInCore();
diff --git a/java/com/google/gerrit/server/restapi/account/AddSshKey.java b/java/com/google/gerrit/server/restapi/account/AddSshKey.java
index 1fcf0bd..f18cc67 100644
--- a/java/com/google/gerrit/server/restapi/account/AddSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/AddSshKey.java
@@ -44,6 +44,11 @@
import java.io.InputStream;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to add an SSH key for an account.
+ *
+ * <p>This REST endpoint handles {@code POST /accounts/<account-identifier>/sshkeys/} requests.
+ */
@Singleton
public class AddSshKey
implements RestCollectionModifyView<AccountResource, AccountResource.SshKey, SshKeyInput> {
diff --git a/java/com/google/gerrit/server/restapi/account/CreateEmail.java b/java/com/google/gerrit/server/restapi/account/CreateEmail.java
index ae45b68..fee5eab 100644
--- a/java/com/google/gerrit/server/restapi/account/CreateEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/CreateEmail.java
@@ -17,6 +17,7 @@
import static com.google.gerrit.extensions.client.AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT;
import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.common.UsedAt;
import com.google.gerrit.exceptions.EmailException;
import com.google.gerrit.extensions.api.accounts.EmailInput;
import com.google.gerrit.extensions.client.AccountFieldName;
@@ -47,6 +48,26 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint for registering a new email address for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT
+ * /accounts/<account-identifier>/emails/<email-identifier>} requests if the specified email doesn't
+ * exist for the account yet. If it already exists, the request is handled by {@link PutEmail}.
+ *
+ * <p>Whether an email address can be registered for the account depends on whether the used {@link
+ * Realm} supports this.
+ *
+ * <p>When a new email address is registered an email with a confirmation link is sent to that
+ * address. Only when the receiver confirms the email by clicking on the confirmation link, the
+ * email address is added to the account (see {@link
+ * com.google.gerrit.server.restapi.config.ConfirmEmail}). Confirming an email address for an
+ * account creates an external ID that links the email address to the account. An email address can
+ * only be added to an account if it is not assigned to any other account yet.
+ *
+ * <p>In some cases it is allowed to skip the email confirmation and add the email directly (calling
+ * user has 'Modify Account' capability or server is running in dev mode).
+ */
@Singleton
public class CreateEmail
implements RestCollectionCreateView<AccountResource, AccountResource.Email, EmailInput> {
@@ -101,6 +122,7 @@
}
/** To be used from plugins that want to create emails without permission checks. */
+ @UsedAt(UsedAt.Project.PLUGIN_SERVICEUSER)
public EmailInfo apply(IdentifiedUser user, IdString id, EmailInput input)
throws RestApiException, EmailException, MethodNotAllowedException, IOException,
ConfigInvalidException, PermissionBackendException {
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteActive.java b/java/com/google/gerrit/server/restapi/account/DeleteActive.java
index ffd7893..7295370 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteActive.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteActive.java
@@ -30,6 +30,15 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to mark an account as inactive.
+ *
+ * <p>This REST endpoint handles {@code DELETE /accounts/<account-identifier>/active} requests.
+ *
+ * <p>Inactive accounts cannot login into Gerrit.
+ *
+ * <p>Marking an account as active is handled by {@link PutActive}.
+ */
@RequiresCapability(GlobalCapability.MODIFY_ACCOUNT)
@Singleton
public class DeleteActive implements RestModifyView<AccountResource, Input> {
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
index 82b445f..442b6a4 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
@@ -44,6 +44,12 @@
import java.util.function.Function;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to delete external IDs from an account.
+ *
+ * <p>This REST endpoint handles {@code POST /accounts/<account-identifier>/external.ids:delete}
+ * requests.
+ */
@Singleton
public class DeleteExternalIds implements RestModifyView<AccountResource, List<String>> {
private final PermissionBackend permissionBackend;
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java b/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
index b470be8..f73f00a 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
@@ -36,6 +36,12 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+/**
+ * REST endpoint to delete an SSH key of an account.
+ *
+ * <p>This REST endpoint handles {@code DELETE
+ * /accounts/<account-identifier>/sshkeys/<ssh-key-identifier>} requests.
+ */
@Singleton
public class DeleteSshKey implements RestModifyView<AccountResource.SshKey, Input> {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java b/java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java
index 9f38b97..e070522 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java
@@ -39,6 +39,12 @@
import java.util.Objects;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to delete project watches from an account.
+ *
+ * <p>This REST endpoint handles {@code POST /accounts/<account-identifier>/watched.projects:delete}
+ * requests.
+ */
@Singleton
public class DeleteWatchedProjects
implements RestModifyView<AccountResource, List<ProjectWatchInfo>> {
diff --git a/java/com/google/gerrit/server/restapi/account/GetAccount.java b/java/com/google/gerrit/server/restapi/account/GetAccount.java
index 898b0bb..2b6a9e6 100644
--- a/java/com/google/gerrit/server/restapi/account/GetAccount.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAccount.java
@@ -23,6 +23,15 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>} requests.
+ *
+ * <p>In the response only a subset of fields is populated (see {@link
+ * AccountLoader#DETAILED_OPTIONS}). In contrast to this {@link GetDetail} populates all fields in
+ * the response.
+ */
@Singleton
public class GetAccount implements RestReadView<AccountResource> {
private final AccountLoader.Factory infoFactory;
diff --git a/java/com/google/gerrit/server/restapi/account/GetActive.java b/java/com/google/gerrit/server/restapi/account/GetActive.java
index 66493f8..38c740c 100644
--- a/java/com/google/gerrit/server/restapi/account/GetActive.java
+++ b/java/com/google/gerrit/server/restapi/account/GetActive.java
@@ -19,6 +19,13 @@
import com.google.gerrit.server.account.AccountResource;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get the active state of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/active} requests.
+ *
+ * <p>Only active accounts can login into Gerrit.
+ */
@Singleton
public class GetActive implements RestReadView<AccountResource> {
@Override
diff --git a/java/com/google/gerrit/server/restapi/account/GetAgreements.java b/java/com/google/gerrit/server/restapi/account/GetAgreements.java
index 572b489..aeaeb1c 100644
--- a/java/com/google/gerrit/server/restapi/account/GetAgreements.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAgreements.java
@@ -42,6 +42,14 @@
import java.util.List;
import org.eclipse.jgit.lib.Config;
+/**
+ * REST endpoint to get all contributor agreements that have been signed by an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/agreements} requests.
+ *
+ * <p>Contributor agreements are only available if contributor agreements have been enabled in
+ * {@code gerrit.config} (see {@code auth.contributorAgreements}).
+ */
@Singleton
public class GetAgreements implements RestReadView<AccountResource> {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
diff --git a/java/com/google/gerrit/server/restapi/account/GetAvatar.java b/java/com/google/gerrit/server/restapi/account/GetAvatar.java
index 3c1752d..5256d68 100644
--- a/java/com/google/gerrit/server/restapi/account/GetAvatar.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAvatar.java
@@ -26,6 +26,13 @@
import java.util.concurrent.TimeUnit;
import org.kohsuke.args4j.Option;
+/**
+ * REST endpoint to get the avatar image of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/avatar} requests.
+ *
+ * <p>Avatar images are only available if an {@link AvatarProvider} plugin is installed.
+ */
public class GetAvatar implements RestReadView<AccountResource> {
private final DynamicItem<AvatarProvider> avatarProvider;
diff --git a/java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java b/java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java
index e97e0a0..a26df64 100644
--- a/java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java
@@ -24,6 +24,15 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get the URL for changing the avatar image of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/avatar.change.url}
+ * requests.
+ *
+ * <p>Avatar images are only available if an {@link AvatarProvider} plugin is installed. Not all
+ * avatar plugins provide a URL for changing avatar images.
+ */
@Singleton
public class GetAvatarChangeUrl implements RestReadView<AccountResource> {
private final DynamicItem<AvatarProvider> avatarProvider;
diff --git a/java/com/google/gerrit/server/restapi/account/GetCapabilities.java b/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
index fa9ab18..f3d9557 100644
--- a/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
+++ b/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
@@ -49,6 +49,11 @@
import java.util.Set;
import org.kohsuke.args4j.Option;
+/**
+ * REST endpoint to list the global capabilities that are assigned to an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/capabilities/} requests.
+ */
public class GetCapabilities implements RestReadView<AccountResource> {
@Option(name = "-q", metaVar = "CAP", usage = "Capability to inspect")
void addQuery(String name) {
@@ -159,6 +164,12 @@
}
}
+ /**
+ * REST endpoint to check if a global capability is assigned to an account.
+ *
+ * <p>This REST endpoint handles {@code GET
+ * /accounts/<account-identifier>/capabilities/<capability-identifier>} requests.
+ */
@Singleton
public static class CheckOne implements RestReadView<AccountResource.Capability> {
private final PermissionBackend permissionBackend;
diff --git a/java/com/google/gerrit/server/restapi/account/GetDetail.java b/java/com/google/gerrit/server/restapi/account/GetDetail.java
index b19559e..1091599 100644
--- a/java/com/google/gerrit/server/restapi/account/GetDetail.java
+++ b/java/com/google/gerrit/server/restapi/account/GetDetail.java
@@ -27,6 +27,14 @@
import java.util.Collections;
import java.util.EnumSet;
+/**
+ * REST endpoint to get details of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/detail} requests.
+ *
+ * <p>In the response all fields are populated. In contrast to this {@link GetAccount} populates
+ * only a subset of the fields in the response.
+ */
@Singleton
public class GetDetail implements RestReadView<AccountResource> {
private final InternalAccountDirectory directory;
diff --git a/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java b/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
index 670ef3b..53ce94b 100644
--- a/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
@@ -34,6 +34,18 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to get the diff preferences of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/preferences.diff}
+ * requests.
+ *
+ * <p>General preferences can be retrieved by {@link GetPreferences} and edit preferences can be
+ * retrieved by {@link GetEditPreferences}.
+ *
+ * <p>Default diff preferences that apply for all accounts can be retrieved by {@link
+ * com.google.gerrit.server.restapi.config.GetDiffPreferences}.
+ */
@Singleton
public class GetDiffPreferences implements RestReadView<AccountResource> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/GetEditPreferences.java b/java/com/google/gerrit/server/restapi/account/GetEditPreferences.java
index 409209e..0f117eb 100644
--- a/java/com/google/gerrit/server/restapi/account/GetEditPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEditPreferences.java
@@ -34,6 +34,18 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to get the edit preferences of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/preferences.edit}
+ * requests.
+ *
+ * <p>General preferences can be retrieved by {@link GetPreferences} and diff preferences can be
+ * retrieved by {@link GetDiffPreferences}.
+ *
+ * <p>Default edit preferences that apply for all accounts can be retrieved by {@link
+ * com.google.gerrit.server.restapi.config.GetEditPreferences}.
+ */
@Singleton
public class GetEditPreferences implements RestReadView<AccountResource> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/GetEmail.java b/java/com/google/gerrit/server/restapi/account/GetEmail.java
index afcdac2..4a71858 100644
--- a/java/com/google/gerrit/server/restapi/account/GetEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEmail.java
@@ -21,6 +21,12 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get an email of an account.
+ *
+ * <p>This REST endpoint handles {@code GET
+ * /accounts/<account-identifier>/emails/<email-identifier>} requests.
+ */
@Singleton
public class GetEmail implements RestReadView<AccountResource.Email> {
@Inject
diff --git a/java/com/google/gerrit/server/restapi/account/GetEmails.java b/java/com/google/gerrit/server/restapi/account/GetEmails.java
index 9db9f05..4d70eb9 100644
--- a/java/com/google/gerrit/server/restapi/account/GetEmails.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEmails.java
@@ -32,6 +32,11 @@
import java.util.List;
import java.util.Objects;
+/**
+ * REST endpoint to list the emails of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/emails/} requests.
+ */
@Singleton
public class GetEmails implements RestReadView<AccountResource> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/GetExternalIds.java b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
index 0e52af2..c5b4454 100644
--- a/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
@@ -39,6 +39,11 @@
import java.util.List;
import java.util.Optional;
+/**
+ * REST endpoint to get the external IDs of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/external.ids} requests.
+ */
@Singleton
public class GetExternalIds implements RestReadView<AccountResource> {
private final PermissionBackend permissionBackend;
diff --git a/java/com/google/gerrit/server/restapi/account/GetGroups.java b/java/com/google/gerrit/server/restapi/account/GetGroups.java
index 22492a7..47fe96f 100644
--- a/java/com/google/gerrit/server/restapi/account/GetGroups.java
+++ b/java/com/google/gerrit/server/restapi/account/GetGroups.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.restapi.account;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.exceptions.NoSuchGroupException;
@@ -31,8 +32,19 @@
import java.util.List;
import java.util.Set;
+/**
+ * REST endpoint to get all known groups of an account (groups that contain the account as member).
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/groups} requests.
+ *
+ * <p>The response may not contain all groups of the account as not all groups may be known (see
+ * {@link com.google.gerrit.server.account.GroupMembership#getKnownGroups()}). In addition groups
+ * that are not visible to the calling user are filtered out.
+ */
@Singleton
public class GetGroups implements RestReadView<AccountResource> {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
private final GroupControl.Factory groupControlFactory;
private final GroupJson json;
@@ -54,11 +66,22 @@
try {
ctl = groupControlFactory.controlFor(uuid);
} catch (NoSuchGroupException e) {
+ logger.atFine().log("skipping non-existing group %s", uuid);
continue;
}
- if (ctl.isVisible() && ctl.canSeeMember(userId)) {
- visibleGroups.add(json.format(ctl.getGroup()));
+
+ if (!ctl.isVisible()) {
+ logger.atFine().log("skipping non-visible group %s", uuid);
+ continue;
}
+
+ if (!ctl.canSeeMember(userId)) {
+ logger.atFine().log(
+ "skipping group %s because member %d cannot be seen", uuid, userId.get());
+ continue;
+ }
+
+ visibleGroups.add(json.format(ctl.getGroup()));
}
return Response.ok(visibleGroups);
}
diff --git a/java/com/google/gerrit/server/restapi/account/GetName.java b/java/com/google/gerrit/server/restapi/account/GetName.java
index ca33887..0e73058 100644
--- a/java/com/google/gerrit/server/restapi/account/GetName.java
+++ b/java/com/google/gerrit/server/restapi/account/GetName.java
@@ -20,6 +20,11 @@
import com.google.gerrit.server.account.AccountResource;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get the full name of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/name} requests.
+ */
@Singleton
public class GetName implements RestReadView<AccountResource> {
@Override
diff --git a/java/com/google/gerrit/server/restapi/account/GetPreferences.java b/java/com/google/gerrit/server/restapi/account/GetPreferences.java
index d4d73c5..bfc6852 100644
--- a/java/com/google/gerrit/server/restapi/account/GetPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetPreferences.java
@@ -35,6 +35,17 @@
import com.google.inject.Provider;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get the general preferences of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/preferences} requests.
+ *
+ * <p>Diff preferences can be retrieved by {@link GetDiffPreferences} and edit preferences can be
+ * retrieved by {@link GetEditPreferences}.
+ *
+ * <p>Default general preferences that apply for all accounts can be retrieved by {@link
+ * com.google.gerrit.server.restapi.config.GetPreferences}.
+ */
@Singleton
public class GetPreferences implements RestReadView<AccountResource> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/GetSshKey.java b/java/com/google/gerrit/server/restapi/account/GetSshKey.java
index 58b5d12..70c1327 100644
--- a/java/com/google/gerrit/server/restapi/account/GetSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/GetSshKey.java
@@ -21,6 +21,12 @@
import com.google.gerrit.server.account.AccountResource.SshKey;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get an SSH key of an account.
+ *
+ * <p>This REST endpoint handles {@code GET
+ * /accounts/<account-identifier>/sshkeys/<ssh-key-identifier>} requests.
+ */
@Singleton
public class GetSshKey implements RestReadView<AccountResource.SshKey> {
diff --git a/java/com/google/gerrit/server/restapi/account/GetSshKeys.java b/java/com/google/gerrit/server/restapi/account/GetSshKeys.java
index 0ca9b9e..6df6c3c 100644
--- a/java/com/google/gerrit/server/restapi/account/GetSshKeys.java
+++ b/java/com/google/gerrit/server/restapi/account/GetSshKeys.java
@@ -36,6 +36,11 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+/**
+ * REST endpoint to list the SSH keys of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/sshkeys/} requests.
+ */
@Singleton
public class GetSshKeys implements RestReadView<AccountResource> {
diff --git a/java/com/google/gerrit/server/restapi/account/GetStatus.java b/java/com/google/gerrit/server/restapi/account/GetStatus.java
index 447ad76..d29cdcd 100644
--- a/java/com/google/gerrit/server/restapi/account/GetStatus.java
+++ b/java/com/google/gerrit/server/restapi/account/GetStatus.java
@@ -20,6 +20,14 @@
import com.google.gerrit.server.account.AccountResource;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get the status of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/status} requests.
+ *
+ * <p>The account status is a free-form text that a user can set for the own account (e.g. the 'OOO'
+ * string is often used to signal that the user is out-of-office).
+ */
@Singleton
public class GetStatus implements RestReadView<AccountResource> {
@Override
diff --git a/java/com/google/gerrit/server/restapi/account/GetUsername.java b/java/com/google/gerrit/server/restapi/account/GetUsername.java
index 7e58f94..c582039 100644
--- a/java/com/google/gerrit/server/restapi/account/GetUsername.java
+++ b/java/com/google/gerrit/server/restapi/account/GetUsername.java
@@ -22,6 +22,11 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
+/**
+ * REST endpoint to get the username of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/username} requests.
+ */
@Singleton
public class GetUsername implements RestReadView<AccountResource> {
@Inject
diff --git a/java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java b/java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java
index 353e3f6..beb5e8f 100644
--- a/java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java
+++ b/java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java
@@ -41,6 +41,12 @@
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to get the project watches of an account.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/watched.projects}
+ * requests.
+ */
@Singleton
public class GetWatchedProjects implements RestReadView<AccountResource> {
private final PermissionBackend permissionBackend;
diff --git a/java/com/google/gerrit/server/restapi/account/Index.java b/java/com/google/gerrit/server/restapi/account/Index.java
index 6ddfc0f4..14c9f40 100644
--- a/java/com/google/gerrit/server/restapi/account/Index.java
+++ b/java/com/google/gerrit/server/restapi/account/Index.java
@@ -29,6 +29,14 @@
import com.google.inject.Singleton;
import java.io.IOException;
+/**
+ * REST endpoint to (re)index an account.
+ *
+ * <p>This REST endpoint handles {@code POST /accounts/<account-identifier>/index} requests.
+ *
+ * <p>If the document of an account in the account index is stale, this REST endpoint can be used to
+ * update the index.
+ */
@Singleton
public class Index implements RestModifyView<AccountResource, Input> {
diff --git a/java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java b/java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java
index 5236174..b2859e6 100644
--- a/java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java
+++ b/java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java
@@ -41,6 +41,12 @@
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to set project watches for an account.
+ *
+ * <p>This REST endpoint handles {@code POST /accounts/<account-identifier>/watched.projects}
+ * requests.
+ */
@Singleton
public class PostWatchedProjects
implements RestModifyView<AccountResource, List<ProjectWatchInfo>> {
diff --git a/java/com/google/gerrit/server/restapi/account/PutActive.java b/java/com/google/gerrit/server/restapi/account/PutActive.java
index a6ffaa6..a80ab3f 100644
--- a/java/com/google/gerrit/server/restapi/account/PutActive.java
+++ b/java/com/google/gerrit/server/restapi/account/PutActive.java
@@ -27,6 +27,15 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to mark an account as active.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/active} requests.
+ *
+ * <p>Only active accounts can login into Gerrit.
+ *
+ * <p>Marking an account as inactive is handled by {@link DeleteActive}.
+ */
@RequiresCapability(GlobalCapability.MODIFY_ACCOUNT)
@Singleton
public class PutActive implements RestModifyView<AccountResource, Input> {
diff --git a/java/com/google/gerrit/server/restapi/account/PutAgreement.java b/java/com/google/gerrit/server/restapi/account/PutAgreement.java
index 1663d00..459ff26 100644
--- a/java/com/google/gerrit/server/restapi/account/PutAgreement.java
+++ b/java/com/google/gerrit/server/restapi/account/PutAgreement.java
@@ -42,6 +42,11 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
+/**
+ * REST endpoint to sign a contributor agreement for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/agreements} requests.
+ */
@Singleton
public class PutAgreement implements RestModifyView<AccountResource, AgreementInput> {
private final ProjectCache projectCache;
diff --git a/java/com/google/gerrit/server/restapi/account/PutEmail.java b/java/com/google/gerrit/server/restapi/account/PutEmail.java
index 6ee9003..747f848 100644
--- a/java/com/google/gerrit/server/restapi/account/PutEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/PutEmail.java
@@ -21,6 +21,22 @@
import com.google.gerrit.server.account.AccountResource;
import com.google.inject.Singleton;
+/**
+ * REST endpoint for updating an existing email address of an account.
+ *
+ * <p>This REST endpoint handles {@code PUT
+ * /accounts/<account-identifier>/emails/<email-identifier>} requests if the specified email address
+ * already exists for the account. If it doesn't exist yet, the request is handled by {@link
+ * CreateEmail}.
+ *
+ * <p>We do not support email address updates via this path, hence this REST endpoint always throws
+ * a {@link ResourceConflictException} which results in a {@code 409 Conflict} response.
+ *
+ * <p>This REST endpoint solely exists to avoid user confusion if they create a new email address
+ * with {@code PUT /accounts/<account-identifier>/emails/<email-identifier>} and then repeat the
+ * same request. Without this REST endpoint the second request would fail with {@code 404 Not
+ * Found}, which would be surprising to the user.
+ */
@Singleton
public class PutEmail implements RestModifyView<AccountResource.Email, EmailInput> {
@Override
diff --git a/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java b/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
index 36a0c71..11bcf74 100644
--- a/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
+++ b/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
@@ -41,12 +41,23 @@
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.inject.Inject;
import com.google.inject.Provider;
+import com.google.inject.Singleton;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to set/delete the password for HTTP access of an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/password.http} and {@code
+ * DELETE /accounts/<account-identifier>/password.http} requests.
+ *
+ * <p>Gerrit only stores the hash of the HTTP password, hence if an HTTP password was set it's not
+ * possible to get it back from Gerrit.
+ */
+@Singleton
public class PutHttpPassword implements RestModifyView<AccountResource, HttpPasswordInput> {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
diff --git a/java/com/google/gerrit/server/restapi/account/PutName.java b/java/com/google/gerrit/server/restapi/account/PutName.java
index d5f6333c..c7496b9 100644
--- a/java/com/google/gerrit/server/restapi/account/PutName.java
+++ b/java/com/google/gerrit/server/restapi/account/PutName.java
@@ -38,6 +38,13 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to set the full name of an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/name} requests.
+ *
+ * <p>Whether a full name can be set depends on whether the used {@link Realm} supports this.
+ */
@Singleton
public class PutName implements RestModifyView<AccountResource, NameInput> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/PutPreferred.java b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
index c781246..32b5ff2 100644
--- a/java/com/google/gerrit/server/restapi/account/PutPreferred.java
+++ b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
@@ -45,6 +45,15 @@
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to set an email address as preferred email address for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT
+ * /accounts/<account-identifier>/emails/<email-identifier>/preferred} requests.
+ *
+ * <p>Users can only set an email address as preferred that is assigned to their account as external
+ * ID.
+ */
@Singleton
public class PutPreferred implements RestModifyView<AccountResource.Email, Input> {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
diff --git a/java/com/google/gerrit/server/restapi/account/PutStatus.java b/java/com/google/gerrit/server/restapi/account/PutStatus.java
index 7e27489..106f39e 100644
--- a/java/com/google/gerrit/server/restapi/account/PutStatus.java
+++ b/java/com/google/gerrit/server/restapi/account/PutStatus.java
@@ -35,6 +35,14 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to set the status of an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/status} requests.
+ *
+ * <p>The account status is a free-form text that a user can set for the own account (e.g. the 'OOO'
+ * string is often used to signal that the user is out-of-office).
+ */
@Singleton
public class PutStatus implements RestModifyView<AccountResource, StatusInput> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/QueryAccounts.java b/java/com/google/gerrit/server/restapi/account/QueryAccounts.java
index f9e753c..0d12fd4 100644
--- a/java/com/google/gerrit/server/restapi/account/QueryAccounts.java
+++ b/java/com/google/gerrit/server/restapi/account/QueryAccounts.java
@@ -53,6 +53,14 @@
import org.eclipse.jgit.lib.Config;
import org.kohsuke.args4j.Option;
+/**
+ * REST endpoint to query accounts.
+ *
+ * <p>This REST endpoint handles {@code GET /accounts/} requests.
+ *
+ * <p>The account queries are parsed by {@link AccountQueryBuilder} and executed by {@link
+ * AccountQueryProcessor}.
+ */
public class QueryAccounts implements RestReadView<TopLevelResource> {
private static final int MAX_SUGGEST_RESULTS = 100;
diff --git a/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java b/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
index cf56965..3f25b3b 100644
--- a/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
@@ -37,6 +37,18 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+/**
+ * REST endpoint to set diff preferences for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/preferences.diff}
+ * requests.
+ *
+ * <p>General preferences can be set by {@link SetPreferences} and edit preferences can be set by
+ * {@link SetEditPreferences}.
+ *
+ * <p>Default diff preferences that apply for all accounts can be set by {@link
+ * com.google.gerrit.server.restapi.config.SetDiffPreferences}.
+ */
@Singleton
public class SetDiffPreferences implements RestModifyView<AccountResource, DiffPreferencesInfo> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java b/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
index 085adaa..a15a751 100644
--- a/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
@@ -37,6 +37,18 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+/**
+ * REST endpoint to set edit preferences for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/preferences.edit}
+ * requests.
+ *
+ * <p>General preferences can be set by {@link SetPreferences} and diff preferences can be set by
+ * {@link SetDiffPreferences}.
+ *
+ * <p>Default edit preferences that apply for all accounts can be set by {@link
+ * com.google.gerrit.server.restapi.config.SetEditPreferences}.
+ */
@Singleton
public class SetEditPreferences implements RestModifyView<AccountResource, EditPreferencesInfo> {
diff --git a/java/com/google/gerrit/server/restapi/account/SetPreferences.java b/java/com/google/gerrit/server/restapi/account/SetPreferences.java
index 3f2211e..a2b29ae 100644
--- a/java/com/google/gerrit/server/restapi/account/SetPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetPreferences.java
@@ -41,6 +41,17 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to set general preferences for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /accounts/<account-identifier>/preferences} requests.
+ *
+ * <p>Diff preferences can be set by {@link SetDiffPreferences} and edit preferences can be set by
+ * {@link SetEditPreferences}.
+ *
+ * <p>Default general preferences that apply for all accounts can be set by {@link
+ * com.google.gerrit.server.restapi.config.SetPreferences}.
+ */
@Singleton
public class SetPreferences implements RestModifyView<AccountResource, GeneralPreferencesInfo> {
private final Provider<CurrentUser> self;
diff --git a/java/com/google/gerrit/server/restapi/change/GetPatch.java b/java/com/google/gerrit/server/restapi/change/GetPatch.java
index ece8c68..31785be 100644
--- a/java/com/google/gerrit/server/restapi/change/GetPatch.java
+++ b/java/com/google/gerrit/server/restapi/change/GetPatch.java
@@ -66,6 +66,7 @@
boolean close = true;
try {
final RevWalk rw = new RevWalk(repo);
+ BinaryResult bin = null;
try {
final RevCommit commit = rw.parseCommit(rsrc.getPatchSet().commitId());
RevCommit[] parents = commit.getParents();
@@ -77,7 +78,7 @@
final RevCommit base = parents[0];
rw.parseBody(base);
- BinaryResult bin =
+ bin =
new BinaryResult() {
@Override
public void writeTo(OutputStream out) throws IOException {
@@ -135,6 +136,7 @@
} finally {
if (close) {
rw.close();
+ bin.close();
}
}
} finally {
diff --git a/java/com/google/gerrit/server/restapi/config/ConfirmEmail.java b/java/com/google/gerrit/server/restapi/config/ConfirmEmail.java
index 4a74fe9..03715c9 100644
--- a/java/com/google/gerrit/server/restapi/config/ConfirmEmail.java
+++ b/java/com/google/gerrit/server/restapi/config/ConfirmEmail.java
@@ -32,6 +32,18 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
+/**
+ * REST endpoint to confirm an email address for an account.
+ *
+ * <p>This REST endpoint handles {@code PUT /config/server/email.confirm} requests.
+ *
+ * <p>When a user registers a new email address for their account (see {@link
+ * com.google.gerrit.server.restapi.account.CreateEmail}) an email with a confirmation link is sent
+ * to that address. When the receiver confirms the email by clicking on the confirmation link, this
+ * REST endpoint is invoked and the email address is added to the account. Confirming an email
+ * address for an account creates an external ID that links the email address to the account. An
+ * email address can only be added to an account if it is not assigned to any other account yet.
+ */
@Singleton
public class ConfirmEmail implements RestModifyView<ConfigResource, Input> {
public static class Input {
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index 203f4a8..07e74d4 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -22,7 +22,6 @@
import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
-import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
@@ -57,6 +56,7 @@
import com.google.common.util.concurrent.AtomicLongMap;
import com.google.common.util.concurrent.Runnables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.AccountIndexedCounter;
import com.google.gerrit.acceptance.ExtensionRegistry;
import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
import com.google.gerrit.acceptance.PushOneCommit;
@@ -89,7 +89,6 @@
import com.google.gerrit.extensions.api.accounts.EmailInput;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.DraftInput;
-import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.StarsInput;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo.ConsistencyProblemInfo;
@@ -103,7 +102,6 @@
import com.google.gerrit.extensions.common.GpgKeyInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.common.SshKeyInfo;
-import com.google.gerrit.extensions.events.AccountIndexedListener;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -122,8 +120,6 @@
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.Emails;
-import com.google.gerrit.server.account.ProjectWatches;
-import com.google.gerrit.server.account.ProjectWatches.NotifyType;
import com.google.gerrit.server.account.VersionedAuthorizedKeys;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
@@ -140,7 +136,6 @@
import com.google.gerrit.server.project.RefPattern;
import com.google.gerrit.server.query.account.InternalAccountQuery;
import com.google.gerrit.server.update.RetryHelper;
-import com.google.gerrit.server.util.MagicBranch;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.server.validators.AccountActivationValidationListener;
import com.google.gerrit.server.validators.ValidationException;
@@ -154,7 +149,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -1486,670 +1480,6 @@
}
@Test
- public void pushToUserBranch() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
- allUsersRepo.reset("userRef");
- PushOneCommit push = pushFactory.create(admin.newIdent(), allUsersRepo);
- push.to(RefNames.refsUsers(admin.id())).assertOkStatus();
- accountIndexedCounter.assertReindexOf(admin);
-
- push = pushFactory.create(admin.newIdent(), allUsersRepo);
- push.to(RefNames.REFS_USERS_SELF).assertOkStatus();
- accountIndexedCounter.assertReindexOf(admin);
- }
- }
-
- @Test
- public void pushToUserBranchForReview() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- String userRefName = RefNames.refsUsers(admin.id());
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRefName + ":userRef");
- allUsersRepo.reset("userRef");
- PushOneCommit push = pushFactory.create(admin.newIdent(), allUsersRepo);
- PushOneCommit.Result r = push.to(MagicBranch.NEW_CHANGE + userRefName);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRefName);
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- gApi.changes().id(r.getChangeId()).current().submit();
- accountIndexedCounter.assertReindexOf(admin);
-
- push = pushFactory.create(admin.newIdent(), allUsersRepo);
- r = push.to(MagicBranch.NEW_CHANGE + RefNames.REFS_USERS_SELF);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRefName);
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- gApi.changes().id(r.getChangeId()).current().submit();
- accountIndexedCounter.assertReindexOf(admin);
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchForReviewAndSubmit() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- String userRef = RefNames.refsUsers(admin.id());
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS, "out-of-office");
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(MagicBranch.NEW_CHANGE + userRef);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
-
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- gApi.changes().id(r.getChangeId()).current().submit();
- accountIndexedCounter.assertReindexOf(admin);
-
- AccountInfo info = gApi.accounts().self().get();
- assertThat(info.email).isEqualTo(admin.email());
- assertThat(info.name).isEqualTo(admin.fullName());
- assertThat(info.status).isEqualTo("out-of-office");
- }
- }
-
- @Test
- public void pushAccountConfigWithPrefEmailThatDoesNotExistAsExtIdToUserBranchForReviewAndSubmit()
- throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestAccount foo = accountCreator.create(name("foo"), name("foo") + "@example.com", "Foo");
- String userRef = RefNames.refsUsers(foo.id());
- accountIndexedCounter.clear();
-
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- String email = "some.email@example.com";
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, email);
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- foo.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(MagicBranch.NEW_CHANGE + userRef);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
-
- requestScopeOperations.setApiUser(foo.id());
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- gApi.changes().id(r.getChangeId()).current().submit();
-
- accountIndexedCounter.assertReindexOf(foo);
-
- AccountInfo info = gApi.accounts().self().get();
- assertThat(info.email).isEqualTo(email);
- assertThat(info.name).isEqualTo(foo.fullName());
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchForReviewIsRejectedOnSubmitIfConfigIsInvalid()
- throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- String userRef = RefNames.refsUsers(admin.id());
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- "invalid config")
- .to(MagicBranch.NEW_CHANGE + userRef);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
-
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- ResourceConflictException thrown =
- assertThrows(
- ResourceConflictException.class,
- () -> gApi.changes().id(r.getChangeId()).current().submit());
- assertThat(thrown)
- .hasMessageThat()
- .contains(
- String.format(
- "invalid account configuration: commit '%s' has an invalid '%s' file for account"
- + " '%s': Invalid config file %s in commit %s",
- r.getCommit().name(),
- AccountProperties.ACCOUNT_CONFIG,
- admin.id(),
- AccountProperties.ACCOUNT_CONFIG,
- r.getCommit().name()));
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchForReviewIsRejectedOnSubmitIfPreferredEmailIsInvalid()
- throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- String userRef = RefNames.refsUsers(admin.id());
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- String noEmail = "no.email";
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, noEmail);
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(MagicBranch.NEW_CHANGE + userRef);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
-
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- ResourceConflictException thrown =
- assertThrows(
- ResourceConflictException.class,
- () -> gApi.changes().id(r.getChangeId()).current().submit());
- assertThat(thrown)
- .hasMessageThat()
- .contains(
- String.format(
- "invalid account configuration: invalid preferred email '%s' for account '%s'",
- noEmail, admin.id()));
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchForReviewIsRejectedOnSubmitIfOwnAccountIsDeactivated()
- throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- String userRef = RefNames.refsUsers(admin.id());
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config ac = getAccountConfig(allUsersRepo);
- ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(MagicBranch.NEW_CHANGE + userRef);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
-
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- ResourceConflictException thrown =
- assertThrows(
- ResourceConflictException.class,
- () -> gApi.changes().id(r.getChangeId()).current().submit());
- assertThat(thrown)
- .hasMessageThat()
- .contains("invalid account configuration: cannot deactivate own account");
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchForReviewDeactivateOtherAccount() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- projectOperations
- .allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
- .update();
-
- TestAccount foo = accountCreator.create(name("foo"));
- assertThat(gApi.accounts().id(foo.id().get()).getActive()).isTrue();
- String userRef = RefNames.refsUsers(foo.id());
- accountIndexedCounter.clear();
-
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
- .add(allowLabel("Code-Review").ref(userRef).group(adminGroupUuid()).range(-2, 2))
- .add(allow(Permission.SUBMIT).ref(userRef).group(adminGroupUuid()))
- .update();
-
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config ac = getAccountConfig(allUsersRepo);
- ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(MagicBranch.NEW_CHANGE + userRef);
- r.assertOkStatus();
- accountIndexedCounter.assertNoReindex();
- assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
-
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- gApi.changes().id(r.getChangeId()).current().submit();
- accountIndexedCounter.assertReindexOf(foo);
-
- assertThat(gApi.accounts().id(foo.id().get()).getActive()).isFalse();
- }
- }
-
- @Test
- public void pushWatchConfigToUserBranch() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config wc = new Config();
- wc.setString(
- ProjectWatches.PROJECT,
- project.get(),
- ProjectWatches.KEY_NOTIFY,
- ProjectWatches.NotifyValue.create(null, EnumSet.of(NotifyType.ALL_COMMENTS)).toString());
- PushOneCommit push =
- pushFactory.create(
- admin.newIdent(),
- allUsersRepo,
- "Add project watch",
- ProjectWatches.WATCH_CONFIG,
- wc.toText());
- push.to(RefNames.REFS_USERS_SELF).assertOkStatus();
- accountIndexedCounter.assertReindexOf(admin);
-
- String invalidNotifyValue = "]invalid[";
- wc.setString(
- ProjectWatches.PROJECT, project.get(), ProjectWatches.KEY_NOTIFY, invalidNotifyValue);
- push =
- pushFactory.create(
- admin.newIdent(),
- allUsersRepo,
- "Add invalid project watch",
- ProjectWatches.WATCH_CONFIG,
- wc.toText());
- PushOneCommit.Result r = push.to(RefNames.REFS_USERS_SELF);
- r.assertErrorStatus("invalid account configuration");
- r.assertMessage(
- String.format(
- "%s: Invalid project watch of account %d for project %s: %s",
- ProjectWatches.WATCH_CONFIG, admin.id().get(), project.get(), invalidNotifyValue));
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranch() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestAccount oooUser = accountCreator.create("away", "away@mail.invalid", "Ambrose Way");
- requestScopeOperations.setApiUser(oooUser.id());
-
- // Must clone as oooUser to ensure the push is allowed.
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, oooUser);
- fetch(allUsersRepo, RefNames.refsUsers(oooUser.id()) + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS, "out-of-office");
-
- accountIndexedCounter.clear();
- pushFactory
- .create(
- oooUser.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(RefNames.refsUsers(oooUser.id()))
- .assertOkStatus();
-
- accountIndexedCounter.assertReindexOf(oooUser);
-
- AccountInfo info = gApi.accounts().self().get();
- assertThat(info.email).isEqualTo(oooUser.email());
- assertThat(info.name).isEqualTo(oooUser.fullName());
- assertThat(info.status).isEqualTo("out-of-office");
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchIsRejectedIfConfigIsInvalid() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
- allUsersRepo.reset("userRef");
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- "invalid config")
- .to(RefNames.REFS_USERS_SELF);
- r.assertErrorStatus("invalid account configuration");
- r.assertMessage(
- String.format(
- "commit '%s' has an invalid '%s' file for account '%s':"
- + " Invalid config file %s in commit %s",
- r.getCommit().name(),
- AccountProperties.ACCOUNT_CONFIG,
- admin.id(),
- AccountProperties.ACCOUNT_CONFIG,
- r.getCommit().name()));
- accountIndexedCounter.assertNoReindex();
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchIsRejectedIfPreferredEmailIsInvalid() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
- allUsersRepo.reset("userRef");
-
- String noEmail = "no.email";
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, noEmail);
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(RefNames.REFS_USERS_SELF);
- r.assertErrorStatus("invalid account configuration");
- r.assertMessage(
- String.format("invalid preferred email '%s' for account '%s'", noEmail, admin.id()));
- accountIndexedCounter.assertNoReindex();
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchInvalidPreferredEmailButNotChanged() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestAccount foo = accountCreator.create(name("foo"), name("foo") + "@example.com", "Foo");
- String userRef = RefNames.refsUsers(foo.id());
-
- String noEmail = "no.email";
- accountsUpdateProvider
- .get()
- .update("Set Preferred Email", foo.id(), u -> u.setPreferredEmail(noEmail));
- accountIndexedCounter.clear();
-
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.PUSH).ref(userRef).group(REGISTERED_USERS))
- .update();
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- String status = "in vacation";
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS, status);
-
- pushFactory
- .create(
- foo.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(userRef)
- .assertOkStatus();
- accountIndexedCounter.assertReindexOf(foo);
-
- AccountInfo info = gApi.accounts().id(foo.id().get()).get();
- assertThat(info.email).isEqualTo(noEmail);
- assertThat(info.name).isEqualTo(foo.fullName());
- assertThat(info.status).isEqualTo(status);
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchIfPreferredEmailDoesNotExistAsExtId() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestAccount foo = accountCreator.create(name("foo"), name("foo") + "@example.com", "Foo");
- String userRef = RefNames.refsUsers(foo.id());
- accountIndexedCounter.clear();
-
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
- .update();
-
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- String email = "some.email@example.com";
- Config ac = getAccountConfig(allUsersRepo);
- ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, email);
-
- pushFactory
- .create(
- foo.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(userRef)
- .assertOkStatus();
- accountIndexedCounter.assertReindexOf(foo);
-
- AccountInfo info = gApi.accounts().id(foo.id().get()).get();
- assertThat(info.email).isEqualTo(email);
- assertThat(info.name).isEqualTo(foo.fullName());
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchIsRejectedIfOwnAccountIsDeactivated() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config ac = getAccountConfig(allUsersRepo);
- ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
-
- PushOneCommit.Result r =
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(RefNames.REFS_USERS_SELF);
- r.assertErrorStatus("invalid account configuration");
- r.assertMessage("cannot deactivate own account");
- accountIndexedCounter.assertNoReindex();
- }
- }
-
- @Test
- public void pushAccountConfigToUserBranchDeactivateOtherAccount() throws Exception {
- AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
- try (Registration registration =
- extensionRegistry.newRegistration().add(accountIndexedCounter)) {
- projectOperations
- .allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
- .update();
-
- TestAccount foo = accountCreator.create(name("foo"));
- assertThat(gApi.accounts().id(foo.id().get()).getActive()).isTrue();
- String userRef = RefNames.refsUsers(foo.id());
- accountIndexedCounter.clear();
-
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
- .update();
-
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- fetch(allUsersRepo, userRef + ":userRef");
- allUsersRepo.reset("userRef");
-
- Config ac = getAccountConfig(allUsersRepo);
- ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
-
- pushFactory
- .create(
- admin.newIdent(),
- allUsersRepo,
- "Update account config",
- AccountProperties.ACCOUNT_CONFIG,
- ac.toText())
- .to(userRef)
- .assertOkStatus();
- accountIndexedCounter.assertReindexOf(foo);
-
- assertThat(gApi.accounts().id(foo.id().get()).getActive()).isFalse();
- }
- }
-
- @Test
- public void cannotCreateUserBranch() throws Exception {
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
- .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
- .update();
-
- String userRef = RefNames.refsUsers(Account.id(seq.nextAccountId()));
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- PushOneCommit.Result r = pushFactory.create(admin.newIdent(), allUsersRepo).to(userRef);
- r.assertErrorStatus();
- assertThat(r.getMessage()).contains("Not allowed to create user branch.");
-
- try (Repository repo = repoManager.openRepository(allUsers)) {
- assertThat(repo.exactRef(userRef)).isNull();
- }
- }
-
- @Test
- public void createUserBranchWithAccessDatabaseCapability() throws Exception {
- projectOperations
- .allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
- .update();
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
- .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
- .update();
-
- String userRef = RefNames.refsUsers(Account.id(seq.nextAccountId()));
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- pushFactory.create(admin.newIdent(), allUsersRepo).to(userRef).assertOkStatus();
-
- try (Repository repo = repoManager.openRepository(allUsers)) {
- assertThat(repo.exactRef(userRef)).isNotNull();
- }
- }
-
- @Test
- public void cannotCreateNonUserBranchUnderRefsUsersWithAccessDatabaseCapability()
- throws Exception {
- projectOperations
- .allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
- .update();
- projectOperations
- .project(allUsers)
- .forUpdate()
- .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
- .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
- .update();
-
- String userRef = RefNames.REFS_USERS + "foo";
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
- PushOneCommit.Result r = pushFactory.create(admin.newIdent(), allUsersRepo).to(userRef);
- r.assertErrorStatus();
- assertThat(r.getMessage()).contains("Not allowed to create non-user branch under refs/users/.");
-
- try (Repository repo = repoManager.openRepository(allUsers)) {
- assertThat(repo.exactRef(userRef)).isNull();
- }
- }
-
- @Test
public void createDefaultUserBranch() throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
assertThat(repo.exactRef(RefNames.REFS_USERS_DEFAULT)).isNull();
@@ -3501,62 +2831,6 @@
assertThat(Iterables.getOnlyElement(accounts)).isEqualTo(expectedAccount.id());
}
- private Config getAccountConfig(TestRepository<?> allUsersRepo) throws Exception {
- Config ac = new Config();
- try (TreeWalk tw =
- TreeWalk.forPath(
- allUsersRepo.getRepository(),
- AccountProperties.ACCOUNT_CONFIG,
- getHead(allUsersRepo.getRepository(), "HEAD").getTree())) {
- assertThat(tw).isNotNull();
- ac.fromText(
- new String(
- allUsersRepo
- .getRevWalk()
- .getObjectReader()
- .open(tw.getObjectId(0), OBJ_BLOB)
- .getBytes(),
- UTF_8));
- }
- return ac;
- }
-
- /** Checks if an account is indexed the correct number of times. */
- private static class AccountIndexedCounter implements AccountIndexedListener {
- private final AtomicLongMap<Integer> countsByAccount = AtomicLongMap.create();
-
- @Override
- public void onAccountIndexed(int id) {
- countsByAccount.incrementAndGet(id);
- }
-
- void clear() {
- countsByAccount.clear();
- }
-
- void assertReindexOf(TestAccount testAccount) {
- assertReindexOf(testAccount, 1);
- }
-
- void assertReindexOf(AccountInfo accountInfo) {
- assertReindexOf(Account.id(accountInfo._accountId), 1);
- }
-
- void assertReindexOf(TestAccount testAccount, long expectedCount) {
- assertThat(countsByAccount.asMap()).containsExactly(testAccount.id().get(), expectedCount);
- clear();
- }
-
- void assertReindexOf(Account.Id accountId, long expectedCount) {
- assertThat(countsByAccount.asMap()).containsEntry(accountId.get(), expectedCount);
- countsByAccount.remove(accountId.get());
- }
-
- void assertNoReindex() {
- assertThat(countsByAccount.asMap()).isEmpty();
- }
- }
-
private static class RefUpdateCounter implements GitReferenceUpdatedListener {
private final AtomicLongMap<String> countsByProjectRefs = AtomicLongMap.create();
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index a6f7aa0..51dee72 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -2056,7 +2056,7 @@
/* Assert the tags - PS#2 comments do not have tags, PS#3 upload is autogenerated */
List<String> messagesTags = allMessages.stream().map(m -> m.tag).collect(toList());
- ;
+
assertThat(messagesTags.get(2)).isEqualTo("autogenerated:gerrit:newPatchSet");
assertThat(messagesTags.get(3)).isNull();
diff --git a/javatests/com/google/gerrit/acceptance/git/PushAccountIT.java b/javatests/com/google/gerrit/acceptance/git/PushAccountIT.java
new file mode 100644
index 0000000..c48eb3b
--- /dev/null
+++ b/javatests/com/google/gerrit/acceptance/git/PushAccountIT.java
@@ -0,0 +1,764 @@
+// Copyright (C) 2020 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.acceptance.git;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.GitUtil.fetch;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.AccountIndexedCounter;
+import com.google.gerrit.acceptance.ExtensionRegistry;
+import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
+import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
+import com.google.gerrit.common.data.GlobalCapability;
+import com.google.gerrit.common.data.Permission;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.common.AccountInfo;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.server.ServerInitiated;
+import com.google.gerrit.server.account.AccountProperties;
+import com.google.gerrit.server.account.AccountsUpdate;
+import com.google.gerrit.server.account.ProjectWatches;
+import com.google.gerrit.server.account.ProjectWatches.NotifyType;
+import com.google.gerrit.server.notedb.Sequences;
+import com.google.gerrit.server.util.MagicBranch;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import java.util.EnumSet;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.junit.Test;
+
+/** Tests account behavior when users push to accounts refs. */
+public class PushAccountIT extends AbstractDaemonTest {
+
+ @ConfigSuite.Default
+ public static Config enableSignedPushConfig() {
+ Config cfg = new Config();
+ cfg.setBoolean("receive", null, "enableSignedPush", true);
+
+ // Disable the staleness checker so that tests that verify the number of expected index events
+ // are stable.
+ cfg.setBoolean("index", null, "autoReindexIfStale", false);
+
+ return cfg;
+ }
+
+ @Inject private @ServerInitiated Provider<AccountsUpdate> accountsUpdateProvider;
+ @Inject private ProjectOperations projectOperations;
+ @Inject private ExtensionRegistry extensionRegistry;
+ @Inject private RequestScopeOperations requestScopeOperations;
+ @Inject private Sequences seq;
+
+ @Test
+ public void pushToUserBranch() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
+ allUsersRepo.reset("userRef");
+ PushOneCommit push = pushFactory.create(admin.newIdent(), allUsersRepo);
+ push.to(RefNames.refsUsers(admin.id())).assertOkStatus();
+ accountIndexedCounter.assertReindexOf(admin);
+
+ push = pushFactory.create(admin.newIdent(), allUsersRepo);
+ push.to(RefNames.REFS_USERS_SELF).assertOkStatus();
+ accountIndexedCounter.assertReindexOf(admin);
+ }
+ }
+
+ @Test
+ public void pushToUserBranchForReview() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ String userRefName = RefNames.refsUsers(admin.id());
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRefName + ":userRef");
+ allUsersRepo.reset("userRef");
+ PushOneCommit push = pushFactory.create(admin.newIdent(), allUsersRepo);
+ PushOneCommit.Result r = push.to(MagicBranch.NEW_CHANGE + userRefName);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRefName);
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ gApi.changes().id(r.getChangeId()).current().submit();
+ accountIndexedCounter.assertReindexOf(admin);
+
+ push = pushFactory.create(admin.newIdent(), allUsersRepo);
+ r = push.to(MagicBranch.NEW_CHANGE + RefNames.REFS_USERS_SELF);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRefName);
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ gApi.changes().id(r.getChangeId()).current().submit();
+ accountIndexedCounter.assertReindexOf(admin);
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchForReviewAndSubmit() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ String userRef = RefNames.refsUsers(admin.id());
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS, "out-of-office");
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(MagicBranch.NEW_CHANGE + userRef);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
+
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ gApi.changes().id(r.getChangeId()).current().submit();
+ accountIndexedCounter.assertReindexOf(admin);
+
+ AccountInfo info = gApi.accounts().self().get();
+ assertThat(info.email).isEqualTo(admin.email());
+ assertThat(info.name).isEqualTo(admin.fullName());
+ assertThat(info.status).isEqualTo("out-of-office");
+ }
+ }
+
+ @Test
+ public void pushAccountConfigWithPrefEmailThatDoesNotExistAsExtIdToUserBranchForReviewAndSubmit()
+ throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestAccount foo = accountCreator.create(name("foo"), name("foo") + "@example.com", "Foo");
+ String userRef = RefNames.refsUsers(foo.id());
+ accountIndexedCounter.clear();
+
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ String email = "some.email@example.com";
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, email);
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ foo.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(MagicBranch.NEW_CHANGE + userRef);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
+
+ requestScopeOperations.setApiUser(foo.id());
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ gApi.changes().id(r.getChangeId()).current().submit();
+
+ accountIndexedCounter.assertReindexOf(foo);
+
+ AccountInfo info = gApi.accounts().self().get();
+ assertThat(info.email).isEqualTo(email);
+ assertThat(info.name).isEqualTo(foo.fullName());
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchForReviewIsRejectedOnSubmitIfConfigIsInvalid()
+ throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ String userRef = RefNames.refsUsers(admin.id());
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ "invalid config")
+ .to(MagicBranch.NEW_CHANGE + userRef);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
+
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "invalid account configuration: commit '%s' has an invalid '%s' file for account"
+ + " '%s': Invalid config file %s in commit %s",
+ r.getCommit().name(),
+ AccountProperties.ACCOUNT_CONFIG,
+ admin.id(),
+ AccountProperties.ACCOUNT_CONFIG,
+ r.getCommit().name()));
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchForReviewIsRejectedOnSubmitIfPreferredEmailIsInvalid()
+ throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ String userRef = RefNames.refsUsers(admin.id());
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ String noEmail = "no.email";
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, noEmail);
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(MagicBranch.NEW_CHANGE + userRef);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
+
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "invalid account configuration: invalid preferred email '%s' for account '%s'",
+ noEmail, admin.id()));
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchForReviewIsRejectedOnSubmitIfOwnAccountIsDeactivated()
+ throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ String userRef = RefNames.refsUsers(admin.id());
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(MagicBranch.NEW_CHANGE + userRef);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
+
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("invalid account configuration: cannot deactivate own account");
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchForReviewDeactivateOtherAccount() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+
+ TestAccount foo = accountCreator.create(name("foo"));
+ assertThat(gApi.accounts().id(foo.id().get()).getActive()).isTrue();
+ String userRef = RefNames.refsUsers(foo.id());
+ accountIndexedCounter.clear();
+
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
+ .add(allowLabel("Code-Review").ref(userRef).group(adminGroupUuid()).range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref(userRef).group(adminGroupUuid()))
+ .update();
+
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(MagicBranch.NEW_CHANGE + userRef);
+ r.assertOkStatus();
+ accountIndexedCounter.assertNoReindex();
+ assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
+
+ gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ gApi.changes().id(r.getChangeId()).current().submit();
+ accountIndexedCounter.assertReindexOf(foo);
+
+ assertThat(gApi.accounts().id(foo.id().get()).getActive()).isFalse();
+ }
+ }
+
+ @Test
+ public void pushWatchConfigToUserBranch() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config wc = new Config();
+ wc.setString(
+ ProjectWatches.PROJECT,
+ project.get(),
+ ProjectWatches.KEY_NOTIFY,
+ ProjectWatches.NotifyValue.create(null, EnumSet.of(NotifyType.ALL_COMMENTS)).toString());
+ PushOneCommit push =
+ pushFactory.create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Add project watch",
+ ProjectWatches.WATCH_CONFIG,
+ wc.toText());
+ push.to(RefNames.REFS_USERS_SELF).assertOkStatus();
+ accountIndexedCounter.assertReindexOf(admin);
+
+ String invalidNotifyValue = "]invalid[";
+ wc.setString(
+ ProjectWatches.PROJECT, project.get(), ProjectWatches.KEY_NOTIFY, invalidNotifyValue);
+ push =
+ pushFactory.create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Add invalid project watch",
+ ProjectWatches.WATCH_CONFIG,
+ wc.toText());
+ PushOneCommit.Result r = push.to(RefNames.REFS_USERS_SELF);
+ r.assertErrorStatus("invalid account configuration");
+ r.assertMessage(
+ String.format(
+ "%s: Invalid project watch of account %d for project %s: %s",
+ ProjectWatches.WATCH_CONFIG, admin.id().get(), project.get(), invalidNotifyValue));
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranch() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestAccount oooUser = accountCreator.create("away", "away@mail.invalid", "Ambrose Way");
+ requestScopeOperations.setApiUser(oooUser.id());
+
+ // Must clone as oooUser to ensure the push is allowed.
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, oooUser);
+ fetch(allUsersRepo, RefNames.refsUsers(oooUser.id()) + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS, "out-of-office");
+
+ accountIndexedCounter.clear();
+ pushFactory
+ .create(
+ oooUser.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(RefNames.refsUsers(oooUser.id()))
+ .assertOkStatus();
+
+ accountIndexedCounter.assertReindexOf(oooUser);
+
+ AccountInfo info = gApi.accounts().self().get();
+ assertThat(info.email).isEqualTo(oooUser.email());
+ assertThat(info.name).isEqualTo(oooUser.fullName());
+ assertThat(info.status).isEqualTo("out-of-office");
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchIsRejectedIfConfigIsInvalid() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ "invalid config")
+ .to(RefNames.REFS_USERS_SELF);
+ r.assertErrorStatus("invalid account configuration");
+ r.assertMessage(
+ String.format(
+ "commit '%s' has an invalid '%s' file for account '%s':"
+ + " Invalid config file %s in commit %s",
+ r.getCommit().name(),
+ AccountProperties.ACCOUNT_CONFIG,
+ admin.id(),
+ AccountProperties.ACCOUNT_CONFIG,
+ r.getCommit().name()));
+ accountIndexedCounter.assertNoReindex();
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchIsRejectedIfPreferredEmailIsInvalid() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ String noEmail = "no.email";
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, noEmail);
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(RefNames.REFS_USERS_SELF);
+ r.assertErrorStatus("invalid account configuration");
+ r.assertMessage(
+ String.format("invalid preferred email '%s' for account '%s'", noEmail, admin.id()));
+ accountIndexedCounter.assertNoReindex();
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchInvalidPreferredEmailButNotChanged() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestAccount foo = accountCreator.create(name("foo"), name("foo") + "@example.com", "Foo");
+ String userRef = RefNames.refsUsers(foo.id());
+
+ String noEmail = "no.email";
+ accountsUpdateProvider
+ .get()
+ .update("Set Preferred Email", foo.id(), u -> u.setPreferredEmail(noEmail));
+ accountIndexedCounter.clear();
+
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(REGISTERED_USERS))
+ .update();
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ String status = "in vacation";
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS, status);
+
+ pushFactory
+ .create(
+ foo.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(userRef)
+ .assertOkStatus();
+ accountIndexedCounter.assertReindexOf(foo);
+
+ AccountInfo info = gApi.accounts().id(foo.id().get()).get();
+ assertThat(info.email).isEqualTo(noEmail);
+ assertThat(info.name).isEqualTo(foo.fullName());
+ assertThat(info.status).isEqualTo(status);
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchIfPreferredEmailDoesNotExistAsExtId() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestAccount foo = accountCreator.create(name("foo"), name("foo") + "@example.com", "Foo");
+ String userRef = RefNames.refsUsers(foo.id());
+ accountIndexedCounter.clear();
+
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
+ .update();
+
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ String email = "some.email@example.com";
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_PREFERRED_EMAIL, email);
+
+ pushFactory
+ .create(
+ foo.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(userRef)
+ .assertOkStatus();
+ accountIndexedCounter.assertReindexOf(foo);
+
+ AccountInfo info = gApi.accounts().id(foo.id().get()).get();
+ assertThat(info.email).isEqualTo(email);
+ assertThat(info.name).isEqualTo(foo.fullName());
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchIsRejectedIfOwnAccountIsDeactivated() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, RefNames.refsUsers(admin.id()) + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
+
+ PushOneCommit.Result r =
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(RefNames.REFS_USERS_SELF);
+ r.assertErrorStatus("invalid account configuration");
+ r.assertMessage("cannot deactivate own account");
+ accountIndexedCounter.assertNoReindex();
+ }
+ }
+
+ @Test
+ public void pushAccountConfigToUserBranchDeactivateOtherAccount() throws Exception {
+ AccountIndexedCounter accountIndexedCounter = new AccountIndexedCounter();
+ try (Registration registration =
+ extensionRegistry.newRegistration().add(accountIndexedCounter)) {
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+
+ TestAccount foo = accountCreator.create(name("foo"));
+ assertThat(gApi.accounts().id(foo.id().get()).getActive()).isTrue();
+ String userRef = RefNames.refsUsers(foo.id());
+ accountIndexedCounter.clear();
+
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
+ .update();
+
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ fetch(allUsersRepo, userRef + ":userRef");
+ allUsersRepo.reset("userRef");
+
+ Config ac = getAccountConfig(allUsersRepo);
+ ac.setBoolean(AccountProperties.ACCOUNT, null, AccountProperties.KEY_ACTIVE, false);
+
+ pushFactory
+ .create(
+ admin.newIdent(),
+ allUsersRepo,
+ "Update account config",
+ AccountProperties.ACCOUNT_CONFIG,
+ ac.toText())
+ .to(userRef)
+ .assertOkStatus();
+ accountIndexedCounter.assertReindexOf(foo);
+
+ assertThat(gApi.accounts().id(foo.id().get()).getActive()).isFalse();
+ }
+ }
+
+ @Test
+ public void cannotCreateNonUserBranchUnderRefsUsersWithAccessDatabaseCapability()
+ throws Exception {
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .update();
+
+ String userRef = RefNames.REFS_USERS + "foo";
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ PushOneCommit.Result r = pushFactory.create(admin.newIdent(), allUsersRepo).to(userRef);
+ r.assertErrorStatus();
+ assertThat(r.getMessage()).contains("Not allowed to create non-user branch under refs/users/.");
+
+ try (Repository repo = repoManager.openRepository(allUsers)) {
+ assertThat(repo.exactRef(userRef)).isNull();
+ }
+ }
+
+ @Test
+ public void cannotCreateUserBranch() throws Exception {
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .update();
+
+ String userRef = RefNames.refsUsers(Account.id(seq.nextAccountId()));
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ PushOneCommit.Result r = pushFactory.create(admin.newIdent(), allUsersRepo).to(userRef);
+ r.assertErrorStatus();
+ assertThat(r.getMessage()).contains("Not allowed to create user branch.");
+
+ try (Repository repo = repoManager.openRepository(allUsers)) {
+ assertThat(repo.exactRef(userRef)).isNull();
+ }
+ }
+
+ @Test
+ public void createUserBranchWithAccessDatabaseCapability() throws Exception {
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .update();
+
+ String userRef = RefNames.refsUsers(Account.id(seq.nextAccountId()));
+ TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
+ pushFactory.create(admin.newIdent(), allUsersRepo).to(userRef).assertOkStatus();
+
+ try (Repository repo = repoManager.openRepository(allUsers)) {
+ assertThat(repo.exactRef(userRef)).isNotNull();
+ }
+ }
+
+ private Config getAccountConfig(TestRepository<?> allUsersRepo) throws Exception {
+ Config ac = new Config();
+ try (TreeWalk tw =
+ TreeWalk.forPath(
+ allUsersRepo.getRepository(),
+ AccountProperties.ACCOUNT_CONFIG,
+ getHead(allUsersRepo.getRepository(), "HEAD").getTree())) {
+ assertThat(tw).isNotNull();
+ ac.fromText(
+ new String(
+ allUsersRepo
+ .getRevWalk()
+ .getObjectReader()
+ .open(tw.getObjectId(0), OBJ_BLOB)
+ .getBytes(),
+ UTF_8));
+ }
+ return ac;
+ }
+}
diff --git a/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java b/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
index 74173a6..b65f4d2 100644
--- a/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
+++ b/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
@@ -14,7 +14,6 @@
package com.google.gerrit.server.schema;
-import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.schema.AllProjectsInput.getDefaultCodeReviewLabel;
import static com.google.gerrit.server.schema.testing.AllProjectsCreatorTestUtil.assertSectionEquivalent;
import static com.google.gerrit.server.schema.testing.AllProjectsCreatorTestUtil.assertTwoConfigsEquivalent;
diff --git a/polygerrit-ui/README.md b/polygerrit-ui/README.md
index 2cb6242..e645972 100644
--- a/polygerrit-ui/README.md
+++ b/polygerrit-ui/README.md
@@ -53,12 +53,6 @@
Then visit http://localhost:8081
-## Local UI, Test Data
-
-```sh
-./polygerrit-ui/run-server.sh --plugins=plugins/my_plugin/static/my_plugin.js,plugins/my_plugin/static/my_plugin.html
-```
-
This method is based on a
[simple hand-written Go webserver](https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/server.go).
Mostly it just switches between serving files locally and proxying the real
diff --git a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js
index 73b8261..19d08ff 100644
--- a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js
+++ b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js
@@ -49,6 +49,7 @@
},
},
+ /** @override */
detached() {
this._handleHideTooltip();
},
diff --git a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html
index d4e2c72..8a1ed87 100644
--- a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html
+++ b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html
@@ -540,6 +540,7 @@
}
},
+ /** @override */
attached() {
const shortcuts = shortcutManager.attachHost(this);
if (!shortcuts) { return; }
@@ -559,6 +560,7 @@
}
},
+ /** @override */
detached() {
if (shortcutManager.detachHost(this)) {
this.removeOwnKeyBindings();
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
index 8c17c49..a421043 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
@@ -40,6 +40,7 @@
/**
* @appliesMixin Gerrit.AccessMixin
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrAccessSection extends Polymer.mixinBehaviors( [
Gerrit.AccessBehavior,
@@ -84,6 +85,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('access-saved',
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js
index 5a62584..96008b7 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.ListViewMixin
+ * @extends Polymer.Element
*/
class GrAdminGroupList extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -77,6 +78,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._getCreateGroupCapability();
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
index afc373d..e300c90 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
@@ -23,6 +23,7 @@
* @appliesMixin Gerrit.AdminNavMixin
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrAdminView extends Polymer.mixinBehaviors( [
Gerrit.AdminNavBehavior,
@@ -82,6 +83,7 @@
];
}
+ /** @override */
attached() {
super.attached();
this.reload();
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js
index 7400d2a..3fde410 100644
--- a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.js
@@ -25,6 +25,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmDeleteItemDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.js b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.js
index eb96794..3b85304 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.js
@@ -24,6 +24,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrCreateChangeDialog extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -64,6 +65,7 @@
};
}
+ /** @override */
attached() {
super.attached();
if (!this.repoName) { return Promise.resolve(); }
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.js b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.js
index 4072986..8a4edab 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrCreateGroupDialog extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.js b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.js
index cf59af8..2d6b4aa 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.js
@@ -25,6 +25,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrCreatePointerDialog extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js
index a6da3a1..290f025 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrCreateRepoDialog extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.js b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.js
index 57b9689..11517d6 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.js
+++ b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.ListViewMixin
+ * @extends Polymer.Element
*/
class GrGroupAuditLog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -42,11 +43,13 @@
};
}
+ /** @override */
attached() {
super.attached();
this.fire('title-change', {title: 'Audit Log'});
}
+ /** @override */
ready() {
super.ready();
this._getAuditLogs();
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
index f3a7ec7..8c29f73 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
@@ -27,6 +27,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrGroupMembers extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -76,6 +77,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._loadGroupDetails();
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group.js b/polygerrit-ui/app/elements/admin/gr-group/gr-group.js
index 6597b4d..42846f4 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group.js
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group.js
@@ -32,6 +32,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrGroup extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -105,6 +106,7 @@
];
}
+ /** @override */
attached() {
super.attached();
this._loadGroup();
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
index 040eabf..e719154 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
@@ -37,6 +37,7 @@
* Fired when a permission that was previously added was removed.
*
* @event added-permission-removed
+ * @extends Polymer.Element
*/
class GrPermission extends Polymer.mixinBehaviors( [
Gerrit.AccessBehavior,
@@ -94,12 +95,14 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('access-saved',
() => this._handleAccessSaved());
}
+ /** @override */
ready() {
super.ready();
this._setupValues();
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.js b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.js
index c0ad9d42..92a8655 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.js
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrPluginConfigArrayEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.js b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.js
index 262f3d5..5dd6ec2 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.ListViewMixin
+ * @extends Polymer.Element
*/
class GrPluginList extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -74,6 +75,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.fire('title-change', {title: 'Plugins'});
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
index bffad1c..b350702 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
@@ -72,6 +72,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrRepoAccess extends Polymer.mixinBehaviors( [
Gerrit.AccessBehavior,
@@ -128,6 +129,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('access-modified',
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
index 48e4c01..622bfe4 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrRepoCommand extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
index 558f004..80b187a 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
@@ -28,6 +28,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrRepoCommands extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -50,6 +51,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._loadRepo();
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.js b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.js
index 00611b6..8e09263 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrRepoDashboards extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.js b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.js
index 109aa10..ccfdfc6 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.js
@@ -28,6 +28,7 @@
* @appliesMixin Gerrit.ListViewMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrRepoDetailList extends Polymer.mixinBehaviors( [
Gerrit.ListViewBehavior,
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js
index 3e706b5..c509717 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.ListViewMixin
+ * @extends Polymer.Element
*/
class GrRepoList extends Polymer.mixinBehaviors( [
Gerrit.ListViewBehavior,
@@ -78,6 +79,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._getCreateRepoCapability();
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js
index 404f93c..7368eb8 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.RepoPluginConfigMixin
+ * @extends Polymer.Element
*/
class GrRepoPluginConfig extends Polymer.mixinBehaviors( [
Gerrit.RepoPluginConfig,
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.js b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.js
index a2097f9..f6328de 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.js
@@ -53,6 +53,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrRepo extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -123,6 +124,7 @@
];
}
+ /** @override */
attached() {
super.attached();
this._loadRepo();
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
index 24e95b6..ac98d33 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
@@ -69,6 +69,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrRuleEditor extends Polymer.mixinBehaviors( [
Gerrit.AccessBehavior,
@@ -118,12 +119,14 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('access-saved',
() => this._handleAccessSaved());
}
+ /** @override */
ready() {
super.ready();
// Called on ready rather than the observer because when new rules are
@@ -132,6 +135,7 @@
this._setupValues(this.rule);
}
+ /** @override */
attached() {
super.attached();
if (!this.rule) { return; } // Check needed for test purposes.
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
index 9ce5e46..013b44b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -30,6 +30,7 @@
* @appliesMixin Gerrit.PathListMixin
* @appliesMixin Gerrit.RESTClientMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrChangeListItem extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -74,6 +75,7 @@
};
}
+ /** @override */
attached() {
super.attached();
Gerrit.awaitPluginsLoaded().then(() => {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js
index 4e08b5c..e3a3b31 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js
@@ -33,6 +33,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrChangeListView extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -133,6 +134,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('next-page',
@@ -141,6 +143,7 @@
() => this._handlePreviousPage());
}
+ /** @override */
attached() {
super.attached();
this._loadPreferences();
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
index bde400b..8fd4214 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
@@ -29,6 +29,7 @@
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.RESTClientMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrChangeList extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -135,17 +136,20 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('keydown',
e => this._scopedKeydownHandler(e));
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('tabindex', 0);
}
+ /** @override */
attached() {
super.attached();
Gerrit.awaitPluginsLoaded().then(() => {
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js
index e6caacb..64d2486 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js
+++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrCreateChangeHelp extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.js b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.js
index 303128b..7abd784 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.js
+++ b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.js
@@ -23,6 +23,7 @@
PUSH_PREFIX: 'git push origin HEAD:refs/for/',
};
+ /** @extends Polymer.Element */
class GrCreateCommandsDialog extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.js b/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.js
index cbc7bcd..35f7450 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.js
+++ b/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.js
@@ -22,6 +22,7 @@
* name and the branch name.
*
* @event confirm
+ * @extends Polymer.Element
*/
class GrCreateDestinationDialog extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
index 05f1abe..d0e1db2 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrDashboardView extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -94,6 +95,7 @@
);
}
+ /** @override */
attached() {
super.attached();
this._loadPreferences();
diff --git a/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.js b/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.js
index 96dcb98..de0a56e 100644
--- a/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.js
+++ b/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrEmbedDashboard extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.js b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.js
index d4bd1df..c0e472a 100644
--- a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.js
+++ b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrRepoHeader extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.js b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.js
index 40f0b73..2fc8170 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.js
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.js
@@ -17,6 +17,9 @@
(function() {
'use strict';
+ /**
+ * @extends Polymer.Element
+ */
class GrUserHeader extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
index 1034389..2c4ca82 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -196,6 +196,7 @@
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrChangeActions extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -432,6 +433,7 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('fullscreen-overlay-opened',
@@ -440,6 +442,7 @@
() => this._handleShowBackgroundContent());
}
+ /** @override */
ready() {
super.ready();
this.$.jsAPI.addElement(this.$.jsAPI.Element.CHANGE_ACTIONS, this);
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index e13b462..3237d72 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -50,6 +50,7 @@
/**
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrChangeMetadata extends Polymer.mixinBehaviors( [
Gerrit.RESTClientBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js
index 346fee3..a413c6f 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrChangeRequirements extends Polymer.mixinBehaviors( [
Gerrit.RESTClientBehavior,
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 cbdd83f..471560d 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
@@ -93,6 +93,9 @@
flex: 1;
font-size: var(--font-size-h3);
}
+ .changeNumberColon {
+ color: transparent;
+ }
.headerTitle .headerSubject {
font-weight: var(--font-weight-bold);
}
@@ -101,6 +104,7 @@
}
gr-change-star {
margin-right: var(--spacing-xs);
+ margin-left: var(--spacing-l);
}
gr-reply-dialog {
width: 60em;
@@ -190,8 +194,6 @@
max-height: 36em;
overflow: hidden;
}
- #relatedChanges {
- }
#relatedChanges.collapsed {
margin-bottom: var(--spacing-l);
max-height: var(--relation-chain-max-height, 2em);
@@ -364,11 +366,6 @@
hidden$="{{_loading}}">
<div class$="[[_computeHeaderClass(_editMode)]]">
<div class="headerTitle">
- <gr-change-star
- id="changeStar"
- change="{{_change}}"
- on-toggle-star="_handleToggleStar"
- hidden$="[[!_loggedIn]]"></gr-change-star>
<div class="changeStatuses">
<template is="dom-repeat" items="[[_changeStatuses]]" as="status">
<gr-change-status
@@ -387,11 +384,20 @@
server-config="[[_serverConfig]]"></gr-commit-info>
</template>
</div>
- <span class="separator"></span>
+ <gr-change-star
+ id="changeStar"
+ change="{{_change}}"
+ on-toggle-star="_handleToggleStar"
+ hidden$="[[!_loggedIn]]"></gr-change-star>
+
<a aria-label$="[[_computeChangePermalinkAriaLabel(_change._number)]]"
href$="[[_computeChangeUrl(_change)]]">[[_change._number]]</a>
- <pre>: </pre>
+ <span class="changeNumberColon">: </span>
<span class="headerSubject">[[_change.subject]]</span>
+ <gr-copy-clipboard
+ hide-input
+ text="[[_computeCopyTextForTitle(_change)]]">
+ </gr-copy-clipboard>
</div><!-- end headerTitle -->
<div class="commitActions" hidden$="[[!_loggedIn]]">
<gr-change-actions
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 4d2f1db..058bce8 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -68,6 +68,7 @@
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrChangeView extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -324,6 +325,7 @@
};
}
+ /** @override */
created() {
super.created();
@@ -346,6 +348,7 @@
() => this._handleReloadCommentThreads());
}
+ /** @override */
attached() {
super.attached();
this._getServerConfig().then(config => {
@@ -391,6 +394,7 @@
this.listen(document, 'visibilitychange', '_handleVisibilityChange');
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'scroll', '_handleScroll');
@@ -1593,6 +1597,17 @@
return collapsed ? '\u25bc Show more' : '\u25b2 Show less';
}
+ /**
+ * Returns the text to be copied when
+ * click the copy icon next to change subject
+ *
+ * @param {!Object} change
+ */
+ _computeCopyTextForTitle(change) {
+ return `${change._number}: ${change.subject}` +
+ ` | https://${location.host}${this._computeChangeUrl(change)}`;
+ }
+
_toggleCommitCollapsed() {
this._commitCollapsed = !this._commitCollapsed;
if (this._commitCollapsed) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index 7e776b5..9c23d0e 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -803,6 +803,24 @@
assert.deepEqual(commit, {commit: 2});
});
+ test('_computeCopyTextForTitle', () => {
+ const change = {
+ _number: 123,
+ subject: 'test subject',
+ revisions: {
+ rev1: {_number: 1},
+ rev3: {_number: 3},
+ },
+ current_revision: 'rev3',
+ };
+ sandbox.stub(Gerrit.Nav, 'getUrlForChange')
+ .returns('/change/123');
+ assert.equal(
+ element._computeCopyTextForTitle(change),
+ '123: test subject | https://localhost:8081/change/123'
+ );
+ });
+
test('get latest revision', () => {
let change = {
revisions: {
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
index 3de51a7..58bdbbc 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
@@ -21,6 +21,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.PathListMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrCommentList extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js
index 2a3fe89..a339865 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrCommitInfo extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.js
index eb6f5f3..555c605 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrConfirmAbandonDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.js
index 0b3639f..35e9afb 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmCherrypickConflictDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
index 6b01465..2b10a97 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
@@ -21,6 +21,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmCherrypickDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.js
index d595f48..feb3d2f 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.js
@@ -21,6 +21,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmMoveDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.js
index 7169437..607f587 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrConfirmRebaseDialog extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js
index 379226a..bf727ec 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmRevertDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog.js
index 51698be..d59f5cd 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog.js
@@ -23,6 +23,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmRevertSubmissionDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.js
index b4d3595..ea8bdb5 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrConfirmSubmitDialog extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
index 72ad5d2..17c6f50 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
@@ -21,6 +21,7 @@
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrDownloadDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -54,6 +55,7 @@
};
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('role', 'dialog');
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.js b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.js
index a611250..5828006 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.js
@@ -24,6 +24,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.PatchSetMixin
+ * @extends Polymer.Element
*/
class GrFileListHeader extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 90ab96c..0bc1a22 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -48,6 +48,7 @@
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.PathListMixin
+ * @extends Polymer.Element
*/
class GrFileList extends Polymer.mixinBehaviors( [
Gerrit.AsyncForeachBehavior,
@@ -236,12 +237,14 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('keydown',
e => this._scopedKeydownHandler(e));
}
+ /** @override */
attached() {
super.attached();
Gerrit.awaitPluginsLoaded().then(() => {
@@ -265,6 +268,7 @@
});
}
+ /** @override */
detached() {
super.detached();
this._cancelDiffs();
diff --git a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.js b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.js
index 134ce10..01c9b6e 100644
--- a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrIncludedInDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
index abfe469..1f9845e 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrLabelScoreRow extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
index ce2a3ef..0cbf2c7 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrLabelScores extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.js b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
index 28348ba..59f12f5 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.js
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrMessage extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -113,12 +114,14 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('click',
e => this._handleClick(e));
}
+ /** @override */
ready() {
super.ready();
this.$.restAPI.getConfig().then(config => {
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js
index 49ff60a..2c47dc1 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js
@@ -25,6 +25,7 @@
SHOW_MORE: 'show-more-messages',
};
+ /** @extends Polymer.Element */
class GrMessagesList extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
index c925142..d4a2398 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
@@ -21,6 +21,7 @@
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrRelatedChangesList extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 1828808..90f8540 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -58,6 +58,7 @@
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrReplyDialog extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -249,6 +250,7 @@
];
}
+ /** @override */
attached() {
super.attached();
this._getAccount().then(account => {
@@ -256,6 +258,7 @@
});
}
+ /** @override */
ready() {
super.ready();
this.$.jsAPI.addElement(this.$.jsAPI.Element.REPLY_DIALOG, this);
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js
index 7bef5dd..ddc6275 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrReviewerList extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
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 de58d72..9e42de1 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
@@ -21,6 +21,7 @@
* Fired when a comment is saved or deleted
*
* @event thread-list-modified
+ * @extends Polymer.Element
*/
class GrThreadList extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
diff --git a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.js b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.js
index 0441129..60cbd42 100644
--- a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.js
@@ -29,6 +29,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrUploadHelpDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -65,6 +66,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.$.restAPI.getLoggedIn()
diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js
index 1cbbf3e..66c00f9 100644
--- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js
+++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js
@@ -21,6 +21,7 @@
/**
* @appliesMixin Gerrit.DisplayNameMixin
+ * @extends Polymer.Element
*/
class GrAccountDropdown extends Polymer.mixinBehaviors( [
Gerrit.DisplayNameBehavior,
@@ -50,6 +51,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._handleLocationChange();
@@ -66,6 +68,7 @@
});
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'location-change', '_handleLocationChange');
diff --git a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.js b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.js
index 2655140..db70d57 100644
--- a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.js
+++ b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrErrorDialog extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
index 2a87708..9ef2461 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
@@ -28,6 +28,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrErrorManager extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -74,6 +75,7 @@
this._authErrorHandlerDeregistrationHook;
}
+ /** @override */
attached() {
super.attached();
this.listen(document, 'server-error', '_handleServerError');
@@ -89,6 +91,7 @@
});
}
+ /** @override */
detached() {
super.detached();
this._clearHideAlertHandle();
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.js b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.js
index 2b86170..3d424bc 100644
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.js
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrKeyBindingDisplay extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.js b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.js
index 788c9e0..4630ca7 100644
--- a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.js
+++ b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrKeyboardShortcutsDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -59,17 +60,20 @@
};
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('role', 'dialog');
}
+ /** @override */
attached() {
super.attached();
this.addKeyboardShortcutDirectoryListener(
this._onDirectoryUpdated.bind(this));
}
+ /** @override */
detached() {
super.detached();
this.removeKeyboardShortcutDirectoryListener(
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
index f868596..53c5ef5 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
@@ -74,6 +74,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.DocsUrlMixin
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrMainHeader extends Polymer.mixinBehaviors( [
Gerrit.AdminNavBehavior,
@@ -150,11 +151,13 @@
];
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('role', 'banner');
}
+ /** @override */
attached() {
super.attached();
this._loadAccount();
@@ -162,6 +165,7 @@
this.listen(window, 'location-change', '_handleLocationChange');
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'location-change', '_handleLocationChange');
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index 1dfa973..2bd403b 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -214,6 +214,7 @@
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrRouter extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js
index 956beea..335813a 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js
@@ -107,6 +107,7 @@
/**
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrSearchBar extends Polymer.mixinBehaviors( [
Gerrit.KeyboardShortcutBehavior,
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js
index 662e1b1..664d59f 100644
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js
@@ -23,6 +23,7 @@
/**
* @appliesMixin Gerrit.DisplayNameMixin
+ * @extends Polymer.Element
*/
class GrSmartSearch extends Polymer.mixinBehaviors( [
Gerrit.DisplayNameBehavior,
@@ -56,6 +57,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.$.restAPI.getConfig().then(cfg => {
diff --git a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.js b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.js
index f2b3d90..490367a 100644
--- a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.js
+++ b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.js
@@ -466,6 +466,7 @@
/**
* @appliesMixin Gerrit.PatchSetMixin
+ * @extends Polymer.Element
*/
class GrCommentApi extends Polymer.mixinBehaviors( [
Gerrit.PatchSetBehavior,
@@ -480,6 +481,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('reload-drafts',
diff --git a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.js b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.js
index 201da05..1bc4674 100644
--- a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.js
+++ b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.js
@@ -24,6 +24,7 @@
[Gerrit.CoverageType.NOT_INSTRUMENTED, 'Not instrumented by any tests.'],
]);
+ /** @extends Polymer.Element */
class GrCoverageLayer extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.js b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.js
index 591ebfe..05a7525 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.js
@@ -35,6 +35,7 @@
const LEFT_SIDE_CLASS = 'target-side-left';
const RIGHT_SIDE_CLASS = 'target-side-right';
+ /** @extends Polymer.Element */
class GrDiffCursor extends Polymer.mixinBehaviors([Gerrit.FireBehavior],
Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(Polymer.Element))) {
@@ -105,6 +106,7 @@
];
}
+ /** @override */
ready() {
super.ready();
Polymer.RenderStatus.afterNextRender(this, () => {
@@ -122,12 +124,14 @@
});
}
+ /** @override */
attached() {
super.attached();
// Catch when users are scrolling as the view loads.
this.listen(window, 'scroll', '_handleWindowScroll');
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'scroll', '_handleWindowScroll');
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js
index adb1be8..e524cd8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrDiffHighlight extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -57,6 +58,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('comment-thread-mouseleave',
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
index 300e72a..cb23308 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
@@ -77,6 +77,8 @@
*
* Webcomponent fetching diffs and related data from restAPI and passing them
* to the presentational gr-diff for rendering.
+ *
+ * @extends Polymer.Element
*/
class GrDiffHost extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -249,6 +251,7 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener(
@@ -276,6 +279,7 @@
event => this._handleDiffContextExpanded(event));
}
+ /** @override */
ready() {
super.ready();
if (this._canReload()) {
@@ -283,6 +287,7 @@
}
}
+ /** @override */
attached() {
super.attached();
this._getLoggedIn().then(loggedIn => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.js b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.js
index ae7ef6d..68bca23 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrDiffModeSelector extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.js b/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.js
index 7ed27dd..6aad66c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrDiffPreferencesDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
index bfccfe9..cdd0c7d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
@@ -63,6 +63,8 @@
* "expand context" widget. This may require splitting a chunk/group so
* that the part that is within the context or has comments is shown, while
* the rest is not.
+ *
+ * @extends Polymer.Element
*/
class GrDiffProcessor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
@@ -119,11 +121,13 @@
};
}
+ /** @override */
attached() {
super.attached();
this.listen(window, 'scroll', '_handleWindowScroll');
}
+ /** @override */
detached() {
super.detached();
this.cancel();
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
index 37d54c9..359a039 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.js
@@ -32,6 +32,7 @@
/**
* @appliesMixin Gerrit.DomUtilMixin
+ * @extends Polymer.Element
*/
class GrDiffSelection extends Polymer.mixinBehaviors( [
Gerrit.DomUtilBehavior,
@@ -58,6 +59,7 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('copy',
@@ -66,6 +68,7 @@
e => this._handleDown(e));
}
+ /** @override */
attached() {
super.attached();
this.classList.add(SelectionClass.RIGHT);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index 3122370..5087d74 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -39,6 +39,7 @@
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.PathListMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrDiffView extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -244,6 +245,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._getLoggedIn().then(loggedIn => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
index 4b075e7..ef22188 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
@@ -94,6 +94,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.PatchSetMixin
+ * @extends Polymer.Element
*/
class GrDiff extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -284,6 +285,7 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('create-range-comment',
@@ -292,11 +294,13 @@
() => this._handleRenderContent());
}
+ /** @override */
attached() {
super.attached();
this._observeNodes();
}
+ /** @override */
detached() {
super.detached();
this._unobserveIncrementalNodes();
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js
index 88c3a0e..d24e0bc 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js
@@ -30,6 +30,7 @@
*
* @property {string} patchNum
* @property {string} basePatchNum
+ * @extends Polymer.Element
*/
class GrPatchRangeSelect extends Polymer.mixinBehaviors( [
Gerrit.PatchSetBehavior,
diff --git a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js
index d9ad795..fd94b61 100644
--- a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js
+++ b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js
@@ -23,6 +23,7 @@
const RANGE_HIGHLIGHT = 'style-scope gr-diff range';
const HOVER_HIGHLIGHT = 'style-scope gr-diff rangeHighlight';
+ /** @extends Polymer.Element */
class GrRangedCommentLayer extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.js b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.js
index 261cd4d..3d831c9 100644
--- a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.js
+++ b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrSelectionActionBox extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -42,6 +43,7 @@
};
}
+ /** @override */
created() {
super.created();
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js
index 9a15703..34bda26 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.js
@@ -131,6 +131,7 @@
const GO_BACKSLASH_LITERAL = '\'\\\\\'';
const GLOBAL_LT_PATTERN = /</g;
+ /** @extends Polymer.Element */
class GrSyntaxLayer extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js
index f317459..022a985 100644
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.ListViewMixin
+ * @extends Polymer.Element
*/
class GrDocumentationSearch extends Polymer.mixinBehaviors( [
Gerrit.ListViewBehavior,
@@ -55,6 +56,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.dispatchEvent(
diff --git a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js
index ce9db61..73dbaf8 100644
--- a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js
+++ b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrDefaultEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.js b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.js
index 052c51c..e655f7b 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.js
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.PatchSetMixin
+ * @extends Polymer.Element
*/
class GrEditControls extends Polymer.mixinBehaviors( [
Gerrit.PatchSetBehavior,
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js
index ddd2d29..d59fcf7 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrEditFileControls extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
index aaafa46..12e16cf 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
@@ -29,6 +29,7 @@
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.PathListMixin
+ * @extends Polymer.Element
*/
class GrEditorView extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -92,12 +93,14 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('content-change',
e => this._handleContentChange(e));
}
+ /** @override */
attached() {
super.attached();
this._getEditPrefs().then(prefs => { this._prefs = prefs; });
diff --git a/polygerrit-ui/app/elements/gr-app-element.js b/polygerrit-ui/app/elements/gr-app-element.js
index 14570f2..d39ba58 100644
--- a/polygerrit-ui/app/elements/gr-app-element.js
+++ b/polygerrit-ui/app/elements/gr-app-element.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrAppElement extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -114,6 +115,7 @@
};
}
+ /** @override */
created() {
super.created();
this._bindKeyboardShortcuts();
@@ -127,6 +129,7 @@
e => this._handleRpcLog(e));
}
+ /** @override */
ready() {
super.ready();
this.$.reporting.appStarted();
diff --git a/polygerrit-ui/app/elements/gr-app.js b/polygerrit-ui/app/elements/gr-app.js
index 46a81ee..da54ac4 100644
--- a/polygerrit-ui/app/elements/gr-app.js
+++ b/polygerrit-ui/app/elements/gr-app.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrApp extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.js b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.js
index 946147d..600421b 100644
--- a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.js
+++ b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.js
@@ -41,6 +41,7 @@
return this._hooks[hookName];
};
+ /** @constructor */
function GrDomHook(hookName, opt_moduleName) {
this._instances = [];
this._callbacks = [];
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js
index fcf4ce8..5a2f104 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js
@@ -19,6 +19,7 @@
const INIT_PROPERTIES_TIMEOUT_MS = 10000;
+ /** @extends Polymer.Element */
class GrEndpointDecorator extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -46,6 +47,7 @@
};
}
+ /** @override */
detached() {
super.detached();
for (const [el, domHook] of this._domHooks) {
@@ -145,6 +147,7 @@
});
}
+ /** @override */
ready() {
super.ready();
Gerrit._endpoints.onNewEndpoint(this.name, this._initModule.bind(this));
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.js b/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.js
index 3010750..bcad7f9 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.js
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrEndpointParam extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js
index aa9b13e..2e3bee1 100644
--- a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js
+++ b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrExternalStyle extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -73,11 +74,13 @@
});
}
+ /** @override */
attached() {
super.attached();
this._importAndApply();
}
+ /** @override */
ready() {
super.ready();
Gerrit.awaitPluginsLoaded().then(() => this._importAndApply());
diff --git a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.js b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.js
index cae3a91..da050fb 100644
--- a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.js
+++ b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrPluginHost extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.js b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.js
index 412e788a..30bf6c8 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.js
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.js
@@ -17,6 +17,7 @@
(function(window) {
'use strict';
+ /** @extends Polymer.Element */
class GrPluginPopup extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html
index 9401a15..588facb 100644
--- a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html
@@ -65,6 +65,7 @@
setup(() => {
fixture('header-title');
stub('gr-custom-plugin-header', {
+ /** @override */
ready() { customHeader = this; },
});
Gerrit._loadPlugins([]);
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js
index 9b17fd7..7bf641d 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrAccountInfo extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.js b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.js
index 2886c87..67dc0c4 100644
--- a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.js
+++ b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
+ * @extends Polymer.Element
*/
class GrAgreementsList extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -33,6 +34,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.loadData();
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js
index aa4e0c5..8521126 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.ChangeTableMixin
+ * @extends Polymer.Element
*/
class GrChangeTableEditor extends Polymer.mixinBehaviors( [
Gerrit.ChangeTableBehavior,
diff --git a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
index e146a90..cff1d54 100644
--- a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrClaView extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -45,6 +46,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.loadData();
diff --git a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.js b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.js
index 36e53b0..9523136 100644
--- a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.js
+++ b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrEditPreferences extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.js b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.js
index 8ec1067..c60568c 100644
--- a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrEmailEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.js b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.js
index d45edff..9f04915 100644
--- a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrGpgEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.js b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.js
index 6c3a448..c7b5faa 100644
--- a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.js
+++ b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrGroupList extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.js b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.js
index 5c0a059..efd0c39 100644
--- a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.js
+++ b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrHttpPassword extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -30,6 +31,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this.loadData();
diff --git a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.js b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.js
index 8b74130..ac4f9e4 100644
--- a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.js
+++ b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.js
@@ -24,6 +24,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
+ * @extends Polymer.Element
*/
class GrIdentities extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.js b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.js
index 5b6c978..0ee232b 100644
--- a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrMenuEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js
index 25499d6..4bb98d0 100644
--- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js
+++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrRegistrationDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -67,6 +68,7 @@
};
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('role', 'dialog');
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js
index 9702280..bae1f38 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrSettingsItem extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js
index e08e3d8..d5a7eb7 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrSettingsMenuItem extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
index 0236261..78bad8c 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
@@ -49,6 +49,7 @@
* @appliesMixin Gerrit.DocsUrlMixin
* @appliesMixin Gerrit.ChangeTableMixin
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrSettingsView extends Polymer.mixinBehaviors( [
Gerrit.DocsUrlBehavior,
@@ -164,6 +165,7 @@
];
}
+ /** @override */
attached() {
super.attached();
// Polymer 2: anchor tag won't work on shadow DOM
@@ -231,6 +233,7 @@
});
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'location-change', '_handleLocationChange');
diff --git a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.js b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.js
index f8e5a5f..44fb48c 100644
--- a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrSshEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.js b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.js
index f638a07..df115ca 100644
--- a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.js
@@ -25,6 +25,7 @@
{name: 'Abandons', key: 'notify_abandoned_changes'},
];
+ /** @extends Polymer.Element */
class GrWatchedProjectsEditor extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js
index 2f9572c..8cd2021 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrAccountChip extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -63,6 +64,7 @@
};
}
+ /** @override */
ready() {
super.ready();
this._getHasAvatars().then(hasAvatars => {
diff --git a/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.js b/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.js
index 0ed3f19..d2a111a 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.js
@@ -20,6 +20,8 @@
/**
* gr-account-entry is an element for entering account
* and/or group with autocomplete support.
+ *
+ * @extends Polymer.Element
*/
class GrAccountEntry extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js
index 1c0cb65..34c4cb6 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.DisplayNameMixin
* @appliesMixin Gerrit.TooltipMixin
+ * @extends Polymer.Element
*/
class GrAccountLabel extends Polymer.mixinBehaviors( [
Gerrit.DisplayNameBehavior,
@@ -61,6 +62,7 @@
};
}
+ /** @override */
ready() {
super.ready();
if (!this.additionalText) { this.additionalText = ''; }
diff --git a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js
index f23959a..b0ce04c 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
+ * @extends Polymer.Element
*/
class GrAccountLink extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list.js b/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list.js
index 0a4100c..7955d50 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list.js
@@ -21,6 +21,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrAccountList extends Polymer.mixinBehaviors( [
// Used in the tests for gr-account-list and other elements tests.
@@ -113,6 +114,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('remove',
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
index 433a57b..215f469 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrAlert extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -52,11 +53,13 @@
};
}
+ /** @override */
attached() {
super.attached();
this.addEventListener('transitionend', this._boundTransitionEndHandler);
}
+ /** @override */
detached() {
super.detached();
this.removeEventListener('transitionend',
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.js b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.js
index f536666..5ca95e1 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.js
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.js
@@ -21,6 +21,7 @@
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Polymer.IronFitMixin
+ * @extends Polymer.Element
*/
class GrAutocompleteDropdown extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
index e2f42b3..60985c1 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
@@ -23,6 +23,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrAutocomplete extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -192,11 +193,13 @@
return this.$.input.$.nativeInput || this.$.input.inputElement;
}
+ /** @override */
attached() {
super.attached();
this.listen(document.body, 'click', '_handleBodyClick');
}
+ /** @override */
detached() {
super.detached();
this.unlisten(document.body, 'click', '_handleBodyClick');
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js
index 4238eed..efa97cf 100644
--- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js
+++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
+ * @extends Polymer.Element
*/
class GrAvatar extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -44,6 +45,7 @@
};
}
+ /** @override */
attached() {
super.attached();
Promise.all([
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
index 75efcdc..abfbb18 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
@@ -20,6 +20,7 @@
/**
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.TooltipMixin
+ * @extends Polymer.Element
*/
class GrButton extends Polymer.mixinBehaviors( [
Gerrit.KeyboardShortcutBehavior,
@@ -68,6 +69,7 @@
];
}
+ /** @override */
created() {
super.created();
this.addEventListener('click',
@@ -76,6 +78,7 @@
e => this._handleKeydown(e));
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('role', 'button');
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
index 05e759f..001632f 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrChangeStar extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.js b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.js
index 35b8ef8..7052a6a 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.js
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.js
@@ -36,6 +36,7 @@
const PRIVATE_TOOLTIP = 'This change is only visible to its owner and ' +
'current reviewers (or anyone with "View Private Changes" permission).';
+ /** @extends Polymer.Element */
class GrChangeStatus extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js
index a1165ca..d8a56f8 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.js
@@ -24,6 +24,7 @@
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
* @appliesMixin Gerrit.PathListMixin
+ * @extends Polymer.Element
*/
class GrCommentThread extends Polymer.mixinBehaviors( [
/**
@@ -157,12 +158,14 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('comment-update',
e => this._handleCommentUpdate(e));
}
+ /** @override */
attached() {
super.attached();
this._getLoggedIn().then(loggedIn => {
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
index 6449416..3f4cc69 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
@@ -34,6 +34,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrComment extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -186,6 +187,7 @@
};
}
+ /** @override */
attached() {
super.attached();
if (this.editing) {
@@ -198,6 +200,7 @@
});
}
+ /** @override */
detached() {
super.detached();
this.cancelDebouncer('fire-update');
diff --git a/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.js b/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.js
index 6a4232f..8d50fe0 100644
--- a/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.js
+++ b/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrConfirmDeleteCommentDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
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 6c062f6..2ce03e3 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
@@ -19,6 +19,7 @@
const COPY_TIMEOUT_MS = 1000;
+ /** @extends Polymer.Element */
class GrCopyClipboard extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.js b/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.js
index 04724df..374204b 100644
--- a/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.js
+++ b/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.js
@@ -22,6 +22,7 @@
KEEP_VISIBLE: 'keep-visible',
};
+ /** @extends Polymer.Element */
class GrCursorManager extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -91,6 +92,7 @@
};
}
+ /** @override */
detached() {
super.detached();
this.unsetCursor();
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js
index 374844d..8c247e3 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js
@@ -33,6 +33,7 @@
/**
* @appliesMixin Gerrit.TooltipMixin
+ * @extends Polymer.Element
*/
class GrDateFormatter extends Polymer.mixinBehaviors( [
Gerrit.TooltipBehavior,
@@ -73,6 +74,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._loadPreferences();
diff --git a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.js b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.js
index d36aa37..8d00452 100644
--- a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.js
+++ b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrDialog extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -60,6 +61,7 @@
};
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('role', 'dialog');
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js
index 6e34bbc..c408e5a 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrDiffPreferences extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
index 9e90ae3..17fafce 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrDownloadCommands extends Polymer.mixinBehaviors( [
Gerrit.RESTClientBehavior,
@@ -43,6 +44,7 @@
};
}
+ /** @override */
attached() {
super.attached();
this._getLoggedIn().then(loggedIn => {
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.js b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.js
index 1fa0f1b..06b4a72 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.js
@@ -45,6 +45,7 @@
*/
Defs.item;
+ /** @extends Polymer.Element */
class GrDropdownList extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
index 619005a..531f2e3 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
@@ -23,6 +23,7 @@
/**
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrDropdown extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
index 0c2d4f5..7d3308e 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrEditableContent extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.js b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.js
index 13000b4..ef5bb8c 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.js
@@ -23,6 +23,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrEditableLabel extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -76,6 +77,7 @@
};
}
+ /** @override */
ready() {
super.ready();
this._ensureAttribute('tabindex', '0');
diff --git a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.js b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.js
index 1e8f767..02e23e8 100644
--- a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.js
+++ b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrFixedPanel extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -61,6 +62,7 @@
};
}
+ /** @override */
attached() {
super.attached();
if (this.floatingDisabled) {
@@ -76,6 +78,7 @@
this._observer.observe(this.$.header, {childList: true, subtree: true});
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'scroll', '_updateOnScroll');
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js
index 39b114d..7483590 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js
@@ -20,6 +20,7 @@
// eslint-disable-next-line no-unused-vars
const QUOTE_MARKER_PATTERN = /\n\s?>\s/g;
+ /** @extends Polymer.Element */
class GrFormattedText extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -45,6 +46,7 @@
];
}
+ /** @override */
ready() {
super.ready();
if (this.noTrailingMargin) {
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.js b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.js
index 37972f9..ce34d3a 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.js
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.js
@@ -25,6 +25,7 @@
*/
const DIAGONAL_OVERFLOW = 15;
+ /** @extends Polymer.Element */
class GrHovercard extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -91,6 +92,7 @@
};
}
+ /** @override */
attached() {
super.attached();
if (!this._target) { this._target = this.target; }
@@ -101,12 +103,14 @@
this.listen(this._target, 'click', 'hide');
}
+ /** @override */
created() {
super.created();
this.addEventListener('mouseleave',
e => this.hide(e));
}
+ /** @override */
ready() {
super.ready();
// First, check to see if the container has already been created.
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
index b1675cc..6f9268c 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
@@ -39,6 +39,7 @@
/**
* @appliesMixin Gerrit.PatchSetMixin
+ * @extends Polymer.Element
*/
class GrJsApiInterface extends Polymer.mixinBehaviors( [
Gerrit.PatchSetBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.js b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.js
index 6e5fd5b..6e99e01 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.js
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrLabelInfo extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-label/gr-label.js b/polygerrit-ui/app/elements/shared/gr-label/gr-label.js
index 440e8e9..b594757 100644
--- a/polygerrit-ui/app/elements/shared/gr-label/gr-label.js
+++ b/polygerrit-ui/app/elements/shared/gr-label/gr-label.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.TooltipMixin
+ * @extends Polymer.Element
*/
class GrLabel extends Polymer.mixinBehaviors( [
Gerrit.TooltipBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.js b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.js
index c02c598..cb5ad7c 100644
--- a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.js
+++ b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrLabeledAutocomplete extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.js b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.js
index 4c221bc..defc6bd 100644
--- a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.js
+++ b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.js
@@ -20,6 +20,7 @@
const HLJS_PATH = 'bower_components/highlightjs/highlight.min.js';
const DARK_THEME_PATH = 'styles/themes/dark-theme.html';
+ /** @extends Polymer.Element */
class GrLibLoader extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.js b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.js
index a57f331..ee032f6 100644
--- a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.js
+++ b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.js
@@ -18,13 +18,13 @@
'use strict';
/**
- * @appliesMixin Gerrit.TooltipMixin
- */
- /*
* The gr-limited-text element is for displaying text with a maximum length
* (in number of characters) to display. If the length of the text exceeds the
* configured limit, then an ellipsis indicates that the text was truncated
* and a tooltip containing the full text is enabled.
+ *
+ * @appliesMixin Gerrit.TooltipMixin
+ * @extends Polymer.Element
*/
class GrLimitedText extends Polymer.mixinBehaviors( [
Gerrit.TooltipBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.js b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.js
index bef9698..ccab685 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.js
+++ b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrLinkedChip extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.js b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.js
index 5d2a1ca..bbe525e 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.js
+++ b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrLinkedText extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.js b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.js
index dd825b3..8913cd8 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.js
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.js
@@ -23,6 +23,7 @@
* @appliesMixin Gerrit.BaseUrlMixin
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrListView extends Polymer.mixinBehaviors( [
Gerrit.BaseUrlBehavior,
@@ -48,6 +49,7 @@
};
}
+ /** @override */
detached() {
super.detached();
this.cancelDebouncer('reload');
diff --git a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.js b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.js
index fc9dc99..8821bcb 100644
--- a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.js
+++ b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.js
@@ -23,6 +23,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrOverlay extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -52,6 +53,7 @@
};
}
+ /** @override */
created() {
super.created();
this.addEventListener('iron-overlay-closed',
diff --git a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.js b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.js
index 23389ee..ac876c4 100644
--- a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.js
+++ b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrPageNav extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
@@ -28,11 +29,13 @@
};
}
+ /** @override */
attached() {
super.attached();
this.listen(window, 'scroll', '_handleBodyScroll');
}
+ /** @override */
detached() {
super.detached();
this.unlisten(window, 'scroll', '_handleBodyScroll');
diff --git a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.js b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.js
index ea39d0e..18e2596 100644
--- a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.js
+++ b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.js
@@ -22,6 +22,7 @@
/**
* @appliesMixin Gerrit.URLEncodingMixin
+ * @extends Polymer.Element
*/
class GrRepoBranchPicker extends Polymer.mixinBehaviors( [
Gerrit.URLEncodingBehavior,
@@ -57,6 +58,7 @@
};
}
+ /** @override */
attached() {
super.attached();
if (this.repo) {
@@ -64,6 +66,7 @@
}
}
+ /** @override */
ready() {
super.ready();
this._branchDisabled = !this.repo;
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth.js
index 0af1d97..2978193 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth.js
@@ -39,6 +39,10 @@
this._last_auth_check_time = Date.now();
}
+ get baseUrl() {
+ return Gerrit.BaseUrlBehavior.getBaseUrl();
+ }
+
/**
* Returns if user is authed or not.
*
@@ -49,7 +53,7 @@
(Date.now() - this._last_auth_check_time > MAX_AUTH_CHECK_WAIT_TIME_MS)
) {
// Refetch after last check expired
- this._authCheckPromise = fetch('/auth-check');
+ this._authCheckPromise = fetch(`${this.baseUrl}/auth-check`);
this._last_auth_check_time = Date.now();
}
@@ -76,7 +80,7 @@
}
/**
- * @param {string} status
+ * @param {Auth.STATUS} status
*/
_setStatus(status) {
if (this._status === status) return;
@@ -209,7 +213,7 @@
if (accessToken) {
params.push(`access_token=${accessToken}`);
- const baseUrl = Gerrit.BaseUrlBehavior.getBaseUrl();
+ const baseUrl = this.baseUrl;
const pathname = baseUrl ?
url.substring(url.indexOf(baseUrl) + baseUrl.length) : url;
if (!pathname.startsWith('/a/')) {
@@ -252,6 +256,7 @@
ACCESS_TOKEN: 'access_token',
};
+ /** @enum {number} */
Auth.STATUS = {
UNDETERMINED: 0,
AUTHED: 1,
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 0e2bef6..472a7ea 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -44,6 +44,7 @@
* @appliesMixin Gerrit.PathListMixin
* @appliesMixin Gerrit.PatchSetMixin
* @appliesMixin Gerrit.RESTClientMixin
+ * @extends Polymer.Element
*/
class GrRestApiInterface extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -105,6 +106,7 @@
};
}
+ /** @override */
created() {
super.created();
this._auth = Gerrit.Auth;
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select.js b/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
index c9f13de..ea838a0 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.FireMixin
+ * @extends Polymer.Element
*/
class GrSelect extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -63,6 +64,7 @@
this.nativeSelect.focus();
}
+ /** @override */
created() {
super.created();
this.addEventListener('change',
@@ -71,6 +73,7 @@
() => this._updateValue());
}
+ /** @override */
ready() {
super.ready();
// If not set via the property, set bind-value to the element value.
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js
index 9456991..4b31086 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrShellCommand extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.js b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.js
index 7950e51..53311b5 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.js
+++ b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.js
@@ -28,6 +28,7 @@
'editablecontent:',
];
+ /** @extends Polymer.Element */
class GrStorage extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.js b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.js
index d3119b7..a604bcf 100644
--- a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.js
+++ b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.js
@@ -55,6 +55,7 @@
/**
* @appliesMixin Gerrit.FireMixin
* @appliesMixin Gerrit.KeyboardShortcutMixin
+ * @extends Polymer.Element
*/
class GrTextarea extends Polymer.mixinBehaviors( [
Gerrit.FireBehavior,
@@ -125,6 +126,7 @@
};
}
+ /** @override */
ready() {
super.ready();
if (this.monospace) {
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.js b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.js
index 22a5ecb..90e6a08 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.js
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.js
@@ -19,6 +19,7 @@
/**
* @appliesMixin Gerrit.TooltipMixin
+ * @extends Polymer.Element
*/
class GrTooltipContent extends Polymer.mixinBehaviors( [
Gerrit.TooltipBehavior,
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.js b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.js
index 170a442..6f458d1 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.js
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.js
@@ -17,6 +17,7 @@
(function() {
'use strict';
+ /** @extends Polymer.Element */
class GrTooltip extends Polymer.GestureEventListeners(
Polymer.LegacyElementMixin(
Polymer.Element)) {
diff --git a/polygerrit-ui/app/samples/bind-parameters.html b/polygerrit-ui/app/samples/bind-parameters.html
index a28c462..e6bf9d1 100644
--- a/polygerrit-ui/app/samples/bind-parameters.html
+++ b/polygerrit-ui/app/samples/bind-parameters.html
@@ -22,6 +22,7 @@
computed: '_computeExample(revision._number)',
},
},
+ /** @override */
attached() {
this.plugin.attributeHelper(this).bind(
'revision', this._onRevisionChanged.bind(this));
diff --git a/polygerrit-ui/app/samples/repo-command.html b/polygerrit-ui/app/samples/repo-command.html
index afbc78c..5b3ee2c 100644
--- a/polygerrit-ui/app/samples/repo-command.html
+++ b/polygerrit-ui/app/samples/repo-command.html
@@ -31,6 +31,7 @@
Polymer({
is: 'repo-command-low',
+ /** @override */
attached() {
console.log(this.repoName);
console.log(this.config);
diff --git a/polygerrit-ui/app/samples/some-screen.html b/polygerrit-ui/app/samples/some-screen.html
index da025a2..593b8ab 100644
--- a/polygerrit-ui/app/samples/some-screen.html
+++ b/polygerrit-ui/app/samples/some-screen.html
@@ -42,6 +42,7 @@
properties: {
rootUrl: String,
},
+ /** @override */
attached() {
this.rootUrl = `${this.plugin.screenUrl()}`;
},
diff --git a/polygerrit-ui/app/styles/themes/app-theme.html b/polygerrit-ui/app/styles/themes/app-theme.html
index 45882cf..0dec63f 100644
--- a/polygerrit-ui/app/styles/themes/app-theme.html
+++ b/polygerrit-ui/app/styles/themes/app-theme.html
@@ -43,8 +43,8 @@
/* background colors */
/* primary background colors */
--background-color-primary: #ffffff;
- --background-color-secondary: rgba(0, 0, 0, 0.025);
- --background-color-tertiary: rgba(0, 0, 0, 0.05);
+ --background-color-secondary: #f8f9fa;
+ --background-color-tertiary: #f1f3f4;
/* directly derived from primary background colors */
--chip-background-color: var(--background-color-tertiary);
--default-button-background-color: var(--background-color-primary);
@@ -59,15 +59,17 @@
--view-background-color: var(--background-color-primary);
/* unique background colors */
--assignee-highlight-color: #fcfad6;
- --comment-background-color: #fcfad6;
- --robot-comment-background-color: #e8f0fe;
--edit-mode-background-color: #ebf5fb;
--emphasis-color: #fff9c4;
--hover-background-color: rgba(161, 194, 250, 0.2);
--primary-button-background-color: #2a66d9;
--selection-background-color: rgba(161, 194, 250, 0.1);
--tooltip-background-color: #333;
- --unresolved-comment-background-color: #fcfaa6;
+ /* comment background colors */
+ --comment-background-color: #fef7f0;
+ --robot-comment-background-color: #e8f0fe;
+ --unresolved-comment-background-color: #e8eaed;
+ /* vote background colors */
--vote-color-approved: #9fcc6b;
--vote-color-disliked: #f7c4cb;
--vote-color-neutral: #ebf5fb;
diff --git a/polygerrit-ui/app/styles/themes/dark-theme.html b/polygerrit-ui/app/styles/themes/dark-theme.html
index 61b2dc6..57ceb32 100644
--- a/polygerrit-ui/app/styles/themes/dark-theme.html
+++ b/polygerrit-ui/app/styles/themes/dark-theme.html
@@ -43,21 +43,23 @@
/* background colors */
/* primary background colors */
--background-color-primary: #202124;
- --background-color-secondary: rgba(255, 255, 255, 0.05);
- --background-color-tertiary: rgba(255, 255, 255, 0.1);
+ --background-color-secondary: #2f3034;
+ --background-color-tertiary: #3b3d3f;
/* directly derived from primary background colors */
/* empty, because inheriting from app-theme is just fine
/* unique background colors */
--assignee-highlight-color: #3a361c;
- --comment-background-color: #0b162b;
- --robot-comment-background-color: rgba(232, 234, 237, 0.08);
--edit-mode-background-color: #5c0a36;
--emphasis-color: #383f4a;
--hover-background-color: rgba(161, 194, 250, 0.2);
--primary-button-background-color: var(--link-color);
--selection-background-color: rgba(161, 194, 250, 0.1);
--tooltip-background-color: #111;
- --unresolved-comment-background-color: #385a9a;
+ /* comment background colors */
+ --comment-background-color: #303134;
+ --robot-comment-background-color: #40454e;
+ --unresolved-comment-background-color: #4b463a;
+ /* vote background colors */
--vote-color-approved: #7fb66b;
--vote-color-disliked: #bf6874;
--vote-color-neutral: #597280;