diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-02-11 23:26:35 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-02-11 23:26:35 +0900 |
| commit | ea2b5a5aace235ce7355644c65ee831dd83e551a (patch) | |
| tree | ea7cae33d4720ea0515128cc3ca2f1c24abbfd78 /src | |
| parent | wip (diff) | |
| download | sharkey-ea2b5a5aace235ce7355644c65ee831dd83e551a.tar.gz sharkey-ea2b5a5aace235ce7355644c65ee831dd83e551a.tar.bz2 sharkey-ea2b5a5aace235ce7355644c65ee831dd83e551a.zip | |
wip
Diffstat (limited to 'src')
| -rw-r--r-- | src/web/app/common/scripts/text-compiler.ts | 48 | ||||
| -rw-r--r-- | src/web/app/common/views/components/index.ts | 2 | ||||
| -rw-r--r-- | src/web/app/common/views/components/post-html.ts | 98 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/timeline-post.vue | 10 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/timeline.vue | 4 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/window.vue | 2 |
6 files changed, 105 insertions, 59 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, '>') - .replace(/</g, '<'); - -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, '>') + .replace(/</g, '<'); + +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); + } +}); diff --git a/src/web/app/desktop/views/components/timeline-post.vue b/src/web/app/desktop/views/components/timeline-post.vue index e4eaa8f793..f722ea3340 100644 --- a/src/web/app/desktop/views/components/timeline-post.vue +++ b/src/web/app/desktop/views/components/timeline-post.vue @@ -32,7 +32,7 @@ <div class="text" ref="text"> <p class="channel" v-if="p.channel"><a :href="`${_CH_URL_}/${p.channel.id}`" target="_blank">{{ p.channel.title }}</a>:</p> <a class="reply" v-if="p.reply">%fa:reply%</a> - <p class="dummy"></p> + <mk-post-html :ast="p.ast" :i="$root.$data.os.i"/> <a class="quote" v-if="p.repost">RP:</a> </div> <div class="media" v-if="p.media"> @@ -94,7 +94,7 @@ export default Vue.extend({ return this.isRepost ? this.post.repost : this.post; }, reactionsCount(): number { - return this.p.reaction_counts ? Object.keys(this.p.reaction_counts).map(key => this.p.reaction_counts[key]).reduce((a, b) => a + b) : 0; + return this.p.reaction_counts ? Object.keys(this.p.reaction_counts).map(key => this.p.reaction_counts[key]).reduce((a, b) => a + b) : 0; }, title(): string { return dateStringify(this.p.created_at); @@ -117,12 +117,6 @@ export default Vue.extend({ if (this.p.text) { const tokens = this.p.ast; - this.$refs.text.innerHTML = this.$refs.text.innerHTML.replace('<p class="dummy"></p>', compile(tokens)); - - Array.from(this.$refs.text.children).forEach(e => { - if (e.tagName == 'MK-URL') riot.mount(e); - }); - // URLをプレビュー tokens .filter(t => (t.type == 'url' || t.type == 'link') && !t.silent) diff --git a/src/web/app/desktop/views/components/timeline.vue b/src/web/app/desktop/views/components/timeline.vue index ba412848fb..161eebdf72 100644 --- a/src/web/app/desktop/views/components/timeline.vue +++ b/src/web/app/desktop/views/components/timeline.vue @@ -7,7 +7,7 @@ <footer data-yield="footer"> <yield from="footer"/> </footer> -</div> +</div> </template> <script lang="ts"> @@ -31,7 +31,7 @@ export default Vue.extend({ }, methods: { focus() { - this.$refs.root.children[0].focus(); + (this.$refs.root as any).children[0].focus(); } } }); diff --git a/src/web/app/desktop/views/components/window.vue b/src/web/app/desktop/views/components/window.vue index ac3af3a57b..28f368253c 100644 --- a/src/web/app/desktop/views/components/window.vue +++ b/src/web/app/desktop/views/components/window.vue @@ -27,7 +27,7 @@ <script lang="ts"> import Vue from 'vue'; import anime from 'animejs'; -import contains from '../../common/scripts/contains'; +import contains from '../../../common/scripts/contains'; const minHeight = 40; const minWidth = 200; |