mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-28 13:25:23 +02:00
chore: upgrade eslint plugins, remove eslint-plugin-github
- Upgrade `typescript-eslint` to 8.61 and `eslint-plugin-unicorn` to 65, configuring the rules introduced in unicorn 65. - Remove `eslint-plugin-github` and its workarounds: rules, the type-stub module declaration, the pnpm peer-dependency override, and the in-code `eslint-disable` comments that referenced its rules. - Remove rules deprecated or deleted in their plugins and switch to their replacements (e.g. `prefer-single-call`, `no-object-constructor`, `id-denylist`, `no-unnecessary-slice-end`). - Apply the resulting autofixes, mainly wrapping interpolated values in CSS selectors with `CSS.escape()`. Assisted-by: claude-code:opus-4.8
This commit is contained in:
@@ -5,14 +5,14 @@ export function initAdminUserListSearchForm(): void {
|
||||
const form = document.querySelector<HTMLFormElement>('#user-list-search-form');
|
||||
if (!form) return;
|
||||
|
||||
for (const button of form.querySelectorAll(`button[name=sort][value="${searchForm.SortType}"]`)) {
|
||||
for (const button of form.querySelectorAll(`button[name=sort][value="${CSS.escape(searchForm.SortType)}"]`)) {
|
||||
button.classList.add('active');
|
||||
}
|
||||
|
||||
if (searchForm.StatusFilterMap) {
|
||||
for (const [k, v] of Object.entries(searchForm.StatusFilterMap)) {
|
||||
if (!v) continue;
|
||||
for (const input of form.querySelectorAll<HTMLInputElement>(`input[name="status_filter[${k}]"][value="${v}"]`)) {
|
||||
for (const input of form.querySelectorAll<HTMLInputElement>(`input[name="status_filter[${CSS.escape(k)}]"][value="${CSS.escape(v)}"]`)) {
|
||||
input.checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function initGlobalDeleteButton(): void {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// eslint-disable-next-line github/no-dataset -- code depends on the camel-casing
|
||||
// `dataset` is used here because the code below depends on it
|
||||
const dataObj = btn.dataset;
|
||||
|
||||
const modalId = btn.getAttribute('data-modal-id');
|
||||
@@ -156,7 +156,7 @@ function onShowModalClick(el: HTMLElement, e: MouseEvent) {
|
||||
const [attrTargetName, attrTargetProp] = attrTargetCombo.split('.');
|
||||
// try to find target by: "#target" -> "[name=target]" -> ".target" -> "<target> tag", and then try the modal itself
|
||||
const attrTarget = elModal.querySelector(`#${attrTargetName}`) ||
|
||||
elModal.querySelector(`[name=${attrTargetName}]`) ||
|
||||
elModal.querySelector(`[name=${CSS.escape(attrTargetName)}]`) ||
|
||||
elModal.querySelector(`.${attrTargetName}`) ||
|
||||
elModal.querySelector(`${attrTargetName}`) ||
|
||||
(elModal.matches(`${attrTargetName}`) || elModal.matches(`#${attrTargetName}`) || elModal.matches(`.${attrTargetName}`) ? elModal : null);
|
||||
|
||||
@@ -245,7 +245,7 @@ async function onLocationHashChange() {
|
||||
const issueCommentPrefix = '#issuecomment-';
|
||||
if (currentHash.startsWith(issueCommentPrefix)) {
|
||||
const commentId = currentHash.substring(issueCommentPrefix.length);
|
||||
const expandButton = document.querySelector<HTMLElement>(`.code-expander-button[data-hidden-comment-ids*=",${commentId},"]`);
|
||||
const expandButton = document.querySelector<HTMLElement>(`.code-expander-button[data-hidden-comment-ids*=",${CSS.escape(commentId)},"]`);
|
||||
if (expandButton) {
|
||||
// avoid infinite loop, do not re-click the button if already clicked
|
||||
const attrAutoLoadClicked = 'data-auto-load-clicked';
|
||||
|
||||
@@ -192,7 +192,7 @@ function initPinRemoveButton() {
|
||||
// Delete the tooltip
|
||||
el._tippy.destroy();
|
||||
// Remove the Card
|
||||
el.closest(`div.issue-card[data-issue-id="${id}"]`)!.remove();
|
||||
el.closest(`div.issue-card[data-issue-id="${CSS.escape(String(id))}"]`)!.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,9 +130,9 @@ export function initRepoIssueCommentDelete() {
|
||||
// on the Conversation page, there is no parent "tr", so no need to do anything for "add-code-comment"
|
||||
if (lineType) {
|
||||
if (lineType === 'same') {
|
||||
document.querySelector(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`)!.classList.remove('tw-invisible');
|
||||
document.querySelector(`[data-path="${CSS.escape(String(path))}"] .add-code-comment[data-idx="${CSS.escape(String(idx))}"]`)!.classList.remove('tw-invisible');
|
||||
} else {
|
||||
document.querySelector(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`)!.classList.remove('tw-invisible');
|
||||
document.querySelector(`[data-path="${CSS.escape(String(path))}"] .add-code-comment[data-side="${CSS.escape(String(side))}"][data-idx="${CSS.escape(String(idx))}"]`)!.classList.remove('tw-invisible');
|
||||
}
|
||||
}
|
||||
conversationHolder.remove();
|
||||
|
||||
@@ -120,11 +120,11 @@ function initRepoProjectColumnEdit(writableProjectBoard: Element): void {
|
||||
}
|
||||
|
||||
// update the newly saved column title and color in the project board (to avoid reload)
|
||||
const elEditButton = writableProjectBoard.querySelector<HTMLButtonElement>(`.show-project-column-modal-edit[${attrDataColumnId}="${columnId}"]`)!;
|
||||
const elEditButton = writableProjectBoard.querySelector<HTMLButtonElement>(`.show-project-column-modal-edit[${CSS.escape(attrDataColumnId)}="${CSS.escape(columnId)}"]`)!;
|
||||
elEditButton.setAttribute(attrDataColumnTitle, elColumnTitle.value);
|
||||
elEditButton.setAttribute(attrDataColumnColor, elColumnColor.value);
|
||||
|
||||
const elBoardColumn = writableProjectBoard.querySelector<HTMLElement>(`.project-column[data-id="${columnId}"]`)!;
|
||||
const elBoardColumn = writableProjectBoard.querySelector<HTMLElement>(`.project-column[data-id="${CSS.escape(columnId)}"]`)!;
|
||||
const elBoardColumnTitle = elBoardColumn.querySelector<HTMLElement>(`.project-column-title-text`)!;
|
||||
elBoardColumnTitle.textContent = elColumnTitle.value;
|
||||
if (elColumnColor.value) {
|
||||
|
||||
@@ -12,7 +12,7 @@ export function initRepoReleaseNew() {
|
||||
registerGlobalEventFunc('click', 'onReleaseEditAttachmentDelete', (el) => {
|
||||
const uuid = el.getAttribute('data-uuid')!;
|
||||
const id = el.getAttribute('data-id')!;
|
||||
document.querySelector<HTMLInputElement>(`input[name='attachment-del-${uuid}']`)!.value = 'true';
|
||||
document.querySelector<HTMLInputElement>(`input[name='attachment-del-${CSS.escape(uuid)}']`)!.value = 'true';
|
||||
hideElem(`#attachment-${id}`);
|
||||
});
|
||||
registerGlobalInitFunc('initReleaseEditForm', (elForm: HTMLFormElement) => {
|
||||
|
||||
@@ -188,7 +188,7 @@ function webAuthnError(errorType: ErrorType, message:string = '') {
|
||||
if (errorType === 'general') {
|
||||
elErrorMsg.textContent = message || 'unknown error';
|
||||
} else {
|
||||
const elTypedError = document.querySelector(`#webauthn-error [data-webauthn-error-msg=${errorType}]`);
|
||||
const elTypedError = document.querySelector(`#webauthn-error [data-webauthn-error-msg=${CSS.escape(errorType)}]`);
|
||||
if (elTypedError) {
|
||||
elErrorMsg.textContent = `${elTypedError.textContent}${message ? ` ${message}` : ''}`;
|
||||
} else {
|
||||
|
||||
@@ -20,7 +20,7 @@ export function showGlobalErrorMessage(msg: string, msgType: Intent = 'error', d
|
||||
}
|
||||
// compact the message to a data attribute to avoid too many duplicated messages
|
||||
const msgCompact = `${msgType}-${msg.trim()}`.replace(/[^-\w\u{80}-\u{10FFFF}]+/gu, '');
|
||||
let msgContainer = parentContainer.querySelector<HTMLDivElement>(`.js-global-error[data-global-error-msg-compact="${msgCompact}"]`);
|
||||
let msgContainer = parentContainer.querySelector<HTMLDivElement>(`.js-global-error[data-global-error-msg-compact="${CSS.escape(msgCompact)}"]`);
|
||||
if (!msgContainer) {
|
||||
const el = document.createElement('div');
|
||||
el.innerHTML = html`<div class="ui container js-global-error tw-my-[--page-spacing]"><details class="ui ${msgType} message"><summary></summary></details></div>`;
|
||||
|
||||
@@ -8,7 +8,7 @@ export function initTabSwitcher(tabItemContainer: Element) {
|
||||
for (const elItem of tabItems) {
|
||||
const tabName = elItem.getAttribute('data-tab')!;
|
||||
elItem.addEventListener('click', () => {
|
||||
const elPanel = document.querySelector(`.ui.tab[data-tab="${tabName}"]`)!;
|
||||
const elPanel = document.querySelector(`.ui.tab[data-tab="${CSS.escape(tabName)}"]`)!;
|
||||
queryElemSiblings(elPanel, '.ui.tab', (el) => el.classList.remove('active'));
|
||||
queryElemSiblings(elItem, '.item[data-tab]', (el) => el.classList.remove('active'));
|
||||
elItem.classList.add('active');
|
||||
|
||||
@@ -9,8 +9,8 @@ type ElementsCallback<T extends Element> = (el: T) => Promisable<any>;
|
||||
type ElementsCallbackWithArgs = (el: Element, ...args: any[]) => Promisable<any>;
|
||||
|
||||
function elementsCall(el: ElementArg, func: ElementsCallbackWithArgs, ...args: any[]): ArrayLikeIterable<Element> {
|
||||
if (typeof el === 'string' || el instanceof String) {
|
||||
el = document.querySelectorAll(el as string);
|
||||
if (typeof el === 'string') {
|
||||
el = document.querySelectorAll(el);
|
||||
}
|
||||
if (el instanceof Node) {
|
||||
func(el, ...args);
|
||||
@@ -268,7 +268,6 @@ export function isElemVisible(el: HTMLElement): boolean {
|
||||
export function createElementFromHTML<T extends Element>(htmlString: string): T {
|
||||
htmlString = htmlString.trim();
|
||||
// There is no way to create some elements without a proper parent, jQuery's approach: https://github.com/jquery/jquery/blob/main/src/manipulation/wrapMap.js
|
||||
// eslint-disable-next-line github/unescaped-html-literal
|
||||
if (htmlString.startsWith('<tr')) {
|
||||
const container = document.createElement('table');
|
||||
container.innerHTML = htmlString;
|
||||
|
||||
@@ -37,7 +37,7 @@ export function firstStartDateAfterDate(inputDate: Date): number {
|
||||
}
|
||||
const dayOfWeek = inputDate.getUTCDay();
|
||||
const daysUntilSunday = 7 - dayOfWeek;
|
||||
const resultDate = new Date(inputDate.getTime());
|
||||
const resultDate = new Date(inputDate);
|
||||
resultDate.setUTCDate(resultDate.getUTCDate() + daysUntilSunday);
|
||||
return resultDate.valueOf();
|
||||
}
|
||||
|
||||
@@ -54,6 +54,6 @@ export function linkifyURLs(html: string): string {
|
||||
const cleanUrl = trailingPunct ? url.slice(0, -trailingPunct[0].length) : url;
|
||||
const trailing = trailingPunct ? trailingPunct[0] : '';
|
||||
// safe because regexp only matches valid URLs (no quotes or angle brackets)
|
||||
return `<a href="${cleanUrl}" target="_blank">${cleanUrl}</a>${trailing}`; // eslint-disable-line github/unescaped-html-literal
|
||||
return `<a href="${cleanUrl}" target="_blank">${cleanUrl}</a>${trailing}`;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user