diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 97f1f0b593..b3e3f41d09 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -29,6 +29,7 @@ "@vue/compiler-sfc": "3.3.5", "astring": "1.8.6", "autosize": "6.0.1", + "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.4", "broadcast-channel": "5.5.0", "browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3", "buraha": "0.0.1", @@ -60,6 +61,7 @@ "rollup": "4.1.4", "sanitize-html": "2.11.0", "sass": "1.69.4", + "shiki": "^0.14.5", "strict-event-emitter-types": "2.0.0", "textarea-caret": "3.1.0", "three": "0.157.0", diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue index a1300be1f6..bc627bff58 100644 --- a/packages/frontend/src/components/MkCode.core.vue +++ b/packages/frontend/src/components/MkCode.core.vue @@ -5,21 +5,65 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/components/MkCode.vue b/packages/frontend/src/components/MkCode.vue index 8972b1863b..b39e6ff23c 100644 --- a/packages/frontend/src/components/MkCode.vue +++ b/packages/frontend/src/components/MkCode.vue @@ -4,11 +4,18 @@ SPDX-License-Identifier: AGPL-3.0-only --> + + diff --git a/packages/frontend/src/pages/flash/flash.vue b/packages/frontend/src/pages/flash/flash.vue index 32a835831c..ebf117ffbf 100644 --- a/packages/frontend/src/pages/flash/flash.vue +++ b/packages/frontend/src/pages/flash/flash.vue @@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
diff --git a/packages/frontend/src/pages/settings/plugin.vue b/packages/frontend/src/pages/settings/plugin.vue index 4a2d8d600e..100f122840 100644 --- a/packages/frontend/src/pages/settings/plugin.vue +++ b/packages/frontend/src/pages/settings/plugin.vue @@ -50,7 +50,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.copy }}
- + diff --git a/packages/frontend/src/scripts/code-highlighter.ts b/packages/frontend/src/scripts/code-highlighter.ts new file mode 100644 index 0000000000..07a6ba2913 --- /dev/null +++ b/packages/frontend/src/scripts/code-highlighter.ts @@ -0,0 +1,29 @@ +import { setWasm, setCDN, Highlighter, getHighlighter as _getHighlighter } from 'shiki'; + +setWasm('/assets/shiki/dist/onig.wasm'); +setCDN('/assets/shiki/'); + +let _highlighter: Highlighter; + +export async function getHighlighter() { + if (!_highlighter) { + await initHighlighter(); + } + return _highlighter; +} + +export async function initHighlighter() { + const highlighter = await _getHighlighter({ + theme: 'dark-plus', + langs: ['js'], + }); + + await highlighter.loadLanguage({ + path: 'languages/aiscript.tmLanguage.json', + id: 'aiscript', + scopeName: 'source.aiscript', + aliases: ['is', 'ais'], + }); + + _highlighter = highlighter; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26e5d05a8c..02d9fc3bbb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -673,6 +673,9 @@ importers: '@vue/compiler-sfc': specifier: 3.3.5 version: 3.3.5 + aiscript-vscode: + specifier: github:aiscript-dev/aiscript-vscode#v0.0.4 + version: github.com/aiscript-dev/aiscript-vscode/fb6534cc7984c28b02c511c07c2dc4b9ef1b71b3 astring: specifier: 1.8.6 version: 1.8.6 @@ -772,6 +775,9 @@ importers: sass: specifier: 1.69.4 version: 1.69.4 + shiki: + specifier: ^0.14.5 + version: 0.14.5 strict-event-emitter-types: specifier: 2.0.0 version: 2.0.0 @@ -871,10 +877,10 @@ importers: version: 7.5.1 '@storybook/vue3': specifier: 7.5.1 - version: 7.5.1(@vue/compiler-core@3.3.4)(vue@3.3.5) + version: 7.5.1(@vue/compiler-core@3.3.5)(vue@3.3.5) '@storybook/vue3-vite': specifier: 7.5.1 - version: 7.5.1(@vue/compiler-core@3.3.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.5) + version: 7.5.1(@vue/compiler-core@3.3.5)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.5) '@testing-library/vue': specifier: 7.0.0 version: 7.0.0(@vue/compiler-sfc@3.3.5)(vue@3.3.5) @@ -979,7 +985,7 @@ importers: version: 7.5.1 storybook-addon-misskey-theme: specifier: github:misskey-dev/storybook-addon-misskey-theme - version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.5.1)(@storybook/components@7.5.0)(@storybook/core-events@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/theming@7.5.1)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0) + version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.5.1)(@storybook/components@7.5.1)(@storybook/core-events@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/theming@7.5.1)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0) summaly: specifier: github:misskey-dev/summaly version: github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7 @@ -6368,17 +6374,6 @@ packages: - supports-color dev: true - /@storybook/channels@7.5.0: - resolution: {integrity: sha512-/7QJS1UA7TX3uhZqCpjv4Ib8nfMnDOJrBWvjiXiUONaRcSk/he5X+W1Zz/c7dgt+wkYuAh+evjc7glIaBhVNVQ==} - dependencies: - '@storybook/client-logger': 7.5.0 - '@storybook/core-events': 7.5.0 - '@storybook/global': 5.0.0 - qs: 6.11.1 - telejson: 7.2.0 - tiny-invariant: 1.3.1 - dev: true - /@storybook/channels@7.5.1: resolution: {integrity: sha512-7hTGHqvtdFTqRx8LuCznOpqPBYfUeMUt/0IIp7SFuZT585yMPxrYoaK//QmLEWnPb80B8HVTSQi7caUkJb32LA==} dependencies: @@ -6442,12 +6437,6 @@ packages: - utf-8-validate dev: true - /@storybook/client-logger@7.5.0: - resolution: {integrity: sha512-JV7J9vc69f9Il4uW62NIeweUU7O38VwFWxtCkhd0bcBA/9RG0go4M2avzxYYEAe9kIOX9IBBk8WGzMacwW4gKQ==} - dependencies: - '@storybook/global': 5.0.0 - dev: true - /@storybook/client-logger@7.5.1: resolution: {integrity: sha512-XxbLvg0aQRoBrzxYLcVYCbjDkGbkU8Rfb74XbV2CLiO2bIbFPmA1l1Nwbp+wkCGA+O6Z1zwzSl6wcKKqZ6XZCg==} dependencies: @@ -6475,29 +6464,6 @@ packages: - supports-color dev: true - /@storybook/components@7.5.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-6lmZ6PbS27xN32vTJ/NvgaiKkFIQRzZuBeBIg2u+FoAEgCiCwRXjZKe/O8NZC2Xr0uf97+7U2P0kD4Hwr9SNhw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@radix-ui/react-select': 1.2.2(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-toolbar': 1.0.4(react-dom@18.2.0)(react@18.2.0) - '@storybook/client-logger': 7.5.0 - '@storybook/csf': 0.1.0 - '@storybook/global': 5.0.0 - '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.5.0 - memoizerific: 1.11.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0) - util-deprecate: 1.0.2 - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - dev: true - /@storybook/components@7.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-fdzzxGBV/Fj9pYwfYL3RZsVUHeBqlfLMBP/L6mPmjaZSwHFqkaRZZUajZc57lCtI+TOy2gY6WH3cPavEtqtgLw==} peerDependencies: @@ -6559,12 +6525,6 @@ packages: - supports-color dev: true - /@storybook/core-events@7.5.0: - resolution: {integrity: sha512-FsD+clTzayqprbVllnL8LLch+uCslJFDgsv7Zh99/zoi7OHtHyauoCZkdLBSiDzgc84qS41dY19HqX1/y7cnOw==} - dependencies: - ts-dedent: 2.2.0 - dev: true - /@storybook/core-events@7.5.1: resolution: {integrity: sha512-2eyaUhTfmEEqOEZVoCXVITCBn6N7QuZCG2UNxv0l//ED+7MuMiFhVw7kS7H3WOVk65R7gb8qbKFTNX8HFTgBHg==} dependencies: @@ -6897,20 +6857,6 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/theming@7.5.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-uTo97oh+pvmlfsZocFq5qae0zGo0VGk7oiBqNSSw6CiTqE1rIuSxoPrMAY+oCTWCUZV7DjONIGvpnGl2QALsAw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) - '@storybook/client-logger': 7.5.0 - '@storybook/global': 5.0.0 - memoizerific: 1.11.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - dev: true - /@storybook/theming@7.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ETLAOn10hI4Mkmjsr0HGcM6HbzaURrrPBYmfXOrdbrzEVN+AHW4FlvP9d8fYyP1gdjPE1F39XvF0jYgt1zXiHQ==} peerDependencies: @@ -6925,15 +6871,6 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/types@7.5.0: - resolution: {integrity: sha512-fiOUnHKFi/UZSfvc53F0WEQCiquqcSqslL3f5EffwQRiXfeXlGavJb0kU03BO+CvOXcliRn6qKSF2dL0Rgb7Xw==} - dependencies: - '@storybook/channels': 7.5.0 - '@types/babel__core': 7.20.0 - '@types/express': 4.17.17 - file-system-cache: 2.3.0 - dev: true - /@storybook/types@7.5.1: resolution: {integrity: sha512-ZcMSaqFNx1E+G00nRDUi8kKL7gxJVlnCvbKLNj3V85guy4DkIYAZr31yDqze07gDWbjvKoHIp3tKpgE+2i8upQ==} dependencies: @@ -6943,7 +6880,7 @@ packages: file-system-cache: 2.3.0 dev: true - /@storybook/vue3-vite@7.5.1(@vue/compiler-core@3.3.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.5): + /@storybook/vue3-vite@7.5.1(@vue/compiler-core@3.3.5)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.5): resolution: {integrity: sha512-5bO5BactTbyOxxeRw8U6t3FqqfTvVLTefzg1NLDkKt2iAL6lGBSsPTKMgpy3dt+cxdiqEis67niQL68ZtW02Zw==} engines: {node: ^14.18 || >=16} peerDependencies: @@ -6953,7 +6890,7 @@ packages: dependencies: '@storybook/builder-vite': 7.5.1(typescript@5.2.2)(vite@4.5.0) '@storybook/core-server': 7.5.1 - '@storybook/vue3': 7.5.1(@vue/compiler-core@3.3.4)(vue@3.3.5) + '@storybook/vue3': 7.5.1(@vue/compiler-core@3.3.5)(vue@3.3.5) '@vitejs/plugin-vue': 4.4.0(vite@4.5.0)(vue@3.3.5) magic-string: 0.30.3 react: 18.2.0 @@ -6972,7 +6909,7 @@ packages: - vue dev: true - /@storybook/vue3@7.5.1(@vue/compiler-core@3.3.4)(vue@3.3.5): + /@storybook/vue3@7.5.1(@vue/compiler-core@3.3.5)(vue@3.3.5): resolution: {integrity: sha512-9srw2rnSYaU45kkunXT8+bX3QMO2QPV6MCWRayKo7Pl+B0H/euHvxPSZb1X8mRpgLtYgVgSNJFoNbk/2Fn8z8g==} engines: {node: '>=16.0.0'} peerDependencies: @@ -6984,7 +6921,7 @@ packages: '@storybook/global': 5.0.0 '@storybook/preview-api': 7.5.1 '@storybook/types': 7.5.1 - '@vue/compiler-core': 3.3.4 + '@vue/compiler-core': 3.3.5 lodash: 4.17.21 ts-dedent: 2.2.0 type-fest: 2.19.0 @@ -8422,15 +8359,6 @@ packages: postcss: 8.4.31 source-map-js: 1.0.2 - /@vue/compiler-ssr@3.3.4: - resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} - requiresBuild: true - dependencies: - '@vue/compiler-dom': 3.3.4 - '@vue/shared': 3.3.4 - dev: true - optional: true - /@vue/compiler-ssr@3.3.5: resolution: {integrity: sha512-v7p2XuEpOcgjd6c49NqOnq3UTJOv5Uo9tirOyGnEadwxTov2O1J3/TUt4SgAAnwA+9gcUyH5c3lIOFsBe+UIyw==} dependencies: @@ -8489,17 +8417,6 @@ packages: '@vue/shared': 3.3.5 csstype: 3.1.2 - /@vue/server-renderer@3.3.4(vue@3.3.5): - resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} - peerDependencies: - vue: 3.3.4 - dependencies: - '@vue/compiler-ssr': 3.3.4 - '@vue/shared': 3.3.4 - vue: 3.3.5(typescript@5.2.2) - dev: true - optional: true - /@vue/server-renderer@3.3.5(vue@3.3.5): resolution: {integrity: sha512-7VIZkohYn8GAnNT9chrm0vDpHJ6mWPL+TmUBKtDWcWxYcq33YJP/VHCPQN5TazkxXCtv3c1KfXAMZowX4giLoQ==} peerDependencies: @@ -8523,8 +8440,8 @@ packages: js-beautify: 1.14.6 vue: 3.3.5(typescript@5.2.2) optionalDependencies: - '@vue/compiler-dom': 3.3.4 - '@vue/server-renderer': 3.3.4(vue@3.3.5) + '@vue/compiler-dom': 3.3.5 + '@vue/server-renderer': 3.3.5(vue@3.3.5) dev: true /@vue/typescript@1.8.19(typescript@5.2.2): @@ -8748,6 +8665,10 @@ packages: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} + /ansi-sequence-parser@1.1.1: + resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} + dev: false + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -13981,7 +13902,6 @@ packages: /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -17513,6 +17433,15 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + /shiki@0.14.5: + resolution: {integrity: sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==} + dependencies: + ansi-sequence-parser: 1.1.1 + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + dev: false + /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: @@ -19265,6 +19194,14 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + /vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + dev: false + + /vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + dev: false + /vue-component-type-helpers@1.8.19: resolution: {integrity: sha512-1OANGSZK4pzHF4uc86usWi+o5Y0zgoDtqWkPg6Am6ot+jHSAmpOah59V/4N82So5xRgivgCxGgK09lBy1XNUfQ==} dev: true @@ -19798,6 +19735,13 @@ packages: readable-stream: 3.6.0 dev: false + github.com/aiscript-dev/aiscript-vscode/fb6534cc7984c28b02c511c07c2dc4b9ef1b71b3: + resolution: {tarball: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/fb6534cc7984c28b02c511c07c2dc4b9ef1b71b3} + name: aiscript-vscode + version: 0.0.4 + engines: {vscode: ^1.83.0} + dev: false + github.com/misskey-dev/browser-image-resizer/0227e860621e55cbed0aabe6dc601096a7748c4a: resolution: {tarball: https://codeload.github.com/misskey-dev/browser-image-resizer/tar.gz/0227e860621e55cbed0aabe6dc601096a7748c4a} name: browser-image-resizer @@ -19814,7 +19758,7 @@ packages: sharp: 0.31.3 dev: false - github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.5.1)(@storybook/components@7.5.0)(@storybook/core-events@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/theming@7.5.1)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0): + github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.5.1)(@storybook/components@7.5.1)(@storybook/core-events@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/theming@7.5.1)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0): resolution: {tarball: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640} id: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640 name: storybook-addon-misskey-theme @@ -19836,7 +19780,7 @@ packages: optional: true dependencies: '@storybook/blocks': 7.5.1(react-dom@18.2.0)(react@18.2.0) - '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/components': 7.5.1(react-dom@18.2.0)(react@18.2.0) '@storybook/core-events': 7.5.1 '@storybook/manager-api': 7.5.1(react-dom@18.2.0)(react@18.2.0) '@storybook/preview-api': 7.5.1 diff --git a/scripts/build-assets.mjs b/scripts/build-assets.mjs index a8a2cafa5f..47b74604b6 100644 --- a/scripts/build-assets.mjs +++ b/scripts/build-assets.mjs @@ -33,6 +33,13 @@ async function copyFrontendLocales() { } } +async function copyFrontendShikiAssets() { + await fs.cp('./packages/frontend/node_modules/shiki/dist', './built/_frontend_dist_/shiki/dist', { dereference: true, recursive: true }); + await fs.cp('./packages/frontend/node_modules/shiki/languages', './built/_frontend_dist_/shiki/languages', { dereference: true, recursive: true }); + await fs.cp('./packages/frontend/node_modules/aiscript-vscode/aiscript/syntaxes', './built/_frontend_dist_/shiki/languages', { dereference: true, recursive: true }); + await fs.cp('./packages/frontend/node_modules/shiki/themes', './built/_frontend_dist_/shiki/themes', { dereference: true, recursive: true }); +} + async function copyBackendViews() { await fs.cp('./packages/backend/src/server/web/views', './packages/backend/built/server/web/views', { recursive: true }); } @@ -71,7 +78,8 @@ async function build() { await Promise.all([ copyFrontendFonts(), copyFrontendTablerIcons(), - copyFrontendLocales(), + copyFrontendLocales(), + copyFrontendShikiAssets(), copyBackendViews(), buildBackendScript(), buildBackendStyle(),