Merge branch 'update-mfm-core' into mk.absturztau.be

This commit is contained in:
Puniko 2023-05-21 18:46:11 +02:00
commit 6809d45f4b
5 changed files with 61 additions and 33 deletions

View file

@ -67,7 +67,7 @@
"koa-send": "5.0.1", "koa-send": "5.0.1",
"koa-slow": "2.1.0", "koa-slow": "2.1.0",
"koa-views": "7.0.2", "koa-views": "7.0.2",
"mfm-js": "0.22.1", "mfm-js": "0.23.3",
"mime-types": "2.1.35", "mime-types": "2.1.35",
"mocha": "10.2.0", "mocha": "10.2.0",
"multer": "1.4.5-lts.1", "multer": "1.4.5-lts.1",

View file

@ -34,7 +34,7 @@
"json5": "2.2.1", "json5": "2.2.1",
"katex": "0.16.0", "katex": "0.16.0",
"matter-js": "0.18.0", "matter-js": "0.18.0",
"mfm-js": "0.22.1", "mfm-js": "0.23.3",
"photoswipe": "5.2.8", "photoswipe": "5.2.8",
"prismjs": "1.28.0", "prismjs": "1.28.0",
"punycode": "2.1.1", "punycode": "2.1.1",

View file

@ -10,7 +10,6 @@ import MkSearch from '@/components/mfm-search.vue';
import MkSparkle from '@/components/sparkle.vue'; import MkSparkle from '@/components/sparkle.vue';
import MkA from '@/components/global/a.vue'; import MkA from '@/components/global/a.vue';
import { host } from '@/config'; import { host } from '@/config';
import { MFM_TAGS } from '@/scripts/mfm-tags';
export default defineComponent({ export default defineComponent({
props: { props: {
@ -37,12 +36,16 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
rootScale: {
type: Number,
default: 1
}
}, },
render() { render() {
if (this.text == null || this.text === '') return; if (this.text == null || this.text === '') return;
const ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text, { fnNameList: MFM_TAGS }); const ast = (this.plain ? mfm.parseSimple : mfm.parse)(this.text);
const validTime = (t: string | true) => { const validTime = (t: string | true) => {
if (typeof t !== 'string') return null; if (typeof t !== 'string') return null;
@ -50,7 +53,7 @@ export default defineComponent({
return t.match(/^[0-9.]+s$/) ? t : null; return t.match(/^[0-9.]+s$/) ? t : null;
}; };
const genEl = (ast: mfm.MfmNode[]) => ast.map((token): VNode | VNode[] => { const genEl = (ast: mfm.MfmNode[], scale: Number) => ast.map((token): VNode | VNode[] => {
switch (token.type) { switch (token.type) {
case 'text': { case 'text': {
const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n'); const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
@ -69,17 +72,17 @@ export default defineComponent({
} }
case 'bold': { case 'bold': {
return h('b', genEl(token.children)); return h('b', genEl(token.children, scale));
} }
case 'strike': { case 'strike': {
return h('del', genEl(token.children)); return h('del', genEl(token.children, scale));
} }
case 'italic': { case 'italic': {
return h('i', { return h('i', {
style: 'font-style: oblique;', style: 'font-style: oblique;',
}, genEl(token.children)); }, genEl(token.children, scale));
} }
case 'fn': { case 'fn': {
@ -139,18 +142,18 @@ export default defineComponent({
} }
case 'x2': { case 'x2': {
return h('span', { return h('span', {
class: 'mfm-x2', class: 'mfm-x2'
}, genEl(token.children)); }, genEl(token.children, scale * 2));
} }
case 'x3': { case 'x3': {
return h('span', { return h('span', {
class: 'mfm-x3', class: 'mfm-x3'
}, genEl(token.children)); }, genEl(token.children, scale * 3));
} }
case 'x4': { case 'x4': {
return h('span', { return h('span', {
class: 'mfm-x4', class: 'mfm-x4'
}, genEl(token.children)); }, genEl(token.children, scale * 4));
} }
case 'font': { case 'font': {
const family = const family =
@ -167,7 +170,7 @@ export default defineComponent({
case 'blur': { case 'blur': {
return h('span', { return h('span', {
class: '_mfm_blur_', class: '_mfm_blur_',
}, genEl(token.children)); }, genEl(token.children, scale));
} }
case 'rainbow': { case 'rainbow': {
const speed = validTime(token.props.args.speed) || '1s'; const speed = validTime(token.props.args.speed) || '1s';
@ -176,35 +179,60 @@ export default defineComponent({
} }
case 'sparkle': { case 'sparkle': {
if (!this.$store.state.animatedMfm) { if (!this.$store.state.animatedMfm) {
return genEl(token.children); return genEl(token.children, scale);
} }
return h(MkSparkle, {}, genEl(token.children)); return h(MkSparkle, {}, genEl(token.children, scale));
} }
case 'rotate': { case 'rotate': {
const degrees = (typeof token.props.args.deg === 'string' ? parseInt(token.props.args.deg) : null) || '90'; const degrees = (typeof token.props.args.deg === 'string' ? parseInt(token.props.args.deg) : null) || '90';
style = `transform: rotate(${degrees}deg); transform-origin: center center;`; style = `transform: rotate(${degrees}deg); transform-origin: center center;`;
break; break;
} }
case 'position': {
const x = parseFloat(token.props.args.x ?? '0');
const y = parseFloat(token.props.args.y ?? '0');
style = `transform: translateX(${x}em) translateY(${y}em);`;
break;
}
case 'scale': {
const x = Math.min(parseFloat(token.props.args.x ?? '1'), 5);
const y = Math.min(parseFloat(token.props.args.y ?? '1'), 5);
style = `transform: scale(${x}, ${y});`;
scale = scale * Math.max(x, y);
break;
}
case 'fg': {
let color = token.props.args.color;
if (!/^[0-9a-f]{3,6}$/i.test(color)) color = 'f00';
style = `color: #${color};`;
break;
}
case 'bg': {
let color = token.props.args.color;
if (!/^[0-9a-f]{3,6}$/i.test(color)) color = 'f00';
style = `background-color: #${color};`;
break;
}
} }
if (style == null) { if (style == null) {
return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children), ']']); return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children, scale), ']']);
} else { } else {
return h('span', { return h('span', {
style: 'display: inline-block;' + style, style: 'display: inline-block;' + style,
}, genEl(token.children)); }, genEl(token.children, scale));
} }
} }
case 'small': { case 'small': {
return h('small', { return h('small', {
class: '_mfm_small_' class: '_mfm_small_'
}, genEl(token.children)); }, genEl(token.children, scale));
} }
case 'center': { case 'center': {
return h('div', { return h('div', {
style: 'text-align:center;', style: 'text-align:center;',
}, genEl(token.children)); }, genEl(token.children, scale));
} }
case 'url': { case 'url': {
@ -220,7 +248,7 @@ export default defineComponent({
key: Math.random(), key: Math.random(),
url: token.props.url, url: token.props.url,
rel: 'nofollow noopener', rel: 'nofollow noopener',
}, genEl(token.children)); }, genEl(token.children, scale));
} }
case 'mention': { case 'mention': {
@ -258,7 +286,7 @@ export default defineComponent({
case 'quote': { case 'quote': {
return h(this.nowrap ? 'span' : 'div', { return h(this.nowrap ? 'span' : 'div', {
class: 'quote', class: 'quote',
}, genEl(token.children)); }, genEl(token.children, scale));
} }
case 'emojiCode': { case 'emojiCode': {
@ -311,6 +339,6 @@ export default defineComponent({
}).flat(); }).flat();
// Parse ast to DOM // Parse ast to DOM
return h('span', genEl(ast)); return h('span', genEl(ast, this.rootScale ?? 1));
}, },
}); });

View file

@ -1 +1 @@
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'font', 'blur', 'rainbow', 'sparkle', 'rotate']; export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'position', 'scale', 'fg', 'bg'];

View file

@ -3750,7 +3750,7 @@ __metadata:
koa-send: 5.0.1 koa-send: 5.0.1
koa-slow: 2.1.0 koa-slow: 2.1.0
koa-views: 7.0.2 koa-views: 7.0.2
mfm-js: 0.22.1 mfm-js: 0.23.3
mime-types: 2.1.35 mime-types: 2.1.35
mocha: 10.2.0 mocha: 10.2.0
multer: 1.4.5-lts.1 multer: 1.4.5-lts.1
@ -4720,7 +4720,7 @@ __metadata:
json5: 2.2.1 json5: 2.2.1
katex: 0.16.0 katex: 0.16.0
matter-js: 0.18.0 matter-js: 0.18.0
mfm-js: 0.22.1 mfm-js: 0.23.3
photoswipe: 5.2.8 photoswipe: 5.2.8
prismjs: 1.28.0 prismjs: 1.28.0
punycode: 2.1.1 punycode: 2.1.1
@ -11671,12 +11671,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mfm-js@npm:0.22.1": "mfm-js@npm:0.23.3":
version: 0.22.1 version: 0.23.3
resolution: "mfm-js@npm:0.22.1" resolution: "mfm-js@npm:0.23.3"
dependencies: dependencies:
twemoji-parser: 14.0.x twemoji-parser: 14.0.0
checksum: 6d9756c7bd8abf6462fb6403de4656f607a83839eb6b66a05b10eddcd201b5f78f5fe3d0df029936546143fd9cbf112e8369287aed32026e50bb03ce89b4c4f8 checksum: 7079f80a53a9afc8599333f3256fb18a6bf7c01102a2f8f2be657843726a34835e2af34e26bc5b27e45b217fb2f120c0d3006e9fab2a972c845e9f7361e3cc1b
languageName: node languageName: node
linkType: hard linkType: hard
@ -16723,7 +16723,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"twemoji-parser@npm:14.0.0, twemoji-parser@npm:14.0.x": "twemoji-parser@npm:14.0.0":
version: 14.0.0 version: 14.0.0
resolution: "twemoji-parser@npm:14.0.0" resolution: "twemoji-parser@npm:14.0.0"
checksum: 8eede69cf71f94735de7b6fddf5dfbfe3cb2e01baefc3201360984ccc97cfc659f206c8f73bd1405a2282779af3b79a8c9bed3864c672e15e2dc6f8ce4810452 checksum: 8eede69cf71f94735de7b6fddf5dfbfe3cb2e01baefc3201360984ccc97cfc659f206c8f73bd1405a2282779af3b79a8c9bed3864c672e15e2dc6f8ce4810452