Skip to content

Commit 8107823

Browse files
authored
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.
1 parent 5e6523a commit 8107823

File tree

9 files changed

+36
-26
lines changed

9 files changed

+36
-26
lines changed

web_src/js/components/DiffCommitSelector.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,19 @@ export default {
142142
Object.assign(this.locale, results.locale);
143143
},
144144
showAllChanges() {
145-
window.location = `${this.issueLink}/files${this.queryParams}`;
145+
window.location.assign(`${this.issueLink}/files${this.queryParams}`);
146146
},
147147
/** Called when user clicks on since last review */
148148
changesSinceLastReviewClick() {
149-
window.location = `${this.issueLink}/files/${this.lastReviewCommitSha}..${this.commits.at(-1).id}${this.queryParams}`;
149+
window.location.assign(`${this.issueLink}/files/${this.lastReviewCommitSha}..${this.commits.at(-1).id}${this.queryParams}`);
150150
},
151151
/** Clicking on a single commit opens this specific commit */
152152
commitClicked(commitId, newWindow = false) {
153153
const url = `${this.issueLink}/commits/${commitId}${this.queryParams}`;
154154
if (newWindow) {
155155
window.open(url);
156156
} else {
157-
window.location = url;
157+
window.location.assign(url);
158158
}
159159
},
160160
/**
@@ -176,14 +176,14 @@ export default {
176176
const lastCommitIdx = this.commits.findLastIndex((x) => x.selected);
177177
if (lastCommitIdx === this.commits.length - 1) {
178178
// user selected all commits - just show the normal diff page
179-
window.location = `${this.issueLink}/files${this.queryParams}`;
179+
window.location.assign(`${this.issueLink}/files${this.queryParams}`);
180180
} else {
181-
window.location = `${this.issueLink}/files/${this.commits[lastCommitIdx].id}${this.queryParams}`;
181+
window.location.assign(`${this.issueLink}/files/${this.commits[lastCommitIdx].id}${this.queryParams}`);
182182
}
183183
} else {
184184
const start = this.commits[this.commits.findIndex((x) => x.selected) - 1].id;
185185
const end = this.commits.findLast((x) => x.selected).id;
186-
window.location = `${this.issueLink}/files/${start}..${end}${this.queryParams}`;
186+
window.location.assign(`${this.issueLink}/files/${start}..${end}${this.queryParams}`);
187187
}
188188
}
189189
},

web_src/js/features/repo-issue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function excludeLabel(item) {
9797
const regStr = `labels=((?:-?[0-9]+%2c)*)(${id})((?:%2c-?[0-9]+)*)&`;
9898
const newStr = 'labels=$1-$2$3&';
9999

100-
window.location = href.replace(new RegExp(regStr), newStr);
100+
window.location.assign(href.replace(new RegExp(regStr), newStr));
101101
}
102102

103103
export function initRepoIssueSidebarList() {

web_src/js/utils/dom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export function onDomReady(cb: () => Promisable<void>) {
9292

9393
// checks whether an element is owned by the current document, and whether it is a document fragment or element node
9494
// if it is, it means it is a "normal" element managed by us, which can be modified safely.
95-
export function isDocumentFragmentOrElementNode(el: Element) {
95+
export function isDocumentFragmentOrElementNode(el: Element | Node) {
9696
try {
9797
return el.ownerDocument === document && el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
9898
} catch {

web_src/js/vendor/jquery.are-you-sure.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @ts-nocheck
12
// Fork of the upstream module. The only changes are:
23
// * use export to make it work with ES6 modules.
34
// * the addition of `const` to make it strict mode compatible.

web_src/js/webcomponents/absolute-date.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ window.customElements.define('absolute-date', class extends HTMLElement {
2626
this.shadowRoot.textContent = toAbsoluteLocaleDate(this.getAttribute('date'), lang, opt);
2727
};
2828

29-
attributeChangedCallback(_name, oldValue, newValue) {
29+
attributeChangedCallback(_name: string, oldValue: string | null, newValue: string | null) {
3030
if (!this.initialized || oldValue === newValue) return;
3131
this.update();
3232
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {toOriginUrl} from './origin-url.ts';
22

33
test('toOriginUrl', () => {
4-
const oldLocation = window.location;
4+
const oldLocation = String(window.location);
55
for (const origin of ['https://example.com', 'https://example.com:3000']) {
6-
window.location = new URL(`${origin}/`);
6+
window.location.assign(`${origin}/`);
77
expect(toOriginUrl('/')).toEqual(`${origin}/`);
88
expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`);
99
expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`);
@@ -13,5 +13,5 @@ test('toOriginUrl', () => {
1313
expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`);
1414
expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`);
1515
}
16-
window.location = oldLocation;
16+
window.location.assign(oldLocation);
1717
});

web_src/js/webcomponents/origin-url.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Convert an absolute or relative URL to an absolute URL with the current origin. It only
22
// processes absolute HTTP/HTTPS URLs or relative URLs like '/xxx' or '//host/xxx'.
33
// NOTE: Keep this function in sync with clone_script.tmpl
4-
export function toOriginUrl(urlStr) {
4+
export function toOriginUrl(urlStr: string) {
55
try {
66
if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
77
const {origin, protocol, hostname, port} = window.location;

web_src/js/webcomponents/overflow-menu.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@ import {isDocumentFragmentOrElementNode} from '../utils/dom.ts';
44
import octiconKebabHorizontal from '../../../public/assets/img/svg/octicon-kebab-horizontal.svg';
55

66
window.customElements.define('overflow-menu', class extends HTMLElement {
7+
tippyContent: HTMLDivElement;
8+
tippyItems: Array<HTMLElement>;
9+
button: HTMLButtonElement;
10+
menuItemsEl: HTMLElement;
11+
resizeObserver: ResizeObserver;
12+
mutationObserver: MutationObserver;
13+
lastWidth: number;
14+
715
updateItems = throttle(100, () => { // eslint-disable-line unicorn/consistent-function-scoping -- https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2088
816
if (!this.tippyContent) {
917
const div = document.createElement('div');
1018
div.classList.add('tippy-target');
1119
div.tabIndex = -1; // for initial focus, programmatic focus only
1220
div.addEventListener('keydown', (e) => {
1321
if (e.key === 'Tab') {
14-
const items = this.tippyContent.querySelectorAll('[role="menuitem"]');
22+
const items = this.tippyContent.querySelectorAll<HTMLElement>('[role="menuitem"]');
1523
if (e.shiftKey) {
1624
if (document.activeElement === items[0]) {
1725
e.preventDefault();
@@ -32,36 +40,36 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
3240
if (document.activeElement?.matches('[role="menuitem"]')) {
3341
e.preventDefault();
3442
e.stopPropagation();
35-
document.activeElement.click();
43+
(document.activeElement as HTMLElement).click();
3644
}
3745
} else if (e.key === 'ArrowDown') {
3846
if (document.activeElement?.matches('.tippy-target')) {
3947
e.preventDefault();
4048
e.stopPropagation();
41-
document.activeElement.querySelector('[role="menuitem"]:first-of-type').focus();
49+
document.activeElement.querySelector<HTMLElement>('[role="menuitem"]:first-of-type').focus();
4250
} else if (document.activeElement?.matches('[role="menuitem"]')) {
4351
e.preventDefault();
4452
e.stopPropagation();
45-
document.activeElement.nextElementSibling?.focus();
53+
(document.activeElement.nextElementSibling as HTMLElement)?.focus();
4654
}
4755
} else if (e.key === 'ArrowUp') {
4856
if (document.activeElement?.matches('.tippy-target')) {
4957
e.preventDefault();
5058
e.stopPropagation();
51-
document.activeElement.querySelector('[role="menuitem"]:last-of-type').focus();
59+
document.activeElement.querySelector<HTMLElement>('[role="menuitem"]:last-of-type').focus();
5260
} else if (document.activeElement?.matches('[role="menuitem"]')) {
5361
e.preventDefault();
5462
e.stopPropagation();
55-
document.activeElement.previousElementSibling?.focus();
63+
(document.activeElement.previousElementSibling as HTMLElement)?.focus();
5664
}
5765
}
5866
});
5967
this.append(div);
6068
this.tippyContent = div;
6169
}
6270

63-
const itemFlexSpace = this.menuItemsEl.querySelector('.item-flex-space');
64-
const itemOverFlowMenuButton = this.querySelector('.overflow-menu-button');
71+
const itemFlexSpace = this.menuItemsEl.querySelector<HTMLSpanElement>('.item-flex-space');
72+
const itemOverFlowMenuButton = this.querySelector<HTMLButtonElement>('.overflow-menu-button');
6573

6674
// move items in tippy back into the menu items for subsequent measurement
6775
for (const item of this.tippyItems || []) {
@@ -78,7 +86,7 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
7886
itemOverFlowMenuButton?.style.setProperty('display', 'none', 'important');
7987
this.tippyItems = [];
8088
const menuRight = this.offsetLeft + this.offsetWidth;
81-
const menuItems = this.menuItemsEl.querySelectorAll('.item, .item-flex-space');
89+
const menuItems = this.menuItemsEl.querySelectorAll<HTMLElement>('.item, .item-flex-space');
8290
let afterFlexSpace = false;
8391
for (const item of menuItems) {
8492
if (item.classList.contains('item-flex-space')) {
@@ -189,14 +197,14 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
189197
// template rendering, wait for its addition.
190198
// The eslint rule is not sophisticated enough or aware of this problem, see
191199
// https://github.com/43081j/eslint-plugin-wc/pull/130
192-
const menuItemsEl = this.querySelector('.overflow-menu-items'); // eslint-disable-line wc/no-child-traversal-in-connectedcallback
200+
const menuItemsEl = this.querySelector<HTMLElement>('.overflow-menu-items'); // eslint-disable-line wc/no-child-traversal-in-connectedcallback
193201
if (menuItemsEl) {
194202
this.menuItemsEl = menuItemsEl;
195203
this.init();
196204
} else {
197205
this.mutationObserver = new MutationObserver((mutations) => {
198206
for (const mutation of mutations) {
199-
for (const node of mutation.addedNodes) {
207+
for (const node of mutation.addedNodes as NodeListOf<HTMLElement>) {
200208
if (!isDocumentFragmentOrElementNode(node)) continue;
201209
if (node.classList.contains('overflow-menu-items')) {
202210
this.menuItemsEl = node;

web_src/js/webcomponents/polyfills.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ try {
44
new Intl.NumberFormat('en', {style: 'unit', unit: 'minute'}).format(1);
55
} catch {
66
const intlNumberFormat = Intl.NumberFormat;
7-
Intl.NumberFormat = function(locales, options) {
7+
// @ts-expect-error - polyfill is incomplete
8+
Intl.NumberFormat = function(locales: string | string[], options: Intl.NumberFormatOptions) {
89
if (options.style === 'unit') {
910
return {
10-
format(value) {
11+
format(value: number | bigint | string) {
1112
return ` ${value} ${options.unit}`;
1213
},
1314
};

0 commit comments

Comments
 (0)