Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some typescript issues #32586

Merged
merged 8 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ rules:
no-this-before-super: [2]
no-throw-literal: [2]
no-undef-init: [2]
no-undef: [2, {typeof: true}]
no-undef: [2, {typeof: true}] # TODO: disable this rule after tsc passes
no-undefined: [0]
no-underscore-dangle: [0]
no-unexpected-multiline: [2]
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/features/autofocus-end.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export function initAutoFocusEnd() {
for (const el of document.querySelectorAll('.js-autofocus-end')) {
for (const el of document.querySelectorAll<HTMLInputElement>('.js-autofocus-end')) {
el.focus(); // expects only one such element on one page. If there are many, then the last one gets the focus.
el.setSelectionRange(el.value.length, el.value.length);
}
Expand Down
2 changes: 2 additions & 0 deletions web_src/js/features/captcha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ export async function initCaptcha() {
}
case 'm-captcha': {
const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue');
// @ts-expect-error
mCaptcha.INPUT_NAME = 'm-captcha-response';
const instanceURL = captchaEl.getAttribute('data-instance-url');

// @ts-expect-error
mCaptcha.default({
siteKey: {
instanceUrl: new URL(instanceURL),
Expand Down
10 changes: 5 additions & 5 deletions web_src/js/features/citation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {fomanticQuery} from '../modules/fomantic/base.ts';

const {pageData} = window.config;

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

if (!pageData.citationFileContent) return;

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

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

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

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

Expand Down
4 changes: 2 additions & 2 deletions web_src/js/features/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ const {copy_success, copy_error} = window.config.i18n;
// - data-clipboard-target: Holds a selector for a <input> or <textarea> whose content is copied
// - data-clipboard-text-type: When set to 'url' will convert relative to absolute urls
export function initGlobalCopyToClipboardListener() {
document.addEventListener('click', async (e) => {
document.addEventListener('click', async (e: MouseEvent & {target: HTMLElement}) => {
const target = e.target.closest('[data-clipboard-text], [data-clipboard-target]');
if (!target) return;

e.preventDefault();

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

if (text && target.getAttribute('data-clipboard-text-type') === 'url') {
Expand Down
16 changes: 8 additions & 8 deletions web_src/js/features/codeeditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const baseOptions = {
automaticLayout: true,
};

function getEditorconfig(input) {
function getEditorconfig(input: HTMLInputElement) {
try {
return JSON.parse(input.getAttribute('data-editorconfig'));
} catch {
Expand Down Expand Up @@ -58,7 +58,7 @@ function exportEditor(editor) {
if (!window.codeEditors.includes(editor)) window.codeEditors.push(editor);
}

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

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

monaco.editor.defineTheme('gitea', {
base: isDarkTheme() ? 'vs-dark' : 'vs',
Expand Down Expand Up @@ -127,13 +127,13 @@ export async function createMonaco(textarea, filename, editorOpts) {
return {monaco, editor};
}

function getFileBasedOptions(filename, lineWrapExts) {
function getFileBasedOptions(filename: string, lineWrapExts: string[]) {
return {
wordWrap: (lineWrapExts || []).includes(extname(filename)) ? 'on' : 'off',
};
}

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

Expand All @@ -152,7 +152,7 @@ function togglePreviewDisplay(previewable) {
}
}

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

function getEditorConfigOptions(ec) {
function getEditorConfigOptions(ec: Record<string, any>): Record<string, any> {
if (!isObject(ec)) return {};

const opts = {};
const opts: Record<string, any> = {};
opts.detectIndentation = !('indent_style' in ec) || !('indent_size' in ec);
if ('indent_size' in ec) opts.indentSize = Number(ec.indent_size);
if ('tab_width' in ec) opts.tabSize = Number(ec.tab_width) || opts.indentSize;
Expand Down
12 changes: 6 additions & 6 deletions web_src/js/features/colorpicker.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {createTippy} from '../modules/tippy.ts';

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

await Promise.all([
Expand All @@ -14,15 +14,15 @@ export async function initColorPickers() {
}
}

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

function updatePicker(el, newValue) {
function updatePicker(el: HTMLElement, newValue: string): void {
el.setAttribute('color', newValue);
}

function initPicker(el) {
function initPicker(el: HTMLElement): void {
const input = el.querySelector('input');

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

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

// init precolors
for (const colorEl of el.querySelectorAll('.precolors .color')) {
colorEl.addEventListener('click', (e) => {
colorEl.addEventListener('click', (e: MouseEvent & {target: HTMLAnchorElement}) => {
const newValue = e.target.getAttribute('data-color-hex');
input.value = newValue;
input.dispatchEvent(new Event('input', {bubbles: true}));
Expand Down
10 changes: 5 additions & 5 deletions web_src/js/features/common-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {POST} from '../modules/fetch.ts';
import {hideElem, showElem, toggleElem} from '../utils/dom.ts';
import {showErrorToast} from '../modules/toast.ts';

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

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

Expand Down Expand Up @@ -46,7 +46,7 @@ export function initGlobalDeleteButton() {
// if `data-type="form"` exists, then submit the form by the selector provided by `data-form="..."`
if (btn.getAttribute('data-type') === 'form') {
const formSelector = btn.getAttribute('data-form');
const form = document.querySelector(formSelector);
const form = document.querySelector<HTMLFormElement>(formSelector);
if (!form) throw new Error(`no form named ${formSelector} found`);
form.submit();
}
Expand All @@ -73,7 +73,7 @@ export function initGlobalDeleteButton() {
}
}

export function initGlobalButtons() {
export function initGlobalButtons(): void {
// There are many "cancel button" elements in modal dialogs, Fomantic UI expects they are button-like elements but never submit a form.
// However, Gitea misuses the modal dialog and put the cancel buttons inside forms, so we must prevent the form submission.
// There are a few cancel buttons in non-modal forms, and there are some dynamically created forms (eg: the "Edit Issue Content")
Expand Down
4 changes: 4 additions & 0 deletions web_src/js/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ interface Window {
push: (e: ErrorEvent & PromiseRejectionEvent) => void | number,
},
__webpack_public_path__: string;
grecaptcha: any,
turnstile: any,
hcaptcha: any,
codeEditors: any[],
}
2 changes: 1 addition & 1 deletion web_src/js/markup/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function targetElement(el: Element) {
return el.classList.contains('is-loading') ? el : el.closest('pre');
}

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

Expand Down
2 changes: 1 addition & 1 deletion web_src/js/modules/dirauto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function attachDirAuto(el: DirElement) {
}
}

export function initDirAuto() {
export function initDirAuto(): void {
const observer = new MutationObserver((mutationList) => {
const len = mutationList.length;
for (let i = 0; i < len; i++) {
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/modules/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const safeMethods = new Set(['GET', 'HEAD', 'OPTIONS', 'TRACE']);
// fetch wrapper, use below method name functions and the `data` option to pass in data
// which will automatically set an appropriate headers. For json content, only object
// and array types are currently supported.
export function request(url: string, {method = 'GET', data, headers = {}, ...other}: RequestOpts = {}) {
export function request(url: string, {method = 'GET', data, headers = {}, ...other}: RequestOpts = {}): Promise<Response> {
let body: RequestData;
let contentType: string;
if (data instanceof FormData || data instanceof URLSearchParams) {
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/modules/fomantic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function initGiteaFomantic() {
// Do not use "cursor: pointer" for dropdown labels
$.fn.dropdown.settings.className.label += ' tw-cursor-default';
// Always use Gitea's SVG icons
$.fn.dropdown.settings.templates.label = function(_value, text, preserveHTML, className) {
$.fn.dropdown.settings.templates.label = function(_value: any, text: any, preserveHTML: any, className: Record<string, string>) {
const escape = $.fn.dropdown.settings.templates.escape;
return escape(text, preserveHTML) + svg('octicon-x', 16, `${className.delete} icon`);
};
Expand Down
5 changes: 3 additions & 2 deletions web_src/js/modules/fomantic/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import $ from 'jquery';
import type {FomanticInitFunction} from '../../types.ts';

export function initFomanticApiPatch() {
//
Expand All @@ -15,15 +16,15 @@ export function initFomanticApiPatch() {
//
const patchKey = '_giteaFomanticApiPatch';
const oldApi = $.api;
$.api = $.fn.api = function(...args) {
$.api = $.fn.api = function(...args: Parameters<FomanticInitFunction>) {
const apiCall = oldApi.bind(this);
const ret = oldApi.apply(this, args);

if (typeof args[0] !== 'string') {
const internalGet = apiCall('internal', 'get');
if (!internalGet.urlEncodedValue[patchKey]) {
const oldUrlEncodedValue = internalGet.urlEncodedValue;
internalGet.urlEncodedValue = function (value) {
internalGet.urlEncodedValue = function (value: any) {
try {
return oldUrlEncodedValue(value);
} catch {
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/modules/fomantic/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function generateAriaId() {
return `_aria_auto_id_${ariaIdCounter++}`;
}

export function linkLabelAndInput(label, input) {
export function linkLabelAndInput(label: Element, input: Element) {
const labelFor = label.getAttribute('for');
const inputId = input.getAttribute('id');

Expand Down
2 changes: 1 addition & 1 deletion web_src/js/modules/fomantic/dimmer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {queryElemChildren} from '../../utils/dom.ts';

export function initFomanticDimmer() {
// stand-in for removed dimmer module
$.fn.dimmer = function (arg0, arg1) {
$.fn.dimmer = function (arg0: string, arg1: any) {
if (arg0 === 'add content') {
const $el = arg1;
const existingDimmer = document.querySelector('body > .ui.dimmer');
Expand Down
Loading