From c2940fd77cba7b0cf912db9fda92e66dbce9110f Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sun, 16 Mar 2025 10:58:06 +0900 Subject: [PATCH 01/75] enhance(frontend): improve usability on touch device --- locales/index.d.ts | 8 ++++++++ locales/ja-JP.yml | 2 ++ packages/frontend/src/boot/common.ts | 4 ++++ packages/frontend/src/components/MkDialog.vue | 4 ++-- packages/frontend/src/components/MkInfo.vue | 2 +- packages/frontend/src/components/MkInput.vue | 8 ++++---- .../frontend/src/components/MkInviteCode.vue | 2 +- packages/frontend/src/components/MkKeyValue.vue | 2 +- packages/frontend/src/components/MkNote.vue | 3 ++- .../frontend/src/components/MkNoteDetailed.vue | 3 ++- packages/frontend/src/components/MkTextarea.vue | 4 ++-- .../src/pages/settings/accessibility.vue | 11 +++++++++++ packages/frontend/src/preferences/def.ts | 3 +++ packages/frontend/src/style.scss | 17 +++++++++++++++++ .../utility/autogen/settings-search-index.ts | 13 +++++++++---- 15 files changed, 69 insertions(+), 17 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index 00d275ee43..7e4892eb39 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -5433,6 +5433,14 @@ export interface Locale extends ILocale { * タイムラインとノート */ "timelineAndNote": string; + /** + * 全てのテキスト要素を選択可能にする + */ + "makeEveryTextElementsSelectable": string; + /** + * 有効にすると、一部のシチュエーションでのユーザビリティが低下する場合があります。 + */ + "makeEveryTextElementsSelectable_description": string; }; "_preferencesProfile": { /** diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 8e787fa02f..f17c5a1278 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1357,6 +1357,8 @@ _settings: appearanceBanner: "好みに応じた、クライアントの見た目・表示方法に関する設定が行えます。" soundsBanner: "クライアントで再生するサウンドの設定が行えます。" timelineAndNote: "タイムラインとノート" + makeEveryTextElementsSelectable: "全てのテキスト要素を選択可能にする" + makeEveryTextElementsSelectable_description: "有効にすると、一部のシチュエーションでのユーザビリティが低下する場合があります。" _preferencesProfile: profileName: "プロファイル名" diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index 73c4256c4b..10bcddbde7 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -234,6 +234,10 @@ export async function common(createVue: () => App) { }); } + if (prefer.s.makeEveryTextElementsSelectable) { + document.documentElement.classList.add('forceSelectableAll'); + } + //#region Fetch user if ($i && $i.token) { if (_DEV_) { diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue index 6c9fa3167a..312c7ab58f 100644 --- a/packages/frontend/src/components/MkDialog.vue +++ b/packages/frontend/src/components/MkDialog.vue @@ -25,8 +25,8 @@ SPDX-License-Identifier: AGPL-3.0-only -
-
+
+
-
+
@@ -20,7 +20,6 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/ui/minimum.vue b/packages/frontend/src/ui/minimum.vue index 95d564f5a3..ebaa46850c 100644 --- a/packages/frontend/src/ui/minimum.vue +++ b/packages/frontend/src/ui/minimum.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -139,53 +157,74 @@ onBeforeUnmount(() => { } } -.root { +.tabs { position: relative; - height: 100%; - overflow: clip; -} - -.tabBg { - position: absolute; - z-index: 1; - top: 0; - left: 0; width: 100%; height: 100%; - background: #0003; - -webkit-backdrop-filter: var(--MI-blur, blur(3px)); - backdrop-filter: var(--MI-blur, blur(3px)); } .tab { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - box-sizing: border-box; + &:first-child { + position: relative; + width: 100%; + height: 100%; + + .tabFg { + position: relative; + width: 100%; + height: 100%; + } + + .tabContent { + position: relative; + width: 100%; + height: 100%; + } + } + + &:not(:first-child) { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + + .tabBg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #0003; + -webkit-backdrop-filter: var(--MI-blur, blur(3px)); + backdrop-filter: var(--MI-blur, blur(3px)); + } - &:not(:nth-child(1)) { .tabFg { position: absolute; - z-index: 1; bottom: 0; left: 0; width: 100%; - height: calc(100% - 20px * var(--i)); + height: calc(100% - (10px + (20px * var(--i)))); + display: flex; + flex-direction: column; + } + + .tabContent { + flex: 1; + width: 100%; + height: 100%; + background: var(--MI_THEME-bg); } } } -.tabFg { - position: relative; - height: 100%; +.tabMenu { + margin-left: auto; background: var(--MI_THEME-bg); - border-radius: 16px 16px 0 0; - overflow: clip; } -.tabContent { - height: 100%; +.tabMenuButton { + padding: 10px; } From 62bf0d53d35f1e2a9b2740b88617334f2eadd219 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 18 Mar 2025 22:21:28 +0900 Subject: [PATCH 24/75] =?UTF-8?q?=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/MkPageWindow.vue | 1 - .../src/components/global/StackingRouterView.vue | 9 +++++++-- packages/frontend/src/pages/settings/index.vue | 2 +- packages/frontend/src/style.scss | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue index eae2ccec4a..8a1a9c58d2 100644 --- a/packages/frontend/src/components/MkPageWindow.vue +++ b/packages/frontend/src/components/MkPageWindow.vue @@ -23,7 +23,6 @@ SPDX-License-Identifier: AGPL-3.0-only
-
diff --git a/packages/frontend/src/components/global/StackingRouterView.vue b/packages/frontend/src/components/global/StackingRouterView.vue index 71a91d4887..8a4afe7360 100644 --- a/packages/frontend/src/components/global/StackingRouterView.vue +++ b/packages/frontend/src/components/global/StackingRouterView.vue @@ -17,7 +17,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- + +
@@ -164,6 +165,8 @@ onBeforeUnmount(() => { } .tab { + overflow: clip; + &:first-child { position: relative; width: 100%; @@ -221,10 +224,12 @@ onBeforeUnmount(() => { .tabMenu { margin-left: auto; + padding: 0 4px; background: var(--MI_THEME-bg); } .tabMenuButton { - padding: 10px; + padding: 8px; + font-size: 13px; } diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue index ea1b714aed..f6feaee453 100644 --- a/packages/frontend/src/pages/settings/index.vue +++ b/packages/frontend/src/pages/settings/index.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/events.ts b/packages/frontend/src/events.ts index a74018223c..dfd3d4120c 100644 --- a/packages/frontend/src/events.ts +++ b/packages/frontend/src/events.ts @@ -10,5 +10,4 @@ export const globalEvents = new EventEmitter<{ themeChanging: () => void; themeChanged: () => void; clientNotification: (notification: Misskey.entities.Notification) => void; - requestClearPageCache: () => void; }>(); diff --git a/packages/frontend/src/lib/nirax.ts b/packages/frontend/src/lib/nirax.ts index cc20d497e6..8783874bc2 100644 --- a/packages/frontend/src/lib/nirax.ts +++ b/packages/frontend/src/lib/nirax.ts @@ -5,7 +5,7 @@ // NIRAX --- A lightweight router -import { onMounted, shallowRef } from 'vue'; +import { onBeforeUnmount, onMounted, shallowRef } from 'vue'; import { EventEmitter } from 'eventemitter3'; import type { Component, ShallowRef } from 'vue'; @@ -45,28 +45,28 @@ type ParsedPath = (string | { optional?: boolean; })[]; -export type RouterEvent = { +export type RouterEvents = { change: (ctx: { - beforePath: string; - path: string; - resolved: Resolved; + beforeFullPath: string; + fullPath: string; + resolved: PathResolvedResult; }) => void; replace: (ctx: { - path: string; + fullPath: string; }) => void; push: (ctx: { - beforePath: string; - path: string; + beforeFullPath: string; + fullPath: string; route: RouteDef | null; props: Map | null; }) => void; same: () => void; }; -export type Resolved = { +export type PathResolvedResult = { route: RouteDef; props: Map; - child?: Resolved; + child?: PathResolvedResult; redirected?: boolean; /** @internal */ @@ -102,39 +102,39 @@ function parsePath(path: string): ParsedPath { return res; } -export class Nirax extends EventEmitter { +export class Nirax extends EventEmitter { private routes: DEF; - public current: Resolved; - public currentRef: ShallowRef; + public current: PathResolvedResult; + public currentRef: ShallowRef; public currentRoute: ShallowRef; - private currentPath: string; + private currentFullPath: string; // /foo/bar?baz=qux#hash private isLoggedIn: boolean; private notFoundPageComponent: Component; private redirectCount = 0; - public navHook: ((path: string, flag?: RouterFlag) => boolean) | null = null; + public navHook: ((fullPath: string, flag?: RouterFlag) => boolean) | null = null; - constructor(routes: DEF, currentPath: Nirax['currentPath'], isLoggedIn: boolean, notFoundPageComponent: Component) { + constructor(routes: DEF, currentFullPath: Nirax['currentFullPath'], isLoggedIn: boolean, notFoundPageComponent: Component) { super(); this.routes = routes; - this.current = this.resolve(currentPath)!; + this.current = this.resolve(currentFullPath)!; this.currentRef = shallowRef(this.current); this.currentRoute = shallowRef(this.current.route); - this.currentPath = currentPath; + this.currentFullPath = currentFullPath; this.isLoggedIn = isLoggedIn; this.notFoundPageComponent = notFoundPageComponent; } public init() { - const res = this.navigate(this.currentPath, false); + const res = this.navigate(this.currentFullPath, false); this.emit('replace', { - path: res._parsedRoute.fullPath, + fullPath: res._parsedRoute.fullPath, }); } - public resolve(path: string): Resolved | null { - const fullPath = path; + public resolve(fullPath: string): PathResolvedResult | null { + let path = fullPath; let queryString: string | null = null; let hash: string | null = null; if (path[0] === '/') path = path.substring(1); @@ -153,7 +153,7 @@ export class Nirax extends EventEmitter { hash, }; - function check(routes: RouteDef[], _parts: string[]): Resolved | null { + function check(routes: RouteDef[], _parts: string[]): PathResolvedResult | null { forEachRouteLoop: for (const route of routes) { let parts = [..._parts]; @@ -256,14 +256,14 @@ export class Nirax extends EventEmitter { return check(this.routes, _parts); } - private navigate(path: string, emitChange = true, _redirected = false): Resolved { - const beforePath = this.currentPath; - this.currentPath = path; + private navigate(fullPath: string, emitChange = true, _redirected = false): PathResolvedResult { + const beforeFullPath = this.currentFullPath; + this.currentFullPath = fullPath; - const res = this.resolve(this.currentPath); + const res = this.resolve(this.currentFullPath); if (res == null) { - throw new Error('no route found for: ' + path); + throw new Error('no route found for: ' + fullPath); } if ('redirect' in res.route) { @@ -291,8 +291,8 @@ export class Nirax extends EventEmitter { if (emitChange && res.route.path !== '/:(*)') { this.emit('change', { - beforePath, - path, + beforeFullPath, + fullPath, resolved: res, }); } @@ -304,37 +304,45 @@ export class Nirax extends EventEmitter { }; } - public getCurrentPath() { - return this.currentPath; + public getCurrentFullPath() { + return this.currentFullPath; } - public push(path: string, flag?: RouterFlag) { - const beforePath = this.currentPath; - if (path === beforePath) { + public push(fullPath: string, flag?: RouterFlag) { + const beforeFullPath = this.currentFullPath; + if (fullPath === beforeFullPath) { this.emit('same'); return; } if (this.navHook) { - const cancel = this.navHook(path, flag); + const cancel = this.navHook(fullPath, flag); if (cancel) return; } - const res = this.navigate(path); + const res = this.navigate(fullPath); if (res.route.path === '/:(*)') { - location.href = path; + location.href = fullPath; } else { this.emit('push', { - beforePath, - path: res._parsedRoute.fullPath, + beforeFullPath, + fullPath: res._parsedRoute.fullPath, route: res.route, props: res.props, }); } } - public replace(path: string) { - const res = this.navigate(path); + public replace(fullPath: string) { + const res = this.navigate(fullPath); this.emit('replace', { - path: res._parsedRoute.fullPath, + fullPath: res._parsedRoute.fullPath, + }); + } + + public useListener(event: E, listener: L) { + this.addListener(event, listener); + + onBeforeUnmount(() => { + this.removeListener(event, listener); }); } } diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue index e9b1ee8101..30b7cf9a86 100644 --- a/packages/frontend/src/pages/settings/profile.vue +++ b/packages/frontend/src/pages/settings/profile.vue @@ -169,7 +169,6 @@ import { langmap } from '@/utility/langmap.js'; import { definePage } from '@/page.js'; import { claimAchievement } from '@/utility/achievements.js'; import { store } from '@/store.js'; -import { globalEvents } from '@/events.js'; import MkInfo from '@/components/MkInfo.vue'; import MkTextarea from '@/components/MkTextarea.vue'; @@ -223,7 +222,6 @@ function saveFields() { os.apiWithDialog('i/update', { fields: fields.value.filter(field => field.name !== '' && field.value !== '').map(field => ({ name: field.name, value: field.value })), }); - globalEvents.emit('requestClearPageCache'); } function save() { @@ -249,7 +247,6 @@ function save() { text: i18n.ts.yourNameContainsProhibitedWordsDescription, }, }); - globalEvents.emit('requestClearPageCache'); claimAchievement('profileFilled'); if (profile.name === 'syuilo' || profile.name === 'しゅいろ') { claimAchievement('setNameToSyuilo'); @@ -281,7 +278,6 @@ function changeAvatar(ev) { }); $i.avatarId = i.avatarId; $i.avatarUrl = i.avatarUrl; - globalEvents.emit('requestClearPageCache'); claimAchievement('profileFilled'); }); } @@ -308,7 +304,6 @@ function changeBanner(ev) { }); $i.bannerId = i.bannerId; $i.bannerUrl = i.bannerUrl; - globalEvents.emit('requestClearPageCache'); }); } diff --git a/packages/frontend/src/router.ts b/packages/frontend/src/router.ts index b5f59b30c1..dd70571d64 100644 --- a/packages/frontend/src/router.ts +++ b/packages/frontend/src/router.ts @@ -13,8 +13,8 @@ import { DI } from '@/di.js'; export type Router = Nirax; -export function createRouter(path: string): Router { - return new Nirax(ROUTE_DEF, path, !!$i, page(() => import('@/pages/not-found.vue'))); +export function createRouter(fullPath: string): Router { + return new Nirax(ROUTE_DEF, fullPath, !!$i, page(() => import('@/pages/not-found.vue'))); } export const mainRouter = createRouter(location.pathname + location.search + location.hash); @@ -24,23 +24,23 @@ window.addEventListener('popstate', (event) => { }); mainRouter.addListener('push', ctx => { - window.history.pushState({ }, '', ctx.path); + window.history.pushState({ }, '', ctx.fullPath); }); mainRouter.addListener('replace', ctx => { - window.history.replaceState({ }, '', ctx.path); + window.history.replaceState({ }, '', ctx.fullPath); }); mainRouter.addListener('change', ctx => { - console.log('mainRouter: change', ctx.path); + console.log('mainRouter: change', ctx.fullPath); analytics.page({ - path: ctx.path, - title: ctx.path, + path: ctx.fullPath, + title: ctx.fullPath, }); }); mainRouter.init(); export function useRouter(): Router { - return inject(DI.router, null) ?? mainRouter; + return inject(DI.router) ?? mainRouter; } diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue index fa63586ef7..2ef06726f9 100644 --- a/packages/frontend/src/ui/classic.vue +++ b/packages/frontend/src/ui/classic.vue @@ -112,7 +112,7 @@ function onContextmenu(ev: MouseEvent) { if (isLink(ev.target)) return; if (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(ev.target.tagName) || ev.target.attributes['contenteditable']) return; if (window.getSelection().toString() !== '') return; - const path = mainRouter.getCurrentPath(); + const path = mainRouter.getCurrentFullPath(); os.contextMenu([{ type: 'label', text: path, diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue index a6695de39d..133360972b 100644 --- a/packages/frontend/src/ui/universal.vue +++ b/packages/frontend/src/ui/universal.vue @@ -186,7 +186,7 @@ const onContextmenu = (ev) => { if (isLink(ev.target)) return; if (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(ev.target.tagName) || ev.target.attributes['contenteditable']) return; if (window.getSelection()?.toString() !== '') return; - const path = mainRouter.getCurrentPath(); + const path = mainRouter.getCurrentFullPath(); os.contextMenu([{ type: 'label', text: path, From 7b323031b774745ee2146c89ead2a9ebe628d613 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Wed, 19 Mar 2025 18:46:03 +0900 Subject: [PATCH 32/75] refactor(frontend): use useTemplateRef for DOM referencing --- .../src/components/MkAbuseReportWindow.vue | 4 ++-- packages/frontend/src/components/MkAnimBg.vue | 4 ++-- .../src/components/MkAnnouncementDialog.vue | 6 ++--- .../src/components/MkAntennaEditorDialog.vue | 4 ++-- .../src/components/MkAutocomplete.vue | 4 ++-- packages/frontend/src/components/MkButton.vue | 6 ++--- .../frontend/src/components/MkCaptcha.vue | 4 ++-- packages/frontend/src/components/MkChart.vue | 14 ++++------- .../frontend/src/components/MkCodeEditor.vue | 4 ++-- .../frontend/src/components/MkColorInput.vue | 4 ++-- .../frontend/src/components/MkContainer.vue | 8 +++---- .../frontend/src/components/MkContextMenu.vue | 4 ++-- .../src/components/MkCropperDialog.vue | 6 ++--- .../MkCustomEmojiDetailedDialog.vue | 6 ++--- packages/frontend/src/components/MkDialog.vue | 4 ++-- packages/frontend/src/components/MkDrive.vue | 6 ++--- .../src/components/MkDriveSelectDialog.vue | 4 ++-- .../src/components/MkEmbedCodeGenDialog.vue | 8 +++---- .../frontend/src/components/MkEmojiPicker.vue | 6 ++--- .../src/components/MkEmojiPickerDialog.vue | 6 ++--- .../components/MkFileCaptionEditWindow.vue | 4 ++-- .../src/components/MkFoldableSection.vue | 4 ++-- packages/frontend/src/components/MkFolder.vue | 4 ++-- .../frontend/src/components/MkFormDialog.vue | 4 ++-- .../frontend/src/components/MkHeatmap.vue | 6 ++--- .../src/components/MkHorizontalSwipe.vue | 4 ++-- .../src/components/MkImgWithBlurhash.vue | 8 +++---- packages/frontend/src/components/MkInput.vue | 8 +++---- .../src/components/MkInstanceStats.vue | 8 +++---- .../frontend/src/components/MkLaunchPad.vue | 4 ++-- .../frontend/src/components/MkMediaAudio.vue | 6 ++--- .../frontend/src/components/MkMediaList.vue | 4 ++-- .../frontend/src/components/MkMediaVideo.vue | 6 ++--- .../frontend/src/components/MkMenu.child.vue | 4 ++-- packages/frontend/src/components/MkMenu.vue | 8 +++---- packages/frontend/src/components/MkModal.vue | 6 ++--- .../frontend/src/components/MkModalWindow.vue | 8 +++---- packages/frontend/src/components/MkNote.vue | 16 ++++++------- .../src/components/MkNoteDetailed.vue | 16 ++++++------- packages/frontend/src/components/MkNotes.vue | 4 ++-- .../components/MkNotificationSelectWindow.vue | 8 +++---- .../src/components/MkNotifications.vue | 4 ++-- packages/frontend/src/components/MkOmit.vue | 4 ++-- .../frontend/src/components/MkPageWindow.vue | 4 ++-- .../frontend/src/components/MkPagination.vue | 4 ++-- .../src/components/MkPasswordDialog.vue | 6 ++--- .../frontend/src/components/MkPopupMenu.vue | 4 ++-- .../frontend/src/components/MkPostForm.vue | 12 +++++----- .../src/components/MkPostFormDialog.vue | 7 +++--- .../src/components/MkPullToRefresh.vue | 6 ++--- packages/frontend/src/components/MkRange.vue | 6 ++--- .../src/components/MkReactionIcon.vue | 4 ++-- .../components/MkReactionsViewer.reaction.vue | 4 ++-- .../src/components/MkRetentionHeatmap.vue | 6 ++--- .../src/components/MkRetentionLineChart.vue | 4 ++-- .../src/components/MkSigninDialog.vue | 4 ++-- .../src/components/MkSignupDialog.vue | 4 ++-- .../frontend/src/components/MkSparkle.vue | 4 ++-- .../src/components/MkSystemWebhookEditor.vue | 8 +++---- .../frontend/src/components/MkTagCloud.vue | 8 +++---- .../frontend/src/components/MkTextarea.vue | 4 ++-- .../frontend/src/components/MkTimeline.vue | 6 ++--- .../src/components/MkTokenGenerateWindow.vue | 4 ++-- .../frontend/src/components/MkTooltip.vue | 4 ++-- .../src/components/MkTutorialDialog.vue | 6 ++--- .../frontend/src/components/MkUpdated.vue | 6 ++--- .../src/components/MkUserSelectDialog.vue | 4 ++-- .../src/components/MkUserSetupDialog.vue | 9 ++++--- .../src/components/MkVisibilityPicker.vue | 4 ++-- .../MkVisitorDashboard.ActiveUsersChart.vue | 4 ++-- .../src/components/MkWaitingDialog.vue | 4 ++-- packages/frontend/src/components/MkWindow.vue | 4 ++-- .../frontend/src/components/global/MkA.vue | 4 ++-- .../frontend/src/components/global/MkLazy.vue | 4 ++-- .../components/global/MkPageHeader.tabs.vue | 6 ++--- .../src/components/global/MkPageHeader.vue | 4 ++-- .../components/global/MkStickyContainer.vue | 3 +-- .../src/components/grid/MkDataCell.vue | 24 ++++++++++--------- packages/frontend/src/pages/about-misskey.vue | 4 ++-- .../frontend/src/pages/admin/_header_.vue | 6 ++--- .../notification-recipient.editor.vue | 6 ++--- packages/frontend/src/pages/admin/abuses.vue | 4 ++-- packages/frontend/src/pages/admin/invites.vue | 6 ++--- packages/frontend/src/pages/admin/modlog.vue | 4 ++-- .../src/pages/admin/overview.active-users.vue | 4 ++-- .../src/pages/admin/overview.ap-requests.vue | 6 ++--- .../frontend/src/pages/admin/overview.pie.vue | 4 ++-- .../src/pages/admin/overview.queue.chart.vue | 4 ++-- .../src/pages/admin/overview.queue.vue | 10 ++++---- .../frontend/src/pages/admin/overview.vue | 4 ++-- .../src/pages/admin/queue.chart.chart.vue | 4 ++-- .../frontend/src/pages/admin/queue.chart.vue | 10 ++++---- packages/frontend/src/pages/admin/users.vue | 4 ++-- .../frontend/src/pages/antenna-timeline.vue | 8 +++---- .../src/pages/custom-emojis-manager.vue | 4 ++-- .../src/pages/drop-and-fusion.game.vue | 6 ++--- packages/frontend/src/pages/explore.users.vue | 4 ++-- packages/frontend/src/pages/explore.vue | 4 ++-- .../frontend/src/pages/follow-requests.vue | 4 ++-- packages/frontend/src/pages/invite.vue | 4 ++-- .../frontend/src/pages/my-clips/index.vue | 4 ++-- .../page-editor/els/page-editor.el.text.vue | 5 ++-- .../src/pages/settings/2fa.qrdialog.vue | 4 ++-- .../settings/avatar-decoration.dialog.vue | 4 ++-- .../frontend/src/pages/settings/index.vue | 4 ++-- .../src/pages/settings/notifications.vue | 4 ++-- packages/frontend/src/pages/timeline.vue | 6 ++--- .../frontend/src/pages/user-list-timeline.vue | 8 +++---- .../src/pages/user/activity.following.vue | 8 +++---- .../src/pages/user/activity.notes.vue | 8 +++---- .../frontend/src/pages/user/activity.pv.vue | 8 +++---- .../src/pages/welcome.timeline.note.vue | 4 ++-- .../frontend/src/pages/welcome.timeline.vue | 6 ++--- packages/frontend/src/ui/classic.sidebar.vue | 4 ++-- packages/frontend/src/ui/classic.vue | 4 ++-- packages/frontend/src/ui/deck.vue | 4 ++-- .../frontend/src/ui/deck/antenna-column.vue | 4 ++-- .../frontend/src/ui/deck/channel-column.vue | 4 ++-- packages/frontend/src/ui/deck/column.vue | 4 ++-- packages/frontend/src/ui/deck/list-column.vue | 4 ++-- .../src/ui/deck/notifications-column.vue | 6 ++--- .../src/ui/deck/role-timeline-column.vue | 4 ++-- packages/frontend/src/ui/deck/tl-column.vue | 4 ++-- packages/frontend/src/ui/universal.vue | 4 ++-- .../frontend/src/widgets/WidgetAichan.vue | 4 ++-- .../src/widgets/WidgetInstanceCloud.vue | 8 +++---- .../frontend/src/widgets/WidgetSlideshow.vue | 8 +++---- 127 files changed, 353 insertions(+), 359 deletions(-) diff --git a/packages/frontend/src/components/MkAbuseReportWindow.vue b/packages/frontend/src/components/MkAbuseReportWindow.vue index a634a748e9..dbac5e9dd7 100644 --- a/packages/frontend/src/components/MkAbuseReportWindow.vue +++ b/packages/frontend/src/components/MkAbuseReportWindow.vue @@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only From 161706c5e2f39347989b499b799aa12bad30b677 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 20 Mar 2025 13:01:20 +0900 Subject: [PATCH 51/75] New Crowdin updates (#15680) * New translations ja-jp.yml (Czech) * New translations ja-jp.yml (English) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Russian) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Korean) * New translations ja-jp.yml (Portuguese) * New translations ja-jp.yml (Chinese Traditional) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Japanese, Kansai) * New translations ja-jp.yml (Romanian) * New translations ja-jp.yml (French) * New translations ja-jp.yml (Spanish) * New translations ja-jp.yml (Arabic) * New translations ja-jp.yml (Czech) * New translations ja-jp.yml (German) * New translations ja-jp.yml (Greek) * New translations ja-jp.yml (Italian) * New translations ja-jp.yml (Dutch) * New translations ja-jp.yml (Norwegian) * New translations ja-jp.yml (Polish) * New translations ja-jp.yml (Slovak) * New translations ja-jp.yml (Swedish) * New translations ja-jp.yml (Ukrainian) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Vietnamese) * New translations ja-jp.yml (Indonesian) * New translations ja-jp.yml (Bengali) * New translations ja-jp.yml (Thai) * New translations ja-jp.yml (Uzbek) * New translations ja-jp.yml (Lao) * New translations ja-jp.yml (Korean (Gyeongsang)) --- locales/ar-SA.yml | 1 + locales/bn-BD.yml | 1 + locales/ca-ES.yml | 3 +-- locales/cs-CZ.yml | 5 +++++ locales/de-DE.yml | 3 +-- locales/el-GR.yml | 1 + locales/en-US.yml | 9 ++++----- locales/es-ES.yml | 3 +-- locales/fr-FR.yml | 3 +-- locales/id-ID.yml | 3 +-- locales/it-IT.yml | 3 +-- locales/ja-KS.yml | 3 +-- locales/ko-GS.yml | 1 + locales/ko-KR.yml | 3 +-- locales/lo-LA.yml | 1 + locales/nl-NL.yml | 1 + locales/no-NO.yml | 1 + locales/pl-PL.yml | 1 + locales/pt-PT.yml | 3 +-- locales/ro-RO.yml | 1 + locales/ru-RU.yml | 1 + locales/sk-SK.yml | 1 + locales/sv-SE.yml | 1 + locales/th-TH.yml | 3 +-- locales/uk-UA.yml | 1 + locales/uz-UZ.yml | 1 + locales/vi-VN.yml | 1 + locales/zh-CN.yml | 3 +-- locales/zh-TW.yml | 3 +-- 29 files changed, 36 insertions(+), 29 deletions(-) diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 4966007061..5e936da80c 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -1013,6 +1013,7 @@ flip: "اقلب" lastNDays: "آخر {n} أيام" surrender: "ألغِ" postForm: "أنشئ ملاحظة" +information: "عن" _delivery: stop: "مُعلّق" _initialAccountSetting: diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 6aea5a1999..36d142bd0b 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -853,6 +853,7 @@ renotes: "রিনোট" sourceCode: "সোর্স কোড" flip: "উল্টান" postForm: "নোট লিখুন" +information: "আপনার সম্পর্কে" _delivery: stop: "স্থগিত করা হয়েছে" _type: diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 44fb48f5f5..23b958252a 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1334,6 +1334,7 @@ paste: "Pegar" emojiPalette: "Calaix d'emojis" postForm: "Formulari de publicació" textCount: "Nombre de caràcters " +information: "Informació" _emojiPalette: palettes: "Calaixos d'emojis" enableSyncBetweenDevicesForPalettes: "Activa la sincronització dels calaixos d'emojis entre dispositius" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Assegura't que qui distribueix aquest recurs és fiable abans d'instal·lar-ho." _plugin: title: "Vols instal·lar aquest afegit?" - metaTitle: "Informació de l'afegit " _theme: title: "Vols instal·lar aquest tema?" - metaTitle: "Informació del tema" _meta: base: "Paleta de colors base" _vendorInfo: diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index a509280862..11ad97c3a5 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -169,6 +169,9 @@ addAccount: "Přidat účet" reloadAccountsList: "Obnovit list účtů" loginFailed: "Přihlášení se nezdařilo." showOnRemote: "Více na původním profilu" +continueOnRemote: "Pokračujte na původní profil" +chooseServerOnMisskeyHub: "Vyberete si server z Misskey Hubu" +inputHostName: "Zadejte doménu" general: "Obecně" wallpaper: "Obrázek na pozadí" setWallpaper: "Nastavení obrázku na pozadí" @@ -193,6 +196,7 @@ perHour: "za hodinu" perDay: "za den" stopActivityDelivery: "Přestat zasílat aktivitu" blockThisInstance: "Blokovat tuto instanci" +silenceThisInstance: "Utišit tuto instanci" operations: "Operace" software: "Software" version: "Verze" @@ -1099,6 +1103,7 @@ flip: "Otočit" lastNDays: "Posledních {n} dnů" surrender: "Zrušit" postForm: "Formulář pro odeslání" +information: "Informace" _delivery: stop: "Suspendováno" _type: diff --git a/locales/de-DE.yml b/locales/de-DE.yml index db692d65e5..c6cc416638 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1309,6 +1309,7 @@ availableRoles: "Verfügbare Rollen" federationSpecified: "Dieser Server arbeitet mit Whitelist-Föderation. Er kann nicht mit anderen als den vom Administrator angegebenen Servern interagieren." federationDisabled: "Föderation ist auf diesem Server deaktiviert. Es ist nicht möglich, mit Benutzern auf anderen Servern zu interagieren." postForm: "Notizfenster" +information: "Über" _settings: webhook: "Webhook" _accountSettings: @@ -2524,10 +2525,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Überprüfe vor Installation die Vertrauenswürdigkeit des Vertreibers." _plugin: title: "Möchtest du dieses Plugin installieren?" - metaTitle: "Plugininformation" _theme: title: "Möchten du dieses Farbschema installieren?" - metaTitle: "Farbschemainfo" _meta: base: "Farbschemavorlage" _vendorInfo: diff --git a/locales/el-GR.yml b/locales/el-GR.yml index be81a824c7..727565ae21 100644 --- a/locales/el-GR.yml +++ b/locales/el-GR.yml @@ -289,6 +289,7 @@ icon: "Εικονίδιο" replies: "Απάντηση" renotes: "Κοινοποίηση σημειώματος" postForm: "Φόρμα δημοσίευσης" +information: "Πληροφορίες" _email: _follow: title: "Έχετε ένα νέο ακόλουθο" diff --git a/locales/en-US.yml b/locales/en-US.yml index 0d2a29edca..79805e65e1 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1317,7 +1317,7 @@ unmarkAsSensitiveConfirm: "Do you want to remove the sensitive designation for t preferences: "Preferences" accessibility: "Accessibility" preferencesProfile: "Preferences profile" -copyPreferenceId: "Copy the proference ID" +copyPreferenceId: "Copy the preference ID" resetToDefaultValue: "Revert to default" overrideByAccount: "Override by the account" untitled: "Untitled" @@ -1334,6 +1334,7 @@ paste: "Paste" emojiPalette: "Emoji palette" postForm: "Posting form" textCount: "Character count" +information: "About" _emojiPalette: palettes: "Palette" enableSyncBetweenDevicesForPalettes: "Enable palette sync between devices" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Make sure the distributor of this resource is trustworthy before installation." _plugin: title: "Do you want to install this plugin?" - metaTitle: "Plugin information" _theme: title: "Do you want to install this theme?" - metaTitle: "Theme information" _meta: base: "Base color scheme" _vendorInfo: @@ -2877,8 +2876,8 @@ _selfXssPrevention: description2: "If you do not understand exactly what you are trying to paste, %cstop working right now and close this window." description3: "For more information, please refer to this. {link}" _followRequest: - recieved: "Received application" - sent: "Sent application" + recieved: "Received request" + sent: "Sent request" _remoteLookupErrors: _federationNotAllowed: title: "Unable to communicate with this server" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 4933b41ddb..cd96d348c3 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -1300,6 +1300,7 @@ target: "Para" federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador." federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores" postForm: "Formulario" +information: "Información" _settings: webhook: "Webhook" _accountSettings: @@ -2521,10 +2522,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Asegúrate de que el distribuidor de este recurso es de confianza antes de proceder a la instalación." _plugin: title: "¿Quieres instalar este plugin?" - metaTitle: "Información del plugin" _theme: title: "¿Quieres instalar este tema?" - metaTitle: "Información del tema" _meta: base: "Esquema de color base" _vendorInfo: diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 6d3a3bb882..4bdcd89422 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -1278,6 +1278,7 @@ lockdown: "Verrouiller" pleaseSelectAccount: "Sélectionner un compte" availableRoles: "Rôles disponibles" postForm: "Formulaire de publication" +information: "Informations" _abuseUserReport: forward: "Transférer" forwardDescription: "Transférer le signalement vers une instance distante en tant qu'anonyme." @@ -2295,10 +2296,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Veuillez confirmer que le distributeur est fiable avant l'installation." _plugin: title: "Voulez-vous installer cette extension ?" - metaTitle: "Informations sur l'extension" _theme: title: "Voulez-vous installer ce thème ?" - metaTitle: "Informations sur le thème" _meta: base: "Palette de couleurs de base" _vendorInfo: diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 62ddc35cad..9a291ca381 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1262,6 +1262,7 @@ modified: "Diubah" thereAreNChanges: "Ada {n} perubahan" prohibitedWordsForNameOfUser: "Kata yang dilarang untuk nama pengguna" postForm: "Buat catatan" +information: "Informasi" _settings: webhook: "Webhook" _abuseUserReport: @@ -2492,10 +2493,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Pastikan sumber dari sumber daya ini terpercaya sebelum melakukan pemasangan." _plugin: title: "Apakah kamu ingin memasang plugin ini?" - metaTitle: "Informasi plugin" _theme: title: "Apakah kamu ingin memasang tema ini?" - metaTitle: "Informasi tema" _meta: base: "Skema warna dasar" _vendorInfo: diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 7a39a8c0e6..4d17d0bf7b 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -1334,6 +1334,7 @@ paste: "Incolla" emojiPalette: "Tavolozza emoji" postForm: "Finestra di pubblicazione" textCount: "Il numero di caratteri" +information: "Informazioni" _emojiPalette: palettes: "Tavolozza" enableSyncBetweenDevicesForPalettes: "Attiva la sincronizzazione tra dispositivi" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Prima di installare, assicurati che la fonte sia affidabile." _plugin: title: "Vuoi davvero installare questo componente aggiuntivo?" - metaTitle: "Informazioni sul componente aggiuntivo" _theme: title: "Vuoi davvero installare questa variazione grafica?" - metaTitle: "Informazioni sulla variazione grafica" _meta: base: "Combinazione base di colori" _vendorInfo: diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index ae45379086..9c0bff4f95 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -1312,6 +1312,7 @@ federationDisabled: "このサーバーは連合が無効化されてるで。 confirmOnReact: "ツッコむときに確認とる" reactAreYouSure: "\" {emoji} \" でツッコむ?" postForm: "投稿フォーム" +information: "情報" _settings: webhook: "Webhook" _accountSettings: @@ -2610,10 +2611,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "配ってるとこが信頼できるか確認した上でインストールしてな。" _plugin: title: "このプラグイン、インストールする?" - metaTitle: "プラグイン情報" _theme: title: "このテーマインストールする?" - metaTitle: "テーマ情報" _meta: base: "" _vendorInfo: diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml index ce83ef0e07..8ff11d35d9 100644 --- a/locales/ko-GS.yml +++ b/locales/ko-GS.yml @@ -655,6 +655,7 @@ replies: "답하기" renotes: "리노트" attach: "옇기" surrender: "아이예" +information: "정보" _delivery: stop: "고만 보내예" _type: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 798c371bc2..4a02b0c64a 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1330,6 +1330,7 @@ preferenceSyncConflictChoiceDevice: "장치 설정값" paste: "붙여넣기" emojiPalette: "이모지 팔레트" postForm: "글 입력란" +information: "정보" _emojiPalette: palettes: "팔레트" paletteForMain: "메인으로 사용할 팔레트" @@ -2650,10 +2651,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "제공자를 신뢰할 수 있는 경우에만 설치하십시오." _plugin: title: "이 플러그인을 설치하시겠습니까?" - metaTitle: "플러그인 정보" _theme: title: "이 테마를 설치하시겠습니까?" - metaTitle: "테마 정보" _meta: base: "기본 컬러 스키마" _vendorInfo: diff --git a/locales/lo-LA.yml b/locales/lo-LA.yml index 06acda44be..52b5a28fb2 100644 --- a/locales/lo-LA.yml +++ b/locales/lo-LA.yml @@ -394,6 +394,7 @@ searchByGoogle: "ຄົ້ນຫາ" file: "ໄຟລ໌" replies: "ຕອບ​ກັບ" renotes: "Renote" +information: "ກ່ຽວກັບ" _delivery: stop: "ໂຈະ" _type: diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index 320b9d62ba..e2f6017f20 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -462,6 +462,7 @@ loggedInAsBot: "Momenteel als bot ingelogd" icon: "Avatar" replies: "Antwoord" renotes: "Herdelen" +information: "Over" _delivery: stop: "Opgeschort" _type: diff --git a/locales/no-NO.yml b/locales/no-NO.yml index c1b145cab4..7981360c41 100644 --- a/locales/no-NO.yml +++ b/locales/no-NO.yml @@ -463,6 +463,7 @@ icon: "Avatar" replies: "Svar" renotes: "Renote" surrender: "Avbryt" +information: "Informasjon" _delivery: stop: "Suspendert" _initialAccountSetting: diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index a4538ee7b2..21b715714d 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -1045,6 +1045,7 @@ lastNDays: "W ciągu ostatnich {n} dni" surrender: "Odrzuć" gameRetry: "Spróbuj ponownie" postForm: "Formularz tworzenia wpisu" +information: "Informacje" _delivery: stop: "Zawieszono" _type: diff --git a/locales/pt-PT.yml b/locales/pt-PT.yml index 4511ce662f..2f46eda784 100644 --- a/locales/pt-PT.yml +++ b/locales/pt-PT.yml @@ -1302,6 +1302,7 @@ pleaseSelectAccount: "Selecione uma conta" availableRoles: "Cargos disponíveis" acknowledgeNotesAndEnable: "Ative após compreender as precauções." postForm: "Campo de postagem" +information: "Informações" _settings: webhook: "Webhook" _accountSettings: @@ -2598,10 +2599,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "Tenha certeza de que o distribuidor desse recurso é confiável antes da instalação." _plugin: title: "Deseja instalar esse plugin?" - metaTitle: "Informações do plugin" _theme: title: "Deseja instalar esse tema?" - metaTitle: "Informações do tema" _meta: base: "Paleta de cores base" _vendorInfo: diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index 0d43e174a7..5d1459480d 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -646,6 +646,7 @@ show: "Arată" icon: "Avatar" replies: "Răspunde" renotes: "Re-notează" +information: "Despre" _delivery: stop: "Suspendat" _type: diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 2a200deac0..33a09d198a 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -1182,6 +1182,7 @@ alwaysConfirmFollow: "Всегда подтверждать подписку" inquiry: "Связаться" messageToFollower: "Сообщение подписчикам" postForm: "Форма отправки" +information: "Описание" _settings: webhook: "Вебхук" _delivery: diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index 7ae264081f..cc8ef9298a 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -918,6 +918,7 @@ sourceCode: "Zdrojový kód" flip: "Preklopiť" lastNDays: "Posledných {n} dní" postForm: "Napísať poznámku" +information: "Informácie" _delivery: stop: "Zmrazené" _type: diff --git a/locales/sv-SE.yml b/locales/sv-SE.yml index 91413e3bc7..c740ab1c0c 100644 --- a/locales/sv-SE.yml +++ b/locales/sv-SE.yml @@ -562,6 +562,7 @@ inquiry: "Kontakt" tryAgain: "Försök igen senare" signinWithPasskey: "Logga in med nyckel" unknownWebAuthnKey: "Okänd nyckel" +information: "Om" _delivery: stop: "Suspenderad" _type: diff --git a/locales/th-TH.yml b/locales/th-TH.yml index 939b0d7269..784e9049dd 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -1293,6 +1293,7 @@ prohibitedWordsForNameOfUserDescription: "หากมีสตริงใด yourNameContainsProhibitedWords: "ชื่อของคุณนั้นมีคำที่ต้องห้าม" yourNameContainsProhibitedWordsDescription: "ถ้าหากคุณต้องการใช้ชื่อนี้ กรุณาติดต่อผู้ดูแลระบบของเซิร์ฟเวอร์นะค่ะ" postForm: "แบบฟอร์มการโพสต์" +information: "เกี่ยวกับ" _settings: webhook: "Webhook" _abuseUserReport: @@ -2572,10 +2573,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "โปรดตรวจสอบให้แน่ใจว่าแหล่งแจกหน่ายมีความน่าเชื่อถือก่อนทำการติดตั้ง" _plugin: title: "ต้องการติดตั้งปลั๊กอินนี้ใช่ไหม?" - metaTitle: "ข้อมูลส่วนเสริม" _theme: title: "ต้องการติดตั้งธีมนี้ใช่ไหม?" - metaTitle: "ข้อมูลธีม" _meta: base: "โทนสีพื้นฐาน" _vendorInfo: diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 3e068127f5..a63e39eff4 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -910,6 +910,7 @@ sourceCode: "Вихідний код" flip: "Перевернути" lastNDays: "Останні {n} днів" postForm: "Створення нотатки" +information: "Інформація" _delivery: stop: "Призупинено" _type: diff --git a/locales/uz-UZ.yml b/locales/uz-UZ.yml index c70802e417..d5b7d4b770 100644 --- a/locales/uz-UZ.yml +++ b/locales/uz-UZ.yml @@ -841,6 +841,7 @@ icon: "Avatar" replies: "Javob berish" renotes: "Qayta qayd etish" flip: "Teskari" +information: "Haqida" _delivery: stop: "To'xtatilgan" _type: diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index d2107eaba4..8edcebcd08 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -1120,6 +1120,7 @@ cwNotationRequired: "Nếu \"Ẩn nội dung\" được bật thì cần phải lastNDays: "{n} ngày trước" surrender: "Từ chối" postForm: "Mẫu đăng" +information: "Giới thiệu" _delivery: stop: "Đã vô hiệu hóa" _type: diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 444ba8bc52..ad3eebfebd 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -1334,6 +1334,7 @@ paste: "粘贴" emojiPalette: "表情符号调色板" postForm: "投稿窗口" textCount: "字数" +information: "关于" _emojiPalette: palettes: "调色板" enableSyncBetweenDevicesForPalettes: "启用调色板的设备间同步" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "请在安装前确保来源可靠" _plugin: title: "要安装此插件吗?" - metaTitle: "插件信息" _theme: title: "要安装此主题吗?" - metaTitle: "主题信息" _meta: base: "基本配色方案" _vendorInfo: diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 2ea4ae8168..0de267688c 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1334,6 +1334,7 @@ paste: "貼上" emojiPalette: "表情符號調色盤" postForm: "發文視窗" textCount: "字數" +information: "關於" _emojiPalette: palettes: "調色盤" enableSyncBetweenDevicesForPalettes: "啟用裝置與裝置之間的調色盤同步化" @@ -2673,10 +2674,8 @@ _externalResourceInstaller: checkVendorBeforeInstall: "安裝前請確認提供者是可信賴的。" _plugin: title: "要安裝此外掛嘛?" - metaTitle: "外掛資訊" _theme: title: "要安裝此佈景主題嗎?" - metaTitle: "佈景主題資訊" _meta: base: "基本配色方案" _vendorInfo: From 070749bdc8750dbda6ccbb43f2c25514a659051c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 20 Mar 2025 04:03:25 +0000 Subject: [PATCH 52/75] Bump version to 2025.3.2-beta.6 --- package.json | 2 +- packages/misskey-js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 142de7513f..51422b3638 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2025.3.2-beta.5", + "version": "2025.3.2-beta.6", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 1c5ae12a9f..b66f202876 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2025.3.2-beta.5", + "version": "2025.3.2-beta.6", "description": "Misskey SDK for JavaScript", "license": "MIT", "main": "./built/index.js", From 8b6d90b7a45422f0c5dd05678c7a4ca8d83b7fe5 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 20 Mar 2025 13:16:08 +0900 Subject: [PATCH 53/75] =?UTF-8?q?=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/MkAnimBg.vue | 2 +- .../frontend/src/pages/install-extensions.vue | 74 ++++++++++--------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/frontend/src/components/MkAnimBg.vue b/packages/frontend/src/components/MkAnimBg.vue index 2938645557..e57fbcdee3 100644 --- a/packages/frontend/src/components/MkAnimBg.vue +++ b/packages/frontend/src/components/MkAnimBg.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> + + diff --git a/packages/frontend/src/pages/install-extensions.vue b/packages/frontend/src/pages/install-extensions.vue index 47c49e547a..40d58027de 100644 --- a/packages/frontend/src/pages/install-extensions.vue +++ b/packages/frontend/src/pages/install-extensions.vue @@ -4,46 +4,43 @@ SPDX-License-Identifier: AGPL-3.0-only --> + + diff --git a/packages/frontend/src/di.ts b/packages/frontend/src/di.ts index e9b2c2b650..4977cdbd62 100644 --- a/packages/frontend/src/di.ts +++ b/packages/frontend/src/di.ts @@ -11,4 +11,5 @@ export const DI = { router: Symbol() as InjectionKey, mock: Symbol() as InjectionKey, pageMetadata: Symbol() as InjectionKey>>, + viewId: Symbol() as InjectionKey, }; diff --git a/packages/frontend/src/utility/random-id.ts b/packages/frontend/src/utility/random-id.ts new file mode 100644 index 0000000000..4e5943a97f --- /dev/null +++ b/packages/frontend/src/utility/random-id.ts @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +const CHARS = 'abcdefghijklmnopqrstuvwxyz'; // CSSのなどで使われることもあるのでa-z以外使うな + +export function randomId(length = 32, characters = CHARS) { + let result = ''; + const charactersLength = characters.length; + for ( let i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +} From c02f0b3b33c833056254b170af8620e9750ae22f Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 20 Mar 2025 18:59:10 +0900 Subject: [PATCH 67/75] Update eslint.config.js --- packages/frontend/eslint.config.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/frontend/eslint.config.js b/packages/frontend/eslint.config.js index e3fba65197..05ac002b53 100644 --- a/packages/frontend/eslint.config.js +++ b/packages/frontend/eslint.config.js @@ -56,7 +56,9 @@ export default [ // open ... window.openと衝突 or 紛らわしい // fetch ... window.fetchと衝突 or 紛らわしい // location ... window.locationと衝突 or 紛らわしい - 'id-denylist': ['warn', 'window', 'e', 'close', 'open', 'fetch', 'location'], + // document ... window.documentと衝突 or 紛らわしい + // history ... window.historyと衝突 or 紛らわしい + 'id-denylist': ['warn', 'window', 'e', 'close', 'open', 'fetch', 'location', 'document', 'history'], 'no-restricted-globals': [ 'error', { @@ -75,6 +77,10 @@ export default [ 'name': 'location', 'message': 'Use `window.location`.', }, + { + 'name': 'document', + 'message': 'Use `window.document`.', + }, { 'name': 'history', 'message': 'Use `window.history`.', From 6015254e59ba0526efbfa139c89546458663ccbd Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:00:09 +0900 Subject: [PATCH 68/75] lint fixes --- packages/frontend/.storybook/fake-utils.ts | 2 +- packages/frontend/.storybook/preview.ts | 6 ++-- packages/frontend/src/boot/common.ts | 30 +++++++++---------- packages/frontend/src/boot/main-boot.ts | 6 ++-- .../frontend/src/components/MkAnalogClock.vue | 2 +- .../src/components/MkAutocomplete.vue | 4 +-- packages/frontend/src/components/MkButton.vue | 2 +- .../frontend/src/components/MkCaptcha.vue | 6 ++-- .../frontend/src/components/MkContextMenu.vue | 4 +-- .../src/components/MkCropperDialog.vue | 2 +- packages/frontend/src/components/MkFolder.vue | 2 +- .../src/components/MkImgWithBlurhash.vue | 4 +-- .../src/components/MkInstanceStats.vue | 2 +- .../frontend/src/components/MkMediaAudio.vue | 2 +- .../frontend/src/components/MkMediaList.vue | 6 ++-- .../frontend/src/components/MkMediaVideo.vue | 8 ++--- packages/frontend/src/components/MkMenu.vue | 16 +++++----- .../frontend/src/components/MkMiniChart.vue | 2 +- .../src/components/MkNotifications.vue | 2 +- .../frontend/src/components/MkPagination.vue | 2 +- packages/frontend/src/components/MkRange.vue | 8 ++--- .../components/MkReactionsViewer.reaction.vue | 2 +- .../src/components/MkRetentionLineChart.vue | 2 +- .../frontend/src/components/MkTagCloud.vue | 4 +-- .../MkVisitorDashboard.ActiveUsersChart.vue | 2 +- packages/frontend/src/components/MkWindow.vue | 2 +- .../components/global/MkPageHeader.tabs.vue | 2 +- .../src/components/global/MkPageHeader.vue | 4 +-- .../src/components/global/RouterView.vue | 6 ++-- .../src/components/global/SearchMarker.vue | 2 +- packages/frontend/src/directives/hotkey.ts | 4 +-- packages/frontend/src/directives/panel.ts | 2 +- packages/frontend/src/directives/tooltip.ts | 2 +- .../frontend/src/directives/user-preview.ts | 4 +-- packages/frontend/src/instance.ts | 2 +- packages/frontend/src/os.ts | 4 +-- .../frontend/src/pages/admin/_header_.vue | 2 +- .../frontend/src/pages/admin/overview.pie.vue | 2 +- packages/frontend/src/pages/auth.form.vue | 2 +- .../src/pages/drop-and-fusion.game.vue | 2 +- packages/frontend/src/pages/oauth.vue | 18 +++++------ .../src/pages/settings/2fa.qrdialog.vue | 2 +- packages/frontend/src/preferences.ts | 6 ++-- packages/frontend/src/preferences/utility.ts | 4 +-- packages/frontend/src/server-context.ts | 2 +- packages/frontend/src/stream.ts | 6 ++-- packages/frontend/src/theme.ts | 12 ++++---- packages/frontend/src/ui/_common_/common.vue | 2 +- packages/frontend/src/ui/_common_/navbar.vue | 4 +-- packages/frontend/src/ui/classic.vue | 6 ++-- packages/frontend/src/ui/deck.vue | 4 +-- packages/frontend/src/ui/minimum.vue | 4 +-- packages/frontend/src/ui/universal.vue | 12 ++++---- packages/frontend/src/ui/visitor.vue | 4 +-- packages/frontend/src/ui/zen.vue | 4 +-- packages/frontend/src/use/use-note-capture.ts | 2 +- packages/frontend/src/use/use-tooltip.ts | 4 +-- packages/frontend/src/utility/focus-trap.ts | 4 +-- packages/frontend/src/utility/focus.ts | 4 +-- packages/frontend/src/utility/fullscreen.ts | 4 +-- packages/frontend/src/utility/hotkey.ts | 6 ++-- packages/frontend/src/utility/init-chart.ts | 2 +- packages/frontend/src/utility/physics.ts | 2 +- packages/frontend/src/utility/select-file.ts | 2 +- .../frontend/src/utility/snowfall-effect.ts | 6 ++-- packages/frontend/src/utility/sound.ts | 4 +-- .../frontend/src/utility/sticky-sidebar.ts | 2 +- .../src/utility/upload/isWebpSupported.ts | 2 +- packages/frontend/src/widgets/WidgetRss.vue | 2 +- .../frontend/src/widgets/WidgetRssTicker.vue | 2 +- packages/frontend/test/scroll.test.ts | 12 ++++---- 71 files changed, 160 insertions(+), 160 deletions(-) diff --git a/packages/frontend/.storybook/fake-utils.ts b/packages/frontend/.storybook/fake-utils.ts index c777cbbe72..44e2263ca0 100644 --- a/packages/frontend/.storybook/fake-utils.ts +++ b/packages/frontend/.storybook/fake-utils.ts @@ -131,7 +131,7 @@ export function imageDataUrl(options?: { alpha?: number, } }, seed?: string): string { - const canvas = document.createElement('canvas'); + const canvas = window.document.createElement('canvas'); canvas.width = options?.size?.width ?? 100; canvas.height = options?.size?.height ?? 100; diff --git a/packages/frontend/.storybook/preview.ts b/packages/frontend/.storybook/preview.ts index 3f6bfb62ff..269bc4fb9a 100644 --- a/packages/frontend/.storybook/preview.ts +++ b/packages/frontend/.storybook/preview.ts @@ -23,9 +23,9 @@ let misskeyOS = null; function loadTheme(applyTheme: typeof import('../src/theme')['applyTheme']) { unobserve(); - const theme = themes[document.documentElement.dataset.misskeyTheme]; + const theme = themes[window.document.documentElement.dataset.misskeyTheme]; if (theme) { - applyTheme(themes[document.documentElement.dataset.misskeyTheme]); + applyTheme(themes[window.document.documentElement.dataset.misskeyTheme]); } else { applyTheme(themes['l-light']); } @@ -42,7 +42,7 @@ function loadTheme(applyTheme: typeof import('../src/theme')['applyTheme']) { } } }); - observer.observe(document.documentElement, { + observer.observe(window.document.documentElement, { attributes: true, attributeFilter: ['data-misskey-theme'], }); diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index 75b74b41f8..9a505ca9f8 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -95,7 +95,7 @@ export async function common(createVue: () => App) { //#endregion // タッチデバイスでCSSの:hoverを機能させる - document.addEventListener('touchend', () => {}, { passive: true }); + window.document.addEventListener('touchend', () => {}, { passive: true }); // URLに#pswpを含む場合は取り除く if (window.location.hash === '#pswp') { @@ -110,13 +110,13 @@ export async function common(createVue: () => App) { // If mobile, insert the viewport meta tag if (['smartphone', 'tablet'].includes(deviceKind)) { - const viewport = document.getElementsByName('viewport').item(0); + const viewport = window.document.getElementsByName('viewport').item(0); viewport.setAttribute('content', `${viewport.getAttribute('content')}, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover`); } //#region Set lang attr - const html = document.documentElement; + const html = window.document.documentElement; html.setAttribute('lang', lang); //#endregion @@ -155,7 +155,7 @@ export async function common(createVue: () => App) { ); }, { immediate: miLocalStorage.getItem('theme') == null }); - document.documentElement.dataset.colorScheme = store.s.darkMode ? 'dark' : 'light'; + window.document.documentElement.dataset.colorScheme = store.s.darkMode ? 'dark' : 'light'; const darkTheme = prefer.model('darkTheme'); const lightTheme = prefer.model('lightTheme'); @@ -201,20 +201,20 @@ export async function common(createVue: () => App) { }, { immediate: true }); watch(prefer.r.useBlurEffectForModal, v => { - document.documentElement.style.setProperty('--MI-modalBgFilter', v ? 'blur(4px)' : 'none'); + window.document.documentElement.style.setProperty('--MI-modalBgFilter', v ? 'blur(4px)' : 'none'); }, { immediate: true }); watch(prefer.r.useBlurEffect, v => { if (v) { - document.documentElement.style.removeProperty('--MI-blur'); + window.document.documentElement.style.removeProperty('--MI-blur'); } else { - document.documentElement.style.setProperty('--MI-blur', 'none'); + window.document.documentElement.style.setProperty('--MI-blur', 'none'); } }, { immediate: true }); // Keep screen on - const onVisibilityChange = () => document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') { + const onVisibilityChange = () => window.document.addEventListener('visibilitychange', () => { + if (window.document.visibilityState === 'visible') { navigator.wakeLock.request('screen'); } }); @@ -224,7 +224,7 @@ export async function common(createVue: () => App) { .catch(() => { // On WebKit-based browsers, user activation is required to send wake lock request // https://webkit.org/blog/13862/the-user-activation-api/ - document.addEventListener( + window.document.addEventListener( 'click', () => navigator.wakeLock.request('screen').then(onVisibilityChange), { once: true }, @@ -233,7 +233,7 @@ export async function common(createVue: () => App) { } if (prefer.s.makeEveryTextElementsSelectable) { - document.documentElement.classList.add('forceSelectableAll'); + window.document.documentElement.classList.add('forceSelectableAll'); } //#region Fetch user @@ -278,16 +278,16 @@ export async function common(createVue: () => App) { const rootEl = ((): HTMLElement => { const MISSKEY_MOUNT_DIV_ID = 'misskey_app'; - const currentRoot = document.getElementById(MISSKEY_MOUNT_DIV_ID); + const currentRoot = window.document.getElementById(MISSKEY_MOUNT_DIV_ID); if (currentRoot) { console.warn('multiple import detected'); return currentRoot; } - const root = document.createElement('div'); + const root = window.document.createElement('div'); root.id = MISSKEY_MOUNT_DIV_ID; - document.body.appendChild(root); + window.document.body.appendChild(root); return root; })(); @@ -330,7 +330,7 @@ export async function common(createVue: () => App) { } function removeSplash() { - const splash = document.getElementById('splash'); + const splash = window.document.getElementById('splash'); if (splash) { splash.style.opacity = '0'; splash.style.pointerEvents = 'none'; diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index f7360a7340..134490e317 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -398,7 +398,7 @@ export async function mainBoot() { let lastVisibilityChangedAt = Date.now(); function claimPlainLucky() { - if (document.visibilityState !== 'visible') { + if (window.document.visibilityState !== 'visible') { if (justPlainLuckyTimer != null) window.clearTimeout(justPlainLuckyTimer); return; } @@ -413,7 +413,7 @@ export async function mainBoot() { window.addEventListener('visibilitychange', () => { const now = Date.now(); - if (document.visibilityState === 'visible') { + if (window.document.visibilityState === 'visible') { // タブを高速で切り替えたら取得処理が何度も走るのを防ぐ if ((now - lastVisibilityChangedAt) < 1000 * 10) { justPlainLuckyTimer = window.setTimeout(claimPlainLucky, 1000 * 10); @@ -554,7 +554,7 @@ export async function mainBoot() { mainRouter.push('/search'); }, } as const satisfies Keymap; - document.addEventListener('keydown', makeHotkey(keymap), { passive: false }); + window.document.addEventListener('keydown', makeHotkey(keymap), { passive: false }); initializeSw(); } diff --git a/packages/frontend/src/components/MkAnalogClock.vue b/packages/frontend/src/components/MkAnalogClock.vue index b39bca5b27..eac1ea9534 100644 --- a/packages/frontend/src/components/MkAnalogClock.vue +++ b/packages/frontend/src/components/MkAnalogClock.vue @@ -192,7 +192,7 @@ function tick() { tick(); function calcColors() { - const computedStyle = getComputedStyle(document.documentElement); + const computedStyle = getComputedStyle(window.document.documentElement); const dark = tinycolor(computedStyle.getPropertyValue('--MI_THEME-bg')).isDark(); const accent = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString(); majorGraduationColor.value = dark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)'; diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue index 5b747a2a1a..03cf107231 100644 --- a/packages/frontend/src/components/MkAutocomplete.vue +++ b/packages/frontend/src/components/MkAutocomplete.vue @@ -359,7 +359,7 @@ onMounted(() => { props.textarea.addEventListener('keydown', onKeydown); - document.body.addEventListener('mousedown', onMousedown); + window.document.body.addEventListener('mousedown', onMousedown); nextTick(() => { exec(); @@ -375,7 +375,7 @@ onMounted(() => { onBeforeUnmount(() => { props.textarea.removeEventListener('keydown', onKeydown); - document.body.removeEventListener('mousedown', onMousedown); + window.document.body.removeEventListener('mousedown', onMousedown); }); diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue index c81edc2a73..5e89dfba12 100644 --- a/packages/frontend/src/components/MkButton.vue +++ b/packages/frontend/src/components/MkButton.vue @@ -92,7 +92,7 @@ function onMousedown(evt: MouseEvent): void { const target = evt.target! as HTMLElement; const rect = target.getBoundingClientRect(); - const ripple = document.createElement('div'); + const ripple = window.document.createElement('div'); ripple.classList.add(ripples.value!.dataset.childrenClass!); ripple.style.top = (evt.clientY - rect.top - 1).toString() + 'px'; ripple.style.left = (evt.clientX - rect.left - 1).toString() + 'px'; diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue index e4f953bda8..30940a34a9 100644 --- a/packages/frontend/src/components/MkCaptcha.vue +++ b/packages/frontend/src/components/MkCaptcha.vue @@ -112,7 +112,7 @@ watch(() => [props.instanceUrl, props.sitekey, props.secretKey], async () => { if (loaded || props.provider === 'mcaptcha' || props.provider === 'testcaptcha') { available.value = true; } else if (src.value !== null) { - (document.getElementById(scriptId.value) ?? document.head.appendChild(Object.assign(document.createElement('script'), { + (window.document.getElementById(scriptId.value) ?? window.document.head.appendChild(Object.assign(window.document.createElement('script'), { async: true, id: scriptId.value, src: src.value, @@ -149,7 +149,7 @@ async function requestRender() { if (captcha.value.render && captchaEl.value instanceof Element && props.sitekey) { // reCAPTCHAのレンダリング重複判定を回避するため、captchaEl配下に仮のdivを用意する. // (同じdivに対して複数回renderを呼び出すとreCAPTCHAはエラーを返すので) - const elem = document.createElement('div'); + const elem = window.document.createElement('div'); captchaEl.value.appendChild(elem); captchaWidgetId.value = captcha.value.render(elem, { @@ -174,7 +174,7 @@ async function requestRender() { function clearWidget() { if (props.provider === 'mcaptcha') { - const container = document.getElementById('mcaptcha__widget-container'); + const container = window.document.getElementById('mcaptcha__widget-container'); if (container) { container.innerHTML = ''; } diff --git a/packages/frontend/src/components/MkContextMenu.vue b/packages/frontend/src/components/MkContextMenu.vue index e47dba4bae..9c6397a72c 100644 --- a/packages/frontend/src/components/MkContextMenu.vue +++ b/packages/frontend/src/components/MkContextMenu.vue @@ -68,11 +68,11 @@ onMounted(() => { rootEl.value.style.left = `${left}px`; } - document.body.addEventListener('mousedown', onMousedown); + window.document.body.addEventListener('mousedown', onMousedown); }); onBeforeUnmount(() => { - document.body.removeEventListener('mousedown', onMousedown); + window.document.body.removeEventListener('mousedown', onMousedown); }); function onMousedown(evt: Event) { diff --git a/packages/frontend/src/components/MkCropperDialog.vue b/packages/frontend/src/components/MkCropperDialog.vue index bd2e6a9cbc..ba21394cbc 100644 --- a/packages/frontend/src/components/MkCropperDialog.vue +++ b/packages/frontend/src/components/MkCropperDialog.vue @@ -122,7 +122,7 @@ onMounted(() => { cropper = new Cropper(imgEl.value!, { }); - const computedStyle = getComputedStyle(document.documentElement); + const computedStyle = getComputedStyle(window.document.documentElement); const selection = cropper.getCropperSelection()!; selection.themeColor = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString(); diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue index b13972f66d..afa09e3125 100644 --- a/packages/frontend/src/components/MkFolder.vue +++ b/packages/frontend/src/components/MkFolder.vue @@ -116,7 +116,7 @@ function toggle() { } onMounted(() => { - const computedStyle = getComputedStyle(document.documentElement); + const computedStyle = getComputedStyle(window.document.documentElement); const parentBg = getBgColor(rootEl.value?.parentElement) ?? 'transparent'; const myBg = computedStyle.getPropertyValue('--MI_THEME-panel'); bgSame.value = parentBg === myBg; diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue index 420e5e392f..e3a0a371b4 100644 --- a/packages/frontend/src/components/MkImgWithBlurhash.vue +++ b/packages/frontend/src/components/MkImgWithBlurhash.vue @@ -55,7 +55,7 @@ import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurha const canvasPromise = new Promise(resolve => { // テスト環境で Web Worker インスタンスは作成できない if (import.meta.env.MODE === 'test') { - const canvas = document.createElement('canvas'); + const canvas = window.document.createElement('canvas'); canvas.width = 64; canvas.height = 64; resolve(canvas); @@ -70,7 +70,7 @@ const canvasPromise = new Promise(resol ); resolve(workers); } else { - const canvas = document.createElement('canvas'); + const canvas = window.document.createElement('canvas'); canvas.width = 64; canvas.height = 64; resolve(canvas); diff --git a/packages/frontend/src/components/MkInstanceStats.vue b/packages/frontend/src/components/MkInstanceStats.vue index 76bec9bc66..90391005bc 100644 --- a/packages/frontend/src/components/MkInstanceStats.vue +++ b/packages/frontend/src/components/MkInstanceStats.vue @@ -126,7 +126,7 @@ function createDoughnut(chartEl, tooltip, data) { labels: data.map(x => x.name), datasets: [{ backgroundColor: data.map(x => x.color), - borderColor: getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel'), + borderColor: getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'), borderWidth: 2, hoverOffset: 0, data: data.map(x => x.value), diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index db6deb161a..b7052ad918 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -148,7 +148,7 @@ const keymap = { // PlayerElもしくはその子要素にフォーカスがあるかどうか function hasFocus() { if (!playerEl.value) return false; - return playerEl.value === document.activeElement || playerEl.value.contains(document.activeElement); + return playerEl.value === window.document.activeElement || playerEl.value.contains(window.document.activeElement); } const playerEl = useTemplateRef('playerEl'); diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 44a9d14a46..ae15776041 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -48,7 +48,7 @@ const props = defineProps<{ const gallery = useTemplateRef('gallery'); const pswpZIndex = os.claimZIndex('middle'); -document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString()); +window.document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString()); const count = computed(() => props.mediaList.filter(media => previewable(media)).length); let lightbox: PhotoSwipeLightbox | null = null; @@ -166,7 +166,7 @@ onMounted(() => { className: 'pswp__alt-text-container', appendTo: 'wrapper', onInit: (el, pswp) => { - const textBox = document.createElement('p'); + const textBox = window.document.createElement('p'); textBox.className = 'pswp__alt-text _acrylic'; el.appendChild(textBox); @@ -178,7 +178,7 @@ onMounted(() => { }); lightbox.on('afterInit', () => { - activeEl = document.activeElement instanceof HTMLElement ? document.activeElement : null; + activeEl = window.document.activeElement instanceof HTMLElement ? window.document.activeElement : null; focusParent(activeEl, true, true); lightbox?.pswp?.element?.focus({ preventScroll: true, diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue index 5475e703a5..629679a971 100644 --- a/packages/frontend/src/components/MkMediaVideo.vue +++ b/packages/frontend/src/components/MkMediaVideo.vue @@ -171,7 +171,7 @@ const keymap = { // PlayerElもしくはその子要素にフォーカスがあるかどうか function hasFocus() { if (!playerEl.value) return false; - return playerEl.value === document.activeElement || playerEl.value.contains(document.activeElement); + return playerEl.value === window.document.activeElement || playerEl.value.contains(window.document.activeElement); } // eslint-disable-next-line vue/no-setup-props-reactivity-loss @@ -216,7 +216,7 @@ function showMenu(ev: MouseEvent) { '2.0x': 2, }, }, - ...(document.pictureInPictureEnabled ? [{ + ...(window.document.pictureInPictureEnabled ? [{ text: i18n.ts._mediaControls.pip, icon: 'ti ti-picture-in-picture', action: togglePictureInPicture, @@ -384,8 +384,8 @@ function toggleFullscreen() { function togglePictureInPicture() { if (videoEl.value) { - if (document.pictureInPictureElement) { - document.exitPictureInPicture(); + if (window.document.pictureInPictureElement) { + window.document.exitPictureInPicture(); } else { videoEl.value.requestPictureInPicture(); } diff --git a/packages/frontend/src/components/MkMenu.vue b/packages/frontend/src/components/MkMenu.vue index e380d0bc37..a84bd9b256 100644 --- a/packages/frontend/src/components/MkMenu.vue +++ b/packages/frontend/src/components/MkMenu.vue @@ -358,10 +358,10 @@ function switchItem(item: MenuSwitch & { ref: any }) { function focusUp() { if (disposed) return; - if (!itemsEl.value?.contains(document.activeElement)) return; + if (!itemsEl.value?.contains(window.document.activeElement)) return; const focusableElements = Array.from(itemsEl.value.children).filter(isFocusable); - const activeIndex = focusableElements.findIndex(el => el === document.activeElement); + const activeIndex = focusableElements.findIndex(el => el === window.document.activeElement); const targetIndex = (activeIndex !== -1 && activeIndex !== 0) ? (activeIndex - 1) : (focusableElements.length - 1); const targetElement = focusableElements.at(targetIndex) ?? itemsEl.value; @@ -370,10 +370,10 @@ function focusUp() { function focusDown() { if (disposed) return; - if (!itemsEl.value?.contains(document.activeElement)) return; + if (!itemsEl.value?.contains(window.document.activeElement)) return; const focusableElements = Array.from(itemsEl.value.children).filter(isFocusable); - const activeIndex = focusableElements.findIndex(el => el === document.activeElement); + const activeIndex = focusableElements.findIndex(el => el === window.document.activeElement); const targetIndex = (activeIndex !== -1 && activeIndex !== (focusableElements.length - 1)) ? (activeIndex + 1) : 0; const targetElement = focusableElements.at(targetIndex) ?? itemsEl.value; @@ -400,9 +400,9 @@ const onGlobalMousedown = (ev: MouseEvent) => { const setupHandlers = () => { if (!isNestingMenu) { - document.addEventListener('focusin', onGlobalFocusin, { passive: true }); + window.document.addEventListener('focusin', onGlobalFocusin, { passive: true }); } - document.addEventListener('mousedown', onGlobalMousedown, { passive: true }); + window.document.addEventListener('mousedown', onGlobalMousedown, { passive: true }); }; let disposed = false; @@ -410,9 +410,9 @@ let disposed = false; const disposeHandlers = () => { disposed = true; if (!isNestingMenu) { - document.removeEventListener('focusin', onGlobalFocusin); + window.document.removeEventListener('focusin', onGlobalFocusin); } - document.removeEventListener('mousedown', onGlobalMousedown); + window.document.removeEventListener('mousedown', onGlobalMousedown); }; onMounted(() => { diff --git a/packages/frontend/src/components/MkMiniChart.vue b/packages/frontend/src/components/MkMiniChart.vue index 7ea585ecc2..98bd471438 100644 --- a/packages/frontend/src/components/MkMiniChart.vue +++ b/packages/frontend/src/components/MkMiniChart.vue @@ -48,7 +48,7 @@ const polygonPoints = ref(''); const headX = ref(null); const headY = ref(null); const clock = ref(null); -const accent = tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-accent')); +const accent = tinycolor(getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-accent')); const color = accent.toRgbString(); function draw(): void { diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue index 08fc846327..21f1967bfa 100644 --- a/packages/frontend/src/components/MkNotifications.vue +++ b/packages/frontend/src/components/MkNotifications.vue @@ -59,7 +59,7 @@ const pagination = computed(() => prefer.r.useGroupedNotifications.value ? { function onNotification(notification) { const isMuted = props.excludeTypes ? props.excludeTypes.includes(notification.type) : false; - if (isMuted || document.visibilityState === 'visible') { + if (isMuted || window.document.visibilityState === 'visible') { useStream().send('readNotification'); } diff --git a/packages/frontend/src/components/MkPagination.vue b/packages/frontend/src/components/MkPagination.vue index 6a1a91a9f4..ab8bda403b 100644 --- a/packages/frontend/src/components/MkPagination.vue +++ b/packages/frontend/src/components/MkPagination.vue @@ -142,7 +142,7 @@ const { } = prefer.r; const contentEl = computed(() => props.pagination.pageEl ?? rootEl.value); -const scrollableElement = computed(() => contentEl.value ? getScrollContainer(contentEl.value) : document.body); +const scrollableElement = computed(() => contentEl.value ? getScrollContainer(contentEl.value) : window.document.body); const visibility = useDocumentVisibility(); diff --git a/packages/frontend/src/components/MkRange.vue b/packages/frontend/src/components/MkRange.vue index 118dbbe15a..734b624541 100644 --- a/packages/frontend/src/components/MkRange.vue +++ b/packages/frontend/src/components/MkRange.vue @@ -151,9 +151,9 @@ function onMousedown(ev: MouseEvent | TouchEvent) { closed: () => dispose(), }); - const style = document.createElement('style'); - style.appendChild(document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }')); - document.head.appendChild(style); + const style = window.document.createElement('style'); + style.appendChild(window.document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }')); + window.document.head.appendChild(style); const thumbWidth = getThumbWidth(); @@ -172,7 +172,7 @@ function onMousedown(ev: MouseEvent | TouchEvent) { let beforeValue = finalValue.value; const onMouseup = () => { - document.head.removeChild(style); + window.document.head.removeChild(style); tooltipForDragShowing.value = false; window.removeEventListener('mousemove', onDrag); window.removeEventListener('touchmove', onDrag); diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue index 590b0f6f19..9d941a949a 100644 --- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue +++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue @@ -136,7 +136,7 @@ async function menu(ev) { } function anime() { - if (document.hidden || !prefer.s.animation || buttonEl.value == null) return; + if (window.document.hidden || !prefer.s.animation || buttonEl.value == null) return; const rect = buttonEl.value.getBoundingClientRect(); const x = rect.left + 16; diff --git a/packages/frontend/src/components/MkRetentionLineChart.vue b/packages/frontend/src/components/MkRetentionLineChart.vue index 60b3f17b14..ba66ffecc0 100644 --- a/packages/frontend/src/components/MkRetentionLineChart.vue +++ b/packages/frontend/src/components/MkRetentionLineChart.vue @@ -44,7 +44,7 @@ onMounted(async () => { const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)'; - const accent = tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-accent')); + const accent = tinycolor(getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-accent')); const color = accent.toHex(); if (chartEl.value == null) return; diff --git a/packages/frontend/src/components/MkTagCloud.vue b/packages/frontend/src/components/MkTagCloud.vue index 8ad9e14015..9d541c8acb 100644 --- a/packages/frontend/src/components/MkTagCloud.vue +++ b/packages/frontend/src/components/MkTagCloud.vue @@ -20,7 +20,7 @@ import tinycolor from 'tinycolor2'; const loaded = !!window.TagCanvas; const SAFE_FOR_HTML_ID = 'abcdefghijklmnopqrstuvwxyz'; -const computedStyle = getComputedStyle(document.documentElement); +const computedStyle = getComputedStyle(window.document.documentElement); const idForCanvas = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join(''); const idForTags = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join(''); const available = ref(false); @@ -57,7 +57,7 @@ onMounted(() => { if (loaded) { available.value = true; } else { - document.head.appendChild(Object.assign(document.createElement('script'), { + window.document.head.appendChild(Object.assign(window.document.createElement('script'), { async: true, src: '/client-assets/tagcanvas.min.js', })).addEventListener('load', () => available.value = true); diff --git a/packages/frontend/src/components/MkVisitorDashboard.ActiveUsersChart.vue b/packages/frontend/src/components/MkVisitorDashboard.ActiveUsersChart.vue index 2c2c515032..79c9e739c4 100644 --- a/packages/frontend/src/components/MkVisitorDashboard.ActiveUsersChart.vue +++ b/packages/frontend/src/components/MkVisitorDashboard.ActiveUsersChart.vue @@ -61,7 +61,7 @@ async function renderChart() { const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)'; - const computedStyle = getComputedStyle(document.documentElement); + const computedStyle = getComputedStyle(window.document.documentElement); const accent = tinycolor(computedStyle.getPropertyValue('--MI_THEME-accent')).toHexString(); const colorRead = accent; diff --git a/packages/frontend/src/components/MkWindow.vue b/packages/frontend/src/components/MkWindow.vue index 98ec448a8e..e5ac791d0b 100644 --- a/packages/frontend/src/components/MkWindow.vue +++ b/packages/frontend/src/components/MkWindow.vue @@ -240,7 +240,7 @@ function onHeaderMousedown(evt: MouseEvent | TouchEvent) { const main = rootEl.value; if (main == null) return; - if (!contains(main, document.activeElement)) main.focus(); + if (!contains(main, window.document.activeElement)) main.focus(); const position = main.getBoundingClientRect(); diff --git a/packages/frontend/src/components/global/MkPageHeader.tabs.vue b/packages/frontend/src/components/global/MkPageHeader.tabs.vue index 81adc07f26..358a17d3e8 100644 --- a/packages/frontend/src/components/global/MkPageHeader.tabs.vue +++ b/packages/frontend/src/components/global/MkPageHeader.tabs.vue @@ -170,7 +170,7 @@ onMounted(() => { if (props.rootEl) { ro2 = new ResizeObserver((entries, observer) => { - if (document.body.contains(el.value as HTMLElement)) { + if (window.document.body.contains(el.value as HTMLElement)) { nextTick(() => renderTab()); } }); diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue index 59bf80cfca..d5680b8413 100644 --- a/packages/frontend/src/components/global/MkPageHeader.vue +++ b/packages/frontend/src/components/global/MkPageHeader.vue @@ -108,7 +108,7 @@ function onTabClick(): void { const calcBg = () => { const rawBg = 'var(--MI_THEME-bg)'; - const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg); + const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(window.document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg); tinyBg.setAlpha(0.85); bg.value = tinyBg.toRgbString(); }; @@ -122,7 +122,7 @@ onMounted(() => { if (el.value && el.value.parentElement) { narrow.value = el.value.parentElement.offsetWidth < 500; ro = new ResizeObserver((entries, observer) => { - if (el.value && el.value.parentElement && document.body.contains(el.value as HTMLElement)) { + if (el.value && el.value.parentElement && window.document.body.contains(el.value as HTMLElement)) { narrow.value = el.value.parentElement.offsetWidth < 500; } }); diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue index 45cb1e3bd5..1c0c35f34e 100644 --- a/packages/frontend/src/components/global/RouterView.vue +++ b/packages/frontend/src/components/global/RouterView.vue @@ -48,7 +48,7 @@ onMounted(() => { }); // view-transition-newなどのにはcss varが使えず、v-bindできないため直接スタイルを生成 -const viewTransitionStylesTag = document.createElement('style'); +const viewTransitionStylesTag = window.document.createElement('style'); viewTransitionStylesTag.textContent = ` @keyframes ${viewId}-old { to { transform: scale(0.95); opacity: 0; } @@ -89,8 +89,8 @@ router.useListener('change', ({ resolved }) => { } // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (prefer.s.animation && document.startViewTransition) { - document.startViewTransition(() => new Promise((res) => { + if (prefer.s.animation && window.document.startViewTransition) { + window.document.startViewTransition(() => new Promise((res) => { _(); nextTick(() => { res(); diff --git a/packages/frontend/src/components/global/SearchMarker.vue b/packages/frontend/src/components/global/SearchMarker.vue index 66a78cb7fd..061ce3f47d 100644 --- a/packages/frontend/src/components/global/SearchMarker.vue +++ b/packages/frontend/src/components/global/SearchMarker.vue @@ -42,7 +42,7 @@ const highlighted = ref(props.markerId === searchMarkerId.value); function checkChildren() { if (props.children?.includes(searchMarkerId.value)) { - const el = document.querySelector(`[data-in-app-search-marker-id="${searchMarkerId.value}"]`); + const el = window.document.querySelector(`[data-in-app-search-marker-id="${searchMarkerId.value}"]`); highlighted.value = el == null; } } diff --git a/packages/frontend/src/directives/hotkey.ts b/packages/frontend/src/directives/hotkey.ts index 75e022e98f..63637ab2ba 100644 --- a/packages/frontend/src/directives/hotkey.ts +++ b/packages/frontend/src/directives/hotkey.ts @@ -13,7 +13,7 @@ export default { el._keyHandler = makeHotkey(binding.value); if (el._hotkey_global) { - document.addEventListener('keydown', el._keyHandler, { passive: false }); + window.document.addEventListener('keydown', el._keyHandler, { passive: false }); } else { el.addEventListener('keydown', el._keyHandler, { passive: false }); } @@ -21,7 +21,7 @@ export default { unmounted(el) { if (el._hotkey_global) { - document.removeEventListener('keydown', el._keyHandler); + window.document.removeEventListener('keydown', el._keyHandler); } else { el.removeEventListener('keydown', el._keyHandler); } diff --git a/packages/frontend/src/directives/panel.ts b/packages/frontend/src/directives/panel.ts index 17916fb6d3..0af19e6ca3 100644 --- a/packages/frontend/src/directives/panel.ts +++ b/packages/frontend/src/directives/panel.ts @@ -10,7 +10,7 @@ export default { mounted(src, binding, vn) { const parentBg = getBgColor(src.parentElement) ?? 'transparent'; - const myBg = getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel'); + const myBg = getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'); if (parentBg === myBg) { src.style.backgroundColor = 'var(--MI_THEME-bg)'; diff --git a/packages/frontend/src/directives/tooltip.ts b/packages/frontend/src/directives/tooltip.ts index 068186dfa0..750acd0588 100644 --- a/packages/frontend/src/directives/tooltip.ts +++ b/packages/frontend/src/directives/tooltip.ts @@ -47,7 +47,7 @@ export default { } self.show = () => { - if (!document.body.contains(el)) return; + if (!window.document.body.contains(el)) return; if (self._close) return; if (self.text == null) return; diff --git a/packages/frontend/src/directives/user-preview.ts b/packages/frontend/src/directives/user-preview.ts index 43a93a0865..94deea82c7 100644 --- a/packages/frontend/src/directives/user-preview.ts +++ b/packages/frontend/src/directives/user-preview.ts @@ -31,7 +31,7 @@ export class UserPreview { } private show() { - if (!document.body.contains(this.el)) return; + if (!window.document.body.contains(this.el)) return; if (this.promise) return; const showing = ref(true); @@ -58,7 +58,7 @@ export class UserPreview { }; this.checkTimer = window.setInterval(() => { - if (!document.body.contains(this.el)) { + if (!window.document.body.contains(this.el)) { window.clearTimeout(this.showTimer); window.clearTimeout(this.hideTimer); this.close(); diff --git a/packages/frontend/src/instance.ts b/packages/frontend/src/instance.ts index c694d49c8a..e75e3dfd34 100644 --- a/packages/frontend/src/instance.ts +++ b/packages/frontend/src/instance.ts @@ -12,7 +12,7 @@ import { DEFAULT_INFO_IMAGE_URL, DEFAULT_NOT_FOUND_IMAGE_URL, DEFAULT_SERVER_ERR // TODO: 他のタブと永続化されたstateを同期 //#region loader -const providedMetaEl = document.getElementById('misskey_meta'); +const providedMetaEl = window.document.getElementById('misskey_meta'); let cachedMeta = miLocalStorage.getItem('instance') ? JSON.parse(miLocalStorage.getItem('instance')!) : null; let cachedAt = miLocalStorage.getItem('instanceCachedAt') ? parseInt(miLocalStorage.getItem('instanceCachedAt')!) : 0; diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index eed929432c..7f4f7c5be3 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -675,7 +675,7 @@ export function popupMenu(items: MenuItem[], src?: HTMLElement | EventTarget | n src = null; } - let returnFocusTo = getHTMLElementOrNull(src) ?? getHTMLElementOrNull(document.activeElement); + let returnFocusTo = getHTMLElementOrNull(src) ?? getHTMLElementOrNull(window.document.activeElement); return new Promise(resolve => nextTick(() => { const { dispose } = popup(MkPopupMenu, { items, @@ -704,7 +704,7 @@ export function contextMenu(items: MenuItem[], ev: MouseEvent): Promise { return Promise.resolve(); } - let returnFocusTo = getHTMLElementOrNull(ev.currentTarget ?? ev.target) ?? getHTMLElementOrNull(document.activeElement); + let returnFocusTo = getHTMLElementOrNull(ev.currentTarget ?? ev.target) ?? getHTMLElementOrNull(window.document.activeElement); ev.preventDefault(); return new Promise(resolve => nextTick(() => { const { dispose } = popup(MkContextMenu, { diff --git a/packages/frontend/src/pages/admin/_header_.vue b/packages/frontend/src/pages/admin/_header_.vue index 819ca2c127..0af56e1b15 100644 --- a/packages/frontend/src/pages/admin/_header_.vue +++ b/packages/frontend/src/pages/admin/_header_.vue @@ -120,7 +120,7 @@ function onTabClick(tab: Tab, ev: MouseEvent): void { const calcBg = () => { const rawBg = pageMetadata.value.bg ?? 'var(--MI_THEME-bg)'; - const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg); + const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(window.document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg); tinyBg.setAlpha(0.85); bg.value = tinyBg.toRgbString(); }; diff --git a/packages/frontend/src/pages/admin/overview.pie.vue b/packages/frontend/src/pages/admin/overview.pie.vue index 32dd981ca9..86c5eff4da 100644 --- a/packages/frontend/src/pages/admin/overview.pie.vue +++ b/packages/frontend/src/pages/admin/overview.pie.vue @@ -41,7 +41,7 @@ onMounted(() => { labels: props.data.map(x => x.name), datasets: [{ backgroundColor: props.data.map(x => x.color), - borderColor: getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-panel'), + borderColor: getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'), borderWidth: 2, hoverOffset: 0, data: props.data.map(x => x.value), diff --git a/packages/frontend/src/pages/auth.form.vue b/packages/frontend/src/pages/auth.form.vue index 1917293c06..5b1fd1a386 100644 --- a/packages/frontend/src/pages/auth.form.vue +++ b/packages/frontend/src/pages/auth.form.vue @@ -38,7 +38,7 @@ const emit = defineEmits<{ const app = computed(() => props.session.app); const name = computed(() => { - const el = document.createElement('div'); + const el = window.document.createElement('div'); el.textContent = app.value.name; return el.innerHTML; }); diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index 3b1a845f5b..b8b0d6aef6 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -875,7 +875,7 @@ function loadImage(url: string) { function getGameImageDriveFile() { return new Promise(res => { - const dcanvas = document.createElement('canvas'); + const dcanvas = window.document.createElement('canvas'); dcanvas.width = game.GAME_WIDTH; dcanvas.height = game.GAME_HEIGHT; const ctx = dcanvas.getContext('2d'); diff --git a/packages/frontend/src/pages/oauth.vue b/packages/frontend/src/pages/oauth.vue index 49664c8b08..04bb1661cf 100644 --- a/packages/frontend/src/pages/oauth.vue +++ b/packages/frontend/src/pages/oauth.vue @@ -27,42 +27,42 @@ import MkPageWithAnimBg from '@/components/MkPageWithAnimBg.vue'; import { definePage } from '@/page.js'; import MkAuthConfirm from '@/components/MkAuthConfirm.vue'; -const transactionIdMeta = document.querySelector('meta[name="misskey:oauth:transaction-id"]'); +const transactionIdMeta = window.document.querySelector('meta[name="misskey:oauth:transaction-id"]'); if (transactionIdMeta) { transactionIdMeta.remove(); } -const name = document.querySelector('meta[name="misskey:oauth:client-name"]')?.content; -const logo = document.querySelector('meta[name="misskey:oauth:client-logo"]')?.content; -const permissions = document.querySelector('meta[name="misskey:oauth:scope"]')?.content.split(' ').filter((p): p is typeof Misskey.permissions[number] => (Misskey.permissions as readonly string[]).includes(p)) ?? []; +const name = window.document.querySelector('meta[name="misskey:oauth:client-name"]')?.content; +const logo = window.document.querySelector('meta[name="misskey:oauth:client-logo"]')?.content; +const permissions = window.document.querySelector('meta[name="misskey:oauth:scope"]')?.content.split(' ').filter((p): p is typeof Misskey.permissions[number] => (Misskey.permissions as readonly string[]).includes(p)) ?? []; function doPost(token: string, decision: 'accept' | 'deny') { - const form = document.createElement('form'); + const form = window.document.createElement('form'); form.action = '/oauth/decision'; form.method = 'post'; form.acceptCharset = 'utf-8'; - const loginToken = document.createElement('input'); + const loginToken = window.document.createElement('input'); loginToken.type = 'hidden'; loginToken.name = 'login_token'; loginToken.value = token; form.appendChild(loginToken); - const transactionId = document.createElement('input'); + const transactionId = window.document.createElement('input'); transactionId.type = 'hidden'; transactionId.name = 'transaction_id'; transactionId.value = transactionIdMeta?.content ?? ''; form.appendChild(transactionId); if (decision === 'deny') { - const cancel = document.createElement('input'); + const cancel = window.document.createElement('input'); cancel.type = 'hidden'; cancel.name = 'cancel'; cancel.value = 'cancel'; form.appendChild(cancel); } - document.body.appendChild(form); + window.document.body.appendChild(form); form.submit(); } diff --git a/packages/frontend/src/pages/settings/2fa.qrdialog.vue b/packages/frontend/src/pages/settings/2fa.qrdialog.vue index a13f1a7813..03f973a33e 100644 --- a/packages/frontend/src/pages/settings/2fa.qrdialog.vue +++ b/packages/frontend/src/pages/settings/2fa.qrdialog.vue @@ -160,7 +160,7 @@ async function tokenDone() { function downloadBackupCodes() { if (backupCodes.value !== undefined) { const txtBlob = new Blob([backupCodes.value.join('\n')], { type: 'text/plain' }); - const dummya = document.createElement('a'); + const dummya = window.document.createElement('a'); dummya.href = URL.createObjectURL(txtBlob); dummya.download = `${$i.username}@${hostname}` + (port !== '' ? `_${port}` : '') + '-2fa-backup-codes.txt'; dummya.click(); diff --git a/packages/frontend/src/preferences.ts b/packages/frontend/src/preferences.ts index 7681333910..73c89e23af 100644 --- a/packages/frontend/src/preferences.ts +++ b/packages/frontend/src/preferences.ts @@ -125,8 +125,8 @@ function syncBetweenTabs() { window.setInterval(syncBetweenTabs, 5000); -document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') { +window.document.addEventListener('visibilitychange', () => { + if (window.document.visibilityState === 'visible') { syncBetweenTabs(); } }); @@ -136,7 +136,7 @@ let latestBackupAt = 0; window.setInterval(() => { if ($i == null) return; if (!store.s.enablePreferencesAutoCloudBackup) return; - if (document.visibilityState !== 'visible') return; // 同期されていない古い値がバックアップされるのを防ぐ + if (window.document.visibilityState !== 'visible') return; // 同期されていない古い値がバックアップされるのを防ぐ if (prefer.profile.modifiedAt <= latestBackupAt) return; cloudBackup().then(() => { diff --git a/packages/frontend/src/preferences/utility.ts b/packages/frontend/src/preferences/utility.ts index bf3dfa157f..7229b7348e 100644 --- a/packages/frontend/src/preferences/utility.ts +++ b/packages/frontend/src/preferences/utility.ts @@ -106,14 +106,14 @@ async function renameProfile() { function exportCurrentProfile() { const p = prefer.profile; const txtBlob = new Blob([JSON.stringify(p)], { type: 'text/plain' }); - const dummya = document.createElement('a'); + const dummya = window.document.createElement('a'); dummya.href = URL.createObjectURL(txtBlob); dummya.download = `${p.name || p.id}.misskeypreferences`; dummya.click(); } function importProfile() { - const input = document.createElement('input'); + const input = window.document.createElement('input'); input.type = 'file'; input.accept = '.misskeypreferences'; input.onchange = async () => { diff --git a/packages/frontend/src/server-context.ts b/packages/frontend/src/server-context.ts index e79d3fa314..744bfa4b7b 100644 --- a/packages/frontend/src/server-context.ts +++ b/packages/frontend/src/server-context.ts @@ -5,7 +5,7 @@ import * as Misskey from 'misskey-js'; -const providedContextEl = document.getElementById('misskey_clientCtx'); +const providedContextEl = window.document.getElementById('misskey_clientCtx'); export type ServerContext = { clip?: Misskey.entities.Clip; diff --git a/packages/frontend/src/stream.ts b/packages/frontend/src/stream.ts index c97d7d4071..25544d9d88 100644 --- a/packages/frontend/src/stream.ts +++ b/packages/frontend/src/stream.ts @@ -29,10 +29,10 @@ export function useStream(): Misskey.IStream { timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL); // send heartbeat right now when last send time is over HEART_BEAT_INTERVAL - document.addEventListener('visibilitychange', () => { + window.document.addEventListener('visibilitychange', () => { if ( !stream - || document.visibilityState !== 'visible' + || window.document.visibilityState !== 'visible' || Date.now() - lastHeartbeatCall < HEART_BEAT_INTERVAL ) return; heartbeat(); @@ -42,7 +42,7 @@ export function useStream(): Misskey.IStream { } function heartbeat(): void { - if (stream != null && document.visibilityState === 'visible') { + if (stream != null && window.document.visibilityState === 'visible') { stream.heartbeat(); } lastHeartbeatCall = Date.now(); diff --git a/packages/frontend/src/theme.ts b/packages/frontend/src/theme.ts index 970d143b97..cd44fff0c4 100644 --- a/packages/frontend/src/theme.ts +++ b/packages/frontend/src/theme.ts @@ -68,10 +68,10 @@ let timeout: number | null = null; export function applyTheme(theme: Theme, persist = true) { if (timeout) window.clearTimeout(timeout); - document.documentElement.classList.add('_themeChanging_'); + window.document.documentElement.classList.add('_themeChanging_'); timeout = window.setTimeout(() => { - document.documentElement.classList.remove('_themeChanging_'); + window.document.documentElement.classList.remove('_themeChanging_'); // 色計算など再度行えるようにクライアント全体に通知 globalEvents.emit('themeChanged'); @@ -79,7 +79,7 @@ export function applyTheme(theme: Theme, persist = true) { const colorScheme = theme.base === 'dark' ? 'dark' : 'light'; - document.documentElement.dataset.colorScheme = colorScheme; + window.document.documentElement.dataset.colorScheme = colorScheme; // Deep copy const _theme = deepClone(theme); @@ -91,7 +91,7 @@ export function applyTheme(theme: Theme, persist = true) { const props = compile(_theme); - for (const tag of document.head.children) { + for (const tag of window.document.head.children) { if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { tag.setAttribute('content', props['htmlThemeColor']); break; @@ -99,10 +99,10 @@ export function applyTheme(theme: Theme, persist = true) { } for (const [k, v] of Object.entries(props)) { - document.documentElement.style.setProperty(`--MI_THEME-${k}`, v.toString()); + window.document.documentElement.style.setProperty(`--MI_THEME-${k}`, v.toString()); } - document.documentElement.style.setProperty('color-scheme', colorScheme); + window.document.documentElement.style.setProperty('color-scheme', colorScheme); if (persist) { miLocalStorage.setItem('theme', JSON.stringify(props)); diff --git a/packages/frontend/src/ui/_common_/common.vue b/packages/frontend/src/ui/_common_/common.vue index a39a4ee86b..930f633c9f 100644 --- a/packages/frontend/src/ui/_common_/common.vue +++ b/packages/frontend/src/ui/_common_/common.vue @@ -67,7 +67,7 @@ const dev = _DEV_; const notifications = ref([]); function onNotification(notification: Misskey.entities.Notification, isClient = false) { - if (document.visibilityState === 'visible') { + if (window.document.visibilityState === 'visible') { if (!isClient && notification.type !== 'test') { // サーバーサイドのテスト通知の際は自動で既読をつけない(テストできないので) useStream().send('readNotification'); diff --git a/packages/frontend/src/ui/_common_/navbar.vue b/packages/frontend/src/ui/_common_/navbar.vue index 754bf070fa..98d6f329ab 100644 --- a/packages/frontend/src/ui/_common_/navbar.vue +++ b/packages/frontend/src/ui/_common_/navbar.vue @@ -129,8 +129,8 @@ watch(store.r.menuDisplay, () => { }); function toggleIconOnly() { - if (document.startViewTransition && prefer.s.animation) { - document.startViewTransition(() => { + if (window.document.startViewTransition && prefer.s.animation) { + window.document.startViewTransition(() => { store.set('menuDisplay', iconOnly.value ? 'sideFull' : 'sideIcon'); }); } else { diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue index 8f35ce0c68..f51577fc68 100644 --- a/packages/frontend/src/ui/classic.vue +++ b/packages/frontend/src/ui/classic.vue @@ -87,9 +87,9 @@ provideMetadataReceiver((metadataGetter) => { pageMetadata.value = info; if (pageMetadata.value) { if (isRoot.value && pageMetadata.value.title === instanceName) { - document.title = pageMetadata.value.title; + window.document.title = pageMetadata.value.title; } else { - document.title = `${pageMetadata.value.title} | ${instanceName}`; + window.document.title = `${pageMetadata.value.title} | ${instanceName}`; } } }); @@ -142,7 +142,7 @@ if (window.innerWidth < 1024) { window.location.reload(); } -document.documentElement.style.overflowY = 'scroll'; +window.document.documentElement.style.overflowY = 'scroll'; onMounted(() => { window.addEventListener('resize', () => { diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index 4c33d7cb27..65aff8455a 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -202,8 +202,8 @@ function onWheel(ev: WheelEvent) { } } -document.documentElement.style.overflowY = 'hidden'; -document.documentElement.style.scrollBehavior = 'auto'; +window.document.documentElement.style.overflowY = 'hidden'; +window.document.documentElement.style.scrollBehavior = 'auto'; async function deleteProfile() { if (prefer.s['deck.profile'] == null) return; diff --git a/packages/frontend/src/ui/minimum.vue b/packages/frontend/src/ui/minimum.vue index 94382b664a..ec20ac1114 100644 --- a/packages/frontend/src/ui/minimum.vue +++ b/packages/frontend/src/ui/minimum.vue @@ -30,9 +30,9 @@ provideMetadataReceiver((metadataGetter) => { pageMetadata.value = info; if (pageMetadata.value) { if (isRoot.value && pageMetadata.value.title === instanceName) { - document.title = pageMetadata.value.title; + window.document.title = pageMetadata.value.title; } else { - document.title = `${pageMetadata.value.title} | ${instanceName}`; + window.document.title = `${pageMetadata.value.title} | ${instanceName}`; } } }); diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue index 92b5d253d3..2742b4cd98 100644 --- a/packages/frontend/src/ui/universal.vue +++ b/packages/frontend/src/ui/universal.vue @@ -143,9 +143,9 @@ provideMetadataReceiver((metadataGetter) => { pageMetadata.value = info; if (pageMetadata.value) { if (isRoot.value && pageMetadata.value.title === instanceName) { - document.title = pageMetadata.value.title; + window.document.title = pageMetadata.value.title; } else { - document.title = `${pageMetadata.value.title} | ${instanceName}`; + window.document.title = `${pageMetadata.value.title} | ${instanceName}`; } } }); @@ -205,12 +205,12 @@ provide>(CURRENT_STICKY_BOTTOM, navFooterHeight); watch(navFooter, () => { if (navFooter.value) { navFooterHeight.value = navFooter.value.offsetHeight; - document.body.style.setProperty('--MI-stickyBottom', `${navFooterHeight.value}px`); - document.body.style.setProperty('--MI-minBottomSpacing', 'var(--MI-minBottomSpacingMobile)'); + window.document.body.style.setProperty('--MI-stickyBottom', `${navFooterHeight.value}px`); + window.document.body.style.setProperty('--MI-minBottomSpacing', 'var(--MI-minBottomSpacingMobile)'); } else { navFooterHeight.value = 0; - document.body.style.setProperty('--MI-stickyBottom', '0px'); - document.body.style.setProperty('--MI-minBottomSpacing', '0px'); + window.document.body.style.setProperty('--MI-stickyBottom', '0px'); + window.document.body.style.setProperty('--MI-minBottomSpacing', '0px'); } }, { immediate: true, diff --git a/packages/frontend/src/ui/visitor.vue b/packages/frontend/src/ui/visitor.vue index ddc3761b04..3e07959458 100644 --- a/packages/frontend/src/ui/visitor.vue +++ b/packages/frontend/src/ui/visitor.vue @@ -51,9 +51,9 @@ provideMetadataReceiver((metadataGetter) => { pageMetadata.value = info; if (pageMetadata.value) { if (isRoot.value && pageMetadata.value.title === instanceName) { - document.title = pageMetadata.value.title; + window.document.title = pageMetadata.value.title; } else { - document.title = `${pageMetadata.value.title} | ${instanceName}`; + window.document.title = `${pageMetadata.value.title} | ${instanceName}`; } } }); diff --git a/packages/frontend/src/ui/zen.vue b/packages/frontend/src/ui/zen.vue index bfb2ef634b..3e4d452281 100644 --- a/packages/frontend/src/ui/zen.vue +++ b/packages/frontend/src/ui/zen.vue @@ -45,9 +45,9 @@ provideMetadataReceiver((metadataGetter) => { pageMetadata.value = info; if (pageMetadata.value) { if (isRoot.value && pageMetadata.value.title === instanceName) { - document.title = pageMetadata.value.title; + window.document.title = pageMetadata.value.title; } else { - document.title = `${pageMetadata.value.title} | ${instanceName}`; + window.document.title = `${pageMetadata.value.title} | ${instanceName}`; } } }); diff --git a/packages/frontend/src/use/use-note-capture.ts b/packages/frontend/src/use/use-note-capture.ts index 0de2dbb3c5..97aec4c1f0 100644 --- a/packages/frontend/src/use/use-note-capture.ts +++ b/packages/frontend/src/use/use-note-capture.ts @@ -86,7 +86,7 @@ export function useNoteCapture(props: { function capture(withHandler = false): void { if (connection) { // TODO: このノートがストリーミング経由で流れてきた場合のみ sr する - connection.send(document.body.contains(props.rootEl.value ?? null as Node | null) ? 'sr' : 's', { id: note.value.id }); + connection.send(window.document.body.contains(props.rootEl.value ?? null as Node | null) ? 'sr' : 's', { id: note.value.id }); if (pureNote.value.id !== note.value.id) connection.send('s', { id: pureNote.value.id }); if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated); } diff --git a/packages/frontend/src/use/use-tooltip.ts b/packages/frontend/src/use/use-tooltip.ts index d9ddfc8b5d..af76a3a1e8 100644 --- a/packages/frontend/src/use/use-tooltip.ts +++ b/packages/frontend/src/use/use-tooltip.ts @@ -29,7 +29,7 @@ export function useTooltip( if (!isHovering) return; if (elRef.value == null) return; const el = elRef.value instanceof Element ? elRef.value : elRef.value.$el; - if (!document.body.contains(el)) return; // openしようとしたときに既に元要素がDOMから消えている場合があるため + if (!window.document.body.contains(el)) return; // openしようとしたときに既に元要素がDOMから消えている場合があるため const showing = ref(true); onShow(showing); @@ -38,7 +38,7 @@ export function useTooltip( }; autoHidingTimer = window.setInterval(() => { - if (elRef.value == null || !document.body.contains(elRef.value instanceof Element ? elRef.value : elRef.value.$el)) { + if (elRef.value == null || !window.document.body.contains(elRef.value instanceof Element ? elRef.value : elRef.value.$el)) { if (!isHovering) return; isHovering = false; window.clearTimeout(timeoutId); diff --git a/packages/frontend/src/utility/focus-trap.ts b/packages/frontend/src/utility/focus-trap.ts index fd17fa38a0..13d3bc56d2 100644 --- a/packages/frontend/src/utility/focus-trap.ts +++ b/packages/frontend/src/utility/focus-trap.ts @@ -50,7 +50,7 @@ function releaseFocusTrap(el: HTMLElement): void { const highestZIndexElement = getHighestZIndexElement(); - if (el.parentElement != null && el !== document.body) { + if (el.parentElement != null && el !== window.document.body) { el.parentElement.childNodes.forEach((siblingNode) => { const siblingEl = getHTMLElementOrNull(siblingNode); if (!siblingEl) return; @@ -104,7 +104,7 @@ export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEl el.inert = false; } - if (el.parentElement != null && el !== document.body) { + if (el.parentElement != null && el !== window.document.body) { el.parentElement.childNodes.forEach((siblingNode) => { const siblingEl = getHTMLElementOrNull(siblingNode); if (!siblingEl) return; diff --git a/packages/frontend/src/utility/focus.ts b/packages/frontend/src/utility/focus.ts index e3fd928d1d..cbbe8226d7 100644 --- a/packages/frontend/src/utility/focus.ts +++ b/packages/frontend/src/utility/focus.ts @@ -58,7 +58,7 @@ export const focusParent = (input: MaybeHTMLElement | null | undefined, self = f const focusOrScroll = (element: HTMLElement, scroll: boolean) => { if (scroll) { - const scrollContainer = getScrollContainer(element) ?? document.documentElement; + const scrollContainer = getScrollContainer(element) ?? window.document.documentElement; const scrollContainerTop = getScrollPosition(scrollContainer); const stickyTop = getStickyTop(element, scrollContainer); const stickyBottom = getStickyBottom(element, scrollContainer); @@ -74,7 +74,7 @@ const focusOrScroll = (element: HTMLElement, scroll: boolean) => { scrollContainer.scrollTo({ top: scrollTo, behavior: 'instant' }); } - if (document.activeElement !== element) { + if (window.document.activeElement !== element) { element.focus({ preventScroll: true }); } }; diff --git a/packages/frontend/src/utility/fullscreen.ts b/packages/frontend/src/utility/fullscreen.ts index 7a0a018ef3..6702393cf1 100644 --- a/packages/frontend/src/utility/fullscreen.ts +++ b/packages/frontend/src/utility/fullscreen.ts @@ -35,8 +35,8 @@ export const requestFullscreen = ({ videoEl, playerEl, options }: RequestFullscr export const exitFullscreen = ({ videoEl }: ExitFullscreenProps) => { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (document.exitFullscreen != null) { - document.exitFullscreen(); + if (window.document.exitFullscreen != null) { + window.document.exitFullscreen(); return; } if (videoEl.webkitExitFullscreen != null) { diff --git a/packages/frontend/src/utility/hotkey.ts b/packages/frontend/src/utility/hotkey.ts index fe62139a74..81fc28d7c8 100644 --- a/packages/frontend/src/utility/hotkey.ts +++ b/packages/frontend/src/utility/hotkey.ts @@ -54,9 +54,9 @@ export const makeHotkey = (keymap: Keymap) => { const actions = parseKeymap(keymap); return (ev: KeyboardEvent) => { if ('pswp' in window && window.pswp != null) return; - if (document.activeElement != null) { - if (IGNORE_ELEMENTS.includes(document.activeElement.tagName.toLowerCase())) return; - if (getHTMLElementOrNull(document.activeElement)?.isContentEditable) return; + if (window.document.activeElement != null) { + if (IGNORE_ELEMENTS.includes(window.document.activeElement.tagName.toLowerCase())) return; + if (getHTMLElementOrNull(window.document.activeElement)?.isContentEditable) return; } for (const action of actions) { if (matchPatterns(ev, action)) { diff --git a/packages/frontend/src/utility/init-chart.ts b/packages/frontend/src/utility/init-chart.ts index 9775b9fec4..260899c1d7 100644 --- a/packages/frontend/src/utility/init-chart.ts +++ b/packages/frontend/src/utility/init-chart.ts @@ -50,7 +50,7 @@ export function initChart() { ); // フォントカラー - Chart.defaults.color = getComputedStyle(document.documentElement).getPropertyValue('--MI_THEME-fg'); + Chart.defaults.color = getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-fg'); Chart.defaults.borderColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'; diff --git a/packages/frontend/src/utility/physics.ts b/packages/frontend/src/utility/physics.ts index 8a4e9319b3..5de34fd094 100644 --- a/packages/frontend/src/utility/physics.ts +++ b/packages/frontend/src/utility/physics.ts @@ -28,7 +28,7 @@ export function physics(container: HTMLElement) { // create renderer const render = Matter.Render.create({ engine: engine, - //element: document.getElementById('debug'), + //element: window.document.getElementById('debug'), options: { width: containerWidth, height: containerHeight, diff --git a/packages/frontend/src/utility/select-file.ts b/packages/frontend/src/utility/select-file.ts index 1bee4986f6..b9b3687483 100644 --- a/packages/frontend/src/utility/select-file.ts +++ b/packages/frontend/src/utility/select-file.ts @@ -25,7 +25,7 @@ export function chooseFileFromPc( const nameConverter = options?.nameConverter ?? (() => undefined); return new Promise((res, rej) => { - const input = document.createElement('input'); + const input = window.document.createElement('input'); input.type = 'file'; input.multiple = multiple; input.onchange = () => { diff --git a/packages/frontend/src/utility/snowfall-effect.ts b/packages/frontend/src/utility/snowfall-effect.ts index d88bdb6660..5c86969876 100644 --- a/packages/frontend/src/utility/snowfall-effect.ts +++ b/packages/frontend/src/utility/snowfall-effect.ts @@ -156,7 +156,7 @@ export class SnowfallEffect { easing: 0.0005, }; /** - * @throws {Error} - Thrown when it fails to get WebGL context for the canvas + * @throws {Error} - Thrown when it fails to get WebGL context for the canvas */ constructor(options: { sakura?: boolean; @@ -172,7 +172,7 @@ export class SnowfallEffect { const gl = canvas.getContext('webgl2', { antialias: true }); if (gl == null) throw new Error('Failed to get WebGL context'); - document.body.append(canvas); + window.document.body.append(canvas); this.canvas = canvas; this.gl = gl; @@ -190,7 +190,7 @@ export class SnowfallEffect { } private initCanvas(): HTMLCanvasElement { - const canvas = document.createElement('canvas'); + const canvas = window.document.createElement('canvas'); Object.assign(canvas.style, { position: 'fixed', diff --git a/packages/frontend/src/utility/sound.ts b/packages/frontend/src/utility/sound.ts index 120f480b63..796af0e5ca 100644 --- a/packages/frontend/src/utility/sound.ts +++ b/packages/frontend/src/utility/sound.ts @@ -226,7 +226,7 @@ export function createSourceNode(buffer: AudioBuffer, opts: { * @param file ファイルのURL(ドライブIDではない) */ export async function getSoundDuration(file: string): Promise { - const audioEl = document.createElement('audio'); + const audioEl = window.document.createElement('audio'); audioEl.src = file; return new Promise((resolve) => { const si = setInterval(() => { @@ -249,7 +249,7 @@ export function isMute(): boolean { } // noinspection RedundantIfStatementJS - if (prefer.s['sound.useSoundOnlyWhenActive'] && document.visibilityState === 'hidden') { + if (prefer.s['sound.useSoundOnlyWhenActive'] && window.document.visibilityState === 'hidden') { // ブラウザがアクティブな時のみサウンドを出力する return true; } diff --git a/packages/frontend/src/utility/sticky-sidebar.ts b/packages/frontend/src/utility/sticky-sidebar.ts index 50f1e6ecc8..867c9b8324 100644 --- a/packages/frontend/src/utility/sticky-sidebar.ts +++ b/packages/frontend/src/utility/sticky-sidebar.ts @@ -18,7 +18,7 @@ export class StickySidebar { this.container = container; this.el = this.container.children[0] as HTMLElement; this.el.style.position = 'sticky'; - this.spacer = document.createElement('div'); + this.spacer = window.document.createElement('div'); this.container.prepend(this.spacer); this.marginTop = marginTop; this.offsetTop = this.container.getBoundingClientRect().top; diff --git a/packages/frontend/src/utility/upload/isWebpSupported.ts b/packages/frontend/src/utility/upload/isWebpSupported.ts index 2511236ecc..affd81fd57 100644 --- a/packages/frontend/src/utility/upload/isWebpSupported.ts +++ b/packages/frontend/src/utility/upload/isWebpSupported.ts @@ -6,7 +6,7 @@ let isWebpSupportedCache: boolean | undefined; export function isWebpSupported() { if (isWebpSupportedCache === undefined) { - const canvas = document.createElement('canvas'); + const canvas = window.document.createElement('canvas'); canvas.width = 1; canvas.height = 1; isWebpSupportedCache = canvas.toDataURL('image/webp').startsWith('data:image/webp'); diff --git a/packages/frontend/src/widgets/WidgetRss.vue b/packages/frontend/src/widgets/WidgetRss.vue index a7213f4c21..132eb0a629 100644 --- a/packages/frontend/src/widgets/WidgetRss.vue +++ b/packages/frontend/src/widgets/WidgetRss.vue @@ -77,7 +77,7 @@ const fetchEndpoint = computed(() => { const intervalClear = ref<(() => void) | undefined>(); const tick = () => { - if (document.visibilityState === 'hidden' && rawItems.value.length !== 0) return; + if (window.document.visibilityState === 'hidden' && rawItems.value.length !== 0) return; window.fetch(fetchEndpoint.value, {}) .then(res => res.json()) diff --git a/packages/frontend/src/widgets/WidgetRssTicker.vue b/packages/frontend/src/widgets/WidgetRssTicker.vue index 13b76533d7..b5be4d35c2 100644 --- a/packages/frontend/src/widgets/WidgetRssTicker.vue +++ b/packages/frontend/src/widgets/WidgetRssTicker.vue @@ -108,7 +108,7 @@ const intervalClear = ref<(() => void) | undefined>(); const key = ref(0); const tick = () => { - if (document.visibilityState === 'hidden' && rawItems.value.length !== 0) return; + if (window.document.visibilityState === 'hidden' && rawItems.value.length !== 0) return; window.fetch(fetchEndpoint.value, {}) .then(res => res.json()) diff --git a/packages/frontend/test/scroll.test.ts b/packages/frontend/test/scroll.test.ts index 32a5a1c558..34e7e64313 100644 --- a/packages/frontend/test/scroll.test.ts +++ b/packages/frontend/test/scroll.test.ts @@ -12,10 +12,10 @@ describe('Scroll', () => { /* 動作しない(happy-domのバグ?) test('Initial onScrollTop callback for connected elements', () => { const { document } = new Window(); - const div = document.createElement('div'); + const div = window.document.createElement('div'); assert.strictEqual(div.scrollTop, 0); - document.body.append(div); + window.document.body.append(div); let called = false; onScrollTop(div as any as HTMLElement, () => called = true); @@ -26,7 +26,7 @@ describe('Scroll', () => { test('No onScrollTop callback for disconnected elements', () => { const { document } = new Window(); - const div = document.createElement('div'); + const div = window.document.createElement('div'); assert.strictEqual(div.scrollTop, 0); let called = false; @@ -40,10 +40,10 @@ describe('Scroll', () => { /* 動作しない(happy-domのバグ?) test('Initial onScrollBottom callback for connected elements', () => { const { document } = new Window(); - const div = document.createElement('div'); + const div = window.document.createElement('div'); assert.strictEqual(div.scrollTop, 0); - document.body.append(div); + window.document.body.append(div); let called = false; onScrollBottom(div as any as HTMLElement, () => called = true); @@ -54,7 +54,7 @@ describe('Scroll', () => { test('No onScrollBottom callback for disconnected elements', () => { const { document } = new Window(); - const div = document.createElement('div'); + const div = window.document.createElement('div'); assert.strictEqual(div.scrollTop, 0); let called = false; From ebc54b1f82454f8bd7b05c54dd9f59b215655a11 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 20 Mar 2025 10:07:37 +0000 Subject: [PATCH 69/75] Bump version to 2025.3.2-beta.7 --- package.json | 2 +- packages/misskey-js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 51422b3638..e8993af22c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2025.3.2-beta.6", + "version": "2025.3.2-beta.7", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index b66f202876..47848f37fd 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2025.3.2-beta.6", + "version": "2025.3.2-beta.7", "description": "Misskey SDK for JavaScript", "license": "MIT", "main": "./built/index.js", From 1fd87bd2e46eb50f718f95f94d844fe694e43a53 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 20 Mar 2025 20:28:16 +0900 Subject: [PATCH 70/75] fix(frontend): prevent transition glitch of MkHorizontalSwipe --- .../src/components/MkHorizontalSwipe.vue | 6 +-- packages/frontend/src/pages/channel.vue | 8 +-- packages/frontend/src/pages/channels.vue | 10 ++-- packages/frontend/src/pages/drive.file.vue | 4 +- packages/frontend/src/pages/explore.vue | 6 +-- .../frontend/src/pages/flash/flash-index.vue | 6 +-- .../frontend/src/pages/follow-requests.vue | 52 +++++++++---------- packages/frontend/src/pages/gallery/index.vue | 6 +-- packages/frontend/src/pages/instance-info.vue | 12 ++--- .../frontend/src/pages/my-clips/index.vue | 4 +- packages/frontend/src/pages/notifications.vue | 8 +-- packages/frontend/src/pages/pages.vue | 6 +-- packages/frontend/src/pages/search.vue | 4 +- packages/frontend/src/pages/timeline.vue | 4 +- packages/frontend/src/pages/user/index.vue | 24 ++++----- 15 files changed, 79 insertions(+), 81 deletions(-) diff --git a/packages/frontend/src/components/MkHorizontalSwipe.vue b/packages/frontend/src/components/MkHorizontalSwipe.vue index 849136eb8f..bc63bef0b6 100644 --- a/packages/frontend/src/components/MkHorizontalSwipe.vue +++ b/packages/frontend/src/components/MkHorizontalSwipe.vue @@ -19,9 +19,9 @@ SPDX-License-Identifier: AGPL-3.0-only :leaveToClass="transitionName === 'swipeAnimationLeft' ? $style.swipeAnimationLeft_leaveTo : $style.swipeAnimationRight_leaveTo" :style="`--swipe: ${pullDistance}px;`" > - - - +
+ +
diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index 1419e83df7..cd66140bf2 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
{{ i18n.ts.thisChannelArchived }} @@ -41,10 +41,10 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
-
+
diff --git a/packages/frontend/src/pages/channels.vue b/packages/frontend/src/pages/channels.vue index cf047fcd5d..79d264944a 100644 --- a/packages/frontend/src/pages/channels.vue +++ b/packages/frontend/src/pages/channels.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
@@ -25,28 +25,28 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
-
+
-
+
-
+
diff --git a/packages/frontend/src/pages/drive.file.vue b/packages/frontend/src/pages/drive.file.vue index ecc1117da9..3063d5a4d6 100644 --- a/packages/frontend/src/pages/drive.file.vue +++ b/packages/frontend/src/pages/drive.file.vue @@ -10,11 +10,11 @@ SPDX-License-Identifier: AGPL-3.0-only - + - + diff --git a/packages/frontend/src/pages/explore.vue b/packages/frontend/src/pages/explore.vue index b76f6a6033..794af86e43 100644 --- a/packages/frontend/src/pages/explore.vue +++ b/packages/frontend/src/pages/explore.vue @@ -7,13 +7,13 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
-
+
-
+
diff --git a/packages/frontend/src/pages/flash/flash-index.vue b/packages/frontend/src/pages/flash/flash-index.vue index 6aee91dfda..fedb2de8fe 100644 --- a/packages/frontend/src/pages/flash/flash-index.vue +++ b/packages/frontend/src/pages/flash/flash-index.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue index 1ea501c34c..95f6ba0bc6 100644 --- a/packages/frontend/src/pages/follow-requests.vue +++ b/packages/frontend/src/pages/follow-requests.vue @@ -8,36 +8,34 @@ SPDX-License-Identifier: AGPL-3.0-only -
- - - + diff --git a/packages/frontend/src/pages/gallery/index.vue b/packages/frontend/src/pages/gallery/index.vue index 04445c913c..9a09250bff 100644 --- a/packages/frontend/src/pages/gallery/index.vue +++ b/packages/frontend/src/pages/gallery/index.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
@@ -26,14 +26,14 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
-
+
{{ i18n.ts.postToGallery }}
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue index c4aed8d6df..3f704e2b88 100644 --- a/packages/frontend/src/pages/instance-info.vue +++ b/packages/frontend/src/pages/instance-info.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
{{ instance.name || `(${i18n.ts.unknown})` }} @@ -91,7 +91,7 @@ SPDX-License-Identifier: AGPL-3.0-only manifest.json
-
+
@@ -116,14 +116,14 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
-
+
@@ -135,8 +135,9 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/components/index.ts b/packages/frontend/src/components/index.ts index c28c457e33..6c6903c3a4 100644 --- a/packages/frontend/src/components/index.ts +++ b/packages/frontend/src/components/index.ts @@ -25,6 +25,8 @@ import MkPageHeader from './global/MkPageHeader.vue'; import MkSpacer from './global/MkSpacer.vue'; import MkStickyContainer from './global/MkStickyContainer.vue'; import MkLazy from './global/MkLazy.vue'; +import PageWithHeader from './global/PageWithHeader.vue'; +import PageWithAnimBg from './global/PageWithAnimBg.vue'; import SearchMarker from './global/SearchMarker.vue'; import SearchLabel from './global/SearchLabel.vue'; import SearchKeyword from './global/SearchKeyword.vue'; @@ -60,6 +62,8 @@ export const components = { MkSpacer: MkSpacer, MkStickyContainer: MkStickyContainer, MkLazy: MkLazy, + PageWithHeader: PageWithHeader, + PageWithAnimBg: PageWithAnimBg, SearchMarker: SearchMarker, SearchLabel: SearchLabel, SearchKeyword: SearchKeyword, @@ -89,6 +93,8 @@ declare module '@vue/runtime-core' { MkSpacer: typeof MkSpacer; MkStickyContainer: typeof MkStickyContainer; MkLazy: typeof MkLazy; + PageWithHeader: typeof PageWithHeader; + PageWithAnimBg: typeof PageWithAnimBg; SearchMarker: typeof SearchMarker; SearchLabel: typeof SearchLabel; SearchKeyword: typeof SearchKeyword; diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index 2d0135e6a6..481088fc30 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue index cad5f2e109..b684d4b68b 100644 --- a/packages/frontend/src/pages/page.vue +++ b/packages/frontend/src/pages/page.vue @@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only -->