1
0
mirror of https://github.com/rhysd/Mstdn.git synced 2025-02-02 06:52:13 +01:00

basic plugin implementation

This commit is contained in:
rhysd 2017-04-21 16:50:14 +09:00
parent bf069f58fc
commit 1e7df65f57
4 changed files with 125 additions and 0 deletions

View File

@ -15,6 +15,7 @@ Features:
- [x] Customizable (and pluggable) shortcut keybinds - [x] Customizable (and pluggable) shortcut keybinds
- [x] Multi-account (switching among accounts) - [x] Multi-account (switching among accounts)
- [x] User CSS - [x] User CSS
- [x] Plugin architecture based on Node.js and Electron APIs
Mastodon is an open source project. So if you want to make a new UI, you can just fork the project, Mastodon is an open source project. So if you want to make a new UI, you can just fork the project,
implement your favorite UI and host it on your place. Then you can participate Mastodon networks from it. implement your favorite UI and host it on your place. Then you can participate Mastodon networks from it.
@ -256,6 +257,93 @@ body {
} }
``` ```
## Preload Plugin
You can make a Node.js package which is preloaded before loading inner mastodon page.
Preload plugin is enabled if `chromium_sandbox` option is set to `false`. Please read above
configuration section before using any plugin.
### How to make
Create `node_modules` directory in your application directory at first. And then, please make
`mstdn-preload-hello` directory. It consists a node package.
Package name must start with `mastdn-preload-`.
Make `package.json` manually or by `$ npm init` in the directory.
```json
{
"name": "mstdn-preload-hello",
"version": "0.0.0",
"description": "sample of preload plugin of Mstdn.app",
"main": "index.js",
"author": "Your name",
"license": "Some license"
}
```
Finally make `index.js` as below:
```javascript
module.exports = (config, account) => {
console.log('Hello from plugin!', config, account);
}
```
Package must export one function which receives two parameters `config` and `account`.
Note that you can use below APIs in the script.
- [Node.js standard libraries][] via `require` (e.g. `require('fs')`)
- Dependant node packages listed in `package.json` of the plugin
- [Electron Renderer APIs][Electron APIs]
- All Web APIs on browser (including DOM API)
#### !!! Security Notice !!!
Do not leak Node.js stuff to global namespace like below.
```javascript
// Never do things like this!
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`.
```
$ cd {Your application directory}
$ npm install mstdn-preload-hello
```
And then write what plugin should be loaded to `"preload"` section of your `config.json`.
`"hello"` should be added to the list.
```json
{
...
"preload" [
"hello"
],
...
}
```
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.
In console, the message 'Hello from plugin!', config information and account information should be output.
### List of Plugins
To be made
## Contact to the Author ## Contact to the Author
Please feel free to make an issue on GitHub or mention on Mastodon/Twitter. Please feel free to make an issue on GitHub or mention on Mastodon/Twitter.
@ -269,3 +357,5 @@ Please feel free to make an issue on GitHub or mention on Mastodon/Twitter.
[Electron]: electron.atom.io [Electron]: electron.atom.io
[sandbox doc]: https://github.com/electron/electron/blob/master/docs/api/sandbox-option.md [sandbox doc]: https://github.com/electron/electron/blob/master/docs/api/sandbox-option.md
[npm version badge]: https://badge.fury.io/js/mstdn.svg [npm version badge]: https://badge.fury.io/js/mstdn.svg
[Node.js standard libraries]: https://nodejs.org/api/
[Electron APIs]: https://electron.atom.io/docs/api/

View File

@ -20,6 +20,7 @@ export interface Config {
chromium_sandbox: boolean; chromium_sandbox: boolean;
__DATA_DIR?: string; __DATA_DIR?: string;
keymaps: {[key: string]: string}; keymaps: {[key: string]: string};
preload: string[];
} }
function makeDefaultConfig(): Config { function makeDefaultConfig(): Config {
@ -51,6 +52,7 @@ function makeDefaultConfig(): Config {
5: '/web/timelines/public', 5: '/web/timelines/public',
6: '/web/getting-started' 6: '/web/getting-started'
}, },
preload: [],
}; };
} }

View File

@ -1,8 +1,12 @@
import {Config, Account} from '../main/config'; import {Config, Account} from '../main/config';
import * as Ipc from './ipc'; import * as Ipc from './ipc';
import setupKeymaps from './key_handler'; import setupKeymaps from './key_handler';
import loadPlugins from './plugins';
import log from './log';
Ipc.on('mstdn:config', (c: Config, a: Account) => { Ipc.on('mstdn:config', (c: Config, a: Account) => {
const plugins = loadPlugins(c, a);
log.info('Loaded plugins:', plugins);
setupKeymaps(c, a); setupKeymaps(c, a);
document.title = `${document.title} @${a.name}@${a.host}`; document.title = `${document.title} @${a.name}@${a.host}`;
}); });

29
renderer/plugins.ts Normal file
View File

@ -0,0 +1,29 @@
import * as path from 'path';
import {Config, Account} from '../main/config';
import r from './require';
import log from './log';
type Plugin = (c: Config, a: Account) => void;
interface Plugins {
[module_path: string]: Plugin;
}
export default function loadPlugins(config: Config, account: Account): Plugins {
const ret = {} as Plugins;
if (config.chromium_sandbox) {
log.info('Chromium sandbox is enabled. Preload plugin is disabled.');
return ret;
}
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}`);
try {
const preloadFunc = r(plugin_path) as Plugin;
preloadFunc(config, account);
ret[plugin_path] = preloadFunc;
} catch (e) {
log.error(`Failed to load plugin ${plugin_path}:`, e);
}
}
return ret;
}