(ApMfmService);
+ });
+
+ describe('getNoteHtml', () => {
+ test('Do not provide _misskey_content for simple text', () => {
+ const note: MiNote = {
+ text: 'テキスト #タグ @mention 🍊 :emoji: https://example.com',
+ mentionedRemoteUsers: '[]',
+ } as any;
+
+ const { content, noMisskeyContent } = apMfmService.getNoteHtml(note);
+
+ assert.equal(noMisskeyContent, true, 'noMisskeyContent');
+ assert.equal(content, 'テキスト #タグ @mention 🍊 :emoji: https://example.com
', 'content');
+ });
+
+ test('Provide _misskey_content for MFM', () => {
+ const note: MiNote = {
+ text: '$[tada foo]',
+ mentionedRemoteUsers: '[]',
+ } as any;
+
+ const { content, noMisskeyContent } = apMfmService.getNoteHtml(note);
+
+ assert.equal(noMisskeyContent, false, 'noMisskeyContent');
+ assert.equal(content, 'foo
', 'content');
+ });
+ });
+});
diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts
index 8f40ae493..b714f2c0f 100644
--- a/packages/backend/test/unit/MfmService.ts
+++ b/packages/backend/test/unit/MfmService.ts
@@ -33,6 +33,12 @@ describe('MfmService', () => {
const output = 'foo
bar
baz
';
assert.equal(mfmService.toHtml(mfm.parse(input)), output);
});
+
+ test('Do not generate unnecessary span', () => {
+ const input = 'foo $[tada bar]';
+ const output = 'foo bar
';
+ assert.equal(mfmService.toHtml(mfm.parse(input)), output);
+ });
});
describe('fromHtml', () => {
diff --git a/packages/frontend/.storybook/mocks.ts b/packages/frontend/.storybook/mocks.ts
index 80e5157c5..f0feff9f7 100644
--- a/packages/frontend/.storybook/mocks.ts
+++ b/packages/frontend/.storybook/mocks.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { type SharedOptions, rest } from 'msw';
+import { type SharedOptions, http, HttpResponse } from 'msw';
export const onUnhandledRequest = ((req, print) => {
if (req.url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emojis?\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(req.url.pathname)) {
@@ -13,19 +13,31 @@ export const onUnhandledRequest = ((req, print) => {
}) satisfies SharedOptions['onUnhandledRequest'];
export const commonHandlers = [
- rest.get('/fluent-emoji/:codepoints.png', async (req, res, ctx) => {
- const { codepoints } = req.params;
+ http.get('/fluent-emoji/:codepoints.png', async ({ params }) => {
+ const { codepoints } = params;
const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob());
- return res(ctx.set('Content-Type', 'image/png'), ctx.body(value));
+ return new HttpResponse(value, {
+ headers: {
+ 'Content-Type': 'image/png',
+ },
+ });
}),
- rest.get('/fluent-emojis/:codepoints.png', async (req, res, ctx) => {
- const { codepoints } = req.params;
+ http.get('/fluent-emojis/:codepoints.png', async ({ params }) => {
+ const { codepoints } = params;
const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob());
- return res(ctx.set('Content-Type', 'image/png'), ctx.body(value));
+ return new HttpResponse(value, {
+ headers: {
+ 'Content-Type': 'image/png',
+ },
+ });
}),
- rest.get('/twemoji/:codepoints.svg', async (req, res, ctx) => {
- const { codepoints } = req.params;
+ http.get('/twemoji/:codepoints.svg', async ({ params }) => {
+ const { codepoints } = params;
const value = await fetch(`https://unpkg.com/@discordapp/twemoji@15.0.2/dist/svg/${codepoints}.svg`).then((response) => response.blob());
- return res(ctx.set('Content-Type', 'image/svg+xml'), ctx.body(value));
+ return new HttpResponse(value, {
+ headers: {
+ 'Content-Type': 'image/svg+xml',
+ },
+ });
}),
];
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 707c15f5c..f5c968ec3 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -30,7 +30,7 @@
"@twemoji/parser": "15.0.0",
"@vitejs/plugin-vue": "5.0.3",
"@vue/compiler-sfc": "3.4.15",
- "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6",
+ "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.2",
"astring": "1.8.6",
"broadcast-channel": "7.0.0",
"buraha": "0.0.1",
@@ -72,7 +72,7 @@
"typescript": "5.3.3",
"uuid": "9.0.1",
"v-code-diff": "1.7.2",
- "vite": "5.0.12",
+ "vite": "5.1.0",
"vue": "3.4.15",
"vuedraggable": "next"
},
@@ -102,7 +102,7 @@
"@types/estree": "1.0.5",
"@types/matter-js": "0.19.6",
"@types/micromatch": "4.0.6",
- "@types/node": "20.11.10",
+ "@types/node": "20.11.17",
"@types/punycode": "2.1.3",
"@types/sanitize-html": "2.9.5",
"@types/throttle-debounce": "5.0.2",
@@ -115,7 +115,7 @@
"@vue/runtime-core": "3.4.15",
"acorn": "8.11.3",
"cross-env": "7.0.3",
- "cypress": "13.6.3",
+ "cypress": "13.6.4",
"eslint": "8.56.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-vue": "9.20.1",
@@ -123,10 +123,10 @@
"happy-dom": "10.0.3",
"intersection-observer": "0.12.2",
"micromatch": "4.0.5",
- "msw": "2.1.2",
- "msw-storybook-addon": "1.10.0",
+ "msw": "2.1.7",
+ "msw-storybook-addon": "2.0.0-beta.1",
"nodemon": "3.0.3",
- "prettier": "3.2.4",
+ "prettier": "3.2.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"start-server-and-test": "2.0.3",
diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts
index f6a3e4030..65bd7cf0f 100644
--- a/packages/frontend/src/boot/common.ts
+++ b/packages/frontend/src/boot/common.ts
@@ -60,12 +60,6 @@ export async function common(createVue: () => App) {
});
}
- const splash = document.getElementById('splash');
- // 念のためnullチェック(HTMLが古い場合があるため(そのうち消す))
- if (splash) splash.addEventListener('transitionend', () => {
- splash.remove();
- });
-
let isClientUpdated = false;
//#region クライアントが更新されたかチェック
@@ -293,5 +287,10 @@ function removeSplash() {
if (splash) {
splash.style.opacity = '0';
splash.style.pointerEvents = 'none';
+
+ // transitionendイベントが発火しない場合があるため
+ window.setTimeout(() => {
+ splash.remove();
+ }, 1000);
}
}
diff --git a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts
index 77e7c84d5..dc2697f25 100644
--- a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts
+++ b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts
@@ -6,7 +6,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { action } from '@storybook/addon-actions';
import { StoryObj } from '@storybook/vue3';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { abuseUserReport } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkAbuseReport from './MkAbuseReport.vue';
@@ -44,9 +44,9 @@ export const Default = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/admin/resolve-abuse-user-report', async (req, res, ctx) => {
- action('POST /api/admin/resolve-abuse-user-report')(await req.json());
- return res(ctx.json({}));
+ http.post('/api/admin/resolve-abuse-user-report', async ({ request }) => {
+ action('POST /api/admin/resolve-abuse-user-report')(await request.json());
+ return HttpResponse.json({});
}),
],
},
diff --git a/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts b/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts
index dc842b3d1..771452cb5 100644
--- a/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts
+++ b/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts
@@ -6,7 +6,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { action } from '@storybook/addon-actions';
import { StoryObj } from '@storybook/vue3';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { userDetailed } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkAbuseReportWindow from './MkAbuseReportWindow.vue';
@@ -44,9 +44,9 @@ export const Default = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/users/report-abuse', async (req, res, ctx) => {
- action('POST /api/users/report-abuse')(await req.json());
- return res(ctx.json({}));
+ http.post('/api/users/report-abuse', async ({ request }) => {
+ action('POST /api/users/report-abuse')(await request.json());
+ return HttpResponse.json({});
}),
],
},
diff --git a/packages/frontend/src/components/MkAchievements.stories.impl.ts b/packages/frontend/src/components/MkAchievements.stories.impl.ts
index 6d972467b..81e9529de 100644
--- a/packages/frontend/src/components/MkAchievements.stories.impl.ts
+++ b/packages/frontend/src/components/MkAchievements.stories.impl.ts
@@ -5,7 +5,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { StoryObj } from '@storybook/vue3';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { userDetailed } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkAchievements from './MkAchievements.vue';
@@ -39,8 +39,8 @@ export const Empty = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/users/achievements', (req, res, ctx) => {
- return res(ctx.json([]));
+ http.post('/api/users/achievements', () => {
+ return HttpResponse.json([]);
}),
],
},
@@ -52,8 +52,8 @@ export const All = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/users/achievements', (req, res, ctx) => {
- return res(ctx.json(ACHIEVEMENT_TYPES.map((name) => ({ name, unlockedAt: 0 }))));
+ http.post('/api/users/achievements', () => {
+ return HttpResponse.json(ACHIEVEMENT_TYPES.map((name) => ({ name, unlockedAt: 0 })));
}),
],
},
diff --git a/packages/frontend/src/components/MkAutocomplete.stories.impl.ts b/packages/frontend/src/components/MkAutocomplete.stories.impl.ts
index 969519386..3ca8c5b86 100644
--- a/packages/frontend/src/components/MkAutocomplete.stories.impl.ts
+++ b/packages/frontend/src/components/MkAutocomplete.stories.impl.ts
@@ -8,7 +8,7 @@ import { action } from '@storybook/addon-actions';
import { expect } from '@storybook/jest';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { userDetailed } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkAutocomplete from './MkAutocomplete.vue';
@@ -99,11 +99,11 @@ export const User = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/users/search-by-username-and-host', (req, res, ctx) => {
- return res(ctx.json([
+ http.post('/api/users/search-by-username-and-host', () => {
+ return HttpResponse.json([
userDetailed('44', 'mizuki', 'misskey-hub.net', 'Mizuki'),
userDetailed('49', 'momoko', 'misskey-hub.net', 'Momoko'),
- ]));
+ ]);
}),
],
},
@@ -132,12 +132,12 @@ export const Hashtag = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/hashtags/search', (req, res, ctx) => {
- return res(ctx.json([
+ http.post('/api/hashtags/search', () => {
+ return HttpResponse.json([
'気象警報注意報',
'気象警報',
'気象情報',
- ]));
+ ]);
}),
],
},
diff --git a/packages/frontend/src/components/MkAvatars.stories.impl.ts b/packages/frontend/src/components/MkAvatars.stories.impl.ts
index d41b64695..a9b4540ca 100644
--- a/packages/frontend/src/components/MkAvatars.stories.impl.ts
+++ b/packages/frontend/src/components/MkAvatars.stories.impl.ts
@@ -5,7 +5,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { StoryObj } from '@storybook/vue3';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { userDetailed } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkAvatars from './MkAvatars.vue';
@@ -38,12 +38,12 @@ export const Default = {
msw: {
handlers: [
...commonHandlers,
- rest.post('/api/users/show', (req, res, ctx) => {
- return res(ctx.json([
+ http.post('/api/users/show', () => {
+ return HttpResponse.json([
userDetailed('17'),
userDetailed('20'),
userDetailed('18'),
- ]));
+ ]);
}),
],
},
diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue
index b06bb70e9..5ad5892b7 100644
--- a/packages/frontend/src/components/MkCode.core.vue
+++ b/packages/frontend/src/components/MkCode.core.vue
@@ -5,14 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+