diff --git a/gulpfile.ts b/gulpfile.ts
index 3b7a12640..21870473e 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -20,16 +20,8 @@ import * as mocha from 'gulp-mocha';
import * as replace from 'gulp-replace';
import * as htmlmin from 'gulp-htmlmin';
const uglifyes = require('uglify-es');
-import * as fontawesome from '@fortawesome/fontawesome';
-import * as regular from '@fortawesome/fontawesome-free-regular';
-import * as solid from '@fortawesome/fontawesome-free-solid';
-import * as brands from '@fortawesome/fontawesome-free-brands';
-
-// Add icons
-fontawesome.library.add(regular);
-fontawesome.library.add(solid);
-fontawesome.library.add(brands);
+import { fa } from './src/common/build/fa';
import version from './src/version';
import config from './src/conf';
@@ -179,7 +171,7 @@ gulp.task('build:client:pug', [
.pipe(pug({
locals: {
themeColor: constants.themeColor,
- facss: fontawesome.dom.css(),
+ facss: fa.dom.css(),
//hljscss: fs.readFileSync('./node_modules/highlight.js/styles/default.css', 'utf8')
hljscss: fs.readFileSync('./src/web/assets/code-highlight.css', 'utf8')
}
diff --git a/src/common/build/fa.ts b/src/common/build/fa.ts
new file mode 100644
index 000000000..0c21be950
--- /dev/null
+++ b/src/common/build/fa.ts
@@ -0,0 +1,57 @@
+/**
+ * Replace fontawesome symbols
+ */
+
+import * as fontawesome from '@fortawesome/fontawesome';
+import * as regular from '@fortawesome/fontawesome-free-regular';
+import * as solid from '@fortawesome/fontawesome-free-solid';
+import * as brands from '@fortawesome/fontawesome-free-brands';
+
+// Add icons
+fontawesome.library.add(regular);
+fontawesome.library.add(solid);
+fontawesome.library.add(brands);
+
+export const pattern = /%fa:(.+?)%/g;
+
+export const replacement = (_, key) => {
+ const args = key.split(' ');
+ let prefix = 'fas';
+ const classes = [];
+ let transform = '';
+ let name;
+
+ args.forEach(arg => {
+ if (arg == 'R' || arg == 'S' || arg == 'B') {
+ prefix =
+ arg == 'R' ? 'far' :
+ arg == 'S' ? 'fas' :
+ arg == 'B' ? 'fab' :
+ '';
+ } else if (arg[0] == '.') {
+ classes.push('fa-' + arg.substr(1));
+ } else if (arg[0] == '-') {
+ transform = arg.substr(1).split('|').join(' ');
+ } else {
+ name = arg;
+ }
+ });
+
+ const icon = fontawesome.icon({ prefix, iconName: name }, {
+ classes: classes
+ });
+
+ if (icon) {
+ icon.transform = fontawesome.parse.transform(transform);
+ return `${icon.html[0]}`;
+ } else {
+ console.warn(`'${name}' not found in fa`);
+ return '';
+ }
+};
+
+export default (src: string) => {
+ return src.replace(pattern, replacement);
+};
+
+export const fa = fontawesome;
diff --git a/src/common/build/i18n.ts b/src/common/build/i18n.ts
new file mode 100644
index 000000000..1ae22147c
--- /dev/null
+++ b/src/common/build/i18n.ts
@@ -0,0 +1,50 @@
+/**
+ * Replace i18n texts
+ */
+
+import locale from '../../../locales';
+
+export default class Replacer {
+ private lang: string;
+
+ public pattern = /"%i18n:(.+?)%"|'%i18n:(.+?)%'|%i18n:(.+?)%/g;
+
+ constructor(lang: string) {
+ this.lang = lang;
+
+ this.get = this.get.bind(this);
+ this.replacement = this.replacement.bind(this);
+ }
+
+ private get(key: string) {
+ let text = locale[this.lang];
+
+ // Check the key existance
+ const error = key.split('.').some(k => {
+ if (text.hasOwnProperty(k)) {
+ text = text[k];
+ return false;
+ } else {
+ return true;
+ }
+ });
+
+ if (error) {
+ console.warn(`key '${key}' not found in '${this.lang}'`);
+ return key; // Fallback
+ } else {
+ return text;
+ }
+ }
+
+ public replacement(match, a, b, c) {
+ const key = a || b || c;
+ if (match[0] == '"') {
+ return '"' + this.get(key).replace(/"/g, '\\"') + '"';
+ } else if (match[0] == "'") {
+ return '\'' + this.get(key).replace(/'/g, '\\\'') + '\'';
+ } else {
+ return this.get(key);
+ }
+ }
+}
diff --git a/src/web/app/desktop/ui.styl b/src/web/app/desktop/ui.styl
index cb98bf06a..058271876 100644
--- a/src/web/app/desktop/ui.styl
+++ b/src/web/app/desktop/ui.styl
@@ -1,4 +1,4 @@
-@import "../app"
+@import "../../const"
button
font-family sans-serif
diff --git a/src/web/const.styl b/src/web/const.styl
new file mode 100644
index 000000000..b6560701d
--- /dev/null
+++ b/src/web/const.styl
@@ -0,0 +1,4 @@
+json('../const.json')
+
+$theme-color = themeColor
+$theme-color-foreground = themeColorForeground
diff --git a/src/web/docs/api.ja.pug b/src/web/docs/api.ja.pug
index 5514a4097..2584b0858 100644
--- a/src/web/docs/api.ja.pug
+++ b/src/web/docs/api.ja.pug
@@ -7,6 +7,7 @@ section
h2 自分の所有するアカウントからAPIにアクセスする場合
p 「設定 > API」で、APIにアクセスするのに必要なAPIキーを取得してください。
p APIにアクセスする際には、リクエストにAPIキーを「i」というパラメータ名で含めます。
+ div.ui.info.warn: p %fa:exclamation-triangle%アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。
p APIの詳しい使用法は「Misskey APIの利用」セクションをご覧ください。
section
@@ -15,7 +16,7 @@ section
| 直接ユーザーのAPIキーをアプリケーションが扱うのは危険なので、
| アプリケーションからAPIを利用する際には、アプリケーションとアプリケーションを利用するユーザーが結び付けられた専用のトークン(アクセストークン)をMisskeyに発行してもらい、
| そのトークンをリクエストのパラメータに含める必要があります。
- | (アクセストークンは、ユーザーが自分のアカウントにあなたのアプリケーションがアクセスすることを許可した場合のみ発行されます)
+ div.ui.info: p %fa:info-circle%アクセストークンは、ユーザーが自分のアカウントにあなたのアプリケーションがアクセスすることを許可した場合のみ発行されます
p それでは、アクセストークンを取得するまでの流れを説明します。
@@ -46,9 +47,8 @@ section
td 権限
td あなたのアプリケーションやWebサービスが要求する権限。ここで要求した機能だけがAPIからアクセスできます。
- p
- | 登録が済むとアプリケーションのシークレットキーが入手できます。このシークレットキーは後で使用します。
- | アプリに成りすまされる可能性があるため、極力このシークレットキーは公開しないようにしてください。
+ p 登録が済むとアプリケーションのシークレットキーが入手できます。このシークレットキーは後で使用します。
+ div.ui.info.warn: p %fa:exclamation-triangle%アプリに成りすまされる可能性があるため、極力このシークレットキーは公開しないようにしてください。
section
h3 2.ユーザーに認証させる
@@ -93,7 +93,7 @@ section
h2 Misskey APIの利用
p APIはすべてリクエストのパラメータ・レスポンスともにJSON形式です。また、すべてのエンドポイントはPOSTメソッドのみ受け付けます。
p APIリファレンスもご確認ください。
-
+
section
h3 レートリミット
p Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。
diff --git a/src/web/docs/api/endpoints/view.pug b/src/web/docs/api/endpoints/view.pug
index 90084ab27..d271a5517 100644
--- a/src/web/docs/api/endpoints/view.pug
+++ b/src/web/docs/api/endpoints/view.pug
@@ -17,7 +17,7 @@ block main
p#desc= desc[lang] || desc['ja']
section
- h2= common.i18n[lang]['docs']['api']['endpoints']['params']
+ h2 %i18n:docs.api.endpoints.params%
+propTable(params)
if paramDefs
@@ -28,5 +28,5 @@ block main
if res
section
- h2= common.i18n[lang]['docs']['api']['endpoints']['res']
+ h2 %i18n:docs.api.endpoints.res%
+propTable(res)
diff --git a/src/web/docs/api/entities/view.pug b/src/web/docs/api/entities/view.pug
index 99e786c69..2156463dc 100644
--- a/src/web/docs/api/entities/view.pug
+++ b/src/web/docs/api/entities/view.pug
@@ -10,7 +10,7 @@ block main
p#desc= desc[lang] || desc['ja']
section
- h2= common.i18n[lang]['docs']['api']['entities']['properties']
+ h2 %i18n:docs.api.entities.properties%
+propTable(props)
if propDefs
diff --git a/src/web/docs/api/gulpfile.ts b/src/web/docs/api/gulpfile.ts
index 2e8409c59..4c30871a0 100644
--- a/src/web/docs/api/gulpfile.ts
+++ b/src/web/docs/api/gulpfile.ts
@@ -10,13 +10,16 @@ import * as pug from 'pug';
import * as yaml from 'js-yaml';
import * as mkdirp from 'mkdirp';
+import locales from '../../../../locales';
+import I18nReplacer from '../../../common/build/i18n';
+import fa from '../../../common/build/fa';
import config from './../../../conf';
import generateVars from '../vars';
const commonVars = generateVars();
-const langs = Object.keys(commonVars.i18n);
+const langs = Object.keys(locales);
const kebab = string => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase();
@@ -124,6 +127,9 @@ gulp.task('doc:api:endpoints', () => {
console.error(renderErr);
return;
}
+ const i18n = new I18nReplacer(lang);
+ html = html.replace(i18n.pattern, i18n.replacement);
+ html = fa(html);
const htmlPath = `./built/web/docs/${lang}/api/endpoints/${ep.endpoint}.html`;
mkdirp(path.dirname(htmlPath), (mkdirErr) => {
if (mkdirErr) {
@@ -164,6 +170,9 @@ gulp.task('doc:api:entities', () => {
console.error(renderErr);
return;
}
+ const i18n = new I18nReplacer(lang);
+ html = html.replace(i18n.pattern, i18n.replacement);
+ html = fa(html);
const htmlPath = `./built/web/docs/${lang}/api/entities/${kebab(entity.name)}.html`;
mkdirp(path.dirname(htmlPath), (mkdirErr) => {
if (mkdirErr) {
diff --git a/src/web/docs/api/mixins.pug b/src/web/docs/api/mixins.pug
index b563a121d..686bf6a2b 100644
--- a/src/web/docs/api/mixins.pug
+++ b/src/web/docs/api/mixins.pug
@@ -1,10 +1,10 @@
mixin propTable(props)
table.props
thead: tr
- th= common.i18n[lang]['docs']['api']['props']['name']
- th= common.i18n[lang]['docs']['api']['props']['type']
- th= common.i18n[lang]['docs']['api']['props']['optional']
- th= common.i18n[lang]['docs']['api']['props']['description']
+ th %i18n:docs.api.props.name%
+ th %i18n:docs.api.props.type%
+ th %i18n:docs.api.props.optional%
+ th %i18n:docs.api.props.description%
tbody
each prop in props
tr
@@ -31,7 +31,7 @@ mixin propTable(props)
| (Date)
td.optional
if prop.optional
- = common.i18n[lang]['docs']['api']['props']['yes']
+ | %i18n:docs.api.props.yes%
else
- = common.i18n[lang]['docs']['api']['props']['no']
+ | %i18n:docs.api.props.no%
td.desc!= prop.desc[lang] || prop.desc['ja']
diff --git a/src/web/docs/gulpfile.ts b/src/web/docs/gulpfile.ts
index 6668abdec..71033e1bc 100644
--- a/src/web/docs/gulpfile.ts
+++ b/src/web/docs/gulpfile.ts
@@ -7,13 +7,12 @@ import * as path from 'path';
import * as glob from 'glob';
import * as gulp from 'gulp';
import * as pug from 'pug';
-//import * as yaml from 'js-yaml';
import * as mkdirp from 'mkdirp';
import stylus = require('gulp-stylus');
import cssnano = require('gulp-cssnano');
-//import config from './../../conf';
-
+import I18nReplacer from '../../common/build/i18n';
+import fa from '../../common/build/fa';
import generateVars from './vars';
require('./api/gulpfile.ts');
@@ -53,6 +52,9 @@ gulp.task('doc:docs', () => {
console.error(renderErr2);
return;
}
+ const i18n = new I18nReplacer(lang);
+ html = html.replace(i18n.pattern, i18n.replacement);
+ html = fa(html);
const htmlPath = `./built/web/docs/${lang}/${name}.html`;
mkdirp(path.dirname(htmlPath), (mkdirErr) => {
if (mkdirErr) {
diff --git a/src/web/docs/layout.pug b/src/web/docs/layout.pug
index ee8018ec6..9dfd0ab7a 100644
--- a/src/web/docs/layout.pug
+++ b/src/web/docs/layout.pug
@@ -9,6 +9,9 @@ html(lang= lang)
link(rel="stylesheet" href="/assets/style.css")
block meta
+ //- FontAwesome style
+ style #{common.facss}
+
body
nav
ul
@@ -33,6 +36,6 @@ html(lang= lang)
footer
p
- = common.i18n[lang]['docs']['edit-this-page-on-github']
- a(href=src target="_blank")= common.i18n[lang]['docs']['edit-this-page-on-github-link']
+ | %i18n:docs.edit-this-page-on-github%
+ a(href=src target="_blank") %i18n:docs.edit-this-page-on-github-link%
small= common.copyright
diff --git a/src/web/docs/style.styl b/src/web/docs/style.styl
index 32a2264f1..414be5c53 100644
--- a/src/web/docs/style.styl
+++ b/src/web/docs/style.styl
@@ -1,4 +1,5 @@
@import "../style"
+@import "./ui"
body
margin 0
diff --git a/src/web/docs/ui.styl b/src/web/docs/ui.styl
new file mode 100644
index 000000000..8d5515712
--- /dev/null
+++ b/src/web/docs/ui.styl
@@ -0,0 +1,19 @@
+.ui.info
+ display block
+ margin 1em 0
+ padding 0 1em
+ font-size 90%
+ color rgba(#000, 0.87)
+ background #f8f8f9
+ border-radius 4px
+ overflow hidden
+
+ > p
+ opacity 0.8
+
+ > [data-fa]:first-child
+ margin-right 0.25em
+
+ &.warn
+ color #573a08
+ background #FFFAF3
diff --git a/src/web/docs/vars.ts b/src/web/docs/vars.ts
index da590d7bd..65b224fbf 100644
--- a/src/web/docs/vars.ts
+++ b/src/web/docs/vars.ts
@@ -1,7 +1,8 @@
import * as fs from 'fs';
import * as glob from 'glob';
import * as yaml from 'js-yaml';
-import langs from '../../../locales';
+
+import { fa } from '../../common/build/fa';
import config from '../../conf';
const constants = require('../../const.json');
@@ -37,9 +38,9 @@ export default function(): { [key: string]: any } {
vars['config'] = config;
- vars['i18n'] = langs;
-
vars['copyright'] = constants.copyright;
+ vars['facss'] = fa.dom.css();
+
return vars;
}
diff --git a/src/web/style.styl b/src/web/style.styl
index 573df10d7..c25fc8fb5 100644
--- a/src/web/style.styl
+++ b/src/web/style.styl
@@ -1,9 +1,6 @@
-json('../const.json')
-
@charset 'utf-8'
-$theme-color = themeColor
-$theme-color-foreground = themeColorForeground
+@import "./const"
/*
::selection
diff --git a/webpack/module/index.ts b/webpack/module/index.ts
index 15f36557c..088aca723 100644
--- a/webpack/module/index.ts
+++ b/webpack/module/index.ts
@@ -1,5 +1,5 @@
import rules from './rules';
-export default (lang, locale) => ({
- rules: rules(lang, locale)
+export default lang => ({
+ rules: rules(lang)
});
diff --git a/webpack/module/rules/fa.ts b/webpack/module/rules/fa.ts
index 47c72a28a..891b78ece 100644
--- a/webpack/module/rules/fa.ts
+++ b/webpack/module/rules/fa.ts
@@ -3,16 +3,7 @@
*/
const StringReplacePlugin = require('string-replace-webpack-plugin');
-
-import * as fontawesome from '@fortawesome/fontawesome';
-import * as regular from '@fortawesome/fontawesome-free-regular';
-import * as solid from '@fortawesome/fontawesome-free-solid';
-import * as brands from '@fortawesome/fontawesome-free-brands';
-
-// Add icons
-fontawesome.library.add(regular);
-fontawesome.library.add(solid);
-fontawesome.library.add(brands);
+import { pattern, replacement } from '../../../src/common/build/fa';
export default () => ({
enforce: 'pre',
@@ -20,41 +11,7 @@ export default () => ({
exclude: /node_modules/,
loader: StringReplacePlugin.replace({
replacements: [{
- pattern: /%fa:(.+?)%/g, replacement: (_, key) => {
- const args = key.split(' ');
- let prefix = 'fas';
- const classes = [];
- let transform = '';
- let name;
-
- args.forEach(arg => {
- if (arg == 'R' || arg == 'S' || arg == 'B') {
- prefix =
- arg == 'R' ? 'far' :
- arg == 'S' ? 'fas' :
- arg == 'B' ? 'fab' :
- '';
- } else if (arg[0] == '.') {
- classes.push('fa-' + arg.substr(1));
- } else if (arg[0] == '-') {
- transform = arg.substr(1).split('|').join(' ');
- } else {
- name = arg;
- }
- });
-
- const icon = fontawesome.icon({ prefix, iconName: name }, {
- classes: classes
- });
-
- if (icon) {
- icon.transform = fontawesome.parse.transform(transform);
- return `${icon.html[0]}`;
- } else {
- console.warn(`'${name}' not found in fa`);
- return '';
- }
- }
+ pattern, replacement
}]
})
});
diff --git a/webpack/module/rules/i18n.ts b/webpack/module/rules/i18n.ts
index aa4e58448..7261548be 100644
--- a/webpack/module/rules/i18n.ts
+++ b/webpack/module/rules/i18n.ts
@@ -3,28 +3,10 @@
*/
const StringReplacePlugin = require('string-replace-webpack-plugin');
+import Replacer from '../../../src/common/build/i18n';
-export default (lang, locale) => {
- function get(key: string) {
- let text = locale;
-
- // Check the key existance
- const error = key.split('.').some(k => {
- if (text.hasOwnProperty(k)) {
- text = text[k];
- return false;
- } else {
- return true;
- }
- });
-
- if (error) {
- console.warn(`key '${key}' not found in '${lang}'`);
- return key; // Fallback
- } else {
- return text;
- }
- }
+export default lang => {
+ const replacer = new Replacer(lang);
return {
enforce: 'pre',
@@ -32,14 +14,7 @@ export default (lang, locale) => {
exclude: /node_modules/,
loader: StringReplacePlugin.replace({
replacements: [{
- pattern: /"%i18n:(.+?)%"/g, replacement: (_, key) =>
- '"' + get(key).replace(/"/g, '\\"') + '"'
- }, {
- pattern: /'%i18n:(.+?)%'/g, replacement: (_, key) =>
- '\'' + get(key).replace(/'/g, '\\\'') + '\''
- }, {
- pattern: /%i18n:(.+?)%/g, replacement: (_, key) =>
- get(key)
+ pattern: replacer.pattern, replacement: replacer.replacement
}]
})
};
diff --git a/webpack/module/rules/index.ts b/webpack/module/rules/index.ts
index b6a0a5e2e..b02bdef72 100644
--- a/webpack/module/rules/index.ts
+++ b/webpack/module/rules/index.ts
@@ -7,8 +7,8 @@ import tag from './tag';
import stylus from './stylus';
import typescript from './typescript';
-export default (lang, locale) => [
- i18n(lang, locale),
+export default lang => [
+ i18n(lang),
license(),
fa(),
base64(),
diff --git a/webpack/webpack.config.ts b/webpack/webpack.config.ts
index 124bd975b..d67b8ef77 100644
--- a/webpack/webpack.config.ts
+++ b/webpack/webpack.config.ts
@@ -8,7 +8,7 @@ import plugins from './plugins';
import langs from '../locales';
import version from '../src/version';
-module.exports = Object.entries(langs).map(([lang, locale]) => {
+module.exports = Object.keys(langs).map(lang => {
// Chunk name
const name = lang;
@@ -32,7 +32,7 @@ module.exports = Object.entries(langs).map(([lang, locale]) => {
return {
name,
entry,
- module: module_(lang, locale),
+ module: module_(lang),
plugins: plugins(version, lang),
output,
resolve: {