summaryrefslogtreecommitdiff
path: root/src/web/app/common
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-02-11 23:26:35 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-02-11 23:26:35 +0900
commitea2b5a5aace235ce7355644c65ee831dd83e551a (patch)
treeea7cae33d4720ea0515128cc3ca2f1c24abbfd78 /src/web/app/common
parentwip (diff)
downloadsharkey-ea2b5a5aace235ce7355644c65ee831dd83e551a.tar.gz
sharkey-ea2b5a5aace235ce7355644c65ee831dd83e551a.tar.bz2
sharkey-ea2b5a5aace235ce7355644c65ee831dd83e551a.zip
wip
Diffstat (limited to 'src/web/app/common')
-rw-r--r--src/web/app/common/scripts/text-compiler.ts48
-rw-r--r--src/web/app/common/views/components/index.ts2
-rw-r--r--src/web/app/common/views/components/post-html.ts98
3 files changed, 100 insertions, 48 deletions
diff --git a/src/web/app/common/scripts/text-compiler.ts b/src/web/app/common/scripts/text-compiler.ts
deleted file mode 100644
index e0ea47df26..0000000000
--- a/src/web/app/common/scripts/text-compiler.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-declare const _URL_: string;
-
-import * as riot from 'riot';
-import * as pictograph from 'pictograph';
-
-const escape = text =>
- text
- .replace(/>/g, '&gt;')
- .replace(/</g, '&lt;');
-
-export default (tokens, shouldBreak) => {
- if (shouldBreak == null) {
- shouldBreak = true;
- }
-
- const me = (riot as any).mixin('i').me;
-
- let text = tokens.map(token => {
- switch (token.type) {
- case 'text':
- return escape(token.content)
- .replace(/(\r\n|\n|\r)/g, shouldBreak ? '<br>' : ' ');
- case 'bold':
- return `<strong>${escape(token.bold)}</strong>`;
- case 'url':
- return `<mk-url href="${escape(token.content)}" target="_blank"></mk-url>`;
- case 'link':
- return `<a class="link" href="${escape(token.url)}" target="_blank" title="${escape(token.url)}">${escape(token.title)}</a>`;
- case 'mention':
- return `<a href="${_URL_ + '/' + escape(token.username)}" target="_blank" data-user-preview="${token.content}" ${me && me.username == token.username ? 'data-is-me' : ''}>${token.content}</a>`;
- case 'hashtag': // TODO
- return `<a>${escape(token.content)}</a>`;
- case 'code':
- return `<pre><code>${token.html}</code></pre>`;
- case 'inline-code':
- return `<code>${token.html}</code>`;
- case 'emoji':
- return pictograph.dic[token.emoji] || token.content;
- }
- }).join('');
-
- // Remove needless whitespaces
- text = text
- .replace(/ <code>/g, '<code>').replace(/<\/code> /g, '</code>')
- .replace(/<br><code><pre>/g, '<code><pre>').replace(/<\/code><\/pre><br>/g, '</code></pre>');
-
- return text;
-};
diff --git a/src/web/app/common/views/components/index.ts b/src/web/app/common/views/components/index.ts
index 9097c30814..c4c3475ee2 100644
--- a/src/web/app/common/views/components/index.ts
+++ b/src/web/app/common/views/components/index.ts
@@ -4,8 +4,10 @@ import signin from './signin.vue';
import signup from './signup.vue';
import forkit from './forkit.vue';
import nav from './nav.vue';
+import postHtml from './post-html';
Vue.component('mk-signin', signin);
Vue.component('mk-signup', signup);
Vue.component('mk-forkit', forkit);
Vue.component('mk-nav', nav);
+Vue.component('mk-post-html', postHtml);
diff --git a/src/web/app/common/views/components/post-html.ts b/src/web/app/common/views/components/post-html.ts
new file mode 100644
index 0000000000..88ced03429
--- /dev/null
+++ b/src/web/app/common/views/components/post-html.ts
@@ -0,0 +1,98 @@
+declare const _URL_: string;
+
+import Vue from 'vue';
+import * as pictograph from 'pictograph';
+
+import MkUrl from './url.vue';
+
+const escape = text =>
+ text
+ .replace(/>/g, '&gt;')
+ .replace(/</g, '&lt;');
+
+export default Vue.component('mk-post-html', {
+ props: {
+ ast: {
+ type: Array,
+ required: true
+ },
+ shouldBreak: {
+ type: Boolean,
+ default: true
+ },
+ i: {
+ type: Object,
+ default: null
+ }
+ },
+ render(createElement) {
+ const els = [].concat.apply([], (this as any).ast.map(token => {
+ switch (token.type) {
+ case 'text':
+ const text = escape(token.content)
+ .replace(/(\r\n|\n|\r)/g, '\n');
+
+ if ((this as any).shouldBreak) {
+ return text.split('\n').map(t => [createElement('span', t), createElement('br')]);
+ } else {
+ return createElement('span', text.replace(/\n/g, ' '));
+ }
+
+ case 'bold':
+ return createElement('strong', escape(token.bold));
+
+ case 'url':
+ return createElement(MkUrl, {
+ props: {
+ href: escape(token.content),
+ target: '_blank'
+ }
+ });
+
+ case 'link':
+ return createElement('a', {
+ attrs: {
+ class: 'link',
+ href: escape(token.url),
+ target: '_blank',
+ title: escape(token.url)
+ }
+ }, escape(token.title));
+
+ case 'mention':
+ return (createElement as any)('a', {
+ attrs: {
+ href: `${_URL_}/${escape(token.username)}`,
+ target: '_blank',
+ dataIsMe: (this as any).i && (this as any).i.username == token.username
+ },
+ directives: [{
+ name: 'user-preview',
+ value: token.content
+ }]
+ }, token.content);
+
+ case 'hashtag':
+ return createElement('a', {
+ attrs: {
+ href: `${_URL_}/search?q=${escape(token.content)}`,
+ target: '_blank'
+ }
+ }, escape(token.content));
+
+ case 'code':
+ return createElement('pre', [
+ createElement('code', token.html)
+ ]);
+
+ case 'inline-code':
+ return createElement('code', token.html);
+
+ case 'emoji':
+ return createElement('span', pictograph.dic[token.emoji] || token.content);
+ }
+ }));
+
+ return createElement('div', els);
+ }
+});