summaryrefslogtreecommitdiff
path: root/src/mfm
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-11-12 02:02:25 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-11-12 02:02:25 +0900
commit0e4a111f81cceed275d9bec2695f6e401fb654d8 (patch)
tree40874799472fa07416f17b50a398ac33b7771905 /src/mfm
parentupdate deps (diff)
downloadmisskey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.gz
misskey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.bz2
misskey-0e4a111f81cceed275d9bec2695f6e401fb654d8.zip
refactoring
Resolve #7779
Diffstat (limited to 'src/mfm')
-rw-r--r--src/mfm/fn-name-list.ts23
-rw-r--r--src/mfm/from-html.ts209
-rw-r--r--src/mfm/to-html.ts159
3 files changed, 0 insertions, 391 deletions
diff --git a/src/mfm/fn-name-list.ts b/src/mfm/fn-name-list.ts
deleted file mode 100644
index 1203bfffde..0000000000
--- a/src/mfm/fn-name-list.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// NOTE: client/components/autocomplete.vueにも関数のリスト(MFM_TAGS)があるので統合?
-
-const fnNameList = [
- 'tada',
- 'jelly',
- 'twitch',
- 'shake',
- 'spin',
- 'jump',
- 'bounce',
- 'flip',
- 'x2',
- 'x3',
- 'x4',
- 'font',
- 'blur',
- 'rainbow',
- 'sparkle',
-];
-
-export {
- fnNameList
-};
diff --git a/src/mfm/from-html.ts b/src/mfm/from-html.ts
deleted file mode 100644
index de6aa3d0cc..0000000000
--- a/src/mfm/from-html.ts
+++ /dev/null
@@ -1,209 +0,0 @@
-import * as parse5 from 'parse5';
-import treeAdapter = require('parse5/lib/tree-adapters/default');
-import { URL } from 'url';
-
-const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
-const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/;
-
-export function fromHtml(html: string, hashtagNames?: string[]): string | null {
- if (html == null) return null;
-
- const dom = parse5.parseFragment(html);
-
- let text = '';
-
- for (const n of dom.childNodes) {
- analyze(n);
- }
-
- return text.trim();
-
- function getText(node: parse5.Node): string {
- if (treeAdapter.isTextNode(node)) return node.value;
- if (!treeAdapter.isElementNode(node)) return '';
- if (node.nodeName === 'br') return '\n';
-
- if (node.childNodes) {
- return node.childNodes.map(n => getText(n)).join('');
- }
-
- return '';
- }
-
- function appendChildren(childNodes: parse5.ChildNode[]): void {
- if (childNodes) {
- for (const n of childNodes) {
- analyze(n);
- }
- }
- }
-
- function analyze(node: parse5.Node) {
- if (treeAdapter.isTextNode(node)) {
- text += node.value;
- return;
- }
-
- // Skip comment or document type node
- if (!treeAdapter.isElementNode(node)) return;
-
- switch (node.nodeName) {
- case 'br':
- text += '\n';
- break;
-
- case 'a':
- {
- const txt = getText(node);
- const rel = node.attrs.find(x => x.name === 'rel');
- const href = node.attrs.find(x => x.name === 'href');
-
- // ハッシュタグ
- if (hashtagNames && href && hashtagNames.map(x => x.toLowerCase()).includes(txt.toLowerCase())) {
- text += txt;
- // メンション
- } else if (txt.startsWith('@') && !(rel && rel.value.match(/^me /))) {
- const part = txt.split('@');
-
- if (part.length === 2 && href) {
- //#region ホスト名部分が省略されているので復元する
- const acct = `${txt}@${(new URL(href.value)).hostname}`;
- text += acct;
- //#endregion
- } else if (part.length === 3) {
- text += txt;
- }
- // その他
- } else {
- const generateLink = () => {
- if (!href && !txt) {
- return '';
- }
- if (!href) {
- return txt;
- }
- if (!txt || txt === href.value) { // #6383: Missing text node
- if (href.value.match(urlRegexFull)) {
- return href.value;
- } else {
- return `<${href.value}>`;
- }
- }
- if (href.value.match(urlRegex) && !href.value.match(urlRegexFull)) {
- return `[${txt}](<${href.value}>)`; // #6846
- } else {
- return `[${txt}](${href.value})`;
- }
- };
-
- text += generateLink();
- }
- break;
- }
-
- case 'h1':
- {
- text += '【';
- appendChildren(node.childNodes);
- text += '】\n';
- break;
- }
-
- case 'b':
- case 'strong':
- {
- text += '**';
- appendChildren(node.childNodes);
- text += '**';
- break;
- }
-
- case 'small':
- {
- text += '<small>';
- appendChildren(node.childNodes);
- text += '</small>';
- break;
- }
-
- case 's':
- case 'del':
- {
- text += '~~';
- appendChildren(node.childNodes);
- text += '~~';
- break;
- }
-
- case 'i':
- case 'em':
- {
- text += '<i>';
- appendChildren(node.childNodes);
- text += '</i>';
- break;
- }
-
- // block code (<pre><code>)
- case 'pre': {
- if (node.childNodes.length === 1 && node.childNodes[0].nodeName === 'code') {
- text += '\n```\n';
- text += getText(node.childNodes[0]);
- text += '\n```\n';
- } else {
- appendChildren(node.childNodes);
- }
- break;
- }
-
- // inline code (<code>)
- case 'code': {
- text += '`';
- appendChildren(node.childNodes);
- text += '`';
- break;
- }
-
- case 'blockquote': {
- const t = getText(node);
- if (t) {
- text += '> ';
- text += t.split('\n').join(`\n> `);
- }
- break;
- }
-
- case 'p':
- case 'h2':
- case 'h3':
- case 'h4':
- case 'h5':
- case 'h6':
- {
- text += '\n\n';
- appendChildren(node.childNodes);
- break;
- }
-
- // other block elements
- case 'div':
- case 'header':
- case 'footer':
- case 'article':
- case 'li':
- case 'dt':
- case 'dd':
- {
- text += '\n';
- appendChildren(node.childNodes);
- break;
- }
-
- default: // includes inline elements
- {
- appendChildren(node.childNodes);
- break;
- }
- }
- }
-}
diff --git a/src/mfm/to-html.ts b/src/mfm/to-html.ts
deleted file mode 100644
index b3678a0dda..0000000000
--- a/src/mfm/to-html.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-import { JSDOM } from 'jsdom';
-import * as mfm from 'mfm-js';
-import config from '@/config/index';
-import { intersperse } from '@/prelude/array';
-import { IMentionedRemoteUsers } from '@/models/entities/note';
-import { wellKnownServices } from '../well-known-services';
-
-export function toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMentionedRemoteUsers = []) {
- if (nodes == null) {
- return null;
- }
-
- const { window } = new JSDOM('');
-
- const doc = window.document;
-
- function appendChildren(children: mfm.MfmNode[], targetElement: any): void {
- if (children) {
- for (const child of children.map(x => (handlers as any)[x.type](x))) targetElement.appendChild(child);
- }
- }
-
- const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => any } = {
- bold(node) {
- const el = doc.createElement('b');
- appendChildren(node.children, el);
- return el;
- },
-
- small(node) {
- const el = doc.createElement('small');
- appendChildren(node.children, el);
- return el;
- },
-
- strike(node) {
- const el = doc.createElement('del');
- appendChildren(node.children, el);
- return el;
- },
-
- italic(node) {
- const el = doc.createElement('i');
- appendChildren(node.children, el);
- return el;
- },
-
- fn(node) {
- const el = doc.createElement('i');
- appendChildren(node.children, el);
- return el;
- },
-
- blockCode(node) {
- const pre = doc.createElement('pre');
- const inner = doc.createElement('code');
- inner.textContent = node.props.code;
- pre.appendChild(inner);
- return pre;
- },
-
- center(node) {
- const el = doc.createElement('div');
- appendChildren(node.children, el);
- return el;
- },
-
- emojiCode(node) {
- return doc.createTextNode(`\u200B:${node.props.name}:\u200B`);
- },
-
- unicodeEmoji(node) {
- return doc.createTextNode(node.props.emoji);
- },
-
- hashtag(node) {
- const a = doc.createElement('a');
- a.href = `${config.url}/tags/${node.props.hashtag}`;
- a.textContent = `#${node.props.hashtag}`;
- a.setAttribute('rel', 'tag');
- return a;
- },
-
- inlineCode(node) {
- const el = doc.createElement('code');
- el.textContent = node.props.code;
- return el;
- },
-
- mathInline(node) {
- const el = doc.createElement('code');
- el.textContent = node.props.formula;
- return el;
- },
-
- mathBlock(node) {
- const el = doc.createElement('code');
- el.textContent = node.props.formula;
- return el;
- },
-
- link(node) {
- const a = doc.createElement('a');
- a.href = node.props.url;
- appendChildren(node.children, a);
- return a;
- },
-
- mention(node) {
- const a = doc.createElement('a');
- const { username, host, acct } = node.props;
- const wellKnown = wellKnownServices.find(x => x[0] === host);
- if (wellKnown) {
- a.href = wellKnown[1](username);
- } else {
- const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
- a.href = remoteUserInfo ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) : `${config.url}/${acct}`;
- a.className = 'u-url mention';
- }
- a.textContent = acct;
- return a;
- },
-
- quote(node) {
- const el = doc.createElement('blockquote');
- appendChildren(node.children, el);
- return el;
- },
-
- text(node) {
- const el = doc.createElement('span');
- const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x));
-
- for (const x of intersperse<FIXME | 'br'>('br', nodes)) {
- el.appendChild(x === 'br' ? doc.createElement('br') : x);
- }
-
- return el;
- },
-
- url(node) {
- const a = doc.createElement('a');
- a.href = node.props.url;
- a.textContent = node.props.url;
- return a;
- },
-
- search(node) {
- const a = doc.createElement('a');
- a.href = `https://www.google.com/search?q=${node.props.query}`;
- a.textContent = node.props.content;
- return a;
- }
- };
-
- appendChildren(nodes, doc.body);
-
- return `<p>${doc.body.innerHTML}</p>`;
-}