From 45e8331e261244628b134a18e3d0fbe0ebb3a7dc Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 18 Mar 2017 20:05:11 +0900 Subject: :sushi: Closes #12, #227 and #58 --- src/api/common/text/core/syntax-highlighter.ts | 334 +++++++++++++++++++++ src/api/common/text/elements/bold.ts | 14 + src/api/common/text/elements/code.ts | 17 ++ src/api/common/text/elements/emoji.ts | 14 + src/api/common/text/elements/hashtag.ts | 19 ++ src/api/common/text/elements/inline-code.ts | 17 ++ src/api/common/text/elements/link.ts | 19 ++ src/api/common/text/elements/mention.ts | 14 + src/api/common/text/elements/url.ts | 14 + src/api/common/text/index.ts | 71 +++++ src/api/serializers/app.ts | 2 - src/api/serializers/auth-session.ts | 2 - src/api/serializers/drive-file.ts | 2 - src/api/serializers/drive-folder.ts | 2 - src/api/serializers/drive-tag.ts | 2 - src/api/serializers/messaging-message.ts | 10 +- src/api/serializers/notification.ts | 2 - src/api/serializers/post.ts | 10 +- src/api/serializers/signin.ts | 2 - src/api/serializers/user.ts | 2 - src/common/text/core/syntax-highlighter.js | 332 -------------------- src/common/text/elements/bold.js | 14 - src/common/text/elements/code.js | 17 -- src/common/text/elements/emoji.js | 14 - src/common/text/elements/hashtag.js | 19 -- src/common/text/elements/inline-code.js | 17 -- src/common/text/elements/link.js | 19 -- src/common/text/elements/mention.js | 14 - src/common/text/elements/url.js | 14 - src/common/text/index.js | 71 ----- src/web/app/auth/script.js | 7 +- src/web/app/boot.js | 31 +- src/web/app/client/script.js | 2 +- src/web/app/common/mixins.js | 48 --- src/web/app/common/mixins/api.js | 8 + src/web/app/common/mixins/i.js | 20 ++ src/web/app/common/mixins/index.js | 9 + src/web/app/common/mixins/stream.js | 9 + src/web/app/common/scripts/api.js | 4 +- src/web/app/common/scripts/bytes-to-size.js | 4 +- src/web/app/common/scripts/check-for-update.js | 14 + src/web/app/common/scripts/config.js | 2 +- src/web/app/common/scripts/contains.js | 4 +- src/web/app/common/scripts/copy-to-clipboard.js | 2 +- src/web/app/common/scripts/date-stringify.js | 10 +- src/web/app/common/scripts/gcd.js | 2 +- .../common/scripts/generate-default-userdata.js | 4 +- src/web/app/common/scripts/get-cat.js | 4 +- src/web/app/common/scripts/get-post-summary.js | 2 +- src/web/app/common/scripts/i.js | 20 -- src/web/app/common/scripts/is-promise.js | 2 +- src/web/app/common/scripts/loading.js | 2 +- src/web/app/common/scripts/messaging-stream.js | 6 +- src/web/app/common/scripts/signout.js | 4 +- src/web/app/common/scripts/stream.js | 79 +++-- src/web/app/common/scripts/text-compiler.js | 22 +- src/web/app/common/scripts/uuid.js | 6 +- src/web/app/common/tags/introduction.tag | 8 +- src/web/app/common/tags/messaging/form.tag | 4 +- src/web/app/common/tags/messaging/message.tag | 7 +- src/web/app/common/tags/messaging/room.tag | 5 +- src/web/app/common/tags/public-timeline.tag | 6 +- src/web/app/common/tags/raw.tag | 5 +- src/web/app/common/tags/signin-history.tag | 7 +- src/web/app/common/tags/signup.tag | 4 +- src/web/app/common/tags/stream-indicator.tag | 17 +- src/web/app/common/tags/url-preview.tag | 2 +- src/web/app/desktop/mixins.js | 41 --- src/web/app/desktop/mixins/index.js | 1 + src/web/app/desktop/mixins/user-preview.js | 66 ++++ src/web/app/desktop/router.js | 4 +- src/web/app/desktop/script.js | 13 +- src/web/app/desktop/scripts/autocomplete.js | 4 +- src/web/app/desktop/scripts/dialog.js | 4 +- src/web/app/desktop/scripts/fuck-ad-block.js | 2 +- src/web/app/desktop/scripts/input-dialog.js | 4 +- .../desktop/scripts/not-implemented-exception.js | 8 + src/web/app/desktop/scripts/notify.js | 4 +- src/web/app/desktop/scripts/stream.js | 7 +- src/web/app/desktop/scripts/update-avatar.js | 10 +- src/web/app/desktop/scripts/update-banner.js | 10 +- src/web/app/desktop/scripts/user-preview.js | 66 ---- src/web/app/desktop/tags/analog-clock.tag | 2 +- .../app/desktop/tags/autocomplete-suggestion.tag | 2 +- src/web/app/desktop/tags/big-follow-button.tag | 16 +- src/web/app/desktop/tags/contextmenu.tag | 2 +- src/web/app/desktop/tags/crop-window.tag | 4 +- src/web/app/desktop/tags/donation.tag | 2 +- src/web/app/desktop/tags/drive/browser.tag | 33 +- .../app/desktop/tags/drive/file-contextmenu.tag | 19 +- src/web/app/desktop/tags/drive/file.tag | 4 +- .../app/desktop/tags/drive/folder-contextmenu.tag | 5 +- src/web/app/desktop/tags/drive/folder.tag | 5 +- src/web/app/desktop/tags/follow-button.tag | 16 +- .../app/desktop/tags/home-widgets/photo-stream.tag | 7 +- src/web/app/desktop/tags/home-widgets/profile.tag | 10 +- .../app/desktop/tags/home-widgets/rss-reader.tag | 4 +- src/web/app/desktop/tags/home-widgets/timeline.tag | 14 +- src/web/app/desktop/tags/notifications.tag | 13 +- src/web/app/desktop/tags/pages/home.tag | 17 +- src/web/app/desktop/tags/pages/post.tag | 8 +- src/web/app/desktop/tags/pages/search.tag | 6 +- src/web/app/desktop/tags/pages/user.tag | 8 +- src/web/app/desktop/tags/post-detail-sub.tag | 10 +- src/web/app/desktop/tags/post-detail.tag | 10 +- src/web/app/desktop/tags/post-form.tag | 12 +- src/web/app/desktop/tags/post-preview.tag | 5 +- src/web/app/desktop/tags/repost-form.tag | 7 +- src/web/app/desktop/tags/set-avatar-suggestion.tag | 5 +- src/web/app/desktop/tags/set-banner-suggestion.tag | 5 +- src/web/app/desktop/tags/settings.tag | 10 +- src/web/app/desktop/tags/sub-post-content.tag | 7 +- src/web/app/desktop/tags/timeline-post-sub.tag | 5 +- src/web/app/desktop/tags/timeline-post.tag | 14 +- src/web/app/desktop/tags/ui-header-account.tag | 4 +- src/web/app/desktop/tags/ui-header-nav.tag | 10 +- .../app/desktop/tags/ui-header-notifications.tag | 2 +- src/web/app/desktop/tags/user-header.tag | 12 +- src/web/app/desktop/tags/user-photos.tag | 5 +- src/web/app/desktop/tags/user-timeline.tag | 6 +- src/web/app/desktop/tags/window.tag | 2 +- src/web/app/dev/router.js | 2 +- src/web/app/dev/script.js | 2 +- src/web/app/mobile/mixins.js | 25 -- src/web/app/mobile/router.js | 4 +- src/web/app/mobile/script.js | 8 +- src/web/app/mobile/scripts/open-post-form.js | 15 + src/web/app/mobile/scripts/stream.js | 11 - src/web/app/mobile/scripts/ui-event.js | 5 + src/web/app/mobile/scripts/ui.js | 7 - src/web/app/mobile/tags/drive.tag | 19 +- src/web/app/mobile/tags/drive/file-viewer.tag | 11 +- src/web/app/mobile/tags/drive/file.tag | 3 +- src/web/app/mobile/tags/follow-button.tag | 16 +- src/web/app/mobile/tags/home-timeline.tag | 15 +- src/web/app/mobile/tags/notification-preview.tag | 3 +- src/web/app/mobile/tags/notification.tag | 3 +- src/web/app/mobile/tags/notifications.tag | 10 +- src/web/app/mobile/tags/page/drive.tag | 20 +- src/web/app/mobile/tags/page/home.tag | 27 +- src/web/app/mobile/tags/page/messaging-room.tag | 5 +- src/web/app/mobile/tags/page/messaging.tag | 5 +- src/web/app/mobile/tags/page/notifications.tag | 11 +- src/web/app/mobile/tags/page/post.tag | 12 +- src/web/app/mobile/tags/page/search.tag | 10 +- src/web/app/mobile/tags/page/settings.tag | 4 +- src/web/app/mobile/tags/page/settings/api.tag | 4 +- .../mobile/tags/page/settings/authorized-apps.tag | 4 +- src/web/app/mobile/tags/page/settings/signin.tag | 4 +- src/web/app/mobile/tags/page/settings/twitter.tag | 4 +- src/web/app/mobile/tags/page/user-followers.tag | 11 +- src/web/app/mobile/tags/page/user-following.tag | 11 +- src/web/app/mobile/tags/page/user.tag | 11 +- src/web/app/mobile/tags/post-detail.tag | 12 +- src/web/app/mobile/tags/post-form.tag | 2 +- src/web/app/mobile/tags/sub-post-content.tag | 6 +- src/web/app/mobile/tags/timeline-post.tag | 15 +- src/web/app/mobile/tags/ui-header.tag | 10 +- src/web/app/mobile/tags/ui.tag | 8 +- 159 files changed, 1207 insertions(+), 1212 deletions(-) create mode 100644 src/api/common/text/core/syntax-highlighter.ts create mode 100644 src/api/common/text/elements/bold.ts create mode 100644 src/api/common/text/elements/code.ts create mode 100644 src/api/common/text/elements/emoji.ts create mode 100644 src/api/common/text/elements/hashtag.ts create mode 100644 src/api/common/text/elements/inline-code.ts create mode 100644 src/api/common/text/elements/link.ts create mode 100644 src/api/common/text/elements/mention.ts create mode 100644 src/api/common/text/elements/url.ts create mode 100644 src/api/common/text/index.ts delete mode 100644 src/common/text/core/syntax-highlighter.js delete mode 100644 src/common/text/elements/bold.js delete mode 100644 src/common/text/elements/code.js delete mode 100644 src/common/text/elements/emoji.js delete mode 100644 src/common/text/elements/hashtag.js delete mode 100644 src/common/text/elements/inline-code.js delete mode 100644 src/common/text/elements/link.js delete mode 100644 src/common/text/elements/mention.js delete mode 100644 src/common/text/elements/url.js delete mode 100644 src/common/text/index.js delete mode 100644 src/web/app/common/mixins.js create mode 100644 src/web/app/common/mixins/api.js create mode 100644 src/web/app/common/mixins/i.js create mode 100644 src/web/app/common/mixins/index.js create mode 100644 src/web/app/common/mixins/stream.js create mode 100644 src/web/app/common/scripts/check-for-update.js delete mode 100644 src/web/app/common/scripts/i.js delete mode 100644 src/web/app/desktop/mixins.js create mode 100644 src/web/app/desktop/mixins/index.js create mode 100644 src/web/app/desktop/mixins/user-preview.js create mode 100644 src/web/app/desktop/scripts/not-implemented-exception.js delete mode 100644 src/web/app/desktop/scripts/user-preview.js delete mode 100644 src/web/app/mobile/mixins.js create mode 100644 src/web/app/mobile/scripts/open-post-form.js delete mode 100644 src/web/app/mobile/scripts/stream.js create mode 100644 src/web/app/mobile/scripts/ui-event.js delete mode 100644 src/web/app/mobile/scripts/ui.js (limited to 'src') diff --git a/src/api/common/text/core/syntax-highlighter.ts b/src/api/common/text/core/syntax-highlighter.ts new file mode 100644 index 0000000000..c0396b1fc6 --- /dev/null +++ b/src/api/common/text/core/syntax-highlighter.ts @@ -0,0 +1,334 @@ +function escape(text) { + return text + .replace(/>/g, '>') + .replace(/ k[0].toUpperCase() + k.substr(1))) + .concat(_keywords.map(k => k.toUpperCase())) + .sort((a, b) => b.length - a.length); + +const symbols = [ + '=', + '+', + '-', + '*', + '/', + '%', + '~', + '^', + '&', + '|', + '>', + '<', + '!', + '?' +]; + +const elements = [ + // comment + code => { + if (code.substr(0, 2) != '//') return null; + const match = code.match(/^\/\/(.+?)(\n|$)/); + if (!match) return null; + const comment = match[0]; + return { + html: `${escape(comment)}`, + next: comment.length + }; + }, + + // block comment + code => { + const match = code.match(/^\/\*([\s\S]+?)\*\//); + if (!match) return null; + return { + html: `${escape(match[0])}`, + next: match[0].length + }; + }, + + // string + code => { + if (!/^['"`]/.test(code)) return null; + const begin = code[0]; + let str = begin; + let thisIsNotAString = false; + for (let i = 1; i < code.length; i++) { + const char = code[i]; + if (char == '\\') { + str += char; + str += code[i + 1] || ''; + i++; + continue; + } else if (char == begin) { + str += char; + break; + } else if (char == '\n' || i == (code.length - 1)) { + thisIsNotAString = true; + break; + } else { + str += char; + } + } + if (thisIsNotAString) { + return null; + } else { + return { + html: `${escape(str)}`, + next: str.length + }; + } + }, + + // regexp + code => { + if (code[0] != '/') return null; + let regexp = ''; + let thisIsNotARegexp = false; + for (let i = 1; i < code.length; i++) { + const char = code[i]; + if (char == '\\') { + regexp += char; + regexp += code[i + 1] || ''; + i++; + continue; + } else if (char == '/') { + break; + } else if (char == '\n' || i == (code.length - 1)) { + thisIsNotARegexp = true; + break; + } else { + regexp += char; + } + } + + if (thisIsNotARegexp) return null; + if (regexp == '') return null; + if (regexp[0] == ' ' && regexp[regexp.length - 1] == ' ') return null; + + return { + html: `/${escape(regexp)}/`, + next: regexp.length + 2 + }; + }, + + // label + code => { + if (code[0] != '@') return null; + const match = code.match(/^@([a-zA-Z_-]+?)\n/); + if (!match) return null; + const label = match[0]; + return { + html: `${label}`, + next: label.length + }; + }, + + // number + (code, i, source) => { + const prev = source[i - 1]; + if (prev && /[a-zA-Z]/.test(prev)) return null; + if (!/^[\-\+]?[0-9\.]+/.test(code)) return null; + const match = code.match(/^[\-\+]?[0-9\.]+/)[0]; + if (match) { + return { + html: `${match}`, + next: match.length + }; + } else { + return null; + } + }, + + // nan + (code, i, source) => { + const prev = source[i - 1]; + if (prev && /[a-zA-Z]/.test(prev)) return null; + if (code.substr(0, 3) == 'NaN') { + return { + html: `NaN`, + next: 3 + }; + } else { + return null; + } + }, + + // method + code => { + const match = code.match(/^([a-zA-Z_-]+?)\(/); + if (!match) return null; + + if (match[1] == '-') return null; + + return { + html: `${match[1]}`, + next: match[1].length + }; + }, + + // property + (code, i, source) => { + const prev = source[i - 1]; + if (prev != '.') return null; + + const match = code.match(/^[a-zA-Z0-9_-]+/); + if (!match) return null; + + return { + html: `${match[0]}`, + next: match[0].length + }; + }, + + // keyword + (code, i, source) => { + const prev = source[i - 1]; + if (prev && /[a-zA-Z]/.test(prev)) return null; + + const match = keywords.filter(k => code.substr(0, k.length) == k)[0]; + if (match) { + if (/^[a-zA-Z]/.test(code.substr(match.length))) return null; + return { + html: `${match}`, + next: match.length + }; + } else { + return null; + } + }, + + // symbol + code => { + const match = symbols.filter(s => code[0] == s)[0]; + if (match) { + return { + html: `${match}`, + next: 1 + }; + } else { + return null; + } + } +]; + +// specify lang is todo +export default (source: string, lang?: string) => { + let code = source; + let html = ''; + + let i = 0; + + function push(token) { + html += token.html; + code = code.substr(token.next); + i += token.next; + } + + while (code != '') { + const parsed = elements.some(el => { + const e = el(code, i, source); + if (e) { + push(e); + return true; + } else { + return false; + } + }); + + if (!parsed) { + push({ + html: escape(code[0]), + next: 1 + }); + } + } + + return html; +}; diff --git a/src/api/common/text/elements/bold.ts b/src/api/common/text/elements/bold.ts new file mode 100644 index 0000000000..ce25764457 --- /dev/null +++ b/src/api/common/text/elements/bold.ts @@ -0,0 +1,14 @@ +/** + * Bold + */ + +module.exports = text => { + const match = text.match(/^\*\*(.+?)\*\*/); + if (!match) return null; + const bold = match[0]; + return { + type: 'bold', + content: bold, + bold: bold.substr(2, bold.length - 4) + }; +}; diff --git a/src/api/common/text/elements/code.ts b/src/api/common/text/elements/code.ts new file mode 100644 index 0000000000..4821e95fe2 --- /dev/null +++ b/src/api/common/text/elements/code.ts @@ -0,0 +1,17 @@ +/** + * Code (block) + */ + +import genHtml from '../core/syntax-highlighter'; + +module.exports = text => { + const match = text.match(/^```([\s\S]+?)```/); + if (!match) return null; + const code = match[0]; + return { + type: 'code', + content: code, + code: code.substr(3, code.length - 6).trim(), + html: genHtml(code.substr(3, code.length - 6).trim()) + }; +}; diff --git a/src/api/common/text/elements/emoji.ts b/src/api/common/text/elements/emoji.ts new file mode 100644 index 0000000000..e24231a223 --- /dev/null +++ b/src/api/common/text/elements/emoji.ts @@ -0,0 +1,14 @@ +/** + * Emoji + */ + +module.exports = text => { + const match = text.match(/^:[a-zA-Z0-9+-_]+:/); + if (!match) return null; + const emoji = match[0]; + return { + type: 'emoji', + content: emoji, + emoji: emoji.substr(1, emoji.length - 2) + }; +}; diff --git a/src/api/common/text/elements/hashtag.ts b/src/api/common/text/elements/hashtag.ts new file mode 100644 index 0000000000..048dbd8929 --- /dev/null +++ b/src/api/common/text/elements/hashtag.ts @@ -0,0 +1,19 @@ +/** + * Hashtag + */ + +module.exports = (text, i) => { + if (!(/^\s#[^\s]+/.test(text) || (i == 0 && /^#[^\s]+/.test(text)))) return null; + const isHead = text[0] == '#'; + const hashtag = text.match(/^\s?#[^\s]+/)[0]; + const res = !isHead ? [{ + type: 'text', + content: text[0] + }] : []; + res.push({ + type: 'hashtag', + content: isHead ? hashtag : hashtag.substr(1), + hashtag: isHead ? hashtag.substr(1) : hashtag.substr(2) + }); + return res; +}; diff --git a/src/api/common/text/elements/inline-code.ts b/src/api/common/text/elements/inline-code.ts new file mode 100644 index 0000000000..9f9ef51a2b --- /dev/null +++ b/src/api/common/text/elements/inline-code.ts @@ -0,0 +1,17 @@ +/** + * Code (inline) + */ + +import genHtml from '../core/syntax-highlighter'; + +module.exports = text => { + const match = text.match(/^`(.+?)`/); + if (!match) return null; + const code = match[0]; + return { + type: 'inline-code', + content: code, + code: code.substr(1, code.length - 2).trim(), + html: genHtml(code.substr(1, code.length - 2).trim()) + }; +}; diff --git a/src/api/common/text/elements/link.ts b/src/api/common/text/elements/link.ts new file mode 100644 index 0000000000..35563ddc3d --- /dev/null +++ b/src/api/common/text/elements/link.ts @@ -0,0 +1,19 @@ +/** + * Link + */ + +module.exports = text => { + const match = text.match(/^\??\[([^\[\]]+?)\]\((https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+?)\)/); + if (!match) return null; + const silent = text[0] == '?'; + const link = match[0]; + const title = match[1]; + const url = match[2]; + return { + type: 'link', + content: link, + title: title, + url: url, + silent: silent + }; +}; diff --git a/src/api/common/text/elements/mention.ts b/src/api/common/text/elements/mention.ts new file mode 100644 index 0000000000..e0fac4dd76 --- /dev/null +++ b/src/api/common/text/elements/mention.ts @@ -0,0 +1,14 @@ +/** + * Mention + */ + +module.exports = text => { + const match = text.match(/^@[a-zA-Z0-9\-]+/); + if (!match) return null; + const mention = match[0]; + return { + type: 'mention', + content: mention, + username: mention.substr(1) + }; +}; diff --git a/src/api/common/text/elements/url.ts b/src/api/common/text/elements/url.ts new file mode 100644 index 0000000000..1003aff9c3 --- /dev/null +++ b/src/api/common/text/elements/url.ts @@ -0,0 +1,14 @@ +/** + * URL + */ + +module.exports = text => { + const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/); + if (!match) return null; + const url = match[0]; + return { + type: 'url', + content: url, + url: url + }; +}; diff --git a/src/api/common/text/index.ts b/src/api/common/text/index.ts new file mode 100644 index 0000000000..47127e8646 --- /dev/null +++ b/src/api/common/text/index.ts @@ -0,0 +1,71 @@ +/** + * Misskey Text Analyzer + */ + +const elements = [ + require('./elements/bold'), + require('./elements/url'), + require('./elements/link'), + require('./elements/mention'), + require('./elements/hashtag'), + require('./elements/code'), + require('./elements/inline-code'), + require('./elements/emoji') +]; + +export default (source: string) => { + + if (source == '') { + return null; + } + + const tokens = []; + + function push(token) { + if (token != null) { + tokens.push(token); + source = source.substr(token.content.length); + } + } + + let i = 0; + + // パース + while (source != '') { + const parsed = elements.some(el => { + let tokens = el(source, i); + if (tokens) { + if (!Array.isArray(tokens)) { + tokens = [tokens]; + } + tokens.forEach(push); + return true; + } else { + return false; + } + }); + + if (!parsed) { + push({ + type: 'text', + content: source[0] + }); + } + + i++; + } + + // テキストを纏める + tokens[0] = [tokens[0]]; + return tokens.reduce((a, b) => { + if (a[a.length - 1].type == 'text' && b.type == 'text') { + const tail = a.pop(); + return a.concat({ + type: 'text', + content: tail.content + b.content + }); + } else { + return a.concat(b); + } + }); +}; diff --git a/src/api/serializers/app.ts b/src/api/serializers/app.ts index fdeef338d9..9d1c46dca4 100644 --- a/src/api/serializers/app.ts +++ b/src/api/serializers/app.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/auth-session.ts b/src/api/serializers/auth-session.ts index 4efb7729c4..a9acf1243a 100644 --- a/src/api/serializers/auth-session.ts +++ b/src/api/serializers/auth-session.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/drive-file.ts b/src/api/serializers/drive-file.ts index e6e2f6cae3..b4e2ab064a 100644 --- a/src/api/serializers/drive-file.ts +++ b/src/api/serializers/drive-file.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/drive-folder.ts b/src/api/serializers/drive-folder.ts index ac3bd13c3a..34fdc0d905 100644 --- a/src/api/serializers/drive-folder.ts +++ b/src/api/serializers/drive-folder.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/drive-tag.ts b/src/api/serializers/drive-tag.ts index 3e800ca5bd..2f152381bd 100644 --- a/src/api/serializers/drive-tag.ts +++ b/src/api/serializers/drive-tag.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/messaging-message.ts b/src/api/serializers/messaging-message.ts index da63f8b99e..4ab95e42a3 100644 --- a/src/api/serializers/messaging-message.ts +++ b/src/api/serializers/messaging-message.ts @@ -1,13 +1,12 @@ -'use strict'; - /** * Module dependencies */ import * as mongo from 'mongodb'; +import deepcopy = require('deepcopy'); import Message from '../models/messaging-message'; import serializeUser from './user'; import serializeDriveFile from './drive-file'; -import deepcopy = require('deepcopy'); +import parse from '../common/text'; /** * Serialize a message @@ -47,6 +46,11 @@ export default ( _message.id = _message._id; delete _message._id; + // Parse text + if (_message.text) { + _message.ast = parse(_message.text); + } + // Populate user _message.user = await serializeUser(_message.user_id, me); diff --git a/src/api/serializers/notification.ts b/src/api/serializers/notification.ts index 43add127e0..50952e5426 100644 --- a/src/api/serializers/notification.ts +++ b/src/api/serializers/notification.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/post.ts b/src/api/serializers/post.ts index b71b42e9a4..f459529697 100644 --- a/src/api/serializers/post.ts +++ b/src/api/serializers/post.ts @@ -1,16 +1,15 @@ -'use strict'; - /** * Module dependencies */ import * as mongo from 'mongodb'; +import deepcopy = require('deepcopy'); import Post from '../models/post'; import Like from '../models/like'; import Vote from '../models/poll-vote'; import serializeApp from './app'; import serializeUser from './user'; import serializeDriveFile from './drive-file'; -import deepcopy = require('deepcopy'); +import parse from '../common/text'; /** * Serialize a post @@ -54,6 +53,11 @@ const self = ( delete _post.mentions; + // Parse text + if (_post.text) { + _post.ast = parse(_post.text); + } + // Populate user _post.user = await serializeUser(_post.user_id, me); diff --git a/src/api/serializers/signin.ts b/src/api/serializers/signin.ts index 39226f8bd4..4068067678 100644 --- a/src/api/serializers/signin.ts +++ b/src/api/serializers/signin.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/api/serializers/user.ts b/src/api/serializers/user.ts index de215808a4..d367dc8657 100644 --- a/src/api/serializers/user.ts +++ b/src/api/serializers/user.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Module dependencies */ diff --git a/src/common/text/core/syntax-highlighter.js b/src/common/text/core/syntax-highlighter.js deleted file mode 100644 index 06c59777e7..0000000000 --- a/src/common/text/core/syntax-highlighter.js +++ /dev/null @@ -1,332 +0,0 @@ -function escape(text) { - return text - .replace(/>/g, '>') - .replace(/ k[0].toUpperCase() + k.substr(1))) - .concat(_keywords.map(k => k.toUpperCase())) - .sort((a, b) => b.length - a.length); - -const symbols = [ - '=', - '+', - '-', - '*', - '/', - '%', - '~', - '^', - '&', - '|', - '>', - '<', - '!', - '?' -]; - -const elements = [ - // comment - code => { - if (code.substr(0, 2) != '//') return null; - const match = code.match(/^\/\/(.+?)\n/); - if (!match) return null; - const comment = match[0]; - return { - html: `${escape(comment)}`, - next: comment.length - }; - }, - - // block comment - code => { - const match = code.match(/^\/\*([\s\S]+?)\*\//); - if (!match) return null; - return { - html: `${escape(match[0])}`, - next: match[0].length - }; - }, - - // string - code => { - if (!/^['"`]/.test(code)) return null; - const begin = code[0]; - let str = begin; - let thisIsNotAString = false; - for (let i = 1; i < code.length; i++) { - const char = code[i]; - if (char == '\\') { - str += char; - str += code[i + 1] || ''; - i++; - continue; - } else if (char == begin) { - str += char; - break; - } else if (char == '\n' || i == (code.length - 1)) { - thisIsNotAString = true; - break; - } else { - str += char; - } - } - if (thisIsNotAString) { - return null; - } else { - return { - html: `${escape(str)}`, - next: str.length - }; - } - }, - - // regexp - code => { - if (code[0] != '/') return null; - let regexp = ''; - let thisIsNotARegexp = false; - for (let i = 1; i < code.length; i++) { - const char = code[i]; - if (char == '\\') { - regexp += char; - regexp += code[i + 1] || ''; - i++; - continue; - } else if (char == '/') { - break; - } else if (char == '\n' || i == (code.length - 1)) { - thisIsNotARegexp = true; - break; - } else { - regexp += char; - } - } - - if (thisIsNotARegexp) return null; - if (regexp == '') return null; - if (regexp[0] == ' ' && regexp[regexp.length - 1] == ' ') return null; - - return { - html: `/${escape(regexp)}/`, - next: regexp.length + 2 - }; - }, - - // label - code => { - if (code[0] != '@') return null; - const match = code.match(/^@([a-zA-Z_-]+?)\n/); - if (!match) return null; - const label = match[0]; - return { - html: `${label}`, - next: label.length - }; - }, - - // number - (code, i, source) => { - const prev = source[i - 1]; - if (prev && /[a-zA-Z]/.test(prev)) return null; - if (!/^[\-\+]?[0-9\.]+/.test(code)) return null; - const match = code.match(/^[\-\+]?[0-9\.]+/)[0]; - if (match) { - return { - html: `${match}`, - next: match.length - }; - } else { - return null; - } - }, - - // nan - (code, i, source) => { - const prev = source[i - 1]; - if (prev && /[a-zA-Z]/.test(prev)) return null; - if (code.substr(0, 3) == 'NaN') { - return { - html: `NaN`, - next: 3 - }; - } else { - return null; - } - }, - - // method - code => { - const match = code.match(/^([a-zA-Z_-]+?)\(/); - if (!match) return null; - - if (match[1] == '-') return null; - - return { - html: `${match[1]}`, - next: match[1].length - }; - }, - - // property - (code, i, source) => { - const prev = source[i - 1]; - if (prev != '.') return null; - - const match = code.match(/^[a-zA-Z0-9_-]+/); - if (!match) return null; - - return { - html: `${match[0]}`, - next: match[0].length - }; - }, - - // keyword - (code, i, source) => { - const prev = source[i - 1]; - if (prev && /[a-zA-Z]/.test(prev)) return null; - - const match = keywords.filter(k => code.substr(0, k.length) == k)[0]; - if (match) { - if (/^[a-zA-Z]/.test(code.substr(match.length))) return null; - return { - html: `${match}`, - next: match.length - }; - } else { - return null; - } - }, - - // symbol - code => { - const match = symbols.filter(s => code[0] == s)[0]; - if (match) { - return { - html: `${match}`, - next: 1 - }; - } else { - return null; - } - } -]; - -// specify lang is todo -module.exports = (source, lang) => { - let code = source; - let html = ''; - - let i = 0; - - function push(token) { - html += token.html; - code = code.substr(token.next); - i += token.next; - } - - while (code != '') { - const parsed = elements.some(el => { - const e = el(code, i, source); - if (e) { - push(e); - return true; - } - }); - - if (!parsed) { - push({ - html: escape(code[0]), - next: 1 - }); - } - } - - return html; -}; diff --git a/src/common/text/elements/bold.js b/src/common/text/elements/bold.js deleted file mode 100644 index ce25764457..0000000000 --- a/src/common/text/elements/bold.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Bold - */ - -module.exports = text => { - const match = text.match(/^\*\*(.+?)\*\*/); - if (!match) return null; - const bold = match[0]; - return { - type: 'bold', - content: bold, - bold: bold.substr(2, bold.length - 4) - }; -}; diff --git a/src/common/text/elements/code.js b/src/common/text/elements/code.js deleted file mode 100644 index 99fe6a183c..0000000000 --- a/src/common/text/elements/code.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Code (block) - */ - -const genHtml = require('../core/syntax-highlighter'); - -module.exports = text => { - const match = text.match(/^```([\s\S]+?)```/); - if (!match) return null; - const code = match[0]; - return { - type: 'code', - content: code, - code: code.substr(3, code.length - 6).trim(), - html: genHtml(code.substr(3, code.length - 6).trim()) - }; -}; diff --git a/src/common/text/elements/emoji.js b/src/common/text/elements/emoji.js deleted file mode 100644 index e24231a223..0000000000 --- a/src/common/text/elements/emoji.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Emoji - */ - -module.exports = text => { - const match = text.match(/^:[a-zA-Z0-9+-_]+:/); - if (!match) return null; - const emoji = match[0]; - return { - type: 'emoji', - content: emoji, - emoji: emoji.substr(1, emoji.length - 2) - }; -}; diff --git a/src/common/text/elements/hashtag.js b/src/common/text/elements/hashtag.js deleted file mode 100644 index 048dbd8929..0000000000 --- a/src/common/text/elements/hashtag.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Hashtag - */ - -module.exports = (text, i) => { - if (!(/^\s#[^\s]+/.test(text) || (i == 0 && /^#[^\s]+/.test(text)))) return null; - const isHead = text[0] == '#'; - const hashtag = text.match(/^\s?#[^\s]+/)[0]; - const res = !isHead ? [{ - type: 'text', - content: text[0] - }] : []; - res.push({ - type: 'hashtag', - content: isHead ? hashtag : hashtag.substr(1), - hashtag: isHead ? hashtag.substr(1) : hashtag.substr(2) - }); - return res; -}; diff --git a/src/common/text/elements/inline-code.js b/src/common/text/elements/inline-code.js deleted file mode 100644 index 37e9b1a0ff..0000000000 --- a/src/common/text/elements/inline-code.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Code (inline) - */ - -const genHtml = require('../core/syntax-highlighter'); - -module.exports = text => { - const match = text.match(/^`(.+?)`/); - if (!match) return null; - const code = match[0]; - return { - type: 'inline-code', - content: code, - code: code.substr(1, code.length - 2).trim(), - html: genHtml(code.substr(1, code.length - 2).trim()) - }; -}; diff --git a/src/common/text/elements/link.js b/src/common/text/elements/link.js deleted file mode 100644 index 35563ddc3d..0000000000 --- a/src/common/text/elements/link.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Link - */ - -module.exports = text => { - const match = text.match(/^\??\[([^\[\]]+?)\]\((https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+?)\)/); - if (!match) return null; - const silent = text[0] == '?'; - const link = match[0]; - const title = match[1]; - const url = match[2]; - return { - type: 'link', - content: link, - title: title, - url: url, - silent: silent - }; -}; diff --git a/src/common/text/elements/mention.js b/src/common/text/elements/mention.js deleted file mode 100644 index e0fac4dd76..0000000000 --- a/src/common/text/elements/mention.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Mention - */ - -module.exports = text => { - const match = text.match(/^@[a-zA-Z0-9\-]+/); - if (!match) return null; - const mention = match[0]; - return { - type: 'mention', - content: mention, - username: mention.substr(1) - }; -}; diff --git a/src/common/text/elements/url.js b/src/common/text/elements/url.js deleted file mode 100644 index 1003aff9c3..0000000000 --- a/src/common/text/elements/url.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * URL - */ - -module.exports = text => { - const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.=\+\-]+/); - if (!match) return null; - const url = match[0]; - return { - type: 'url', - content: url, - url: url - }; -}; diff --git a/src/common/text/index.js b/src/common/text/index.js deleted file mode 100644 index ab1342230c..0000000000 --- a/src/common/text/index.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Misskey Text Analyzer - */ - -const elements = [ - require('./elements/bold'), - require('./elements/url'), - require('./elements/link'), - require('./elements/mention'), - require('./elements/hashtag'), - require('./elements/code'), - require('./elements/inline-code'), - require('./elements/emoji') -]; - -function analyze(source) { - - if (source == '') { - return null; - } - - const tokens = []; - - function push(token) { - if (token != null) { - tokens.push(token); - source = source.substr(token.content.length); - } - } - - let i = 0; - - // パース - while (source != '') { - const parsed = elements.some(el => { - let tokens = el(source, i); - if (tokens) { - if (!Array.isArray(tokens)) { - tokens = [tokens]; - } - tokens.forEach(push); - return true; - } - }); - - if (!parsed) { - push({ - type: 'text', - content: source[0] - }); - } - - i++; - } - - // テキストを纏める - tokens[0] = [tokens[0]]; - return tokens.reduce((a, b) => { - if (a[a.length - 1].type == 'text' && b.type == 'text') { - const tail = a.pop(); - return a.concat({ - type: 'text', - content: tail.content + b.content - }); - } else { - return a.concat(b); - } - }); -} - -module.exports = analyze; diff --git a/src/web/app/auth/script.js b/src/web/app/auth/script.js index cded308091..19391b2b9e 100644 --- a/src/web/app/auth/script.js +++ b/src/web/app/auth/script.js @@ -5,10 +5,11 @@ // Style import './style.styl'; -const riot = require('riot'); -document.title = 'Misskey | アプリの連携'; +import * as riot from 'riot'; require('./tags'); -const boot = require('../boot.js'); +import boot from '../boot'; + +document.title = 'Misskey | アプリの連携'; /** * Boot diff --git a/src/web/app/boot.js b/src/web/app/boot.js index 4d008ad66f..24981c5889 100644 --- a/src/web/app/boot.js +++ b/src/web/app/boot.js @@ -2,12 +2,14 @@ * boot */ -const riot = require('riot'); +import * as riot from 'riot'; require('velocity-animate'); -const api = require('./common/scripts/api'); -const signout = require('./common/scripts/signout'); -const generateDefaultUserdata = require('./common/scripts/generate-default-userdata'); -const mixins = require('./common/mixins'); +import api from './common/scripts/api'; +import signout from './common/scripts/signout'; +import checkForUpdate from './common/scripts/check-for-update'; +import mixin from './common/mixins'; +import generateDefaultUserdata from './common/scripts/generate-default-userdata'; +import CONFIG from './common/scripts/config'; require('./common/tags'); /** @@ -16,7 +18,7 @@ require('./common/tags'); "use strict"; -const CONFIG = require('./common/scripts/config'); +console.info(`Misskey v${VERSION}`); document.domain = CONFIG.host; @@ -56,21 +58,10 @@ if (localStorage.getItem('should-refresh') == 'true') { } // 更新チェック -setTimeout(() => { - fetch(CONFIG.apiUrl + '/meta', { - method: 'POST' - }).then(res => { - res.json().then(meta => { - if (meta.version != VERSION) { - localStorage.setItem('should-refresh', 'true'); - alert('Misskeyの新しいバージョンがあります。ページを再度読み込みすると更新が適用されます。'); - } - }); - }); -}, 3000); +setTimeout(checkForUpdate, 3000); // ユーザーをフェッチしてコールバックする -module.exports = callback => { +export default callback => { // Get cached account data let cachedMe = JSON.parse(localStorage.getItem('me')); @@ -113,7 +104,7 @@ module.exports = callback => { } } - mixins(me); + mixin(me); const ini = document.getElementById('ini'); ini.parentNode.removeChild(ini); diff --git a/src/web/app/client/script.js b/src/web/app/client/script.js index ffc9c892cd..ee07edd60d 100644 --- a/src/web/app/client/script.js +++ b/src/web/app/client/script.js @@ -1,5 +1,5 @@ /** - * MISSKEY ENTRY POINT + * MISSKEY CLIENT ENTRY POINT */ (() => { const head = document.getElementsByTagName('head')[0]; diff --git a/src/web/app/common/mixins.js b/src/web/app/common/mixins.js deleted file mode 100644 index 220e033846..0000000000 --- a/src/web/app/common/mixins.js +++ /dev/null @@ -1,48 +0,0 @@ -const riot = require('riot'); - -module.exports = me => { - const i = me ? me.token : null; - - require('./scripts/i')(me); - - riot.mixin('api', { - api: require('./scripts/api').bind(null, i) - }); - - riot.mixin('cropper', { - Cropper: require('cropperjs') - }); - - riot.mixin('signout', { - signout: require('./scripts/signout') - }); - - riot.mixin('messaging-stream', { - MessagingStreamConnection: require('./scripts/messaging-stream') - }); - - riot.mixin('is-promise', { - isPromise: require('./scripts/is-promise') - }); - - riot.mixin('get-post-summary', { - getPostSummary: require('./scripts/get-post-summary') - }); - - riot.mixin('date-stringify', { - dateStringify: require('./scripts/date-stringify') - }); - - riot.mixin('text', { - analyze: require('../../../common/text/index'), - compile: require('./scripts/text-compiler') - }); - - riot.mixin('get-password-strength', { - getPasswordStrength: require('syuilo-password-strength') - }); - - riot.mixin('ui-progress', { - Progress: require('./scripts/loading') - }); -}; diff --git a/src/web/app/common/mixins/api.js b/src/web/app/common/mixins/api.js new file mode 100644 index 0000000000..42d96db559 --- /dev/null +++ b/src/web/app/common/mixins/api.js @@ -0,0 +1,8 @@ +import * as riot from 'riot'; +import api from '../scripts/api'; + +export default me => { + riot.mixin('api', { + api: api.bind(null, me ? me.token : null) + }); +}; diff --git a/src/web/app/common/mixins/i.js b/src/web/app/common/mixins/i.js new file mode 100644 index 0000000000..5225147766 --- /dev/null +++ b/src/web/app/common/mixins/i.js @@ -0,0 +1,20 @@ +import * as riot from 'riot'; + +export default me => { + riot.mixin('i', { + init: function() { + this.I = me; + this.SIGNIN = me != null; + + if (this.SIGNIN) { + this.on('mount', () => { + me.on('updated', this.update); + }); + this.on('unmount', () => { + me.off('updated', this.update); + }); + } + }, + me: me + }); +}; diff --git a/src/web/app/common/mixins/index.js b/src/web/app/common/mixins/index.js new file mode 100644 index 0000000000..29cb6c9b6a --- /dev/null +++ b/src/web/app/common/mixins/index.js @@ -0,0 +1,9 @@ +import activateMe from './i'; +import activateApi from './api'; +import activateStream from './stream'; + +export default me => { + activateMe(me); + activateApi(me); + activateStream(me); +}; diff --git a/src/web/app/common/mixins/stream.js b/src/web/app/common/mixins/stream.js new file mode 100644 index 0000000000..e3b616a1a5 --- /dev/null +++ b/src/web/app/common/mixins/stream.js @@ -0,0 +1,9 @@ +import * as riot from 'riot'; +import Connection from '../scripts/stream'; + +export default me => { + const stream = me ? new Connection(me) : null; + riot.mixin('stream', { + stream: stream + }); +}; diff --git a/src/web/app/common/scripts/api.js b/src/web/app/common/scripts/api.js index 3df54b645a..4855f736c7 100644 --- a/src/web/app/common/scripts/api.js +++ b/src/web/app/common/scripts/api.js @@ -2,7 +2,7 @@ * API Request */ -const CONFIG = require('./config'); +import CONFIG from './config'; let spinner = null; let pending = 0; @@ -14,7 +14,7 @@ let pending = 0; * @param {any} [data={}] Data * @return {Promise} Response */ -module.exports = (i, endpoint, data = {}) => { +export default (i, endpoint, data = {}) => { if (++pending === 1) { spinner = document.createElement('div'); spinner.setAttribute('id', 'wait'); diff --git a/src/web/app/common/scripts/bytes-to-size.js b/src/web/app/common/scripts/bytes-to-size.js index 717f9ad507..e143387141 100644 --- a/src/web/app/common/scripts/bytes-to-size.js +++ b/src/web/app/common/scripts/bytes-to-size.js @@ -1,6 +1,6 @@ -module.exports = function(bytes) { +export default bytes => { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if (bytes == 0) return '0Byte'; var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); return Math.round(bytes / Math.pow(1024, i), 2) + sizes[i]; -} +}; diff --git a/src/web/app/common/scripts/check-for-update.js b/src/web/app/common/scripts/check-for-update.js new file mode 100644 index 0000000000..637e6a9fb8 --- /dev/null +++ b/src/web/app/common/scripts/check-for-update.js @@ -0,0 +1,14 @@ +import CONFIG from './config'; + +export default function() { + fetch(CONFIG.apiUrl + '/meta', { + method: 'POST' + }).then(res => { + res.json().then(meta => { + if (meta.version != VERSION) { + localStorage.setItem('should-refresh', 'true'); + alert('Misskeyの新しいバージョンがあります。ページを再度読み込みすると更新が適用されます。'); + } + }); + }); +}; diff --git a/src/web/app/common/scripts/config.js b/src/web/app/common/scripts/config.js index 4203431bd0..16f75d6e16 100644 --- a/src/web/app/common/scripts/config.js +++ b/src/web/app/common/scripts/config.js @@ -9,7 +9,7 @@ const apiUrl = `${scheme}//api.${host}`; const devUrl = `${scheme}//dev.${host}`; const aboutUrl = `${scheme}//about.${host}`; -module.exports = { +export default { host, scheme, url, diff --git a/src/web/app/common/scripts/contains.js b/src/web/app/common/scripts/contains.js index fe73666193..a5071b3f25 100644 --- a/src/web/app/common/scripts/contains.js +++ b/src/web/app/common/scripts/contains.js @@ -1,8 +1,8 @@ -module.exports = function(parent, child) { +export default (parent, child) => { let node = child.parentNode; while (node) { if (node == parent) return true; node = node.parentNode; } return false; -} +}; diff --git a/src/web/app/common/scripts/copy-to-clipboard.js b/src/web/app/common/scripts/copy-to-clipboard.js index 2e67024c85..3d2741f8d7 100644 --- a/src/web/app/common/scripts/copy-to-clipboard.js +++ b/src/web/app/common/scripts/copy-to-clipboard.js @@ -1,7 +1,7 @@ /** * Clipboardに値をコピー(TODO: 文字列以外も対応) */ -module.exports = val => { +export default val => { const form = document.createElement('textarea'); form.textContent = val; document.body.appendChild(form); diff --git a/src/web/app/common/scripts/date-stringify.js b/src/web/app/common/scripts/date-stringify.js index d803587f2c..e51de8833d 100644 --- a/src/web/app/common/scripts/date-stringify.js +++ b/src/web/app/common/scripts/date-stringify.js @@ -1,12 +1,12 @@ -module.exports = date => { +export default date => { if (typeof date == 'string') date = new Date(date); return ( - date.getFullYear() + '年' + - (date.getMonth() + 1) + '月' + + date.getFullYear() + '年' + + (date.getMonth() + 1) + '月' + date.getDate() + '日' + ' ' + - date.getHours() + '時' + - date.getMinutes() + '分' + + date.getHours() + '時' + + date.getMinutes() + '分' + ' ' + `(${['日', '月', '火', '水', '木', '金', '土'][date.getDay()]})` ); diff --git a/src/web/app/common/scripts/gcd.js b/src/web/app/common/scripts/gcd.js index 43bfbc57ae..9a19f9da66 100644 --- a/src/web/app/common/scripts/gcd.js +++ b/src/web/app/common/scripts/gcd.js @@ -1,2 +1,2 @@ const gcd = (a, b) => !b ? a : gcd(b, a % b); -module.exports = gcd; +export default gcd; diff --git a/src/web/app/common/scripts/generate-default-userdata.js b/src/web/app/common/scripts/generate-default-userdata.js index fbe2e99075..c19228dd49 100644 --- a/src/web/app/common/scripts/generate-default-userdata.js +++ b/src/web/app/common/scripts/generate-default-userdata.js @@ -1,4 +1,4 @@ -const uuid = require('./uuid.js'); +import uuid from './uuid'; const home = { left: [ @@ -17,7 +17,7 @@ const home = { ] }; -module.exports = () => { +export default () => { const homeData = []; home.left.forEach(widget => { diff --git a/src/web/app/common/scripts/get-cat.js b/src/web/app/common/scripts/get-cat.js index cd28c7bdaa..cad42c88c8 100644 --- a/src/web/app/common/scripts/get-cat.js +++ b/src/web/app/common/scripts/get-cat.js @@ -1,3 +1 @@ -module.exports = () => { - return '(=^・・^=)'; -}; +export default () => '(=^・・^=)'; diff --git a/src/web/app/common/scripts/get-post-summary.js b/src/web/app/common/scripts/get-post-summary.js index 5e8319b61c..83eda8f6b4 100644 --- a/src/web/app/common/scripts/get-post-summary.js +++ b/src/web/app/common/scripts/get-post-summary.js @@ -32,4 +32,4 @@ const summarize = post => { return summary.trim(); }; -module.exports = summarize; +export default summarize; diff --git a/src/web/app/common/scripts/i.js b/src/web/app/common/scripts/i.js deleted file mode 100644 index 20c33c6402..0000000000 --- a/src/web/app/common/scripts/i.js +++ /dev/null @@ -1,20 +0,0 @@ -const riot = require('riot'); - -module.exports = me => { - riot.mixin('i', { - init: function() { - this.I = me; - this.SIGNIN = me != null; - - if (this.SIGNIN) { - this.on('mount', () => { - me.on('updated', this.update); - }); - this.on('unmount', () => { - me.off('updated', this.update); - }); - } - }, - me: me - }); -}; diff --git a/src/web/app/common/scripts/is-promise.js b/src/web/app/common/scripts/is-promise.js index fd3dc42da3..3b4cd70b49 100644 --- a/src/web/app/common/scripts/is-promise.js +++ b/src/web/app/common/scripts/is-promise.js @@ -1 +1 @@ -module.exports = x => typeof x.then == 'function'; +export default x => typeof x.then == 'function'; diff --git a/src/web/app/common/scripts/loading.js b/src/web/app/common/scripts/loading.js index fa7eafaf96..c48e626648 100644 --- a/src/web/app/common/scripts/loading.js +++ b/src/web/app/common/scripts/loading.js @@ -6,7 +6,7 @@ NProgress.configure({ const root = document.getElementsByTagName('html')[0]; -module.exports = { +export default { start: () => { root.classList.add('progress'); NProgress.start(); diff --git a/src/web/app/common/scripts/messaging-stream.js b/src/web/app/common/scripts/messaging-stream.js index 0c8ce3c9d2..50d41c2be9 100644 --- a/src/web/app/common/scripts/messaging-stream.js +++ b/src/web/app/common/scripts/messaging-stream.js @@ -1,6 +1,6 @@ const ReconnectingWebSocket = require('reconnecting-websocket'); -const riot = require('riot'); -const CONFIG = require('./config'); +import * as riot from 'riot'; +import CONFIG from './config'; class Connection { constructor(me, otherparty) { @@ -40,4 +40,4 @@ class Connection { } } -module.exports = Connection; +export default Connection; diff --git a/src/web/app/common/scripts/signout.js b/src/web/app/common/scripts/signout.js index 7242ebc5b0..6c95cfbc9c 100644 --- a/src/web/app/common/scripts/signout.js +++ b/src/web/app/common/scripts/signout.js @@ -1,6 +1,6 @@ -const CONFIG = require('./config'); +import CONFIG from './config'; -module.exports = () => { +export default () => { localStorage.removeItem('me'); document.cookie = `i=; domain=.${CONFIG.host}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`; location.href = '/'; diff --git a/src/web/app/common/scripts/stream.js b/src/web/app/common/scripts/stream.js index fd7bac7faa..d6e6bf8aa5 100644 --- a/src/web/app/common/scripts/stream.js +++ b/src/web/app/common/scripts/stream.js @@ -1,40 +1,53 @@ const ReconnectingWebSocket = require('reconnecting-websocket'); -const riot = require('riot'); -const CONFIG = require('./config'); - -module.exports = me => { - let state = 'initializing'; - const stateEv = riot.observable(); - const event = riot.observable(); - const host = CONFIG.apiUrl.replace('http', 'ws'); - const socket = new ReconnectingWebSocket(`${host}?i=${me.token}`); - - socket.onopen = () => { - state = 'connected'; - stateEv.trigger('connected'); - }; - - socket.onclose = () => { - state = 'reconnecting'; - stateEv.trigger('closed'); - }; - - socket.onmessage = message => { +import * as riot from 'riot'; +import CONFIG from './config'; + +class Connection { + constructor(me) { + // BIND ----------------------------------- + this.onOpen = this.onOpen.bind(this); + this.onClose = this.onClose.bind(this); + this.onMessage = this.onMessage.bind(this); + this.close = this.close.bind(this); + // ---------------------------------------- + + this.state = 'initializing'; + this.stateEv = riot.observable(); + this.event = riot.observable(); + this.me = me; + + const host = CONFIG.apiUrl.replace('http', 'ws'); + this.socket = new ReconnectingWebSocket(`${host}?i=${me.token}`); + this.socket.addEventListener('open', this.onOpen); + this.socket.addEventListener('close', this.onClose); + this.socket.addEventListener('message', this.onMessage); + + this.event.on('i_updated', me.update); + } + + onOpen() { + this.state = 'connected'; + this.stateEv.trigger('connected'); + } + + onClose() { + this.state = 'reconnecting'; + this.stateEv.trigger('closed'); + } + + onMessage(message) { try { const msg = JSON.parse(message.data); - if (msg.type) { - event.trigger(msg.type, msg.body); - } - } catch (e) { + if (msg.type) this.event.trigger(msg.type, msg.body); + } catch(e) { // noop } - }; + } - event.on('i_updated', me.update); + close() { + this.socket.removeEventListener('open', this.onOpen); + this.socket.removeEventListener('message', this.onMessage); + } +} - return { - stateEv: stateEv, - getState: () => state, - event: event - }; -}; +export default Connection; diff --git a/src/web/app/common/scripts/text-compiler.js b/src/web/app/common/scripts/text-compiler.js index d4570ca923..1743a549aa 100644 --- a/src/web/app/common/scripts/text-compiler.js +++ b/src/web/app/common/scripts/text-compiler.js @@ -1,13 +1,13 @@ -const riot = require('riot'); +import * as riot from 'riot'; //const emojinize = require('emojinize'); -const CONFIG = require('./config'); +import CONFIG from './config'; const escape = text => text .replace(/>/g, '>') .replace(/ { +export default (tokens, shouldBreak) => { if (shouldBreak == null) { shouldBreak = true; } @@ -20,21 +20,21 @@ module.exports = (tokens, shouldBreak) => { return escape(token.content) .replace(/(\r\n|\n|\r)/g, shouldBreak ? '
' : ' '); case 'bold': - return '' + escape(token.bold) + ''; + return `${escape(token.bold)}`; case 'url': - return ''; + return ``; case 'link': - return '' + escape(token.title) + ''; + return `${escape(token.title)}`; case 'mention': - return '' + token.content + ''; + return `${token.content}`; case 'hashtag': // TODO - return '' + escape(token.content) + ''; + return `${escape(token.content)}`; case 'code': - return '
' + token.html + '
'; + return `
${token.html}
`; case 'inline-code': - return '' + token.html + ''; + return `${token.html}`; case 'emoji': - return '' + token.content + ''; + return `${token.content}`; //return emojinize.encode(token.content) } }).join(''); diff --git a/src/web/app/common/scripts/uuid.js b/src/web/app/common/scripts/uuid.js index 6161190d63..6a103d6e04 100644 --- a/src/web/app/common/scripts/uuid.js +++ b/src/web/app/common/scripts/uuid.js @@ -1,12 +1,12 @@ -module.exports = function () { +export default () => { var uuid = '', i, random; for (i = 0; i < 32; i++) { random = Math.random() * 16 | 0; if (i == 8 || i == 12 || i == 16 || i == 20) { - uuid += '-' + uuid += '-'; } uuid += (i == 12 ? 4 : (i == 16 ? (random & 3 | 8) : random)).toString(16); } return uuid; -} +}; diff --git a/src/web/app/common/tags/introduction.tag b/src/web/app/common/tags/introduction.tag index fda011efff..fa1b1e247a 100644 --- a/src/web/app/common/tags/introduction.tag +++ b/src/web/app/common/tags/introduction.tag @@ -1,9 +1,9 @@
-

Misskeyとは?

Misskeyみすきーは、syuiloが2014年くらいからオープンソースで開発・運営を行っている、ミニブログベースのSNSです。

-

Twitter, Facebook, LINE, Google+ などをパクって参考にしています。

-

無料で誰でも利用でき、広告は一切掲載していません。

-

もっと知りたい方はこちら

+

Misskeyとは?

+

Misskeyみすきーは、syuiloが2014年くらいからオープンソースで開発・運営を行っている、ミニブログベースのSNSです。

+

無料で誰でも利用でき、広告も掲載していません。

+

もっと知りたい方はこちら

diff --git a/src/web/app/common/tags/raw.tag b/src/web/app/common/tags/raw.tag index 0637675c45..e1285694e4 100644 --- a/src/web/app/common/tags/raw.tag +++ b/src/web/app/common/tags/raw.tag @@ -2,7 +2,8 @@ - + diff --git a/src/web/app/common/tags/signin-history.tag b/src/web/app/common/tags/signin-history.tag index 3868980058..00b0cecced 100644 --- a/src/web/app/common/tags/signin-history.tag +++ b/src/web/app/common/tags/signin-history.tag @@ -48,9 +48,12 @@ diff --git a/src/web/app/desktop/tags/drive/file.tag b/src/web/app/desktop/tags/drive/file.tag index 519d04f6dc..7da0f8b0d0 100644 --- a/src/web/app/desktop/tags/drive/file.tag +++ b/src/web/app/desktop/tags/drive/file.tag @@ -144,13 +144,13 @@ diff --git a/src/web/app/desktop/tags/home-widgets/rss-reader.tag b/src/web/app/desktop/tags/home-widgets/rss-reader.tag index c8700a8b63..b8cfd8bddc 100644 --- a/src/web/app/desktop/tags/home-widgets/rss-reader.tag +++ b/src/web/app/desktop/tags/home-widgets/rss-reader.tag @@ -65,7 +65,6 @@ diff --git a/src/web/app/desktop/tags/home-widgets/timeline.tag b/src/web/app/desktop/tags/home-widgets/timeline.tag index a0a8790eaa..f4c870b99c 100644 --- a/src/web/app/desktop/tags/home-widgets/timeline.tag +++ b/src/web/app/desktop/tags/home-widgets/timeline.tag @@ -36,15 +36,17 @@ this.mixin('api'); this.mixin('stream'); + const stream = this.stream.event; + this.isLoading = true; this.isEmpty = false; this.moreLoading = false; this.noFollowing = this.I.following_count == 0; this.on('mount', () => { - this.stream.on('post', this.onStreamPost); - this.stream.on('follow', this.onStreamFollow); - this.stream.on('unfollow', this.onStreamUnfollow); + stream.on('post', this.onStreamPost); + stream.on('follow', this.onStreamFollow); + stream.on('unfollow', this.onStreamUnfollow); document.addEventListener('keydown', this.onDocumentKeydown); window.addEventListener('scroll', this.onScroll); @@ -53,9 +55,9 @@ }); this.on('unmount', () => { - this.stream.off('post', this.onStreamPost); - this.stream.off('follow', this.onStreamFollow); - this.stream.off('unfollow', this.onStreamUnfollow); + stream.off('post', this.onStreamPost); + stream.off('follow', this.onStreamFollow); + stream.off('unfollow', this.onStreamUnfollow); document.removeEventListener('keydown', this.onDocumentKeydown); window.removeEventListener('scroll', this.onScroll); diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag index 7ba74412ea..d459b7f31a 100644 --- a/src/web/app/desktop/tags/notifications.tag +++ b/src/web/app/desktop/tags/notifications.tag @@ -177,10 +177,15 @@ diff --git a/src/web/app/desktop/tags/pages/search.tag b/src/web/app/desktop/tags/pages/search.tag index ace9e27ab9..7a97e4781d 100644 --- a/src/web/app/desktop/tags/pages/search.tag +++ b/src/web/app/desktop/tags/pages/search.tag @@ -7,13 +7,13 @@ display block diff --git a/src/web/app/desktop/tags/pages/user.tag b/src/web/app/desktop/tags/pages/user.tag index 767af31e9a..9e35383088 100644 --- a/src/web/app/desktop/tags/pages/user.tag +++ b/src/web/app/desktop/tags/pages/user.tag @@ -7,20 +7,20 @@ display block diff --git a/src/web/app/desktop/tags/post-detail-sub.tag b/src/web/app/desktop/tags/post-detail-sub.tag index 2de123d1ac..a0473eb709 100644 --- a/src/web/app/desktop/tags/post-detail-sub.tag +++ b/src/web/app/desktop/tags/post-detail-sub.tag @@ -115,8 +115,10 @@ diff --git a/src/web/app/desktop/tags/repost-form.tag b/src/web/app/desktop/tags/repost-form.tag index 2bbed8aca7..b7a25fc1dd 100644 --- a/src/web/app/desktop/tags/repost-form.tag +++ b/src/web/app/desktop/tags/repost-form.tag @@ -85,8 +85,9 @@ diff --git a/src/web/app/desktop/tags/timeline-post.tag b/src/web/app/desktop/tags/timeline-post.tag index 8929a8dd5a..0559aaf6a0 100644 --- a/src/web/app/desktop/tags/timeline-post.tag +++ b/src/web/app/desktop/tags/timeline-post.tag @@ -55,7 +55,7 @@ -