diff --git a/app/javascript/mastodon/components/blurhash.tsx b/app/javascript/mastodon/components/blurhash.tsx index 8e2a8af23..b7331755b 100644 --- a/app/javascript/mastodon/components/blurhash.tsx +++ b/app/javascript/mastodon/components/blurhash.tsx @@ -30,9 +30,12 @@ const Blurhash: React.FC = ({ try { const pixels = decode(hash, width, height); const ctx = canvas.getContext('2d'); - const imageData = new ImageData(pixels, width, height); + const imageData = ctx?.createImageData(width, height); + imageData?.data.set(pixels); - ctx?.putImageData(imageData, 0, 0); + if (imageData) { + ctx?.putImageData(imageData, 0, 0); + } } catch (err) { console.error('Blurhash decoding failure', { err, hash }); } diff --git a/app/javascript/mastodon/components/hashtag_bar.tsx b/app/javascript/mastodon/components/hashtag_bar.tsx index 4f88385be..f6b72d434 100644 --- a/app/javascript/mastodon/components/hashtag_bar.tsx +++ b/app/javascript/mastodon/components/hashtag_bar.tsx @@ -33,7 +33,7 @@ function isNodeLinkHashtag(element: Node): element is HTMLLinkElement { return ( element instanceof HTMLAnchorElement && // it may be a starting with a hashtag - (element.textContent?.[0] === '#' || + (element.textContent.startsWith('#') || // or a # element.previousSibling?.textContent?.[ element.previousSibling.textContent.length - 1 diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 1a38be536..855e160fa 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -64,7 +64,7 @@ export const EmbeddedStatusContent: React.FC<{ link.setAttribute('title', `@${mention.get('acct')}`); link.setAttribute('href', `/@${mention.get('acct')}`); } else if ( - link.textContent?.[0] === '#' || + link.textContent.startsWith('#') || link.previousSibling?.textContent?.endsWith('#') ) { link.addEventListener( diff --git a/app/javascript/mastodon/features/onboarding/profile.tsx b/app/javascript/mastodon/features/onboarding/profile.tsx index d9b394acf..7e725e97c 100644 --- a/app/javascript/mastodon/features/onboarding/profile.tsx +++ b/app/javascript/mastodon/features/onboarding/profile.tsx @@ -54,9 +54,7 @@ export const Profile: React.FC<{ me ? state.accounts.get(me) : undefined, ); const [displayName, setDisplayName] = useState(account?.display_name ?? ''); - const [note, setNote] = useState( - account ? (unescapeHTML(account.note) ?? '') : '', - ); + const [note, setNote] = useState(account ? unescapeHTML(account.note) : ''); const [avatar, setAvatar] = useState(); const [header, setHeader] = useState(); const [discoverable, setDiscoverable] = useState( diff --git a/app/javascript/mastodon/features/ui/components/embed_modal.tsx b/app/javascript/mastodon/features/ui/components/embed_modal.tsx index b78d5b64c..0290b01d2 100644 --- a/app/javascript/mastodon/features/ui/components/embed_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/embed_modal.tsx @@ -36,6 +36,7 @@ const EmbedModal: React.FC<{ } iframeDocument.open(); + // eslint-disable-next-line @typescript-eslint/no-deprecated iframeDocument.write(data.html); iframeDocument.close(); diff --git a/app/javascript/mastodon/hooks/useLinks.ts b/app/javascript/mastodon/hooks/useLinks.ts index 160fe1850..00e1dd9bb 100644 --- a/app/javascript/mastodon/hooks/useLinks.ts +++ b/app/javascript/mastodon/hooks/useLinks.ts @@ -12,7 +12,7 @@ const isMentionClick = (element: HTMLAnchorElement) => !element.classList.contains('hashtag'); const isHashtagClick = (element: HTMLAnchorElement) => - element.textContent?.[0] === '#' || + element.textContent.startsWith('#') || element.previousSibling?.textContent?.endsWith('#'); export const useLinks = (skipHashtags?: boolean) => { diff --git a/eslint.config.mjs b/eslint.config.mjs index 43aabc511..883ddf5fc 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,7 +5,6 @@ import path from 'node:path'; import js from '@eslint/js'; import { globalIgnores } from 'eslint/config'; import formatjs from 'eslint-plugin-formatjs'; -// @ts-expect-error -- No typings import importPlugin from 'eslint-plugin-import'; import jsdoc from 'eslint-plugin-jsdoc'; import jsxA11Y from 'eslint-plugin-jsx-a11y'; diff --git a/package.json b/package.json index fcc74dc83..e38bc68e3 100644 --- a/package.json +++ b/package.json @@ -190,7 +190,7 @@ "stylelint": "^16.19.1", "stylelint-config-prettier-scss": "^1.0.0", "stylelint-config-standard-scss": "^15.0.1", - "typescript": "~5.7.3", + "typescript": "~5.9.0", "typescript-eslint": "^8.29.1", "vitest": "^3.2.4" }, diff --git a/streaming/package.json b/streaming/package.json index 40a737a61..05acc5803 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -39,7 +39,7 @@ "@types/ws": "^8.5.9", "globals": "^16.0.0", "pino-pretty": "^13.0.0", - "typescript": "~5.7.3", + "typescript": "~5.9.0", "typescript-eslint": "^8.28.0" }, "optionalDependencies": { diff --git a/yarn.lock b/yarn.lock index 384a55338..9a5ac444b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2859,7 +2859,7 @@ __metadata: tesseract.js: "npm:^6.0.0" tiny-queue: "npm:^0.2.1" twitter-text: "npm:3.1.0" - typescript: "npm:~5.7.3" + typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.29.1" use-debounce: "npm:^10.0.0" vite: "npm:^7.1.1" @@ -2907,7 +2907,7 @@ __metadata: pino-http: "npm:^10.0.0" pino-pretty: "npm:^13.0.0" prom-client: "npm:^15.0.0" - typescript: "npm:~5.7.3" + typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.28.0" utf-8-validate: "npm:^6.0.3" uuid: "npm:^11.0.0" @@ -13459,43 +13459,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.6.0": - version: 5.8.2 - resolution: "typescript@npm:5.8.2" +"typescript@npm:^5.6.0, typescript@npm:~5.9.0": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/5c4f6fbf1c6389b6928fe7b8fcd5dc73bb2d58cd4e3883f1d774ed5bd83b151cbac6b7ecf11723de56d4676daeba8713894b1e9af56174f2f9780ae7848ec3c6 + checksum: 10c0/cd635d50f02d6cf98ed42de2f76289701c1ec587a363369255f01ed15aaf22be0813226bff3c53e99d971f9b540e0b3cc7583dbe05faded49b1b0bed2f638a18 languageName: node linkType: hard -"typescript@npm:~5.7.3": - version: 5.7.3 - resolution: "typescript@npm:5.7.3" +"typescript@patch:typescript@npm%3A^5.6.0#optional!builtin, typescript@patch:typescript@npm%3A~5.9.0#optional!builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A^5.6.0#optional!builtin": - version: 5.8.2 - resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin::version=5.8.2&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/5448a08e595cc558ab321e49d4cac64fb43d1fa106584f6ff9a8d8e592111b373a995a1d5c7f3046211c8a37201eb6d0f1566f15cdb7a62a5e3be01d087848e2 - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A~5.7.3#optional!builtin": - version: 5.7.3 - resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin::version=5.7.3&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4 + checksum: 10c0/34d2a8e23eb8e0d1875072064d5e1d9c102e0bdce56a10a25c0b917b8aa9001a9cf5c225df12497e99da107dc379360bc138163c66b55b95f5b105b50578067e languageName: node linkType: hard