Skip to content

Commit 675c288

Browse files
authored
Fix some typescript issues (#32586)
Fixes around 30 or so typescript errors. No runtime changes.
1 parent 9bf821a commit 675c288

24 files changed

+89
-73
lines changed

.eslintrc.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ rules:
642642
no-this-before-super: [2]
643643
no-throw-literal: [2]
644644
no-undef-init: [2]
645-
no-undef: [2, {typeof: true}]
645+
no-undef: [2, {typeof: true}] # TODO: disable this rule after tsc passes
646646
no-undefined: [0]
647647
no-underscore-dangle: [0]
648648
no-unexpected-multiline: [2]

web_src/js/features/autofocus-end.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export function initAutoFocusEnd() {
2-
for (const el of document.querySelectorAll('.js-autofocus-end')) {
2+
for (const el of document.querySelectorAll<HTMLInputElement>('.js-autofocus-end')) {
33
el.focus(); // expects only one such element on one page. If there are many, then the last one gets the focus.
44
el.setSelectionRange(el.value.length, el.value.length);
55
}

web_src/js/features/captcha.ts

+2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ export async function initCaptcha() {
3535
}
3636
case 'm-captcha': {
3737
const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue');
38+
// @ts-expect-error
3839
mCaptcha.INPUT_NAME = 'm-captcha-response';
3940
const instanceURL = captchaEl.getAttribute('data-instance-url');
4041

42+
// @ts-expect-error
4143
mCaptcha.default({
4244
siteKey: {
4345
instanceUrl: new URL(instanceURL),

web_src/js/features/citation.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {fomanticQuery} from '../modules/fomantic/base.ts';
33

44
const {pageData} = window.config;
55

6-
async function initInputCitationValue(citationCopyApa, citationCopyBibtex) {
6+
async function initInputCitationValue(citationCopyApa: HTMLButtonElement, citationCopyBibtex: HTMLButtonElement) {
77
const [{Cite, plugins}] = await Promise.all([
88
import(/* webpackChunkName: "citation-js-core" */'@citation-js/core'),
99
import(/* webpackChunkName: "citation-js-formats" */'@citation-js/plugin-software-formats'),
@@ -27,9 +27,9 @@ export async function initCitationFileCopyContent() {
2727

2828
if (!pageData.citationFileContent) return;
2929

30-
const citationCopyApa = document.querySelector('#citation-copy-apa');
31-
const citationCopyBibtex = document.querySelector('#citation-copy-bibtex');
32-
const inputContent = document.querySelector('#citation-copy-content');
30+
const citationCopyApa = document.querySelector<HTMLButtonElement>('#citation-copy-apa');
31+
const citationCopyBibtex = document.querySelector<HTMLButtonElement>('#citation-copy-bibtex');
32+
const inputContent = document.querySelector<HTMLInputElement>('#citation-copy-content');
3333

3434
if ((!citationCopyApa && !citationCopyBibtex) || !inputContent) return;
3535

@@ -41,7 +41,7 @@ export async function initCitationFileCopyContent() {
4141
citationCopyApa.classList.toggle('primary', !isBibtex);
4242
};
4343

44-
document.querySelector('#cite-repo-button')?.addEventListener('click', async (e) => {
44+
document.querySelector('#cite-repo-button')?.addEventListener('click', async (e: MouseEvent & {target: HTMLAnchorElement}) => {
4545
const dropdownBtn = e.target.closest('.ui.dropdown.button');
4646
dropdownBtn.classList.add('is-loading');
4747

web_src/js/features/clipboard.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ const {copy_success, copy_error} = window.config.i18n;
99
// - data-clipboard-target: Holds a selector for a <input> or <textarea> whose content is copied
1010
// - data-clipboard-text-type: When set to 'url' will convert relative to absolute urls
1111
export function initGlobalCopyToClipboardListener() {
12-
document.addEventListener('click', async (e) => {
12+
document.addEventListener('click', async (e: MouseEvent & {target: HTMLElement}) => {
1313
const target = e.target.closest('[data-clipboard-text], [data-clipboard-target]');
1414
if (!target) return;
1515

1616
e.preventDefault();
1717

1818
let text = target.getAttribute('data-clipboard-text');
1919
if (!text) {
20-
text = document.querySelector(target.getAttribute('data-clipboard-target'))?.value;
20+
text = document.querySelector<HTMLInputElement>(target.getAttribute('data-clipboard-target'))?.value;
2121
}
2222

2323
if (text && target.getAttribute('data-clipboard-text-type') === 'url') {

web_src/js/features/codeeditor.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const baseOptions = {
2121
automaticLayout: true,
2222
};
2323

24-
function getEditorconfig(input) {
24+
function getEditorconfig(input: HTMLInputElement) {
2525
try {
2626
return JSON.parse(input.getAttribute('data-editorconfig'));
2727
} catch {
@@ -58,7 +58,7 @@ function exportEditor(editor) {
5858
if (!window.codeEditors.includes(editor)) window.codeEditors.push(editor);
5959
}
6060

61-
export async function createMonaco(textarea, filename, editorOpts) {
61+
export async function createMonaco(textarea: HTMLTextAreaElement, filename: string, editorOpts: Record<string, any>) {
6262
const monaco = await import(/* webpackChunkName: "monaco" */'monaco-editor');
6363

6464
initLanguages(monaco);
@@ -72,7 +72,7 @@ export async function createMonaco(textarea, filename, editorOpts) {
7272
// https://github.com/microsoft/monaco-editor/issues/2427
7373
// also, monaco can only parse 6-digit hex colors, so we convert the colors to that format
7474
const styles = window.getComputedStyle(document.documentElement);
75-
const getColor = (name) => tinycolor(styles.getPropertyValue(name).trim()).toString('hex6');
75+
const getColor = (name: string) => tinycolor(styles.getPropertyValue(name).trim()).toString('hex6');
7676

7777
monaco.editor.defineTheme('gitea', {
7878
base: isDarkTheme() ? 'vs-dark' : 'vs',
@@ -127,13 +127,13 @@ export async function createMonaco(textarea, filename, editorOpts) {
127127
return {monaco, editor};
128128
}
129129

130-
function getFileBasedOptions(filename, lineWrapExts) {
130+
function getFileBasedOptions(filename: string, lineWrapExts: string[]) {
131131
return {
132132
wordWrap: (lineWrapExts || []).includes(extname(filename)) ? 'on' : 'off',
133133
};
134134
}
135135

136-
function togglePreviewDisplay(previewable) {
136+
function togglePreviewDisplay(previewable: boolean) {
137137
const previewTab = document.querySelector('a[data-tab="preview"]');
138138
if (!previewTab) return;
139139

@@ -152,7 +152,7 @@ function togglePreviewDisplay(previewable) {
152152
}
153153
}
154154

155-
export async function createCodeEditor(textarea, filenameInput) {
155+
export async function createCodeEditor(textarea: HTMLTextAreaElement, filenameInput: HTMLInputElement) {
156156
const filename = basename(filenameInput.value);
157157
const previewableExts = new Set((textarea.getAttribute('data-previewable-extensions') || '').split(','));
158158
const lineWrapExts = (textarea.getAttribute('data-line-wrap-extensions') || '').split(',');
@@ -177,10 +177,10 @@ export async function createCodeEditor(textarea, filenameInput) {
177177
return editor;
178178
}
179179

180-
function getEditorConfigOptions(ec) {
180+
function getEditorConfigOptions(ec: Record<string, any>): Record<string, any> {
181181
if (!isObject(ec)) return {};
182182

183-
const opts = {};
183+
const opts: Record<string, any> = {};
184184
opts.detectIndentation = !('indent_style' in ec) || !('indent_size' in ec);
185185
if ('indent_size' in ec) opts.indentSize = Number(ec.indent_size);
186186
if ('tab_width' in ec) opts.tabSize = Number(ec.tab_width) || opts.indentSize;

web_src/js/features/colorpicker.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {createTippy} from '../modules/tippy.ts';
22

33
export async function initColorPickers() {
4-
const els = document.querySelectorAll('.js-color-picker-input');
4+
const els = document.querySelectorAll<HTMLElement>('.js-color-picker-input');
55
if (!els.length) return;
66

77
await Promise.all([
@@ -14,15 +14,15 @@ export async function initColorPickers() {
1414
}
1515
}
1616

17-
function updateSquare(el, newValue) {
17+
function updateSquare(el: HTMLElement, newValue: string): void {
1818
el.style.color = /#[0-9a-f]{6}/i.test(newValue) ? newValue : 'transparent';
1919
}
2020

21-
function updatePicker(el, newValue) {
21+
function updatePicker(el: HTMLElement, newValue: string): void {
2222
el.setAttribute('color', newValue);
2323
}
2424

25-
function initPicker(el) {
25+
function initPicker(el: HTMLElement): void {
2626
const input = el.querySelector('input');
2727

2828
const square = document.createElement('div');
@@ -37,7 +37,7 @@ function initPicker(el) {
3737
updateSquare(square, e.detail.value);
3838
});
3939

40-
input.addEventListener('input', (e) => {
40+
input.addEventListener('input', (e: Event & {target: HTMLInputElement}) => {
4141
updateSquare(square, e.target.value);
4242
updatePicker(picker, e.target.value);
4343
});
@@ -56,7 +56,7 @@ function initPicker(el) {
5656

5757
// init precolors
5858
for (const colorEl of el.querySelectorAll('.precolors .color')) {
59-
colorEl.addEventListener('click', (e) => {
59+
colorEl.addEventListener('click', (e: MouseEvent & {target: HTMLAnchorElement}) => {
6060
const newValue = e.target.getAttribute('data-color-hex');
6161
input.value = newValue;
6262
input.dispatchEvent(new Event('input', {bubbles: true}));

web_src/js/features/common-button.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {POST} from '../modules/fetch.ts';
33
import {hideElem, showElem, toggleElem} from '../utils/dom.ts';
44
import {showErrorToast} from '../modules/toast.ts';
55

6-
export function initGlobalButtonClickOnEnter() {
6+
export function initGlobalButtonClickOnEnter(): void {
77
$(document).on('keypress', 'div.ui.button,span.ui.button', (e) => {
88
if (e.code === ' ' || e.code === 'Enter') {
99
$(e.target).trigger('click');
@@ -12,13 +12,13 @@ export function initGlobalButtonClickOnEnter() {
1212
});
1313
}
1414

15-
export function initGlobalDeleteButton() {
15+
export function initGlobalDeleteButton(): void {
1616
// ".delete-button" shows a confirmation modal defined by `data-modal-id` attribute.
1717
// Some model/form elements will be filled by `data-id` / `data-name` / `data-data-xxx` attributes.
1818
// If there is a form defined by `data-form`, then the form will be submitted as-is (without any modification).
1919
// If there is no form, then the data will be posted to `data-url`.
2020
// TODO: it's not encouraged to use this method. `show-modal` does far better than this.
21-
for (const btn of document.querySelectorAll('.delete-button')) {
21+
for (const btn of document.querySelectorAll<HTMLElement>('.delete-button')) {
2222
btn.addEventListener('click', (e) => {
2323
e.preventDefault();
2424

@@ -46,7 +46,7 @@ export function initGlobalDeleteButton() {
4646
// if `data-type="form"` exists, then submit the form by the selector provided by `data-form="..."`
4747
if (btn.getAttribute('data-type') === 'form') {
4848
const formSelector = btn.getAttribute('data-form');
49-
const form = document.querySelector(formSelector);
49+
const form = document.querySelector<HTMLFormElement>(formSelector);
5050
if (!form) throw new Error(`no form named ${formSelector} found`);
5151
form.submit();
5252
}
@@ -73,7 +73,7 @@ export function initGlobalDeleteButton() {
7373
}
7474
}
7575

76-
export function initGlobalButtons() {
76+
export function initGlobalButtons(): void {
7777
// There are many "cancel button" elements in modal dialogs, Fomantic UI expects they are button-like elements but never submit a form.
7878
// However, Gitea misuses the modal dialog and put the cancel buttons inside forms, so we must prevent the form submission.
7979
// There are a few cancel buttons in non-modal forms, and there are some dynamically created forms (eg: the "Edit Issue Content")

web_src/js/globals.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,8 @@ interface Window {
5858
push: (e: ErrorEvent & PromiseRejectionEvent) => void | number,
5959
},
6060
__webpack_public_path__: string;
61+
grecaptcha: any,
62+
turnstile: any,
63+
hcaptcha: any,
64+
codeEditors: any[],
6165
}

web_src/js/markup/math.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function targetElement(el: Element) {
66
return el.classList.contains('is-loading') ? el : el.closest('pre');
77
}
88

9-
export async function renderMath(): void {
9+
export async function renderMath(): Promise<void> {
1010
const els = document.querySelectorAll('.markup code.language-math');
1111
if (!els.length) return;
1212

web_src/js/modules/dirauto.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function attachDirAuto(el: DirElement) {
1313
}
1414
}
1515

16-
export function initDirAuto() {
16+
export function initDirAuto(): void {
1717
const observer = new MutationObserver((mutationList) => {
1818
const len = mutationList.length;
1919
for (let i = 0; i < len; i++) {

web_src/js/modules/fetch.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const safeMethods = new Set(['GET', 'HEAD', 'OPTIONS', 'TRACE']);
99
// fetch wrapper, use below method name functions and the `data` option to pass in data
1010
// which will automatically set an appropriate headers. For json content, only object
1111
// and array types are currently supported.
12-
export function request(url: string, {method = 'GET', data, headers = {}, ...other}: RequestOpts = {}) {
12+
export function request(url: string, {method = 'GET', data, headers = {}, ...other}: RequestOpts = {}): Promise<Response> {
1313
let body: RequestData;
1414
let contentType: string;
1515
if (data instanceof FormData || data instanceof URLSearchParams) {

web_src/js/modules/fomantic.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function initGiteaFomantic() {
1919
// Do not use "cursor: pointer" for dropdown labels
2020
$.fn.dropdown.settings.className.label += ' tw-cursor-default';
2121
// Always use Gitea's SVG icons
22-
$.fn.dropdown.settings.templates.label = function(_value, text, preserveHTML, className) {
22+
$.fn.dropdown.settings.templates.label = function(_value: any, text: any, preserveHTML: any, className: Record<string, string>) {
2323
const escape = $.fn.dropdown.settings.templates.escape;
2424
return escape(text, preserveHTML) + svg('octicon-x', 16, `${className.delete} icon`);
2525
};

web_src/js/modules/fomantic/api.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import $ from 'jquery';
2+
import type {FomanticInitFunction} from '../../types.ts';
23

34
export function initFomanticApiPatch() {
45
//
@@ -15,15 +16,15 @@ export function initFomanticApiPatch() {
1516
//
1617
const patchKey = '_giteaFomanticApiPatch';
1718
const oldApi = $.api;
18-
$.api = $.fn.api = function(...args) {
19+
$.api = $.fn.api = function(...args: Parameters<FomanticInitFunction>) {
1920
const apiCall = oldApi.bind(this);
2021
const ret = oldApi.apply(this, args);
2122

2223
if (typeof args[0] !== 'string') {
2324
const internalGet = apiCall('internal', 'get');
2425
if (!internalGet.urlEncodedValue[patchKey]) {
2526
const oldUrlEncodedValue = internalGet.urlEncodedValue;
26-
internalGet.urlEncodedValue = function (value) {
27+
internalGet.urlEncodedValue = function (value: any) {
2728
try {
2829
return oldUrlEncodedValue(value);
2930
} catch {

web_src/js/modules/fomantic/base.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export function generateAriaId() {
55
return `_aria_auto_id_${ariaIdCounter++}`;
66
}
77

8-
export function linkLabelAndInput(label, input) {
8+
export function linkLabelAndInput(label: Element, input: Element) {
99
const labelFor = label.getAttribute('for');
1010
const inputId = input.getAttribute('id');
1111

web_src/js/modules/fomantic/dimmer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {queryElemChildren} from '../../utils/dom.ts';
33

44
export function initFomanticDimmer() {
55
// stand-in for removed dimmer module
6-
$.fn.dimmer = function (arg0, arg1) {
6+
$.fn.dimmer = function (arg0: string, arg1: any) {
77
if (arg0 === 'add content') {
88
const $el = arg1;
99
const existingDimmer = document.querySelector('body > .ui.dimmer');

0 commit comments

Comments
 (0)