From 582aae64946561b97e3f903e002d2c968b2db466 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 27 Jan 2019 19:32:35 +0900 Subject: [PATCH] [MFM] Resolve #4009 --- CHANGELOG.md | 4 +++ src/client/app/common/views/components/mfm.ts | 9 +++++- src/mfm/parser.ts | 13 +++++++-- test/mfm.ts | 29 ++++++++++++++----- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 606ee7e99..22772636b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ ChangeLog ========= +unreleased +---------- +* MFMで左回転、往復回転を行えるように + 10.79.0 ---------- * 返信するときにCWを維持するかどうか設定できるように diff --git a/src/client/app/common/views/components/mfm.ts b/src/client/app/common/views/components/mfm.ts index 542f1e34c..1cf7752cb 100644 --- a/src/client/app/common/views/components/mfm.ts +++ b/src/client/app/common/views/components/mfm.ts @@ -128,9 +128,16 @@ export default Vue.component('misskey-flavored-markdown', { motionCount++; const isLong = sumTextsLength(token.children) > 5 || countNodesF(token.children) > 3; const isMany = motionCount > 3; + const direction = + token.node.props.attr == 'left' ? 'reverse' : + token.node.props.attr == 'alternate' ? 'alternate' : + 'normal'; + const style = (this.$store.state.settings.disableAnimatedMfm || isLong || isMany) + ? '' + : `animation: spin 1.5s linear infinite; animation-direction: ${direction};`; return (createElement as any)('span', { attrs: { - style: (this.$store.state.settings.disableAnimatedMfm || isLong || isMany) ? 'display: inline-block;' : 'display: inline-block; animation: spin 1.5s linear infinite;' + style: 'display: inline-block;' + style }, }, genEl(token.children)); } diff --git a/src/mfm/parser.ts b/src/mfm/parser.ts index 6b7c3c584..3c917f8d0 100644 --- a/src/mfm/parser.ts +++ b/src/mfm/parser.ts @@ -148,12 +148,21 @@ const mfm = P.createLanguage({ //#region Spin spin: r => - P.regexp(/(.+?)<\/spin>/, 1) + P((input, i) => { + const text = input.substr(i); + const match = text.match(/^(.+?)<\/spin>/i); + if (!match) return P.makeFailure(i, 'not a spin'); + return P.makeSuccess(i + match[0].length, { + content: match[2], attr: match[1] ? match[1].trim() : null + }); + }) .map(x => createTree('spin', P.alt( r.emoji, r.flip, r.text - ).atLeast(1).tryParse(x), {})), + ).atLeast(1).tryParse(x.content), { + attr: x.attr + })), //#endregion //#region Jump diff --git a/test/mfm.ts b/test/mfm.ts index 0d07add0e..a1f83fe1d 100644 --- a/test/mfm.ts +++ b/test/mfm.ts @@ -253,13 +253,28 @@ describe('MFM', () => { ]); }); - it('spin', () => { - const tokens = analyze(':foo:'); - assert.deepStrictEqual(tokens, [ - tree('spin', [ - leaf('emoji', { name: 'foo' }) - ], {}), - ]); + describe('spin', () => { + it('simple', () => { + const tokens = analyze(':foo:'); + assert.deepStrictEqual(tokens, [ + tree('spin', [ + leaf('emoji', { name: 'foo' }) + ], { + attr: null + }), + ]); + }); + + it('with attr', () => { + const tokens = analyze(':foo:'); + assert.deepStrictEqual(tokens, [ + tree('spin', [ + leaf('emoji', { name: 'foo' }) + ], { + attr: 'left' + }), + ]); + }); }); it('jump', () => {