From 3d4237e6770b7f1ca126de2ebafb10f2658a238f Mon Sep 17 00:00:00 2001 From: rhysd Date: Tue, 25 Apr 2017 17:30:18 +0900 Subject: [PATCH] move plugins config into account config --- README.md | 49 +++++++++++++++++++++++++++++---------------- main/config.ts | 4 ++-- renderer/plugins.ts | 26 +++++++++++++++--------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 62c37ac..2c3dad1 100644 --- a/README.md +++ b/README.md @@ -134,12 +134,15 @@ You need to write up this config at first. If `true` is specified, Chromium's native sandbox is enabled (and default value is `true`). Sandbox provides some OS level security protection such as resource access control like tabs -in Chromium. However, sandbox also blocks preload scripts for Electron application. +in Chromium. However, sandbox also blocks plugins for Electron application. If `false` is specified, you can use some advanced features (user CSS and key shortcut plugin). Before setting `false` to this value, please read and understand [sandbox documentation in Electron repo][sandbox doc] to know what you're doing. +Please note that this sandbox feature is different from Node.js integration in Electron. Node.js +integration is always disabled. + ### `keymaps` Object whose key is a key sequence and whose value is an action name. @@ -281,27 +284,27 @@ body { } ``` -## Preload Plugin (experimental) +## Plugin (experimental) -You can make a Node.js package which is preloaded before loading inner mastodon page. +You can make a Node.js package which is run inner mastodon page. -Preload plugin is enabled if `chromium_sandbox` option is set to `false`. Please read above +Plugin is enabled if `chromium_sandbox` option is set to `false`. Please read above configuration section before using any plugin. ### How to make a plugin Create `node_modules` directory in your application directory at first. And then, please make -`mstdn-preload-hello` directory. It consists a node package. +`mstdn-plugin-hello` directory. It consists a node package. -Package name must start with `mastdn-preload-`. +Package name must start with `mastdn-plugin-`. Make `package.json` manually or by `$ npm init` in the directory. ```json { - "name": "mstdn-preload-hello", + "name": "mstdn-plugin-hello", "version": "0.0.0", - "description": "sample of preload plugin of Mstdn.app", + "description": "Sample plugin of Mstdn.app", "main": "index.js", "author": "Your name", "license": "Some license" @@ -311,12 +314,16 @@ Make `package.json` manually or by `$ npm init` in the directory. Finally make `index.js` as below: ```javascript -module.exports = (config, account) => { - console.log('Hello from plugin!', config, account); -} +module.exports = { + preload(config, account) { + console.log('Hello from plugin!', config, account); + } +}; ``` -Package must export one function which receives two parameters `config` and `account`. +Package must export one object. +If the object has a function as a value of `preload` key, it will be called at page being loaded. +The function which receives two parameters `config` and `account`. Note that you can use below APIs in the script. @@ -337,28 +344,36 @@ window.my_require = require; ### How to use If you didn't try above 'How to make' section, please install plugin package at first. -Below will install 'hello' plugin to `{app directory}/node_modules/mstdn-preload-hello`. +Below will install 'hello' plugin to `{app directory}/node_modules/mstdn-plugin-hello`. ``` $ cd {Your application directory} -$ npm install mstdn-preload-hello +$ npm install mstdn-plugin-hello ``` -And then write what plugin should be loaded to `"preload"` section of your `config.json`. +And then write what plugin should be loaded to `"plugins"` section of your account in `config.json`. `"hello"` should be added to the list. ```json { ... - "preload" [ - "hello" + "accounts": [ + { + ... + + "plugins": [ + "hello" + ] + } ], ... } ``` +You can enable different plugin for each your accounts. + Finally open Mstdn.app and see DevTools via [Menu] -> [View] -> [Developper Tools] -> console. If window is too small to see DevTools, please make window size bigger. diff --git a/main/config.ts b/main/config.ts index 715f735..0040d3a 100644 --- a/main/config.ts +++ b/main/config.ts @@ -7,6 +7,7 @@ export interface Account { host: string; name: string; default_page: string; + plugins: string[]; } export interface Config { @@ -20,7 +21,6 @@ export interface Config { chromium_sandbox: boolean; __DATA_DIR?: string; keymaps: {[key: string]: string}; - preload: string[]; } function makeDefaultConfig(): Config { @@ -39,6 +39,7 @@ function makeDefaultConfig(): Config { name: '', host: '', default_page: '/web/timelines/home', + plugins: [], }], keymaps: { j: 'scroll-down', @@ -52,7 +53,6 @@ function makeDefaultConfig(): Config { 5: '/web/timelines/public', 6: '/web/getting-started' }, - preload: [], }; } diff --git a/renderer/plugins.ts b/renderer/plugins.ts index 3587210..3eecbd1 100644 --- a/renderer/plugins.ts +++ b/renderer/plugins.ts @@ -3,7 +3,9 @@ import {Config, Account} from '../main/config'; import r from './require'; import log from './log'; -type Plugin = (c: Config, a: Account) => void; +interface Plugin { + preload(c: Config, a: Account): void; +} interface Plugins { [module_path: string]: Plugin; } @@ -17,13 +19,13 @@ export default class PluginsLoader { this.preloads = {}; if (config.chromium_sandbox) { - log.info('Chromium sandbox is enabled. Preload plugin is disabled.'); + log.info('Chromium sandbox is enabled. Plugin is disabled.'); return; } const dir_base = path.join(config.__DATA_DIR!, 'node_modules'); - for (const plugin of config.preload || []) { - const plugin_path = path.join(dir_base, `mstdn-preload-${plugin}`); + for (const plugin of this.account.plugins || []) { + const plugin_path = path.join(dir_base, `mstdn-plugin-${plugin}`); try { this.preloads[plugin_path] = r(plugin_path) as Plugin; } catch (e) { @@ -34,7 +36,7 @@ export default class PluginsLoader { loadAfterAppPrepared() { if (Object.keys(this.preloads).length === 0) { - log.info('No preload plugin found. Skip loading'); + log.info('No Plugin found. Skip loading'); this.loaded = true; return; } @@ -43,7 +45,7 @@ export default class PluginsLoader { // In order not to prevent application's initial loading, load preload plugins // on an idle callback. window.requestIdleCallback(() => { - log.debug('Start loading preload plugins', this.config, this.account); + log.debug('Start loading plugins', this.preloads); if (this.tryLoading()) { return resolve(); } @@ -55,6 +57,8 @@ export default class PluginsLoader { observeAppPrepared(callback: () => void) { // TODO: // Make an instance of MutationObserver to observe React root. + // But it may be unnecessary because application shell is rendered + // in server side. return Promise.resolve(callback()); } @@ -65,15 +69,19 @@ export default class PluginsLoader { } for (const key in this.preloads) { - const f = this.preloads[key]; + const f = this.preloads[key].preload; + if (!f) { + log.info('Plugin does not have preload function. Skipped:', key); + continue; + } try { f(this.config, this.account); } catch (e) { - log.error(`Error while loading preload plugin '${key}':`, e); + log.error(`Error while loading plugin '${key}':`, e); } } - log.info('Preload plugins were loaded:', this.preloads); + log.info('Plugins were loaded:', this.preloads); return true; } }