mirror of https://github.com/go-gitea/gitea.git
Fix a number of typescript issues (#32308)
- Prefer [window.location.assign](https://developer.mozilla.org/en-US/docs/Web/API/Location/assign) over assigning to [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) which typescript does not like. This works in all browsers including PaleMoon. - Fix all typescript issues in `web_src/js/webcomponents`, no behaviour changes. - ~~Workaround bug in `@typescript-eslint/no-unnecessary-type-assertion` rule.~~ - Omit vendored file from type checks. - `tsc` error count is reduce by 53 with these changes.
This commit is contained in:
parent
5e6523aa57
commit
8107823026
|
@ -142,11 +142,11 @@ export default {
|
||||||
Object.assign(this.locale, results.locale);
|
Object.assign(this.locale, results.locale);
|
||||||
},
|
},
|
||||||
showAllChanges() {
|
showAllChanges() {
|
||||||
window.location = `${this.issueLink}/files${this.queryParams}`;
|
window.location.assign(`${this.issueLink}/files${this.queryParams}`);
|
||||||
},
|
},
|
||||||
/** Called when user clicks on since last review */
|
/** Called when user clicks on since last review */
|
||||||
changesSinceLastReviewClick() {
|
changesSinceLastReviewClick() {
|
||||||
window.location = `${this.issueLink}/files/${this.lastReviewCommitSha}..${this.commits.at(-1).id}${this.queryParams}`;
|
window.location.assign(`${this.issueLink}/files/${this.lastReviewCommitSha}..${this.commits.at(-1).id}${this.queryParams}`);
|
||||||
},
|
},
|
||||||
/** Clicking on a single commit opens this specific commit */
|
/** Clicking on a single commit opens this specific commit */
|
||||||
commitClicked(commitId, newWindow = false) {
|
commitClicked(commitId, newWindow = false) {
|
||||||
|
@ -154,7 +154,7 @@ export default {
|
||||||
if (newWindow) {
|
if (newWindow) {
|
||||||
window.open(url);
|
window.open(url);
|
||||||
} else {
|
} else {
|
||||||
window.location = url;
|
window.location.assign(url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -176,14 +176,14 @@ export default {
|
||||||
const lastCommitIdx = this.commits.findLastIndex((x) => x.selected);
|
const lastCommitIdx = this.commits.findLastIndex((x) => x.selected);
|
||||||
if (lastCommitIdx === this.commits.length - 1) {
|
if (lastCommitIdx === this.commits.length - 1) {
|
||||||
// user selected all commits - just show the normal diff page
|
// user selected all commits - just show the normal diff page
|
||||||
window.location = `${this.issueLink}/files${this.queryParams}`;
|
window.location.assign(`${this.issueLink}/files${this.queryParams}`);
|
||||||
} else {
|
} else {
|
||||||
window.location = `${this.issueLink}/files/${this.commits[lastCommitIdx].id}${this.queryParams}`;
|
window.location.assign(`${this.issueLink}/files/${this.commits[lastCommitIdx].id}${this.queryParams}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const start = this.commits[this.commits.findIndex((x) => x.selected) - 1].id;
|
const start = this.commits[this.commits.findIndex((x) => x.selected) - 1].id;
|
||||||
const end = this.commits.findLast((x) => x.selected).id;
|
const end = this.commits.findLast((x) => x.selected).id;
|
||||||
window.location = `${this.issueLink}/files/${start}..${end}${this.queryParams}`;
|
window.location.assign(`${this.issueLink}/files/${start}..${end}${this.queryParams}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -97,7 +97,7 @@ function excludeLabel(item) {
|
||||||
const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`;
|
const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`;
|
||||||
const newStr = 'labels=$1-$2$3&';
|
const newStr = 'labels=$1-$2$3&';
|
||||||
|
|
||||||
window.location = href.replace(new RegExp(regStr), newStr);
|
window.location.assign(href.replace(new RegExp(regStr), newStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initRepoIssueSidebarList() {
|
export function initRepoIssueSidebarList() {
|
||||||
|
|
|
@ -92,7 +92,7 @@ export function onDomReady(cb: () => Promisable<void>) {
|
||||||
|
|
||||||
// checks whether an element is owned by the current document, and whether it is a document fragment or element node
|
// checks whether an element is owned by the current document, and whether it is a document fragment or element node
|
||||||
// if it is, it means it is a "normal" element managed by us, which can be modified safely.
|
// if it is, it means it is a "normal" element managed by us, which can be modified safely.
|
||||||
export function isDocumentFragmentOrElementNode(el: Element) {
|
export function isDocumentFragmentOrElementNode(el: Element | Node) {
|
||||||
try {
|
try {
|
||||||
return el.ownerDocument === document && el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
return el.ownerDocument === document && el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
// Fork of the upstream module. The only changes are:
|
// Fork of the upstream module. The only changes are:
|
||||||
// * use export to make it work with ES6 modules.
|
// * use export to make it work with ES6 modules.
|
||||||
// * the addition of `const` to make it strict mode compatible.
|
// * the addition of `const` to make it strict mode compatible.
|
||||||
|
|
|
@ -26,7 +26,7 @@ window.customElements.define('absolute-date', class extends HTMLElement {
|
||||||
this.shadowRoot.textContent = toAbsoluteLocaleDate(this.getAttribute('date'), lang, opt);
|
this.shadowRoot.textContent = toAbsoluteLocaleDate(this.getAttribute('date'), lang, opt);
|
||||||
};
|
};
|
||||||
|
|
||||||
attributeChangedCallback(_name, oldValue, newValue) {
|
attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null) {
|
||||||
if (!this.initialized || oldValue === newValue) return;
|
if (!this.initialized || oldValue === newValue) return;
|
||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import {toOriginUrl} from './origin-url.ts';
|
import {toOriginUrl} from './origin-url.ts';
|
||||||
|
|
||||||
test('toOriginUrl', () => {
|
test('toOriginUrl', () => {
|
||||||
const oldLocation = window.location;
|
const oldLocation = String(window.location);
|
||||||
for (const origin of ['https://example.com', 'https://example.com:3000']) {
|
for (const origin of ['https://example.com', 'https://example.com:3000']) {
|
||||||
window.location = new URL(`${origin}/`);
|
window.location.assign(`${origin}/`);
|
||||||
expect(toOriginUrl('/')).toEqual(`${origin}/`);
|
expect(toOriginUrl('/')).toEqual(`${origin}/`);
|
||||||
expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`);
|
expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`);
|
||||||
expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`);
|
expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`);
|
||||||
|
@ -13,5 +13,5 @@ test('toOriginUrl', () => {
|
||||||
expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`);
|
expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`);
|
||||||
expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`);
|
expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`);
|
||||||
}
|
}
|
||||||
window.location = oldLocation;
|
window.location.assign(oldLocation);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Convert an absolute or relative URL to an absolute URL with the current origin. It only
|
// Convert an absolute or relative URL to an absolute URL with the current origin. It only
|
||||||
// processes absolute HTTP/HTTPS URLs or relative URLs like '/xxx' or '//host/xxx'.
|
// processes absolute HTTP/HTTPS URLs or relative URLs like '/xxx' or '//host/xxx'.
|
||||||
// NOTE: Keep this function in sync with clone_script.tmpl
|
// NOTE: Keep this function in sync with clone_script.tmpl
|
||||||
export function toOriginUrl(urlStr) {
|
export function toOriginUrl(urlStr: string) {
|
||||||
try {
|
try {
|
||||||
if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
|
if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
|
||||||
const {origin, protocol, hostname, port} = window.location;
|
const {origin, protocol, hostname, port} = window.location;
|
||||||
|
|
|
@ -4,6 +4,14 @@ import {isDocumentFragmentOrElementNode} from '../utils/dom.ts';
|
||||||
import octiconKebabHorizontal from '../../../public/assets/img/svg/octicon-kebab-horizontal.svg';
|
import octiconKebabHorizontal from '../../../public/assets/img/svg/octicon-kebab-horizontal.svg';
|
||||||
|
|
||||||
window.customElements.define('overflow-menu', class extends HTMLElement {
|
window.customElements.define('overflow-menu', class extends HTMLElement {
|
||||||
|
tippyContent: HTMLDivElement;
|
||||||
|
tippyItems: Array<HTMLElement>;
|
||||||
|
button: HTMLButtonElement;
|
||||||
|
menuItemsEl: HTMLElement;
|
||||||
|
resizeObserver: ResizeObserver;
|
||||||
|
mutationObserver: MutationObserver;
|
||||||
|
lastWidth: number;
|
||||||
|
|
||||||
updateItems = throttle(100, () => { // eslint-disable-line unicorn/consistent-function-scoping -- https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2088
|
updateItems = throttle(100, () => { // eslint-disable-line unicorn/consistent-function-scoping -- https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2088
|
||||||
if (!this.tippyContent) {
|
if (!this.tippyContent) {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
|
@ -11,7 +19,7 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
|
||||||
div.tabIndex = -1; // for initial focus, programmatic focus only
|
div.tabIndex = -1; // for initial focus, programmatic focus only
|
||||||
div.addEventListener('keydown', (e) => {
|
div.addEventListener('keydown', (e) => {
|
||||||
if (e.key === 'Tab') {
|
if (e.key === 'Tab') {
|
||||||
const items = this.tippyContent.querySelectorAll('[role="menuitem"]');
|
const items = this.tippyContent.querySelectorAll<HTMLElement>('[role="menuitem"]');
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
if (document.activeElement === items[0]) {
|
if (document.activeElement === items[0]) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -32,27 +40,27 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
|
||||||
if (document.activeElement?.matches('[role="menuitem"]')) {
|
if (document.activeElement?.matches('[role="menuitem"]')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
document.activeElement.click();
|
(document.activeElement as HTMLElement).click();
|
||||||
}
|
}
|
||||||
} else if (e.key === 'ArrowDown') {
|
} else if (e.key === 'ArrowDown') {
|
||||||
if (document.activeElement?.matches('.tippy-target')) {
|
if (document.activeElement?.matches('.tippy-target')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
document.activeElement.querySelector('[role="menuitem"]:first-of-type').focus();
|
document.activeElement.querySelector<HTMLElement>('[role="menuitem"]:first-of-type').focus();
|
||||||
} else if (document.activeElement?.matches('[role="menuitem"]')) {
|
} else if (document.activeElement?.matches('[role="menuitem"]')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
document.activeElement.nextElementSibling?.focus();
|
(document.activeElement.nextElementSibling as HTMLElement)?.focus();
|
||||||
}
|
}
|
||||||
} else if (e.key === 'ArrowUp') {
|
} else if (e.key === 'ArrowUp') {
|
||||||
if (document.activeElement?.matches('.tippy-target')) {
|
if (document.activeElement?.matches('.tippy-target')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
document.activeElement.querySelector('[role="menuitem"]:last-of-type').focus();
|
document.activeElement.querySelector<HTMLElement>('[role="menuitem"]:last-of-type').focus();
|
||||||
} else if (document.activeElement?.matches('[role="menuitem"]')) {
|
} else if (document.activeElement?.matches('[role="menuitem"]')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
document.activeElement.previousElementSibling?.focus();
|
(document.activeElement.previousElementSibling as HTMLElement)?.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -60,8 +68,8 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
|
||||||
this.tippyContent = div;
|
this.tippyContent = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemFlexSpace = this.menuItemsEl.querySelector('.item-flex-space');
|
const itemFlexSpace = this.menuItemsEl.querySelector<HTMLSpanElement>('.item-flex-space');
|
||||||
const itemOverFlowMenuButton = this.querySelector('.overflow-menu-button');
|
const itemOverFlowMenuButton = this.querySelector<HTMLButtonElement>('.overflow-menu-button');
|
||||||
|
|
||||||
// move items in tippy back into the menu items for subsequent measurement
|
// move items in tippy back into the menu items for subsequent measurement
|
||||||
for (const item of this.tippyItems || []) {
|
for (const item of this.tippyItems || []) {
|
||||||
|
@ -78,7 +86,7 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
|
||||||
itemOverFlowMenuButton?.style.setProperty('display', 'none', 'important');
|
itemOverFlowMenuButton?.style.setProperty('display', 'none', 'important');
|
||||||
this.tippyItems = [];
|
this.tippyItems = [];
|
||||||
const menuRight = this.offsetLeft + this.offsetWidth;
|
const menuRight = this.offsetLeft + this.offsetWidth;
|
||||||
const menuItems = this.menuItemsEl.querySelectorAll('.item, .item-flex-space');
|
const menuItems = this.menuItemsEl.querySelectorAll<HTMLElement>('.item, .item-flex-space');
|
||||||
let afterFlexSpace = false;
|
let afterFlexSpace = false;
|
||||||
for (const item of menuItems) {
|
for (const item of menuItems) {
|
||||||
if (item.classList.contains('item-flex-space')) {
|
if (item.classList.contains('item-flex-space')) {
|
||||||
|
@ -189,14 +197,14 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
|
||||||
// template rendering, wait for its addition.
|
// template rendering, wait for its addition.
|
||||||
// The eslint rule is not sophisticated enough or aware of this problem, see
|
// The eslint rule is not sophisticated enough or aware of this problem, see
|
||||||
// https://github.com/43081j/eslint-plugin-wc/pull/130
|
// https://github.com/43081j/eslint-plugin-wc/pull/130
|
||||||
const menuItemsEl = this.querySelector('.overflow-menu-items'); // eslint-disable-line wc/no-child-traversal-in-connectedcallback
|
const menuItemsEl = this.querySelector<HTMLElement>('.overflow-menu-items'); // eslint-disable-line wc/no-child-traversal-in-connectedcallback
|
||||||
if (menuItemsEl) {
|
if (menuItemsEl) {
|
||||||
this.menuItemsEl = menuItemsEl;
|
this.menuItemsEl = menuItemsEl;
|
||||||
this.init();
|
this.init();
|
||||||
} else {
|
} else {
|
||||||
this.mutationObserver = new MutationObserver((mutations) => {
|
this.mutationObserver = new MutationObserver((mutations) => {
|
||||||
for (const mutation of mutations) {
|
for (const mutation of mutations) {
|
||||||
for (const node of mutation.addedNodes) {
|
for (const node of mutation.addedNodes as NodeListOf<HTMLElement>) {
|
||||||
if (!isDocumentFragmentOrElementNode(node)) continue;
|
if (!isDocumentFragmentOrElementNode(node)) continue;
|
||||||
if (node.classList.contains('overflow-menu-items')) {
|
if (node.classList.contains('overflow-menu-items')) {
|
||||||
this.menuItemsEl = node;
|
this.menuItemsEl = node;
|
||||||
|
|
|
@ -4,10 +4,11 @@ try {
|
||||||
new Intl.NumberFormat('en', {style: 'unit', unit: 'minute'}).format(1);
|
new Intl.NumberFormat('en', {style: 'unit', unit: 'minute'}).format(1);
|
||||||
} catch {
|
} catch {
|
||||||
const intlNumberFormat = Intl.NumberFormat;
|
const intlNumberFormat = Intl.NumberFormat;
|
||||||
Intl.NumberFormat = function(locales, options) {
|
// @ts-expect-error - polyfill is incomplete
|
||||||
|
Intl.NumberFormat = function(locales: string | string[], options: Intl.NumberFormatOptions) {
|
||||||
if (options.style === 'unit') {
|
if (options.style === 'unit') {
|
||||||
return {
|
return {
|
||||||
format(value) {
|
format(value: number | bigint | string) {
|
||||||
return ` ${value} ${options.unit}`;
|
return ` ${value} ${options.unit}`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue