2018-06-17 19:55:39 +09:00
|
|
|
const { lib: emojilib } = require('emojilib');
|
2018-08-04 11:39:59 +09:00
|
|
|
const jsdom = require('jsdom');
|
|
|
|
const { JSDOM } = jsdom;
|
2018-05-17 08:14:30 +09:00
|
|
|
import config from '../config';
|
2018-06-17 15:58:23 +09:00
|
|
|
import { INote } from '../models/note';
|
2018-06-17 19:55:39 +09:00
|
|
|
import { TextElement } from './parse';
|
2018-03-31 19:53:30 +09:00
|
|
|
|
2018-08-19 00:31:25 +09:00
|
|
|
function intersperse<T>(sep: T, xs: T[]): T[] {
|
|
|
|
return [].concat(...xs.map(x => [sep, x])).slice(1);
|
|
|
|
}
|
|
|
|
|
2018-06-18 14:28:43 +09:00
|
|
|
const handlers: { [key: string]: (window: any, token: any, mentionedRemoteUsers: INote['mentionedRemoteUsers']) => void } = {
|
2018-03-31 19:53:30 +09:00
|
|
|
bold({ document }, { bold }) {
|
|
|
|
const b = document.createElement('b');
|
|
|
|
b.textContent = bold;
|
|
|
|
document.body.appendChild(b);
|
|
|
|
},
|
|
|
|
|
2018-08-03 23:27:37 +09:00
|
|
|
big({ document }, { big }) {
|
|
|
|
const b = document.createElement('strong');
|
|
|
|
b.textContent = big;
|
|
|
|
document.body.appendChild(b);
|
|
|
|
},
|
|
|
|
|
2018-08-05 12:33:51 +09:00
|
|
|
motion({ document }, { big }) {
|
|
|
|
const b = document.createElement('strong');
|
|
|
|
b.textContent = big;
|
|
|
|
document.body.appendChild(b);
|
|
|
|
},
|
|
|
|
|
2018-03-31 19:53:30 +09:00
|
|
|
code({ document }, { code }) {
|
|
|
|
const pre = document.createElement('pre');
|
|
|
|
const inner = document.createElement('code');
|
|
|
|
inner.innerHTML = code;
|
|
|
|
pre.appendChild(inner);
|
|
|
|
document.body.appendChild(pre);
|
|
|
|
},
|
|
|
|
|
|
|
|
emoji({ document }, { content, emoji }) {
|
|
|
|
const found = emojilib[emoji];
|
|
|
|
const node = document.createTextNode(found ? found.char : content);
|
|
|
|
document.body.appendChild(node);
|
|
|
|
},
|
|
|
|
|
|
|
|
hashtag({ document }, { hashtag }) {
|
2018-06-10 03:55:51 +09:00
|
|
|
const a = document.createElement('a');
|
2018-09-01 23:12:51 +09:00
|
|
|
a.href = `${config.url}/tags/${hashtag}`;
|
|
|
|
a.textContent = `#${hashtag}`;
|
2018-06-10 03:55:51 +09:00
|
|
|
a.setAttribute('rel', 'tag');
|
|
|
|
document.body.appendChild(a);
|
2018-03-31 19:53:30 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
'inline-code'({ document }, { code }) {
|
|
|
|
const element = document.createElement('code');
|
|
|
|
element.textContent = code;
|
|
|
|
document.body.appendChild(element);
|
|
|
|
},
|
|
|
|
|
|
|
|
link({ document }, { url, title }) {
|
|
|
|
const a = document.createElement('a');
|
|
|
|
a.href = url;
|
|
|
|
a.textContent = title;
|
|
|
|
document.body.appendChild(a);
|
|
|
|
},
|
|
|
|
|
2018-06-17 15:58:23 +09:00
|
|
|
mention({ document }, { content, username, host }, mentionedRemoteUsers) {
|
2018-03-31 19:53:30 +09:00
|
|
|
const a = document.createElement('a');
|
2018-06-17 15:58:23 +09:00
|
|
|
const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
|
|
|
|
a.href = remoteUserInfo ? remoteUserInfo.uri : `${config.url}/${content}`;
|
2018-03-31 19:53:30 +09:00
|
|
|
a.textContent = content;
|
|
|
|
document.body.appendChild(a);
|
|
|
|
},
|
|
|
|
|
|
|
|
quote({ document }, { quote }) {
|
|
|
|
const blockquote = document.createElement('blockquote');
|
|
|
|
blockquote.textContent = quote;
|
|
|
|
document.body.appendChild(blockquote);
|
|
|
|
},
|
|
|
|
|
2018-04-21 18:25:25 +09:00
|
|
|
title({ document }, { content }) {
|
2018-04-19 15:05:39 +09:00
|
|
|
const h1 = document.createElement('h1');
|
2018-04-21 18:25:25 +09:00
|
|
|
h1.textContent = content;
|
2018-04-19 15:05:39 +09:00
|
|
|
document.body.appendChild(h1);
|
|
|
|
},
|
|
|
|
|
2018-03-31 19:53:30 +09:00
|
|
|
text({ document }, { content }) {
|
2018-08-19 00:31:25 +09:00
|
|
|
const nodes = (content as string).split('\n').map(x => document.createTextNode(x));
|
|
|
|
for (const x of intersperse(document.createElement('br'), nodes)) {
|
|
|
|
document.body.appendChild(x);
|
2018-03-31 19:53:30 +09:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
url({ document }, { url }) {
|
|
|
|
const a = document.createElement('a');
|
|
|
|
a.href = url;
|
|
|
|
a.textContent = url;
|
|
|
|
document.body.appendChild(a);
|
2018-04-21 18:59:16 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
search({ document }, { content, query }) {
|
|
|
|
const a = document.createElement('a');
|
|
|
|
a.href = `https://www.google.com/?#q=${query}`;
|
|
|
|
a.textContent = content;
|
|
|
|
document.body.appendChild(a);
|
2018-03-31 19:53:30 +09:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-06-17 19:55:39 +09:00
|
|
|
export default (tokens: TextElement[], mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) => {
|
2018-07-01 13:46:34 +09:00
|
|
|
if (tokens == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-03-31 19:53:30 +09:00
|
|
|
const { window } = new JSDOM('');
|
|
|
|
|
|
|
|
for (const token of tokens) {
|
2018-06-17 15:58:23 +09:00
|
|
|
handlers[token.type](window, token, mentionedRemoteUsers);
|
2018-03-31 19:53:30 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
return `<p>${window.document.body.innerHTML}</p>`;
|
|
|
|
};
|