diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts index 50a566d331..5282bffdef 100644 --- a/packages/client/src/components/mfm.ts +++ b/packages/client/src/components/mfm.ts @@ -57,6 +57,12 @@ export default defineComponent({ if (t == null) return null; return t.match(/^[0-9.]+s$/) ? t : null; }; + + const validNumber = (n: string | null | undefined) => { + if (n == null) return null; + const parsed = parseFloat(n); + return !isNaN(parsed) && isFinite(parsed) && parsed > 0; + }; // const validEase = (e: string | null | undefined) => { // if (e == null) return null; // return e.match(/(steps)?\(-?[0-9.]+,-?[0-9.]+,-?[0-9.]+,-?[0-9.]+\)/) @@ -109,26 +115,30 @@ export default defineComponent({ case "tada": { const speed = validTime(token.props.args.speed) || "1s"; const delay = validTime(token.props.args.delay) || "0s"; + const loop = validNumber(token.props.args.loop) || "infinite"; // const ease = validEase(token.props.args.ease) || "linear"; - style = `font-size: 150%; animation: tada ${speed} ${delay} linear infinite both;`; + style = `font-size: 150%; animation: tada ${speed} ${delay} linear ${loop} both;`; break; } case "jelly": { const speed = validTime(token.props.args.speed) || "1s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-rubberBand ${speed} ${delay} linear infinite both;`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-rubberBand ${speed} ${delay} linear ${loop} both;`; break; } case "twitch": { const speed = validTime(token.props.args.speed) || "0.5s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-twitch ${speed} ${delay} ease infinite;`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-twitch ${speed} ${delay} ease ${loop};`; break; } case "shake": { const speed = validTime(token.props.args.speed) || "0.5s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-shake ${speed} ${delay} ease infinite;`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-shake ${speed} ${delay} ease ${loop};`; break; } case "spin": { @@ -144,25 +154,29 @@ export default defineComponent({ : "mfm-spin"; const speed = validTime(token.props.args.speed) || "1.5s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: ${anime} ${speed} ${delay} linear infinite; animation-direction: ${direction};`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: ${anime} ${speed} ${delay} linear ${loop}; animation-direction: ${direction};`; break; } case "jump": { const speed = validTime(token.props.args.speed) || "0.75s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-jump ${speed} ${delay} linear infinite;`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-jump ${speed} ${delay} linear ${loop};`; break; } case "bounce": { const speed = validTime(token.props.args.speed) || "0.75s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-bounce ${speed} ${delay} linear infinite; transform-origin: center bottom;`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-bounce ${speed} ${delay} linear ${loop}; transform-origin: center bottom;`; break; } case "rainbow": { const speed = validTime(token.props.args.speed) || "1s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-rainbow ${speed} ${delay} linear infinite;`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-rainbow ${speed} ${delay} linear ${loop};`; break; } case "sparkle": { @@ -177,7 +191,8 @@ export default defineComponent({ : "alternate"; const speed = validTime(token.props.args.speed) || "1.5s"; const delay = validTime(token.props.args.delay) || "0s"; - style = `animation: mfm-fade ${speed} ${delay} linear infinite; animation-direction: ${direction};`; + const loop = validNumber(token.props.args.loop) || "infinite"; + style = `animation: mfm-fade ${speed} ${delay} linear ${loop}; animation-direction: ${direction};`; break; } case "flip": { diff --git a/packages/client/src/pages/mfm-cheat-sheet.vue b/packages/client/src/pages/mfm-cheat-sheet.vue index 046231dbc0..dd01ec8526 100644 --- a/packages/client/src/pages/mfm-cheat-sheet.vue +++ b/packages/client/src/pages/mfm-cheat-sheet.vue @@ -472,14 +472,14 @@ let preview_quote = $ref(`> ${i18n.ts._mfm.dummy}`); let preview_search = $ref( `${i18n.ts._mfm.dummy} [search]\n${i18n.ts._mfm.dummy} [ๆคœ็ดข]\n${i18n.ts._mfm.dummy} ๆคœ็ดข` ); -let preview_jelly = $ref("$[jelly ๐Ÿฎ] $[jelly.speed=3s ๐Ÿฎ] $[jelly.delay=3s ๐Ÿฎ]"); -let preview_tada = $ref("$[tada ๐Ÿฎ] $[tada.speed=3s ๐Ÿฎ] $[tada.delay=3s ๐Ÿฎ]"); -let preview_jump = $ref("$[jump ๐Ÿฎ] $[jump.speed=3s ๐Ÿฎ] $[jump.delay=3s ๐Ÿฎ]"); -let preview_bounce = $ref("$[bounce ๐Ÿฎ] $[bounce.speed=3s ๐Ÿฎ] $[bounce.delay=3s ๐Ÿฎ]"); -let preview_shake = $ref("$[shake ๐Ÿฎ] $[shake.speed=3s ๐Ÿฎ] $[shake.delay=3s ๐Ÿฎ]"); -let preview_twitch = $ref("$[twitch ๐Ÿฎ] $[twitch.speed=3s ๐Ÿฎ] $[twitch.delay=3s ๐Ÿฎ]"); +let preview_jelly = $ref("$[jelly ๐Ÿฎ] $[jelly.speed=3s ๐Ÿฎ] $[jelly.delay=3s ๐Ÿฎ] $[jelly.loop=3 ๐Ÿฎ]"); +let preview_tada = $ref("$[tada ๐Ÿฎ] $[tada.speed=3s ๐Ÿฎ] $[tada.delay=3s ๐Ÿฎ] $[tada.loop=3 ๐Ÿฎ]"); +let preview_jump = $ref("$[jump ๐Ÿฎ] $[jump.speed=3s ๐Ÿฎ] $[jump.delay=3s ๐Ÿฎ] $[jump.loop=3 ๐Ÿฎ]"); +let preview_bounce = $ref("$[bounce ๐Ÿฎ] $[bounce.speed=3s ๐Ÿฎ] $[bounce.delay=3s ๐Ÿฎ] $[bounce.loop=3 ๐Ÿฎ]"); +let preview_shake = $ref("$[shake ๐Ÿฎ] $[shake.speed=3s ๐Ÿฎ] $[shake.delay=3s ๐Ÿฎ] $[shake.loop=3 ๐Ÿฎ]"); +let preview_twitch = $ref("$[twitch ๐Ÿฎ] $[twitch.speed=3s ๐Ÿฎ] $[twitch.delay=3s ๐Ÿฎ] $[twitch.loop=3 ๐Ÿฎ]"); let preview_spin = $ref( - "$[spin ๐Ÿฎ] $[spin.left ๐Ÿฎ] $[spin.alternate ๐Ÿฎ]\n$[spin.x ๐Ÿฎ] $[spin.x,left ๐Ÿฎ] $[spin.x,alternate ๐Ÿฎ]\n$[spin.y ๐Ÿฎ] $[spin.y,left ๐Ÿฎ] $[spin.y,alternate ๐Ÿฎ]\n\n$[spin.speed=3s ๐Ÿฎ] $[spin.delay=3s ๐Ÿฎ]" + "$[spin ๐Ÿฎ] $[spin.left ๐Ÿฎ] $[spin.alternate ๐Ÿฎ]\n$[spin.x ๐Ÿฎ] $[spin.x,left ๐Ÿฎ] $[spin.x,alternate ๐Ÿฎ]\n$[spin.y ๐Ÿฎ] $[spin.y,left ๐Ÿฎ] $[spin.y,alternate ๐Ÿฎ]\n\n$[spin.speed=3s ๐Ÿฎ] $[spin.delay=3s ๐Ÿฎ] $[spin.loop=3 ๐Ÿฎ]" ); let preview_flip = $ref( `$[flip ${i18n.ts._mfm.dummy}]\n$[flip.v ${i18n.ts._mfm.dummy}]\n$[flip.h,v ${i18n.ts._mfm.dummy}]` @@ -491,7 +491,7 @@ let preview_x2 = $ref("$[x2 ๐Ÿฎ]"); let preview_x3 = $ref("$[x3 ๐Ÿฎ]"); let preview_x4 = $ref("$[x4 ๐Ÿฎ]"); let preview_blur = $ref(`$[blur ${i18n.ts._mfm.dummy}]`); -let preview_rainbow = $ref("$[rainbow ๐Ÿฎ] $[rainbow.speed=3s ๐Ÿฎ] $[rainbow.delay=3s ๐Ÿฎ]"); +let preview_rainbow = $ref("$[rainbow ๐Ÿฎ] $[rainbow.speed=3s ๐Ÿฎ] $[rainbow.delay=3s ๐Ÿฎ] $[rainbow.loop=3 ๐Ÿฎ]"); let preview_sparkle = $ref("$[sparkle ๐Ÿฎ]"); let preview_rotate = $ref( "$[rotate ๐Ÿฎ]\n$[rotate.deg=45 ๐Ÿฎ]\n$[rotate.x,deg=45 Hello, world!]"