fix(frontend): MFMパース時に意図せずnyaizeされる問題を修正 (#12161)
* Update MkMisskeyFlavoredMarkdown.ts * Update MkMisskeyFlavoredMarkdown.ts * Update MkMisskeyFlavoredMarkdown.ts * Update MkNote.vue * (fix) にゃいずをノートでのみ適用 * fix * Fix lint
This commit is contained in:
parent
a8dc6d08b1
commit
481db8aba4
|
@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
|
<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
|
||||||
<MkAvatar :class="$style.collapsedRenoteTargetAvatar" :user="appearNote.user" link preview/>
|
<MkAvatar :class="$style.collapsedRenoteTargetAvatar" :user="appearNote.user" link preview/>
|
||||||
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :class="$style.collapsedRenoteTargetText" @click="renoteCollapsed = false"/>
|
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :nyaize="'account'" :class="$style.collapsedRenoteTargetText" @click="renoteCollapsed = false"/>
|
||||||
</div>
|
</div>
|
||||||
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
||||||
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
||||||
|
@ -53,19 +53,19 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
<MkInstanceTicker v-if="showTicker" :instance="appearNote.user.instance"/>
|
||||||
<div style="container-type: inline-size;">
|
<div style="container-type: inline-size;">
|
||||||
<p v-if="appearNote.cw != null" :class="$style.cw">
|
<p v-if="appearNote.cw != null" :class="$style.cw">
|
||||||
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :i="$i"/>
|
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :nyaize="'account'" :i="$i"/>
|
||||||
<MkCwButton v-model="showContent" :note="appearNote" style="margin: 4px 0;"/>
|
<MkCwButton v-model="showContent" :note="appearNote" style="margin: 4px 0;"/>
|
||||||
</p>
|
</p>
|
||||||
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
|
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
|
||||||
<div :class="$style.text">
|
<div :class="$style.text">
|
||||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||||
<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
||||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :nyaize="'account'" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||||
<div v-if="translating || translation" :class="$style.translation">
|
<div v-if="translating || translation" :class="$style.translation">
|
||||||
<MkLoading v-if="translating" mini/>
|
<MkLoading v-if="translating" mini/>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
|
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
|
||||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
<Mfm :text="translation.text" :author="appearNote.user" :nyaize="'account'" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -67,19 +67,19 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</header>
|
</header>
|
||||||
<div :class="$style.noteContent">
|
<div :class="$style.noteContent">
|
||||||
<p v-if="appearNote.cw != null" :class="$style.cw">
|
<p v-if="appearNote.cw != null" :class="$style.cw">
|
||||||
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :i="$i"/>
|
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :nyaize="'account'" :i="$i"/>
|
||||||
<MkCwButton v-model="showContent" :note="appearNote"/>
|
<MkCwButton v-model="showContent" :note="appearNote"/>
|
||||||
</p>
|
</p>
|
||||||
<div v-show="appearNote.cw == null || showContent">
|
<div v-show="appearNote.cw == null || showContent">
|
||||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
||||||
<MkA v-if="appearNote.replyId" :class="$style.noteReplyTarget" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
<MkA v-if="appearNote.replyId" :class="$style.noteReplyTarget" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
||||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :nyaize="'account'" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||||
<a v-if="appearNote.renote != null" :class="$style.rn">RN:</a>
|
<a v-if="appearNote.renote != null" :class="$style.rn">RN:</a>
|
||||||
<div v-if="translating || translation" :class="$style.translation">
|
<div v-if="translating || translation" :class="$style.translation">
|
||||||
<MkLoading v-if="translating" mini/>
|
<MkLoading v-if="translating" mini/>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
|
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
|
||||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
|
<Mfm :text="translation.text" :author="appearNote.user" :nyaize="'account'" :i="$i" :emojiUrls="appearNote.emojis"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="appearNote.files.length > 0">
|
<div v-if="appearNote.files.length > 0">
|
||||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<Mfm :text="text.trim()" :author="user" :i="user"/>
|
<Mfm :text="text.trim()" :author="user" :nyaize="'account'" :i="user"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkNoteHeader :class="$style.header" :note="note" :mini="true"/>
|
<MkNoteHeader :class="$style.header" :note="note" :mini="true"/>
|
||||||
<div>
|
<div>
|
||||||
<p v-if="note.cw != null" :class="$style.cw">
|
<p v-if="note.cw != null" :class="$style.cw">
|
||||||
<Mfm v-if="note.cw != ''" style="margin-right: 8px;" :text="note.cw" :author="note.user" :i="$i" :emojiUrls="note.emojis"/>
|
<Mfm v-if="note.cw != ''" style="margin-right: 8px;" :text="note.cw" :author="note.user" :nyaize="'account'" :i="$i" :emojiUrls="note.emojis"/>
|
||||||
<MkCwButton v-model="showContent" :note="note"/>
|
<MkCwButton v-model="showContent" :note="note"/>
|
||||||
</p>
|
</p>
|
||||||
<div v-show="note.cw == null || showContent">
|
<div v-show="note.cw == null || showContent">
|
||||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkNoteHeader :class="$style.header" :note="note" :mini="true"/>
|
<MkNoteHeader :class="$style.header" :note="note" :mini="true"/>
|
||||||
<div>
|
<div>
|
||||||
<p v-if="note.cw != null" :class="$style.cw">
|
<p v-if="note.cw != null" :class="$style.cw">
|
||||||
<Mfm v-if="note.cw != ''" style="margin-right: 8px;" :text="note.cw" :author="note.user" :i="$i"/>
|
<Mfm v-if="note.cw != ''" style="margin-right: 8px;" :text="note.cw" :author="note.user" :nyaize="'account'" :i="$i"/>
|
||||||
<MkCwButton v-model="showContent" :note="note"/>
|
<MkCwButton v-model="showContent" :note="note"/>
|
||||||
</p>
|
</p>
|
||||||
<div v-show="note.cw == null || showContent">
|
<div v-show="note.cw == null || showContent">
|
||||||
|
|
|
@ -17,7 +17,7 @@ import MkSparkle from '@/components/MkSparkle.vue';
|
||||||
import MkA from '@/components/global/MkA.vue';
|
import MkA from '@/components/global/MkA.vue';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@/config.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import { nyaize } from '@/scripts/nyaize.js';
|
import { nyaize as doNyaize } from '@/scripts/nyaize.js';
|
||||||
|
|
||||||
const QUOTE_STYLE = `
|
const QUOTE_STYLE = `
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -28,21 +28,27 @@ border-left: solid 3px var(--fg);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
`.split('\n').join(' ');
|
`.split('\n').join(' ');
|
||||||
|
|
||||||
export default function(props: {
|
type MfmProps = {
|
||||||
text: string;
|
text: string;
|
||||||
plain?: boolean;
|
plain?: boolean;
|
||||||
nowrap?: boolean;
|
nowrap?: boolean;
|
||||||
author?: Misskey.entities.UserLite;
|
author?: Misskey.entities.UserLite;
|
||||||
i?: Misskey.entities.UserLite;
|
i?: Misskey.entities.UserLite | null;
|
||||||
isNote?: boolean;
|
isNote?: boolean;
|
||||||
emojiUrls?: string[];
|
emojiUrls?: string[];
|
||||||
rootScale?: number;
|
rootScale?: number;
|
||||||
}) {
|
nyaize: boolean | 'account';
|
||||||
const isNote = props.isNote !== undefined ? props.isNote : true;
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
export default function(props: MfmProps) {
|
||||||
|
const isNote = props.isNote ?? true;
|
||||||
|
const shouldNyaize = props.nyaize ? props.nyaize === 'account' ? props.author?.isCat : false : false;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (props.text == null || props.text === '') return;
|
if (props.text == null || props.text === '') return;
|
||||||
|
|
||||||
const ast = (props.plain ? mfm.parseSimple : mfm.parse)(props.text);
|
const rootAst = (props.plain ? mfm.parseSimple : mfm.parse)(props.text);
|
||||||
|
|
||||||
const validTime = (t: string | null | undefined) => {
|
const validTime = (t: string | null | undefined) => {
|
||||||
if (t == null) return null;
|
if (t == null) return null;
|
||||||
|
@ -55,13 +61,14 @@ export default function(props: {
|
||||||
* Gen Vue Elements from MFM AST
|
* Gen Vue Elements from MFM AST
|
||||||
* @param ast MFM AST
|
* @param ast MFM AST
|
||||||
* @param scale How times large the text is
|
* @param scale How times large the text is
|
||||||
|
* @param disableNyaize Whether nyaize is disabled or not
|
||||||
*/
|
*/
|
||||||
const genEl = (ast: mfm.MfmNode[], scale: number, disableNyaize = false) => ast.map((token): VNode | string | (VNode | string)[] => {
|
const genEl = (ast: mfm.MfmNode[], scale: number, disableNyaize = false) => ast.map((token): VNode | string | (VNode | string)[] => {
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case 'text': {
|
case 'text': {
|
||||||
let text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
|
let text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
|
||||||
if (!disableNyaize && props.author?.isCat) {
|
if (!disableNyaize && shouldNyaize) {
|
||||||
text = nyaize(text);
|
text = doNyaize(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!props.plain) {
|
if (!props.plain) {
|
||||||
|
@ -377,5 +384,5 @@ export default function(props: {
|
||||||
return h('span', {
|
return h('span', {
|
||||||
// https://codeday.me/jp/qa/20190424/690106.html
|
// https://codeday.me/jp/qa/20190424/690106.html
|
||||||
style: props.nowrap ? 'white-space: pre; word-wrap: normal; overflow: hidden; text-overflow: ellipsis;' : 'white-space: pre-wrap;',
|
style: props.nowrap ? 'white-space: pre; word-wrap: normal; overflow: hidden; text-overflow: ellipsis;' : 'white-space: pre-wrap;',
|
||||||
}, genEl(ast, props.rootScale ?? 1));
|
}, genEl(rootAst, props.rootScale ?? 1));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue