summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-06-21 01:21:57 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-06-21 01:21:57 +0900
commit79d1bf30a49e1fd1ef1f8b743a9aff84d104fb89 (patch)
treeed8f50f01cc50cf851dc0d0f399ed7e0f514f6c6 /src
parentDisable transitions to avoid memory leak (diff)
downloadsharkey-79d1bf30a49e1fd1ef1f8b743a9aff84d104fb89.tar.gz
sharkey-79d1bf30a49e1fd1ef1f8b743a9aff84d104fb89.tar.bz2
sharkey-79d1bf30a49e1fd1ef1f8b743a9aff84d104fb89.zip
リモートユーザーのHTMLで表現されたプロフィールをMFMに変換するように
Diffstat (limited to 'src')
-rw-r--r--src/client/app/common/views/components/messaging-room.message.vue2
-rw-r--r--src/client/app/common/views/components/misskey-flavored-markdown.ts2
-rw-r--r--src/client/app/desktop/views/components/note-detail.vue2
-rw-r--r--src/client/app/desktop/views/components/notes.note.vue2
-rw-r--r--src/client/app/desktop/views/components/post-form.vue2
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.note.vue2
-rw-r--r--src/client/app/mobile/views/components/note-detail.vue2
-rw-r--r--src/client/app/mobile/views/components/note.vue2
-rw-r--r--src/client/app/mobile/views/components/post-form.vue2
-rw-r--r--src/mfm/html-to-mfm.ts71
-rw-r--r--src/mfm/html.ts (renamed from src/text/html.ts)0
-rw-r--r--src/mfm/parse/core/syntax-highlighter.ts (renamed from src/text/parse/core/syntax-highlighter.ts)0
-rw-r--r--src/mfm/parse/elements/bold.ts (renamed from src/text/parse/elements/bold.ts)0
-rw-r--r--src/mfm/parse/elements/code.ts (renamed from src/text/parse/elements/code.ts)0
-rw-r--r--src/mfm/parse/elements/emoji.ts (renamed from src/text/parse/elements/emoji.ts)0
-rw-r--r--src/mfm/parse/elements/hashtag.ts (renamed from src/text/parse/elements/hashtag.ts)0
-rw-r--r--src/mfm/parse/elements/inline-code.ts (renamed from src/text/parse/elements/inline-code.ts)0
-rw-r--r--src/mfm/parse/elements/link.ts (renamed from src/text/parse/elements/link.ts)0
-rw-r--r--src/mfm/parse/elements/mention.ts (renamed from src/text/parse/elements/mention.ts)0
-rw-r--r--src/mfm/parse/elements/quote.ts (renamed from src/text/parse/elements/quote.ts)0
-rw-r--r--src/mfm/parse/elements/search.ts (renamed from src/text/parse/elements/search.ts)0
-rw-r--r--src/mfm/parse/elements/title.ts (renamed from src/text/parse/elements/title.ts)0
-rw-r--r--src/mfm/parse/elements/url.ts (renamed from src/text/parse/elements/url.ts)0
-rw-r--r--src/mfm/parse/index.ts (renamed from src/text/parse/index.ts)0
-rw-r--r--src/remote/activitypub/misc/get-note-html.ts4
-rw-r--r--src/remote/activitypub/models/note.ts74
-rw-r--r--src/remote/activitypub/models/person.ts9
-rw-r--r--src/services/note/create.ts2
28 files changed, 88 insertions, 90 deletions
diff --git a/src/client/app/common/views/components/messaging-room.message.vue b/src/client/app/common/views/components/messaging-room.message.vue
index d7e7c6dcb5..f33173da6f 100644
--- a/src/client/app/common/views/components/messaging-room.message.vue
+++ b/src/client/app/common/views/components/messaging-room.message.vue
@@ -32,7 +32,7 @@
<script lang="ts">
import Vue from 'vue';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
export default Vue.extend({
props: {
diff --git a/src/client/app/common/views/components/misskey-flavored-markdown.ts b/src/client/app/common/views/components/misskey-flavored-markdown.ts
index 61dbc02d9a..30ad3ce3f2 100644
--- a/src/client/app/common/views/components/misskey-flavored-markdown.ts
+++ b/src/client/app/common/views/components/misskey-flavored-markdown.ts
@@ -1,6 +1,6 @@
import Vue from 'vue';
import * as emojilib from 'emojilib';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import getAcct from '../../../../../acct/render';
import { url } from '../../../config';
import MkUrl from './url.vue';
diff --git a/src/client/app/desktop/views/components/note-detail.vue b/src/client/app/desktop/views/components/note-detail.vue
index 017f599e31..a9640ff9c4 100644
--- a/src/client/app/desktop/views/components/note-detail.vue
+++ b/src/client/app/desktop/views/components/note-detail.vue
@@ -83,7 +83,7 @@
<script lang="ts">
import Vue from 'vue';
import dateStringify from '../../../common/scripts/date-stringify';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import MkPostFormWindow from './post-form-window.vue';
import MkRenoteFormWindow from './renote-form-window.vue';
diff --git a/src/client/app/desktop/views/components/notes.note.vue b/src/client/app/desktop/views/components/notes.note.vue
index 661223ee25..b96ae2da5a 100644
--- a/src/client/app/desktop/views/components/notes.note.vue
+++ b/src/client/app/desktop/views/components/notes.note.vue
@@ -76,7 +76,7 @@
import Vue from 'vue';
import dateStringify from '../../../common/scripts/date-stringify';
import canHideText from '../../../common/scripts/can-hide-text';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import MkPostFormWindow from './post-form-window.vue';
import MkRenoteFormWindow from './renote-form-window.vue';
diff --git a/src/client/app/desktop/views/components/post-form.vue b/src/client/app/desktop/views/components/post-form.vue
index 33f2288e06..3832e5b38c 100644
--- a/src/client/app/desktop/views/components/post-form.vue
+++ b/src/client/app/desktop/views/components/post-form.vue
@@ -49,7 +49,7 @@ import Vue from 'vue';
import * as XDraggable from 'vuedraggable';
import getKao from '../../../common/scripts/get-kao';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import { host } from '../../../config';
export default Vue.extend({
diff --git a/src/client/app/desktop/views/pages/deck/deck.note.vue b/src/client/app/desktop/views/pages/deck/deck.note.vue
index 067297af37..d50fc3c235 100644
--- a/src/client/app/desktop/views/pages/deck/deck.note.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.note.vue
@@ -67,7 +67,7 @@
<script lang="ts">
import Vue from 'vue';
-import parse from '../../../../../../text/parse';
+import parse from '../../../../../../mfm/parse';
import canHideText from '../../../../common/scripts/can-hide-text';
import MkNoteMenu from '../../../../common/views/components/note-menu.vue';
diff --git a/src/client/app/mobile/views/components/note-detail.vue b/src/client/app/mobile/views/components/note-detail.vue
index 6499f78f1b..76633490fd 100644
--- a/src/client/app/mobile/views/components/note-detail.vue
+++ b/src/client/app/mobile/views/components/note-detail.vue
@@ -83,7 +83,7 @@
<script lang="ts">
import Vue from 'vue';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
diff --git a/src/client/app/mobile/views/components/note.vue b/src/client/app/mobile/views/components/note.vue
index 77513a6591..ecdfee3b44 100644
--- a/src/client/app/mobile/views/components/note.vue
+++ b/src/client/app/mobile/views/components/note.vue
@@ -68,7 +68,7 @@
<script lang="ts">
import Vue from 'vue';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import canHideText from '../../../common/scripts/can-hide-text';
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
diff --git a/src/client/app/mobile/views/components/post-form.vue b/src/client/app/mobile/views/components/post-form.vue
index 62fa185085..1015a44115 100644
--- a/src/client/app/mobile/views/components/post-form.vue
+++ b/src/client/app/mobile/views/components/post-form.vue
@@ -45,7 +45,7 @@ import Vue from 'vue';
import * as XDraggable from 'vuedraggable';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
import getKao from '../../../common/scripts/get-kao';
-import parse from '../../../../../text/parse';
+import parse from '../../../../../mfm/parse';
import { host } from '../../../config';
export default Vue.extend({
diff --git a/src/mfm/html-to-mfm.ts b/src/mfm/html-to-mfm.ts
new file mode 100644
index 0000000000..540635036a
--- /dev/null
+++ b/src/mfm/html-to-mfm.ts
@@ -0,0 +1,71 @@
+const parse5 = require('parse5');
+
+export default function(html: string): string {
+ const dom = parse5.parseFragment(html);
+
+ let text = '';
+
+ dom.childNodes.forEach((n: any) => analyze(n));
+
+ return text.trim();
+
+ function getText(node: any) {
+ if (node.nodeName == '#text') return node.value;
+
+ if (node.childNodes) {
+ return node.childNodes.map((n: any) => getText(n)).join('');
+ }
+
+ return '';
+ }
+
+ function analyze(node: any) {
+ switch (node.nodeName) {
+ case '#text':
+ text += node.value;
+ break;
+
+ case 'br':
+ text += '\n';
+ break;
+
+ case 'a':
+ const txt = getText(node);
+
+ // メンション
+ if (txt.startsWith('@')) {
+ const part = txt.split('@');
+
+ if (part.length == 2) {
+ //#region ホスト名部分が省略されているので復元する
+ const href = new URL(node.attrs.find((x: any) => x.name == 'href').value);
+ const acct = txt + '@' + href.hostname;
+ text += acct;
+ break;
+ //#endregion
+ } else if (part.length == 3) {
+ text += txt;
+ break;
+ }
+ }
+
+ if (node.childNodes) {
+ node.childNodes.forEach((n: any) => analyze(n));
+ }
+ break;
+
+ case 'p':
+ text += '\n\n';
+ if (node.childNodes) {
+ node.childNodes.forEach((n: any) => analyze(n));
+ }
+ break;
+
+ default:
+ if (node.childNodes) {
+ node.childNodes.forEach((n: any) => analyze(n));
+ }
+ break;
+ }
+ }
+}
diff --git a/src/text/html.ts b/src/mfm/html.ts
index 64208af88b..64208af88b 100644
--- a/src/text/html.ts
+++ b/src/mfm/html.ts
diff --git a/src/text/parse/core/syntax-highlighter.ts b/src/mfm/parse/core/syntax-highlighter.ts
index 3fb7a3b73d..3fb7a3b73d 100644
--- a/src/text/parse/core/syntax-highlighter.ts
+++ b/src/mfm/parse/core/syntax-highlighter.ts
diff --git a/src/text/parse/elements/bold.ts b/src/mfm/parse/elements/bold.ts
index cf615cd3cc..cf615cd3cc 100644
--- a/src/text/parse/elements/bold.ts
+++ b/src/mfm/parse/elements/bold.ts
diff --git a/src/text/parse/elements/code.ts b/src/mfm/parse/elements/code.ts
index f48e945048..f48e945048 100644
--- a/src/text/parse/elements/code.ts
+++ b/src/mfm/parse/elements/code.ts
diff --git a/src/text/parse/elements/emoji.ts b/src/mfm/parse/elements/emoji.ts
index 83d3effef5..83d3effef5 100644
--- a/src/text/parse/elements/emoji.ts
+++ b/src/mfm/parse/elements/emoji.ts
diff --git a/src/text/parse/elements/hashtag.ts b/src/mfm/parse/elements/hashtag.ts
index 129041774f..129041774f 100644
--- a/src/text/parse/elements/hashtag.ts
+++ b/src/mfm/parse/elements/hashtag.ts
diff --git a/src/text/parse/elements/inline-code.ts b/src/mfm/parse/elements/inline-code.ts
index 1dd5affa51..1dd5affa51 100644
--- a/src/text/parse/elements/inline-code.ts
+++ b/src/mfm/parse/elements/inline-code.ts
diff --git a/src/text/parse/elements/link.ts b/src/mfm/parse/elements/link.ts
index b353aebc5c..b353aebc5c 100644
--- a/src/text/parse/elements/link.ts
+++ b/src/mfm/parse/elements/link.ts
diff --git a/src/text/parse/elements/mention.ts b/src/mfm/parse/elements/mention.ts
index eda60b530a..eda60b530a 100644
--- a/src/text/parse/elements/mention.ts
+++ b/src/mfm/parse/elements/mention.ts
diff --git a/src/text/parse/elements/quote.ts b/src/mfm/parse/elements/quote.ts
index bef9ad4988..bef9ad4988 100644
--- a/src/text/parse/elements/quote.ts
+++ b/src/mfm/parse/elements/quote.ts
diff --git a/src/text/parse/elements/search.ts b/src/mfm/parse/elements/search.ts
index e5d9b9f0c2..e5d9b9f0c2 100644
--- a/src/text/parse/elements/search.ts
+++ b/src/mfm/parse/elements/search.ts
diff --git a/src/text/parse/elements/title.ts b/src/mfm/parse/elements/title.ts
index b89739a7c5..b89739a7c5 100644
--- a/src/text/parse/elements/title.ts
+++ b/src/mfm/parse/elements/title.ts
diff --git a/src/text/parse/elements/url.ts b/src/mfm/parse/elements/url.ts
index 78b9b1f2f1..78b9b1f2f1 100644
--- a/src/text/parse/elements/url.ts
+++ b/src/mfm/parse/elements/url.ts
diff --git a/src/text/parse/index.ts b/src/mfm/parse/index.ts
index 2b6a459b1e..2b6a459b1e 100644
--- a/src/text/parse/index.ts
+++ b/src/mfm/parse/index.ts
diff --git a/src/remote/activitypub/misc/get-note-html.ts b/src/remote/activitypub/misc/get-note-html.ts
index 0ceecdd00b..8df440930b 100644
--- a/src/remote/activitypub/misc/get-note-html.ts
+++ b/src/remote/activitypub/misc/get-note-html.ts
@@ -1,6 +1,6 @@
import { INote } from '../../../models/note';
-import toHtml from '../../../text/html';
-import parse from '../../../text/parse';
+import toHtml from '../../../mfm/html';
+import parse from '../../../mfm/parse';
import config from '../../../config';
export default function(note: INote) {
diff --git a/src/remote/activitypub/models/note.ts b/src/remote/activitypub/models/note.ts
index b0fe045e6d..85a8f89bc8 100644
--- a/src/remote/activitypub/models/note.ts
+++ b/src/remote/activitypub/models/note.ts
@@ -1,5 +1,4 @@
import * as mongo from 'mongodb';
-const parse5 = require('parse5');
import * as debug from 'debug';
import config from '../../../config';
@@ -10,79 +9,10 @@ import { INote as INoteActivityStreamsObject, IObject } from '../type';
import { resolvePerson, updatePerson } from './person';
import { resolveImage } from './image';
import { IRemoteUser, IUser } from '../../../models/user';
+import htmlToMFM from '../../../mfm/html-to-mfm';
const log = debug('misskey:activitypub');
-function parse(html: string): string {
- const dom = parse5.parseFragment(html);
-
- let text = '';
-
- dom.childNodes.forEach((n: any) => analyze(n));
-
- return text.trim();
-
- function getText(node: any) {
- if (node.nodeName == '#text') return node.value;
-
- if (node.childNodes) {
- return node.childNodes.map((n: any) => getText(n)).join('');
- }
-
- return '';
- }
-
- function analyze(node: any) {
- switch (node.nodeName) {
- case '#text':
- text += node.value;
- break;
-
- case 'br':
- text += '\n';
- break;
-
- case 'a':
- const txt = getText(node);
-
- // メンション
- if (txt.startsWith('@')) {
- const part = txt.split('@');
-
- if (part.length == 2) {
- //#region ホスト名部分が省略されているので復元する
- const href = new URL(node.attrs.find((x: any) => x.name == 'href').value);
- const acct = txt + '@' + href.hostname;
- text += acct;
- break;
- //#endregion
- } else if (part.length == 3) {
- text += txt;
- break;
- }
- }
-
- if (node.childNodes) {
- node.childNodes.forEach((n: any) => analyze(n));
- }
- break;
-
- case 'p':
- text += '\n\n';
- if (node.childNodes) {
- node.childNodes.forEach((n: any) => analyze(n));
- }
- break;
-
- default:
- if (node.childNodes) {
- node.childNodes.forEach((n: any) => analyze(n));
- }
- break;
- }
- }
-}
-
/**
* Noteをフェッチします。
*
@@ -158,7 +88,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
const reply = note.inReplyTo ? await resolveNote(note.inReplyTo, resolver) : null;
// テキストのパース
- const text = parse(note.content);
+ const text = htmlToMFM(note.content);
// ユーザーの情報が古かったらついでに更新しておく
if (actor.updatedAt == null || Date.now() - actor.updatedAt.getTime() > 1000 * 60 * 60 * 24) {
diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts
index 42ee5a27df..f233346395 100644
--- a/src/remote/activitypub/models/person.ts
+++ b/src/remote/activitypub/models/person.ts
@@ -1,5 +1,4 @@
import * as mongo from 'mongodb';
-import { JSDOM } from 'jsdom';
import { toUnicode } from 'punycode';
import * as debug from 'debug';
@@ -11,6 +10,7 @@ import { resolveImage } from './image';
import { isCollectionOrOrderedCollection, IObject, IPerson } from '../type';
import { IDriveFile } from '../../../models/drive-file';
import Meta from '../../../models/meta';
+import htmlToMFM from '../../../mfm/html-to-mfm';
const log = debug('misskey:activitypub');
@@ -80,7 +80,6 @@ export async function createPerson(value: any, resolver?: Resolver): Promise<IUs
]);
const host = toUnicode(finger.subject.replace(/^.*?@/, '')).toLowerCase();
- const summaryDOM = JSDOM.fragment(person.summary);
// Create user
let user: IRemoteUser;
@@ -89,7 +88,7 @@ export async function createPerson(value: any, resolver?: Resolver): Promise<IUs
avatarId: null,
bannerId: null,
createdAt: Date.parse(person.published) || null,
- description: summaryDOM.textContent,
+ description: htmlToMFM(person.summary),
followersCount,
followingCount,
notesCount,
@@ -211,8 +210,6 @@ export async function updatePerson(value: string | IObject, resolver?: Resolver)
)
]);
- const summaryDOM = JSDOM.fragment(person.summary);
-
// アイコンとヘッダー画像をフェッチ
const [avatar, banner] = (await Promise.all<IDriveFile>([
person.icon,
@@ -231,7 +228,7 @@ export async function updatePerson(value: string | IObject, resolver?: Resolver)
bannerId: banner ? banner._id : null,
avatarUrl: avatar && avatar.metadata.isMetaOnly ? avatar.metadata.url : null,
bannerUrl: banner && banner.metadata.isMetaOnly ? banner.metadata.url : null,
- description: summaryDOM.textContent,
+ description: htmlToMFM(person.summary),
followersCount,
followingCount,
notesCount,
diff --git a/src/services/note/create.ts b/src/services/note/create.ts
index ef03c4e044..782ac5a4fe 100644
--- a/src/services/note/create.ts
+++ b/src/services/note/create.ts
@@ -14,7 +14,7 @@ import watch from './watch';
import Mute from '../../models/mute';
import pushSw from '../../publishers/push-sw';
import event from '../../publishers/stream';
-import parse from '../../text/parse';
+import parse from '../../mfm/parse';
import { IApp } from '../../models/app';
import UserList from '../../models/user-list';
import resolveUser from '../../remote/resolve-user';