Use `querySelector` over alternative DOM methods (#31280)

As per
https://github.com/go-gitea/gitea/pull/30115#discussion_r1626060164,
prefer `querySelector` by enabling
[`unicorn/prefer-query-selector`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-query-selector.md)
and autofixing all except 10 issues.

According to
[this](https://old.reddit.com/r/learnjavascript/comments/i0f5o8/performance_of_getelementbyid_vs_queryselector/),
querySelector may be faster as well, so it's a win-win.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
silverwind 2024-06-10 22:49:33 +02:00 committed by GitHub
parent a2304cb163
commit 507fbf4c3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 165 additions and 168 deletions

View File

@ -798,7 +798,7 @@ rules:
unicorn/prefer-object-has-own: [0] unicorn/prefer-object-has-own: [0]
unicorn/prefer-optional-catch-binding: [2] unicorn/prefer-optional-catch-binding: [2]
unicorn/prefer-prototype-methods: [0] unicorn/prefer-prototype-methods: [0]
unicorn/prefer-query-selector: [0] unicorn/prefer-query-selector: [2]
unicorn/prefer-reflect-apply: [0] unicorn/prefer-reflect-apply: [0]
unicorn/prefer-regexp-test: [2] unicorn/prefer-regexp-test: [2]
unicorn/prefer-set-has: [0] unicorn/prefer-set-has: [0]

View File

@ -101,7 +101,7 @@ const sfc = {
}, },
mounted() { mounted() {
const el = document.getElementById('dashboard-repo-list'); const el = document.querySelector('#dashboard-repo-list');
this.changeReposFilter(this.reposFilter); this.changeReposFilter(this.reposFilter);
$(el).find('.dropdown').dropdown(); $(el).find('.dropdown').dropdown();
nextTick(() => { nextTick(() => {
@ -330,7 +330,7 @@ const sfc = {
}; };
export function initDashboardRepoList() { export function initDashboardRepoList() {
const el = document.getElementById('dashboard-repo-list'); const el = document.querySelector('#dashboard-repo-list');
if (el) { if (el) {
createApp(sfc).mount(el); createApp(sfc).mount(el);
} }

View File

@ -5,7 +5,7 @@ import {GET} from '../modules/fetch.js';
export default { export default {
components: {SvgIcon}, components: {SvgIcon},
data: () => { data: () => {
const el = document.getElementById('diff-commit-select'); const el = document.querySelector('#diff-commit-select');
return { return {
menuVisible: false, menuVisible: false,
isLoading: false, isLoading: false,

View File

@ -7,10 +7,10 @@ export default {
return {store: diffTreeStore()}; return {store: diffTreeStore()};
}, },
mounted() { mounted() {
document.getElementById('show-file-list-btn').addEventListener('click', this.toggleFileList); document.querySelector('#show-file-list-btn').addEventListener('click', this.toggleFileList);
}, },
unmounted() { unmounted() {
document.getElementById('show-file-list-btn').removeEventListener('click', this.toggleFileList); document.querySelector('#show-file-list-btn').removeEventListener('click', this.toggleFileList);
}, },
methods: { methods: {
toggleFileList() { toggleFileList() {

View File

@ -112,7 +112,7 @@ export default {
updateState(visible) { updateState(visible) {
const btn = document.querySelector('.diff-toggle-file-tree-button'); const btn = document.querySelector('.diff-toggle-file-tree-button');
const [toShow, toHide] = btn.querySelectorAll('.icon'); const [toShow, toHide] = btn.querySelectorAll('.icon');
const tree = document.getElementById('diff-file-tree'); const tree = document.querySelector('#diff-file-tree');
const newTooltip = btn.getAttribute(visible ? 'data-hide-text' : 'data-show-text'); const newTooltip = btn.getAttribute(visible ? 'data-hide-text' : 'data-show-text');
btn.setAttribute('data-tooltip-content', newTooltip); btn.setAttribute('data-tooltip-content', newTooltip);
toggleElem(tree, visible); toggleElem(tree, visible);

View File

@ -325,7 +325,7 @@ const sfc = {
export default sfc; export default sfc;
export function initRepositoryActionView() { export function initRepositoryActionView() {
const el = document.getElementById('repo-action-view'); const el = document.querySelector('#repo-action-view');
if (!el) return; if (!el) return;
// TODO: the parent element's full height doesn't work well now, // TODO: the parent element's full height doesn't work well now,

View File

@ -51,7 +51,7 @@ const sfc = {
}; };
export function initRepoActivityTopAuthorsChart() { export function initRepoActivityTopAuthorsChart() {
const el = document.getElementById('repo-activity-top-authors-chart'); const el = document.querySelector('#repo-activity-top-authors-chart');
if (el) { if (el) {
createApp(sfc).mount(el); createApp(sfc).mount(el);
} }

View File

@ -85,7 +85,7 @@ const sfc = {
this.isViewBranch = false; this.isViewBranch = false;
this.$refs.dropdownRefName.textContent = item.name; this.$refs.dropdownRefName.textContent = item.name;
if (this.setAction) { if (this.setAction) {
document.getElementById(this.branchForm)?.setAttribute('action', url); document.querySelector(`#${this.branchForm}`)?.setAttribute('action', url);
} else { } else {
$(`#${this.branchForm} input[name="refURL"]`).val(url); $(`#${this.branchForm} input[name="refURL"]`).val(url);
} }

View File

@ -43,25 +43,25 @@ const sfc = {
}, },
mounted() { mounted() {
document.getElementById('scoped-access-submit').addEventListener('click', this.onClickSubmit); document.querySelector('#scoped-access-submit').addEventListener('click', this.onClickSubmit);
}, },
unmounted() { unmounted() {
document.getElementById('scoped-access-submit').removeEventListener('click', this.onClickSubmit); document.querySelector('#scoped-access-submit').removeEventListener('click', this.onClickSubmit);
}, },
methods: { methods: {
onClickSubmit(e) { onClickSubmit(e) {
e.preventDefault(); e.preventDefault();
const warningEl = document.getElementById('scoped-access-warning'); const warningEl = document.querySelector('#scoped-access-warning');
// check that at least one scope has been selected // check that at least one scope has been selected
for (const el of document.getElementsByClassName('access-token-select')) { for (const el of document.querySelectorAll('.access-token-select')) {
if (el.value) { if (el.value) {
// Hide the error if it was visible from previous attempt. // Hide the error if it was visible from previous attempt.
hideElem(warningEl); hideElem(warningEl);
// Submit the form. // Submit the form.
document.getElementById('scoped-access-form').submit(); document.querySelector('#scoped-access-form').submit();
// Don't show the warning. // Don't show the warning.
return; return;
} }
@ -78,7 +78,7 @@ export default sfc;
* Initialize category toggle sections * Initialize category toggle sections
*/ */
export function initScopedAccessTokenCategories() { export function initScopedAccessTokenCategories() {
for (const el of document.getElementsByClassName('scoped-access-token-mount')) { for (const el of document.querySelectorAll('.scoped-access-token-mount')) {
createApp({}) createApp({})
.component('scoped-access-token-selector', sfc) .component('scoped-access-token-selector', sfc)
.mount(el); .mount(el);

View File

@ -6,7 +6,7 @@ import {POST} from '../../modules/fetch.js';
const {appSubUrl} = window.config; const {appSubUrl} = window.config;
function onSecurityProtocolChange() { function onSecurityProtocolChange() {
if (Number(document.getElementById('security_protocol')?.value) > 0) { if (Number(document.querySelector('#security_protocol')?.value) > 0) {
showElem('.has-tls'); showElem('.has-tls');
} else { } else {
hideElem('.has-tls'); hideElem('.has-tls');
@ -21,34 +21,34 @@ export function initAdminCommon() {
// New user // New user
if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) { if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) {
document.getElementById('login_type')?.addEventListener('change', function () { document.querySelector('#login_type')?.addEventListener('change', function () {
if (this.value?.substring(0, 1) === '0') { if (this.value?.substring(0, 1) === '0') {
document.getElementById('user_name')?.removeAttribute('disabled'); document.querySelector('#user_name')?.removeAttribute('disabled');
document.getElementById('login_name')?.removeAttribute('required'); document.querySelector('#login_name')?.removeAttribute('required');
hideElem('.non-local'); hideElem('.non-local');
showElem('.local'); showElem('.local');
document.getElementById('user_name')?.focus(); document.querySelector('#user_name')?.focus();
if (this.getAttribute('data-password') === 'required') { if (this.getAttribute('data-password') === 'required') {
document.getElementById('password')?.setAttribute('required', 'required'); document.querySelector('#password')?.setAttribute('required', 'required');
} }
} else { } else {
if (document.querySelector('.admin.edit.user')) { if (document.querySelector('.admin.edit.user')) {
document.getElementById('user_name')?.setAttribute('disabled', 'disabled'); document.querySelector('#user_name')?.setAttribute('disabled', 'disabled');
} }
document.getElementById('login_name')?.setAttribute('required', 'required'); document.querySelector('#login_name')?.setAttribute('required', 'required');
showElem('.non-local'); showElem('.non-local');
hideElem('.local'); hideElem('.local');
document.getElementById('login_name')?.focus(); document.querySelector('#login_name')?.focus();
document.getElementById('password')?.removeAttribute('required'); document.querySelector('#password')?.removeAttribute('required');
} }
}); });
} }
function onUsePagedSearchChange() { function onUsePagedSearchChange() {
const searchPageSizeElements = document.querySelectorAll('.search-page-size'); const searchPageSizeElements = document.querySelectorAll('.search-page-size');
if (document.getElementById('use_paged_search').checked) { if (document.querySelector('#use_paged_search').checked) {
showElem('.search-page-size'); showElem('.search-page-size');
for (const el of searchPageSizeElements) { for (const el of searchPageSizeElements) {
el.querySelector('input')?.setAttribute('required', 'required'); el.querySelector('input')?.setAttribute('required', 'required');
@ -67,7 +67,7 @@ export function initAdminCommon() {
input.removeAttribute('required'); input.removeAttribute('required');
} }
const provider = document.getElementById('oauth2_provider').value; const provider = document.querySelector('#oauth2_provider').value;
switch (provider) { switch (provider) {
case 'openidConnect': case 'openidConnect':
document.querySelector('.open_id_connect_auto_discovery_url input').setAttribute('required', 'required'); document.querySelector('.open_id_connect_auto_discovery_url input').setAttribute('required', 'required');
@ -91,19 +91,19 @@ export function initAdminCommon() {
} }
function onOAuth2UseCustomURLChange(applyDefaultValues) { function onOAuth2UseCustomURLChange(applyDefaultValues) {
const provider = document.getElementById('oauth2_provider').value; const provider = document.querySelector('#oauth2_provider').value;
hideElem('.oauth2_use_custom_url_field'); hideElem('.oauth2_use_custom_url_field');
for (const input of document.querySelectorAll('.oauth2_use_custom_url_field input[required]')) { for (const input of document.querySelectorAll('.oauth2_use_custom_url_field input[required]')) {
input.removeAttribute('required'); input.removeAttribute('required');
} }
const elProviderCustomUrlSettings = document.querySelector(`#${provider}_customURLSettings`); const elProviderCustomUrlSettings = document.querySelector(`#${provider}_customURLSettings`);
if (elProviderCustomUrlSettings && document.getElementById('oauth2_use_custom_url').checked) { if (elProviderCustomUrlSettings && document.querySelector('#oauth2_use_custom_url').checked) {
for (const custom of ['token_url', 'auth_url', 'profile_url', 'email_url', 'tenant']) { for (const custom of ['token_url', 'auth_url', 'profile_url', 'email_url', 'tenant']) {
if (applyDefaultValues) { if (applyDefaultValues) {
document.getElementById(`oauth2_${custom}`).value = document.getElementById(`${provider}_${custom}`).value; document.querySelector(`#oauth2_${custom}`).value = document.querySelector(`#${provider}_${custom}`).value;
} }
const customInput = document.getElementById(`${provider}_${custom}`); const customInput = document.querySelector(`#${provider}_${custom}`);
if (customInput && customInput.getAttribute('data-available') === 'true') { if (customInput && customInput.getAttribute('data-available') === 'true') {
for (const input of document.querySelectorAll(`.oauth2_${custom} input`)) { for (const input of document.querySelectorAll(`.oauth2_${custom} input`)) {
input.setAttribute('required', 'required'); input.setAttribute('required', 'required');
@ -115,12 +115,12 @@ export function initAdminCommon() {
} }
function onEnableLdapGroupsChange() { function onEnableLdapGroupsChange() {
toggleElem(document.getElementById('ldap-group-options'), $('.js-ldap-group-toggle')[0].checked); toggleElem(document.querySelector('#ldap-group-options'), $('.js-ldap-group-toggle')[0].checked);
} }
// New authentication // New authentication
if (document.querySelector('.admin.new.authentication')) { if (document.querySelector('.admin.new.authentication')) {
document.getElementById('auth_type')?.addEventListener('change', function () { document.querySelector('#auth_type')?.addEventListener('change', function () {
hideElem('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi'); hideElem('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi');
for (const input of document.querySelectorAll('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]')) { for (const input of document.querySelectorAll('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]')) {
@ -180,25 +180,25 @@ export function initAdminCommon() {
} }
}); });
$('#auth_type').trigger('change'); $('#auth_type').trigger('change');
document.getElementById('security_protocol')?.addEventListener('change', onSecurityProtocolChange); document.querySelector('#security_protocol')?.addEventListener('change', onSecurityProtocolChange);
document.getElementById('use_paged_search')?.addEventListener('change', onUsePagedSearchChange); document.querySelector('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange);
document.getElementById('oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true)); document.querySelector('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true));
document.getElementById('oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(true)); document.querySelector('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(true));
$('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange); $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange);
} }
// Edit authentication // Edit authentication
if (document.querySelector('.admin.edit.authentication')) { if (document.querySelector('.admin.edit.authentication')) {
const authType = document.getElementById('auth_type')?.value; const authType = document.querySelector('#auth_type')?.value;
if (authType === '2' || authType === '5') { if (authType === '2' || authType === '5') {
document.getElementById('security_protocol')?.addEventListener('change', onSecurityProtocolChange); document.querySelector('#security_protocol')?.addEventListener('change', onSecurityProtocolChange);
$('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange); $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange);
onEnableLdapGroupsChange(); onEnableLdapGroupsChange();
if (authType === '2') { if (authType === '2') {
document.getElementById('use_paged_search')?.addEventListener('change', onUsePagedSearchChange); document.querySelector('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange);
} }
} else if (authType === '6') { } else if (authType === '6') {
document.getElementById('oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true)); document.querySelector('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true));
document.getElementById('oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(false)); document.querySelector('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(false));
onOAuth2Change(false); onOAuth2Change(false);
} }
} }
@ -206,13 +206,13 @@ export function initAdminCommon() {
if (document.querySelector('.admin.authentication')) { if (document.querySelector('.admin.authentication')) {
$('#auth_name').on('input', function () { $('#auth_name').on('input', function () {
// appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash. // appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash.
document.getElementById('oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent(this.value)}/callback`; document.querySelector('#oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent(this.value)}/callback`;
}).trigger('input'); }).trigger('input');
} }
// Notice // Notice
if (document.querySelector('.admin.notice')) { if (document.querySelector('.admin.notice')) {
const detailModal = document.getElementById('detail-modal'); const detailModal = document.querySelector('#detail-modal');
// Attach view detail modals // Attach view detail modals
$('.view-detail').on('click', function () { $('.view-detail').on('click', function () {
@ -244,7 +244,7 @@ export function initAdminCommon() {
break; break;
} }
}); });
document.getElementById('delete-selection')?.addEventListener('click', async function (e) { document.querySelector('#delete-selection')?.addEventListener('click', async function (e) {
e.preventDefault(); e.preventDefault();
this.classList.add('is-loading', 'disabled'); this.classList.add('is-loading', 'disabled');
const data = new FormData(); const data = new FormData();

View File

@ -27,9 +27,9 @@ export async function initCitationFileCopyContent() {
if (!pageData.citationFileContent) return; if (!pageData.citationFileContent) return;
const citationCopyApa = document.getElementById('citation-copy-apa'); const citationCopyApa = document.querySelector('#citation-copy-apa');
const citationCopyBibtex = document.getElementById('citation-copy-bibtex'); const citationCopyBibtex = document.querySelector('#citation-copy-bibtex');
const inputContent = document.getElementById('citation-copy-content'); const inputContent = document.querySelector('#citation-copy-content');
if ((!citationCopyApa && !citationCopyBibtex) || !inputContent) return; if ((!citationCopyApa && !citationCopyBibtex) || !inputContent) return;
@ -41,7 +41,7 @@ export async function initCitationFileCopyContent() {
citationCopyApa.classList.toggle('primary', !isBibtex); citationCopyApa.classList.toggle('primary', !isBibtex);
}; };
document.getElementById('cite-repo-button')?.addEventListener('click', async (e) => { document.querySelector('#cite-repo-button')?.addEventListener('click', async (e) => {
const dropdownBtn = e.target.closest('.ui.dropdown.button'); const dropdownBtn = e.target.closest('.ui.dropdown.button');
dropdownBtn.classList.add('is-loading'); dropdownBtn.classList.add('is-loading');

View File

@ -1,7 +1,7 @@
import {createApp} from 'vue'; import {createApp} from 'vue';
export async function initRepoCodeFrequency() { export async function initRepoCodeFrequency() {
const el = document.getElementById('repo-code-frequency-chart'); const el = document.querySelector('#repo-code-frequency-chart');
if (!el) return; if (!el) return;
const {default: RepoCodeFrequency} = await import(/* webpackChunkName: "code-frequency-graph" */'../components/RepoCodeFrequency.vue'); const {default: RepoCodeFrequency} = await import(/* webpackChunkName: "code-frequency-graph" */'../components/RepoCodeFrequency.vue');

View File

@ -1,7 +1,7 @@
import {createTippy} from '../modules/tippy.js'; import {createTippy} from '../modules/tippy.js';
export async function initColorPickers() { export async function initColorPickers() {
const els = document.getElementsByClassName('js-color-picker-input'); const els = document.querySelectorAll('.js-color-picker-input');
if (!els.length) return; if (!els.length) return;
await Promise.all([ await Promise.all([

View File

@ -24,8 +24,8 @@ export function initGlobalFormDirtyLeaveConfirm() {
} }
export function initHeadNavbarContentToggle() { export function initHeadNavbarContentToggle() {
const navbar = document.getElementById('navbar'); const navbar = document.querySelector('#navbar');
const btn = document.getElementById('navbar-expand-toggle'); const btn = document.querySelector('#navbar-expand-toggle');
if (!navbar || !btn) return; if (!navbar || !btn) return;
btn.addEventListener('click', () => { btn.addEventListener('click', () => {

View File

@ -29,7 +29,7 @@ export function parseIssueListQuickGotoLink(repoLink, searchText) {
} }
export function initCommonIssueListQuickGoto() { export function initCommonIssueListQuickGoto() {
const goto = document.getElementById('issue-list-quick-goto'); const goto = document.querySelector('#issue-list-quick-goto');
if (!goto) return; if (!goto) return;
const form = goto.closest('form'); const form = goto.closest('form');

View File

@ -5,7 +5,7 @@ const {appSubUrl} = window.config;
const looksLikeEmailAddressCheck = /^\S+@\S+$/; const looksLikeEmailAddressCheck = /^\S+@\S+$/;
export function initCompSearchUserBox() { export function initCompSearchUserBox() {
const searchUserBox = document.getElementById('search-user-box'); const searchUserBox = document.querySelector('#search-user-box');
if (!searchUserBox) return; if (!searchUserBox) return;
const $searchUserBox = $(searchUserBox); const $searchUserBox = $(searchUserBox);

View File

@ -23,18 +23,18 @@ export function initCompWebHookEditor() {
} }
// some webhooks (like Gitea) allow to set the request method (GET/POST), and it would toggle the "Content Type" field // some webhooks (like Gitea) allow to set the request method (GET/POST), and it would toggle the "Content Type" field
const httpMethodInput = document.getElementById('http_method'); const httpMethodInput = document.querySelector('#http_method');
if (httpMethodInput) { if (httpMethodInput) {
const updateContentType = function () { const updateContentType = function () {
const visible = httpMethodInput.value === 'POST'; const visible = httpMethodInput.value === 'POST';
toggleElem(document.getElementById('content_type').closest('.field'), visible); toggleElem(document.querySelector('#content_type').closest('.field'), visible);
}; };
updateContentType(); updateContentType();
httpMethodInput.addEventListener('change', updateContentType); httpMethodInput.addEventListener('change', updateContentType);
} }
// Test delivery // Test delivery
document.getElementById('test-delivery')?.addEventListener('click', async function () { document.querySelector('#test-delivery')?.addEventListener('click', async function () {
this.classList.add('is-loading', 'disabled'); this.classList.add('is-loading', 'disabled');
await POST(this.getAttribute('data-link')); await POST(this.getAttribute('data-link'));
setTimeout(() => { setTimeout(() => {

View File

@ -1,7 +1,7 @@
import {createApp} from 'vue'; import {createApp} from 'vue';
export async function initRepoContributors() { export async function initRepoContributors() {
const el = document.getElementById('repo-contributors-chart'); const el = document.querySelector('#repo-contributors-chart');
if (!el) return; if (!el) return;
const {default: RepoContributors} = await import(/* webpackChunkName: "contributors-graph" */'../components/RepoContributors.vue'); const {default: RepoContributors} = await import(/* webpackChunkName: "contributors-graph" */'../components/RepoContributors.vue');

View File

@ -6,7 +6,7 @@ import {GET} from '../modules/fetch.js';
const {i18n} = window.config; const {i18n} = window.config;
export function initCopyContent() { export function initCopyContent() {
const btn = document.getElementById('copy-content'); const btn = document.querySelector('#copy-content');
if (!btn || btn.classList.contains('disabled')) return; if (!btn || btn.classList.contains('disabled')) return;
btn.addEventListener('click', async () => { btn.addEventListener('click', async () => {

View File

@ -3,7 +3,7 @@ import ActivityHeatmap from '../components/ActivityHeatmap.vue';
import {translateMonth, translateDay} from '../utils.js'; import {translateMonth, translateDay} from '../utils.js';
export function initHeatmap() { export function initHeatmap() {
const el = document.getElementById('user-heatmap'); const el = document.querySelector('#user-heatmap');
if (!el) return; if (!el) return;
try { try {

View File

@ -22,12 +22,12 @@ function initPreInstall() {
mssql: '127.0.0.1:1433', mssql: '127.0.0.1:1433',
}; };
const dbHost = document.getElementById('db_host'); const dbHost = document.querySelector('#db_host');
const dbUser = document.getElementById('db_user'); const dbUser = document.querySelector('#db_user');
const dbName = document.getElementById('db_name'); const dbName = document.querySelector('#db_name');
// Database type change detection. // Database type change detection.
document.getElementById('db_type').addEventListener('change', function () { document.querySelector('#db_type').addEventListener('change', function () {
const dbType = this.value; const dbType = this.value;
hideElem('div[data-db-setting-for]'); hideElem('div[data-db-setting-for]');
showElem(`div[data-db-setting-for=${dbType}]`); showElem(`div[data-db-setting-for=${dbType}]`);
@ -46,14 +46,14 @@ function initPreInstall() {
} }
} // else: for SQLite3, the default path is always prepared by backend code (setting) } // else: for SQLite3, the default path is always prepared by backend code (setting)
}); });
document.getElementById('db_type').dispatchEvent(new Event('change')); document.querySelector('#db_type').dispatchEvent(new Event('change'));
const appUrl = document.getElementById('app_url'); const appUrl = document.querySelector('#app_url');
if (appUrl.value.includes('://localhost')) { if (appUrl.value.includes('://localhost')) {
appUrl.value = window.location.href; appUrl.value = window.location.href;
} }
const domain = document.getElementById('domain'); const domain = document.querySelector('#domain');
if (domain.value.trim() === 'localhost') { if (domain.value.trim() === 'localhost') {
domain.value = window.location.hostname; domain.value = window.location.hostname;
} }
@ -103,7 +103,7 @@ function initPreInstall() {
} }
function initPostInstall() { function initPostInstall() {
const el = document.getElementById('goto-user-login'); const el = document.querySelector('#goto-user-login');
if (!el) return; if (!el) return;
const targetUrl = el.getAttribute('href'); const targetUrl = el.getAttribute('href');

View File

@ -7,13 +7,13 @@ const {appSubUrl, notificationSettings, assetVersionEncoded} = window.config;
let notificationSequenceNumber = 0; let notificationSequenceNumber = 0;
export function initNotificationsTable() { export function initNotificationsTable() {
const table = document.getElementById('notification_table'); const table = document.querySelector('#notification_table');
if (!table) return; if (!table) return;
// when page restores from bfcache, delete previously clicked items // when page restores from bfcache, delete previously clicked items
window.addEventListener('pageshow', (e) => { window.addEventListener('pageshow', (e) => {
if (e.persisted) { // page was restored from bfcache if (e.persisted) { // page was restored from bfcache
const table = document.getElementById('notification_table'); const table = document.querySelector('#notification_table');
const unreadCountEl = document.querySelector('.notifications-unread-count'); const unreadCountEl = document.querySelector('.notifications-unread-count');
let unreadCount = parseInt(unreadCountEl.textContent); let unreadCount = parseInt(unreadCountEl.textContent);
for (const item of table.querySelectorAll('.notifications-item[data-remove="true"]')) { for (const item of table.querySelectorAll('.notifications-item[data-remove="true"]')) {
@ -145,7 +145,7 @@ async function updateNotificationCountWithCallback(callback, timeout, lastCount)
} }
async function updateNotificationTable() { async function updateNotificationTable() {
const notificationDiv = document.getElementById('notification_div'); const notificationDiv = document.querySelector('#notification_div');
if (notificationDiv) { if (notificationDiv) {
try { try {
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
@ -181,7 +181,7 @@ async function updateNotificationCount() {
toggleElem('.notification_count', data.new !== 0); toggleElem('.notification_count', data.new !== 0);
for (const el of document.getElementsByClassName('notification_count')) { for (const el of document.querySelectorAll('.notification_count')) {
el.textContent = `${data.new}`; el.textContent = `${data.new}`;
} }

View File

@ -12,9 +12,9 @@ const collapseFilesBtnSelector = '#collapse-files-btn';
// Refreshes the summary of viewed files if present // Refreshes the summary of viewed files if present
// The data used will be window.config.pageData.prReview.numberOf{Viewed}Files // The data used will be window.config.pageData.prReview.numberOf{Viewed}Files
function refreshViewedFilesSummary() { function refreshViewedFilesSummary() {
const viewedFilesProgress = document.getElementById('viewed-files-summary'); const viewedFilesProgress = document.querySelector('#viewed-files-summary');
viewedFilesProgress?.setAttribute('value', prReview.numberOfViewedFiles); viewedFilesProgress?.setAttribute('value', prReview.numberOfViewedFiles);
const summaryLabel = document.getElementById('viewed-files-summary-label'); const summaryLabel = document.querySelector('#viewed-files-summary-label');
if (summaryLabel) summaryLabel.innerHTML = summaryLabel.getAttribute('data-text-changed-template') if (summaryLabel) summaryLabel.innerHTML = summaryLabel.getAttribute('data-text-changed-template')
.replace('%[1]d', prReview.numberOfViewedFiles) .replace('%[1]d', prReview.numberOfViewedFiles)
.replace('%[2]d', prReview.numberOfFiles); .replace('%[2]d', prReview.numberOfFiles);

View File

@ -1,7 +1,7 @@
import {createApp} from 'vue'; import {createApp} from 'vue';
export async function initRepoRecentCommits() { export async function initRepoRecentCommits() {
const el = document.getElementById('repo-recent-commits-chart'); const el = document.querySelector('#repo-recent-commits-chart');
if (!el) return; if (!el) return;
const {default: RepoRecentCommits} = await import(/* webpackChunkName: "recent-commits-graph" */'../components/RepoRecentCommits.vue'); const {default: RepoRecentCommits} = await import(/* webpackChunkName: "recent-commits-graph" */'../components/RepoRecentCommits.vue');

View File

@ -2,7 +2,7 @@ import {createApp} from 'vue';
import DiffCommitSelector from '../components/DiffCommitSelector.vue'; import DiffCommitSelector from '../components/DiffCommitSelector.vue';
export function initDiffCommitSelect() { export function initDiffCommitSelect() {
const el = document.getElementById('diff-commit-select'); const el = document.querySelector('#diff-commit-select');
if (!el) return; if (!el) return;
const commitSelect = createApp(DiffCommitSelector); const commitSelect = createApp(DiffCommitSelector);

View File

@ -3,13 +3,13 @@ import DiffFileTree from '../components/DiffFileTree.vue';
import DiffFileList from '../components/DiffFileList.vue'; import DiffFileList from '../components/DiffFileList.vue';
export function initDiffFileTree() { export function initDiffFileTree() {
const el = document.getElementById('diff-file-tree'); const el = document.querySelector('#diff-file-tree');
if (!el) return; if (!el) return;
const fileTreeView = createApp(DiffFileTree); const fileTreeView = createApp(DiffFileTree);
fileTreeView.mount(el); fileTreeView.mount(el);
const fileListElement = document.getElementById('diff-file-list'); const fileListElement = document.querySelector('#diff-file-list');
if (!fileListElement) return; if (!fileListElement) return;
const fileListView = createApp(DiffFileList); const fileListView = createApp(DiffFileList);

View File

@ -13,7 +13,7 @@ import {POST, GET} from '../modules/fetch.js';
const {pageData, i18n} = window.config; const {pageData, i18n} = window.config;
function initRepoDiffReviewButton() { function initRepoDiffReviewButton() {
const reviewBox = document.getElementById('review-box'); const reviewBox = document.querySelector('#review-box');
if (!reviewBox) return; if (!reviewBox) return;
const counter = reviewBox.querySelector('.review-comments-counter'); const counter = reviewBox.querySelector('.review-comments-counter');

View File

@ -112,7 +112,7 @@ export function initRepoEditor() {
// Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage
// to enable or disable the commit button // to enable or disable the commit button
const commitButton = document.getElementById('commit-button'); const commitButton = document.querySelector('#commit-button');
const $editForm = $('.ui.edit.form'); const $editForm = $('.ui.edit.form');
const dirtyFileClass = 'dirty-file'; const dirtyFileClass = 'dirty-file';

View File

@ -106,11 +106,11 @@ async function loadRepoFiles() {
} }
export function initFindFileInRepo() { export function initFindFileInRepo() {
repoFindFileInput = document.getElementById('repo-file-find-input'); repoFindFileInput = document.querySelector('#repo-file-find-input');
if (!repoFindFileInput) return; if (!repoFindFileInput) return;
repoFindFileTableBody = document.querySelector('#repo-find-file-table tbody'); repoFindFileTableBody = document.querySelector('#repo-find-file-table tbody');
repoFindFileNoResult = document.getElementById('repo-find-file-no-result'); repoFindFileNoResult = document.querySelector('#repo-find-file-no-result');
repoFindFileInput.addEventListener('input', () => filterRepoFiles(repoFindFileInput.value)); repoFindFileInput.addEventListener('input', () => filterRepoFiles(repoFindFileInput.value));
loadRepoFiles(); loadRepoFiles();

View File

@ -3,12 +3,12 @@ import {hideElem, showElem} from '../utils/dom.js';
import {GET} from '../modules/fetch.js'; import {GET} from '../modules/fetch.js';
export function initRepoGraphGit() { export function initRepoGraphGit() {
const graphContainer = document.getElementById('git-graph-container'); const graphContainer = document.querySelector('#git-graph-container');
if (!graphContainer) return; if (!graphContainer) return;
document.getElementById('flow-color-monochrome')?.addEventListener('click', () => { document.querySelector('#flow-color-monochrome')?.addEventListener('click', () => {
document.getElementById('flow-color-monochrome').classList.add('active'); document.querySelector('#flow-color-monochrome').classList.add('active');
document.getElementById('flow-color-colored')?.classList.remove('active'); document.querySelector('#flow-color-colored')?.classList.remove('active');
graphContainer.classList.remove('colored'); graphContainer.classList.remove('colored');
graphContainer.classList.add('monochrome'); graphContainer.classList.add('monochrome');
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
@ -30,9 +30,9 @@ export function initRepoGraphGit() {
} }
}); });
document.getElementById('flow-color-colored')?.addEventListener('click', () => { document.querySelector('#flow-color-colored')?.addEventListener('click', () => {
document.getElementById('flow-color-colored').classList.add('active'); document.querySelector('#flow-color-colored').classList.add('active');
document.getElementById('flow-color-monochrome')?.classList.remove('active'); document.querySelector('#flow-color-monochrome')?.classList.remove('active');
graphContainer.classList.add('colored'); graphContainer.classList.add('colored');
graphContainer.classList.remove('monochrome'); graphContainer.classList.remove('monochrome');
for (const link of document.querySelectorAll('.pagination a')) { for (const link of document.querySelectorAll('.pagination a')) {
@ -60,7 +60,7 @@ export function initRepoGraphGit() {
const ajaxUrl = new URL(url); const ajaxUrl = new URL(url);
ajaxUrl.searchParams.set('div-only', 'true'); ajaxUrl.searchParams.set('div-only', 'true');
window.history.replaceState({}, '', queryString ? `?${queryString}` : window.location.pathname); window.history.replaceState({}, '', queryString ? `?${queryString}` : window.location.pathname);
document.getElementById('pagination').innerHTML = ''; document.querySelector('#pagination').innerHTML = '';
hideElem('#rel-container'); hideElem('#rel-container');
hideElem('#rev-container'); hideElem('#rev-container');
showElem('#loading-indicator'); showElem('#loading-indicator');
@ -69,9 +69,9 @@ export function initRepoGraphGit() {
const html = await response.text(); const html = await response.text();
const div = document.createElement('div'); const div = document.createElement('div');
div.innerHTML = html; div.innerHTML = html;
document.getElementById('pagination').innerHTML = div.getElementById('pagination').innerHTML; document.querySelector('#pagination').innerHTML = div.querySelector('#pagination').innerHTML;
document.getElementById('rel-container').innerHTML = div.getElementById('rel-container').innerHTML; document.querySelector('#rel-container').innerHTML = div.querySelector('#rel-container').innerHTML;
document.getElementById('rev-container').innerHTML = div.getElementById('rev-container').innerHTML; document.querySelector('#rev-container').innerHTML = div.querySelector('#rev-container').innerHTML;
hideElem('#loading-indicator'); hideElem('#loading-indicator');
showElem('#rel-container'); showElem('#rel-container');
showElem('#rev-container'); showElem('#rev-container');
@ -82,7 +82,7 @@ export function initRepoGraphGit() {
dropdownSelected.splice(0, 0, '...flow-hide-pr-refs'); dropdownSelected.splice(0, 0, '...flow-hide-pr-refs');
} }
const flowSelectRefsDropdown = document.getElementById('flow-select-refs-dropdown'); const flowSelectRefsDropdown = document.querySelector('#flow-select-refs-dropdown');
$(flowSelectRefsDropdown).dropdown('set selected', dropdownSelected); $(flowSelectRefsDropdown).dropdown('set selected', dropdownSelected);
$(flowSelectRefsDropdown).dropdown({ $(flowSelectRefsDropdown).dropdown({
clearable: true, clearable: true,
@ -115,7 +115,7 @@ export function initRepoGraphGit() {
if (e.target.matches('#rev-list li')) { if (e.target.matches('#rev-list li')) {
const flow = e.target.getAttribute('data-flow'); const flow = e.target.getAttribute('data-flow');
if (flow === '0') return; if (flow === '0') return;
document.getElementById(`flow-${flow}`)?.classList.add('highlight'); document.querySelector(`#flow-${flow}`)?.classList.add('highlight');
e.target.classList.add('hover'); e.target.classList.add('hover');
for (const item of document.querySelectorAll(`#rev-list li[data-flow='${flow}']`)) { for (const item of document.querySelectorAll(`#rev-list li[data-flow='${flow}']`)) {
item.classList.add('highlight'); item.classList.add('highlight');
@ -136,7 +136,7 @@ export function initRepoGraphGit() {
if (e.target.matches('#rev-list li')) { if (e.target.matches('#rev-list li')) {
const flow = e.target.getAttribute('data-flow'); const flow = e.target.getAttribute('data-flow');
if (flow === '0') return; if (flow === '0') return;
document.getElementById(`flow-${flow}`)?.classList.remove('highlight'); document.querySelector(`#flow-${flow}`)?.classList.remove('highlight');
e.target.classList.remove('hover'); e.target.classList.remove('hover');
for (const item of document.querySelectorAll(`#rev-list li[data-flow='${flow}']`)) { for (const item of document.querySelectorAll(`#rev-list li[data-flow='${flow}']`)) {
item.classList.remove('highlight'); item.classList.remove('highlight');

View File

@ -7,11 +7,11 @@ import {showErrorToast} from '../modules/toast.js';
const {appSubUrl} = window.config; const {appSubUrl} = window.config;
export function initRepoTopicBar() { export function initRepoTopicBar() {
const mgrBtn = document.getElementById('manage_topic'); const mgrBtn = document.querySelector('#manage_topic');
if (!mgrBtn) return; if (!mgrBtn) return;
const editDiv = document.getElementById('topic_edit'); const editDiv = document.querySelector('#topic_edit');
const viewDiv = document.getElementById('repo-topics'); const viewDiv = document.querySelector('#repo-topics');
const topicDropdown = editDiv.querySelector('.ui.dropdown'); const topicDropdown = editDiv.querySelector('.ui.dropdown');
let lastErrorToast; let lastErrorToast;
@ -28,7 +28,7 @@ export function initRepoTopicBar() {
mgrBtn.focus(); mgrBtn.focus();
}); });
document.getElementById('save_topic').addEventListener('click', async (e) => { document.querySelector('#save_topic').addEventListener('click', async (e) => {
lastErrorToast?.hideToast(); lastErrorToast?.hideToast();
const topics = editDiv.querySelector('input[name=topics]').value; const topics = editDiv.querySelector('input[name=topics]').value;

View File

@ -55,7 +55,7 @@ async function onEditContent(event) {
dropzone.querySelector('.files').append(input); dropzone.querySelector('.files').append(input);
}); });
this.on('removedfile', async (file) => { this.on('removedfile', async (file) => {
document.getElementById(file.uuid)?.remove(); document.querySelector(`#${file.uuid}`)?.remove();
if (disableRemovedfileEvent) return; if (disableRemovedfileEvent) return;
if (dropzone.getAttribute('data-remove-url') && !fileUuidDict[file.uuid].submitted) { if (dropzone.getAttribute('data-remove-url') && !fileUuidDict[file.uuid].submitted) {
try { try {
@ -137,7 +137,7 @@ async function onEditContent(event) {
} }
editContentZone.setAttribute('data-content-version', data.contentVersion); editContentZone.setAttribute('data-content-version', data.contentVersion);
if (!data.content) { if (!data.content) {
renderContent.innerHTML = document.getElementById('no-content').innerHTML; renderContent.innerHTML = document.querySelector('#no-content').innerHTML;
rawContent.textContent = ''; rawContent.textContent = '';
} else { } else {
renderContent.innerHTML = data.content; renderContent.innerHTML = data.content;
@ -166,7 +166,7 @@ async function onEditContent(event) {
comboMarkdownEditor = getComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor')); comboMarkdownEditor = getComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor'));
if (!comboMarkdownEditor) { if (!comboMarkdownEditor) {
editContentZone.innerHTML = document.getElementById('issue-comment-editor-template').innerHTML; editContentZone.innerHTML = document.querySelector('#issue-comment-editor-template').innerHTML;
comboMarkdownEditor = await initComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor')); comboMarkdownEditor = await initComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor'));
comboMarkdownEditor.attachedDropzoneInst = await setupDropzone(editContentZone.querySelector('.dropzone')); comboMarkdownEditor.attachedDropzoneInst = await setupDropzone(editContentZone.querySelector('.dropzone'));
editContentZone.querySelector('.ui.cancel.button').addEventListener('click', cancelAndReset); editContentZone.querySelector('.ui.cancel.button').addEventListener('click', cancelAndReset);

View File

@ -158,7 +158,7 @@ function initRepoIssueListAuthorDropdown() {
} }
function initPinRemoveButton() { function initPinRemoveButton() {
for (const button of document.getElementsByClassName('issue-card-unpin')) { for (const button of document.querySelectorAll('.issue-card-unpin')) {
button.addEventListener('click', async (event) => { button.addEventListener('click', async (event) => {
const el = event.currentTarget; const el = event.currentTarget;
const id = Number(el.getAttribute('data-issue-id')); const id = Number(el.getAttribute('data-issue-id'));
@ -182,7 +182,7 @@ async function pinMoveEnd(e) {
} }
async function initIssuePinSort() { async function initIssuePinSort() {
const pinDiv = document.getElementById('issue-pins'); const pinDiv = document.querySelector('#issue-pins');
if (pinDiv === null) return; if (pinDiv === null) return;

View File

@ -2,7 +2,7 @@ import {createApp} from 'vue';
import PullRequestMergeForm from '../components/PullRequestMergeForm.vue'; import PullRequestMergeForm from '../components/PullRequestMergeForm.vue';
export function initRepoPullRequestMergeForm() { export function initRepoPullRequestMergeForm() {
const el = document.getElementById('pull-request-merge-form'); const el = document.querySelector('#pull-request-merge-form');
if (!el) return; if (!el) return;
const view = createApp(PullRequestMergeForm); const view = createApp(PullRequestMergeForm);

View File

@ -44,14 +44,14 @@ export function initRepoIssueTimeTracking() {
async function updateDeadline(deadlineString) { async function updateDeadline(deadlineString) {
hideElem('#deadline-err-invalid-date'); hideElem('#deadline-err-invalid-date');
document.getElementById('deadline-loader')?.classList.add('is-loading'); document.querySelector('#deadline-loader')?.classList.add('is-loading');
let realDeadline = null; let realDeadline = null;
if (deadlineString !== '') { if (deadlineString !== '') {
const newDate = Date.parse(deadlineString); const newDate = Date.parse(deadlineString);
if (Number.isNaN(newDate)) { if (Number.isNaN(newDate)) {
document.getElementById('deadline-loader')?.classList.remove('is-loading'); document.querySelector('#deadline-loader')?.classList.remove('is-loading');
showElem('#deadline-err-invalid-date'); showElem('#deadline-err-invalid-date');
return false; return false;
} }
@ -59,7 +59,7 @@ async function updateDeadline(deadlineString) {
} }
try { try {
const response = await POST(document.getElementById('update-issue-deadline-form').getAttribute('action'), { const response = await POST(document.querySelector('#update-issue-deadline-form').getAttribute('action'), {
data: {due_date: realDeadline}, data: {due_date: realDeadline},
}); });
@ -70,7 +70,7 @@ async function updateDeadline(deadlineString) {
} }
} catch (error) { } catch (error) {
console.error(error); console.error(error);
document.getElementById('deadline-loader').classList.remove('is-loading'); document.querySelector('#deadline-loader').classList.remove('is-loading');
showElem('#deadline-err-invalid-date'); showElem('#deadline-err-invalid-date');
} }
} }
@ -182,7 +182,7 @@ export function initRepoIssueCommentDelete() {
counter.textContent = String(num); counter.textContent = String(num);
} }
document.getElementById(deleteButton.getAttribute('data-comment-id'))?.remove(); document.querySelector(`#${deleteButton.getAttribute('data-comment-id')}`)?.remove();
if (conversationHolder && !conversationHolder.querySelector('.comment')) { if (conversationHolder && !conversationHolder.querySelector('.comment')) {
const path = conversationHolder.getAttribute('data-path'); const path = conversationHolder.getAttribute('data-path');
@ -298,7 +298,7 @@ export function initRepoPullRequestMergeInstruction() {
} }
export function initRepoPullRequestAllowMaintainerEdit() { export function initRepoPullRequestAllowMaintainerEdit() {
const wrapper = document.getElementById('allow-edits-from-maintainers'); const wrapper = document.querySelector('#allow-edits-from-maintainers');
if (!wrapper) return; if (!wrapper) return;
const checkbox = wrapper.querySelector('input[type="checkbox"]'); const checkbox = wrapper.querySelector('input[type="checkbox"]');
checkbox.addEventListener('input', async () => { checkbox.addEventListener('input', async () => {
@ -678,7 +678,7 @@ export function initSingleCommentEditor($commentForm) {
// * normal new issue/pr page, no status-button // * normal new issue/pr page, no status-button
// * issue/pr view page, with comment form, has status-button // * issue/pr view page, with comment form, has status-button
const opts = {}; const opts = {};
const statusButton = document.getElementById('status-button'); const statusButton = document.querySelector('#status-button');
if (statusButton) { if (statusButton) {
opts.onContentChanged = (editor) => { opts.onContentChanged = (editor) => {
const statusText = statusButton.getAttribute(editor.value().trim() ? 'data-status-and-comment' : 'data-status'); const statusText = statusButton.getAttribute(editor.value().trim() ? 'data-status-and-comment' : 'data-status');

View File

@ -4,10 +4,10 @@ import {GET, POST} from '../modules/fetch.js';
const {appSubUrl} = window.config; const {appSubUrl} = window.config;
export function initRepoMigrationStatusChecker() { export function initRepoMigrationStatusChecker() {
const repoMigrating = document.getElementById('repo_migrating'); const repoMigrating = document.querySelector('#repo_migrating');
if (!repoMigrating) return; if (!repoMigrating) return;
document.getElementById('repo_migrating_retry').addEventListener('click', doMigrationRetry); document.querySelector('#repo_migrating_retry').addEventListener('click', doMigrationRetry);
const task = repoMigrating.getAttribute('data-migrating-task-id'); const task = repoMigrating.getAttribute('data-migrating-task-id');
@ -20,7 +20,7 @@ export function initRepoMigrationStatusChecker() {
// for all status // for all status
if (data.message) { if (data.message) {
document.getElementById('repo_migrating_progress_message').textContent = data.message; document.querySelector('#repo_migrating_progress_message').textContent = data.message;
} }
// TaskStatusFinished // TaskStatusFinished
@ -36,7 +36,7 @@ export function initRepoMigrationStatusChecker() {
showElem('#repo_migrating_retry'); showElem('#repo_migrating_retry');
showElem('#repo_migrating_failed'); showElem('#repo_migrating_failed');
showElem('#repo_migrating_failed_image'); showElem('#repo_migrating_failed_image');
document.getElementById('repo_migrating_failed_error').textContent = data.message; document.querySelector('#repo_migrating_failed_error').textContent = data.message;
return false; return false;
} }

View File

@ -1,13 +1,13 @@
import {hideElem, showElem, toggleElem} from '../utils/dom.js'; import {hideElem, showElem, toggleElem} from '../utils/dom.js';
const service = document.getElementById('service_type'); const service = document.querySelector('#service_type');
const user = document.getElementById('auth_username'); const user = document.querySelector('#auth_username');
const pass = document.getElementById('auth_password'); const pass = document.querySelector('#auth_password');
const token = document.getElementById('auth_token'); const token = document.querySelector('#auth_token');
const mirror = document.getElementById('mirror'); const mirror = document.querySelector('#mirror');
const lfs = document.getElementById('lfs'); const lfs = document.querySelector('#lfs');
const lfsSettings = document.getElementById('lfs_settings'); const lfsSettings = document.querySelector('#lfs_settings');
const lfsEndpoint = document.getElementById('lfs_endpoint'); const lfsEndpoint = document.querySelector('#lfs_endpoint');
const items = document.querySelectorAll('#migrate_items input[type=checkbox]'); const items = document.querySelectorAll('#migrate_items input[type=checkbox]');
export function initRepoMigration() { export function initRepoMigration() {
@ -18,16 +18,16 @@ export function initRepoMigration() {
pass?.addEventListener('input', () => {checkItems(false)}); pass?.addEventListener('input', () => {checkItems(false)});
token?.addEventListener('input', () => {checkItems(true)}); token?.addEventListener('input', () => {checkItems(true)});
mirror?.addEventListener('change', () => {checkItems(true)}); mirror?.addEventListener('change', () => {checkItems(true)});
document.getElementById('lfs_settings_show')?.addEventListener('click', (e) => { document.querySelector('#lfs_settings_show')?.addEventListener('click', (e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
showElem(lfsEndpoint); showElem(lfsEndpoint);
}); });
lfs?.addEventListener('change', setLFSSettingsVisibility); lfs?.addEventListener('change', setLFSSettingsVisibility);
const cloneAddr = document.getElementById('clone_addr'); const cloneAddr = document.querySelector('#clone_addr');
cloneAddr?.addEventListener('change', () => { cloneAddr?.addEventListener('change', () => {
const repoName = document.getElementById('repo_name'); const repoName = document.querySelector('#repo_name');
if (cloneAddr.value && !repoName?.value) { // Only modify if repo_name input is blank if (cloneAddr.value && !repoName?.value) { // Only modify if repo_name input is blank
repoName.value = cloneAddr.value.match(/^(.*\/)?((.+?)(\.git)?)$/)[3]; repoName.value = cloneAddr.value.match(/^(.*\/)?((.+?)(\.git)?)$/)[3];
} }

View File

@ -5,8 +5,8 @@ import {POST, DELETE, PUT} from '../modules/fetch.js';
function updateIssueCount(cards) { function updateIssueCount(cards) {
const parent = cards.parentElement; const parent = cards.parentElement;
const cnt = parent.getElementsByClassName('issue-card').length; const cnt = parent.querySelectorAll('.issue-card').length;
parent.getElementsByClassName('project-column-issue-count')[0].textContent = cnt; parent.querySelectorAll('.project-column-issue-count')[0].textContent = cnt;
} }
async function createNewColumn(url, columnTitle, projectColorInput) { async function createNewColumn(url, columnTitle, projectColorInput) {
@ -26,7 +26,7 @@ async function createNewColumn(url, columnTitle, projectColorInput) {
} }
async function moveIssue({item, from, to, oldIndex}) { async function moveIssue({item, from, to, oldIndex}) {
const columnCards = to.getElementsByClassName('issue-card'); const columnCards = to.querySelectorAll('.issue-card');
updateIssueCount(from); updateIssueCount(from);
updateIssueCount(to); updateIssueCount(to);
@ -53,7 +53,7 @@ async function initRepoProjectSortable() {
// the HTML layout is: #project-board > .board > .project-column .cards > .issue-card // the HTML layout is: #project-board > .board > .project-column .cards > .issue-card
const mainBoard = els[0]; const mainBoard = els[0];
let boardColumns = mainBoard.getElementsByClassName('project-column'); let boardColumns = mainBoard.querySelectorAll('.project-column');
createSortable(mainBoard, { createSortable(mainBoard, {
group: 'project-column', group: 'project-column',
draggable: '.project-column', draggable: '.project-column',
@ -61,7 +61,7 @@ async function initRepoProjectSortable() {
delayOnTouchOnly: true, delayOnTouchOnly: true,
delay: 500, delay: 500,
onSort: async () => { onSort: async () => {
boardColumns = mainBoard.getElementsByClassName('project-column'); boardColumns = mainBoard.querySelectorAll('.project-column');
const columnSorting = { const columnSorting = {
columns: Array.from(boardColumns, (column, i) => ({ columns: Array.from(boardColumns, (column, i) => ({
@ -81,7 +81,7 @@ async function initRepoProjectSortable() {
}); });
for (const boardColumn of boardColumns) { for (const boardColumn of boardColumns) {
const boardCardList = boardColumn.getElementsByClassName('cards')[0]; const boardCardList = boardColumn.querySelectorAll('.cards')[0];
createSortable(boardCardList, { createSortable(boardCardList, {
group: 'shared', group: 'shared',
onAdd: moveIssue, onAdd: moveIssue,
@ -99,7 +99,7 @@ export function initRepoProject() {
const _promise = initRepoProjectSortable(); const _promise = initRepoProjectSortable();
for (const modal of document.getElementsByClassName('edit-project-column-modal')) { for (const modal of document.querySelectorAll('.edit-project-column-modal')) {
const projectHeader = modal.closest('.project-column-header'); const projectHeader = modal.closest('.project-column-header');
const projectTitleLabel = projectHeader?.querySelector('.project-column-title-label'); const projectTitleLabel = projectHeader?.querySelector('.project-column-title-label');
const projectTitleInput = modal.querySelector('.project-column-title-input'); const projectTitleInput = modal.querySelector('.project-column-title-input');

View File

@ -20,7 +20,7 @@ export function initRepoReleaseNew() {
} }
function initTagNameEditor() { function initTagNameEditor() {
const el = document.getElementById('tag-name-editor'); const el = document.querySelector('#tag-name-editor');
if (!el) return; if (!el) return;
const existingTags = JSON.parse(el.getAttribute('data-existing-tags')); const existingTags = JSON.parse(el.getAttribute('data-existing-tags'));
@ -30,10 +30,10 @@ function initTagNameEditor() {
const newTagHelperText = el.getAttribute('data-tag-helper-new'); const newTagHelperText = el.getAttribute('data-tag-helper-new');
const existingTagHelperText = el.getAttribute('data-tag-helper-existing'); const existingTagHelperText = el.getAttribute('data-tag-helper-existing');
const tagNameInput = document.getElementById('tag-name'); const tagNameInput = document.querySelector('#tag-name');
const hideTargetInput = function(tagNameInput) { const hideTargetInput = function(tagNameInput) {
const value = tagNameInput.value; const value = tagNameInput.value;
const tagHelper = document.getElementById('tag-helper'); const tagHelper = document.querySelector('#tag-helper');
if (existingTags.includes(value)) { if (existingTags.includes(value)) {
// If the tag already exists, hide the target branch selector. // If the tag already exists, hide the target branch selector.
hideElem('#tag-target-selector'); hideElem('#tag-target-selector');

View File

@ -44,7 +44,7 @@ export function initRepoSettingsCollaboration() {
} }
export function initRepoSettingSearchTeamBox() { export function initRepoSettingSearchTeamBox() {
const searchTeamBox = document.getElementById('search-team-box'); const searchTeamBox = document.querySelector('#search-team-box');
if (!searchTeamBox) return; if (!searchTeamBox) return;
$(searchTeamBox).search({ $(searchTeamBox).search({
@ -78,29 +78,29 @@ export function initRepoSettingGitHook() {
export function initRepoSettingBranches() { export function initRepoSettingBranches() {
if (!document.querySelector('.repository.settings.branches')) return; if (!document.querySelector('.repository.settings.branches')) return;
for (const el of document.getElementsByClassName('toggle-target-enabled')) { for (const el of document.querySelectorAll('.toggle-target-enabled')) {
el.addEventListener('change', function () { el.addEventListener('change', function () {
const target = document.querySelector(this.getAttribute('data-target')); const target = document.querySelector(this.getAttribute('data-target'));
target?.classList.toggle('disabled', !this.checked); target?.classList.toggle('disabled', !this.checked);
}); });
} }
for (const el of document.getElementsByClassName('toggle-target-disabled')) { for (const el of document.querySelectorAll('.toggle-target-disabled')) {
el.addEventListener('change', function () { el.addEventListener('change', function () {
const target = document.querySelector(this.getAttribute('data-target')); const target = document.querySelector(this.getAttribute('data-target'));
if (this.checked) target?.classList.add('disabled'); // only disable, do not auto enable if (this.checked) target?.classList.add('disabled'); // only disable, do not auto enable
}); });
} }
document.getElementById('dismiss_stale_approvals')?.addEventListener('change', function () { document.querySelector('#dismiss_stale_approvals')?.addEventListener('change', function () {
document.getElementById('ignore_stale_approvals_box')?.classList.toggle('disabled', this.checked); document.querySelector('#ignore_stale_approvals_box')?.classList.toggle('disabled', this.checked);
}); });
// show the `Matched` mark for the status checks that match the pattern // show the `Matched` mark for the status checks that match the pattern
const markMatchedStatusChecks = () => { const markMatchedStatusChecks = () => {
const patterns = (document.getElementById('status_check_contexts').value || '').split(/[\r\n]+/); const patterns = (document.querySelector('#status_check_contexts').value || '').split(/[\r\n]+/);
const validPatterns = patterns.map((item) => item.trim()).filter(Boolean); const validPatterns = patterns.map((item) => item.trim()).filter(Boolean);
const marks = document.getElementsByClassName('status-check-matched-mark'); const marks = document.querySelectorAll('.status-check-matched-mark');
for (const el of marks) { for (const el of marks) {
let matched = false; let matched = false;
@ -115,5 +115,5 @@ export function initRepoSettingBranches() {
} }
}; };
markMatchedStatusChecks(); markMatchedStatusChecks();
document.getElementById('status_check_contexts').addEventListener('input', onInputDebounce(markMatchedStatusChecks)); document.querySelector('#status_check_contexts').addEventListener('input', onInputDebounce(markMatchedStatusChecks));
} }

View File

@ -1,8 +1,8 @@
export function initSshKeyFormParser() { export function initSshKeyFormParser() {
// Parse SSH Key // Parse SSH Key
document.getElementById('ssh-key-content')?.addEventListener('input', function () { document.querySelector('#ssh-key-content')?.addEventListener('input', function () {
const arrays = this.value.split(' '); const arrays = this.value.split(' ');
const title = document.getElementById('ssh-key-title'); const title = document.querySelector('#ssh-key-title');
if (!title.value && arrays.length === 3 && arrays[2] !== '') { if (!title.value && arrays.length === 3 && arrays[2] !== '') {
title.value = arrays[2]; title.value = arrays[2];
} }

View File

@ -109,7 +109,7 @@ async function webauthnRegistered(newCredential) {
} }
function webAuthnError(errorType, message) { function webAuthnError(errorType, message) {
const elErrorMsg = document.getElementById(`webauthn-error-msg`); const elErrorMsg = document.querySelector(`#webauthn-error-msg`);
if (errorType === 'general') { if (errorType === 'general') {
elErrorMsg.textContent = message || 'unknown error'; elErrorMsg.textContent = message || 'unknown error';
@ -140,7 +140,7 @@ function detectWebAuthnSupport() {
} }
export function initUserAuthWebAuthnRegister() { export function initUserAuthWebAuthnRegister() {
const elRegister = document.getElementById('register-webauthn'); const elRegister = document.querySelector('#register-webauthn');
if (!elRegister) { if (!elRegister) {
return; return;
} }
@ -155,7 +155,7 @@ export function initUserAuthWebAuthnRegister() {
} }
async function webAuthnRegisterRequest() { async function webAuthnRegisterRequest() {
const elNickname = document.getElementById('nickname'); const elNickname = document.querySelector('#nickname');
const formData = new FormData(); const formData = new FormData();
formData.append('name', elNickname.value); formData.append('name', elNickname.value);

View File

@ -1,9 +1,9 @@
import {checkAppUrl} from './common-global.js'; import {checkAppUrl} from './common-global.js';
export function initUserAuthOauth2() { export function initUserAuthOauth2() {
const outer = document.getElementById('oauth2-login-navigator'); const outer = document.querySelector('#oauth2-login-navigator');
if (!outer) return; if (!outer) return;
const inner = document.getElementById('oauth2-login-navigator-inner'); const inner = document.querySelector('#oauth2-login-navigator-inner');
checkAppUrl(); checkAppUrl();

View File

@ -3,11 +3,11 @@ import {hideElem, showElem} from '../utils/dom.js';
export function initUserSettings() { export function initUserSettings() {
if (!document.querySelectorAll('.user.settings.profile').length) return; if (!document.querySelectorAll('.user.settings.profile').length) return;
const usernameInput = document.getElementById('username'); const usernameInput = document.querySelector('#username');
if (!usernameInput) return; if (!usernameInput) return;
usernameInput.addEventListener('input', function () { usernameInput.addEventListener('input', function () {
const prompt = document.getElementById('name-change-prompt'); const prompt = document.querySelector('#name-change-prompt');
const promptRedirect = document.getElementById('name-change-redirect-prompt'); const promptRedirect = document.querySelector('#name-change-redirect-prompt');
if (this.value.toLowerCase() !== this.getAttribute('data-name').toLowerCase()) { if (this.value.toLowerCase() !== this.getAttribute('data-name').toLowerCase()) {
showElem(prompt); showElem(prompt);
showElem(promptRedirect); showElem(promptRedirect);

View File

@ -9,19 +9,16 @@ function scrollToAnchor(encodedId) {
if (!encodedId) return; if (!encodedId) return;
const id = decodeURIComponent(encodedId); const id = decodeURIComponent(encodedId);
const prefixedId = addPrefix(id); const prefixedId = addPrefix(id);
let el = document.getElementById(prefixedId); let el = document.querySelector(`#${prefixedId}`);
// check for matching user-generated `a[name]` // check for matching user-generated `a[name]`
if (!el) { if (!el) {
const nameAnchors = document.getElementsByName(prefixedId); el = document.querySelector(`a[name="${CSS.escape(prefixedId)}"]`);
if (nameAnchors.length) {
el = nameAnchors[0];
}
} }
// compat for links with old 'user-content-' prefixed hashes // compat for links with old 'user-content-' prefixed hashes
if (!el && hasPrefix(id)) { if (!el && hasPrefix(id)) {
return document.getElementById(id)?.scrollIntoView(); return document.querySelector(`#${id}`)?.scrollIntoView();
} }
el?.scrollIntoView(); el?.scrollIntoView();

View File

@ -1,11 +1,11 @@
import {showInfoToast, showWarningToast, showErrorToast} from '../modules/toast.js'; import {showInfoToast, showWarningToast, showErrorToast} from '../modules/toast.js';
document.getElementById('info-toast').addEventListener('click', () => { document.querySelector('#info-toast').addEventListener('click', () => {
showInfoToast('success 😀'); showInfoToast('success 😀');
}); });
document.getElementById('warning-toast').addEventListener('click', () => { document.querySelector('#warning-toast').addEventListener('click', () => {
showWarningToast('warning 😐'); showWarningToast('warning 😐');
}); });
document.getElementById('error-toast').addEventListener('click', () => { document.querySelector('#error-toast').addEventListener('click', () => {
showErrorToast('error 🙁'); showErrorToast('error 🙁');
}); });

View File

@ -2,7 +2,7 @@ import SwaggerUI from 'swagger-ui-dist/swagger-ui-es-bundle.js';
import 'swagger-ui-dist/swagger-ui.css'; import 'swagger-ui-dist/swagger-ui.css';
window.addEventListener('load', async () => { window.addEventListener('load', async () => {
const url = document.getElementById('swagger-ui').getAttribute('data-source'); const url = document.querySelector('#swagger-ui').getAttribute('data-source');
const res = await fetch(url); const res = await fetch(url);
const spec = await res.json(); const spec = await res.json();