mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-11 18:24:43 +02:00
Plugins: Added a way to execute commands from Markdown-it content scripts
This commit is contained in:
parent
bc76e4a918
commit
65cc6853bd
@ -3,6 +3,22 @@ import { ContentScriptType } from 'api/types';
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
await joplin.commands.register({
|
||||
name: 'testCommand',
|
||||
label: 'My Test Command',
|
||||
execute: async (...args) => {
|
||||
alert('Got command "testCommand" with args: ' + JSON.stringify(args));
|
||||
},
|
||||
});
|
||||
|
||||
await joplin.commands.register({
|
||||
name: 'testCommandNoArgs',
|
||||
label: 'My Test Command (no args)',
|
||||
execute: async () => {
|
||||
alert('Got command "testCommandNoArgs"');
|
||||
},
|
||||
});
|
||||
|
||||
await joplin.plugins.registerContentScript(
|
||||
ContentScriptType.MarkdownItPlugin,
|
||||
'justtesting',
|
||||
|
@ -1,4 +1,9 @@
|
||||
.just-testing {
|
||||
background-color: red;
|
||||
color: yellow;
|
||||
background-color: rgb(202, 255, 255);
|
||||
color: rgb(82, 0, 78);
|
||||
}
|
||||
|
||||
.just-testing a {
|
||||
background-color: rgb(202, 255, 255);
|
||||
color: rgb(10, 0, 104);
|
||||
}
|
@ -6,7 +6,13 @@ function plugin(markdownIt, _options) {
|
||||
markdownIt.renderer.rules.fence = function(tokens, idx, options, env, self) {
|
||||
const token = tokens[idx];
|
||||
if (token.info !== 'justtesting') return defaultRender(tokens, idx, options, env, self);
|
||||
return `<div class="just-testing">JUST TESTING: ${token.content}</div>`;
|
||||
return `
|
||||
<div class="just-testing">
|
||||
<p>JUST TESTING: ${token.content}</p>
|
||||
<p><a href="#" onclick="webviewApi.executeCommand('testCommand', 'one', 'two'); return false;">Click to send "testCommand" to plugin</a></p>
|
||||
<p><a href="#" onclick="webviewApi.executeCommand('testCommandNoArgs'); return false;">Click to send "testCommandNoArgs" to plugin</a></p>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { FormNote } from './types';
|
||||
import contextMenu from './contextMenu';
|
||||
import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
const BaseItem = require('@joplin/lib/models/BaseItem');
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const Resource = require('@joplin/lib/models/Resource.js');
|
||||
@ -90,6 +91,10 @@ export default function useMessageHandler(scrollWhenReady: any, setScrollWhenRea
|
||||
}
|
||||
} else if (msg.indexOf('#') === 0) {
|
||||
// This is an internal anchor, which is handled by the WebView so skip this case
|
||||
} else if (msg === 'contentScriptExecuteCommand') {
|
||||
const commandName = arg0.name;
|
||||
const commandArgs = arg0.args || [];
|
||||
void CommandService.instance().execute(commandName, ...commandArgs);
|
||||
} else {
|
||||
bridge().showErrorMessageBox(_('Unsupported link or message: %s', msg));
|
||||
}
|
||||
|
@ -49,10 +49,24 @@
|
||||
<script src="./lib.js"></script>
|
||||
|
||||
<script>
|
||||
// This is function used internally to send message from the webview to
|
||||
// the host.
|
||||
const ipcProxySendToHost = (methodName, arg) => {
|
||||
window.postMessage({ target: 'main', name: methodName, args: [ arg ] }, '*');
|
||||
}
|
||||
|
||||
// This function is reserved for plugin, currently only to allow
|
||||
// executing a command, but more features could be added to the object
|
||||
// later on.
|
||||
const webviewApi = {
|
||||
executeCommand: function (commandName, ...args) {
|
||||
return ipcProxySendToHost('contentScriptExecuteCommand', {
|
||||
name: commandName,
|
||||
args: args,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let pluginAssetsAdded_ = {};
|
||||
|
||||
try {
|
||||
|
@ -51,14 +51,20 @@ export default class JoplinPlugins {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new content script. Unlike regular plugin code, which runs in a separate process, content scripts run within the main process code
|
||||
* and thus allow improved performances and more customisations in specific cases. It can be used for example to load a Markdown or editor plugin.
|
||||
* Registers a new content script. Unlike regular plugin code, which
|
||||
* runs in a separate process, content scripts run within the main
|
||||
* process code and thus allow improved performances and more
|
||||
* customisations in specific cases. It can be used for example to load
|
||||
* a Markdown or editor plugin.
|
||||
*
|
||||
* Note that registering a content script in itself will do nothing - it will only be loaded in specific cases by the relevant app modules
|
||||
* (eg. the Markdown renderer or the code editor). So it is not a way to inject and run arbitrary code in the app, which for safety and performance reasons is not supported.
|
||||
* Note that registering a content script in itself will do nothing -
|
||||
* it will only be loaded in specific cases by the relevant app modules
|
||||
* (eg. the Markdown renderer or the code editor). So it is not a way
|
||||
* to inject and run arbitrary code in the app, which for safety and
|
||||
* performance reasons is not supported.
|
||||
*
|
||||
* [View the renderer demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script)
|
||||
* [View the editor demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/codemirror_content_script)
|
||||
* * [View the renderer demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script)
|
||||
* * [View the editor demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/codemirror_content_script)
|
||||
*
|
||||
* @param type Defines how the script will be used. See the type definition for more information about each supported type.
|
||||
* @param id A unique ID for the content script.
|
||||
|
@ -334,7 +334,8 @@ export type Path = string[];
|
||||
|
||||
export enum ContentScriptType {
|
||||
/**
|
||||
* Registers a new Markdown-It plugin, which should follow the template below.
|
||||
* Registers a new Markdown-It plugin, which should follow the template
|
||||
* below.
|
||||
*
|
||||
* ```javascript
|
||||
* module.exports = {
|
||||
@ -350,14 +351,49 @@ export enum ContentScriptType {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* See [the
|
||||
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script)
|
||||
* for a simple Markdown-it plugin example.
|
||||
*
|
||||
* - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate.
|
||||
* ## Exported members
|
||||
*
|
||||
* - The **required** `plugin` key is the actual Markdown-It plugin - check the [official doc](https://github.com/markdown-it/markdown-it) for more information. The `options` parameter is of type [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml.ts), which contains a number of options, mostly useful for Joplin's internal code.
|
||||
* - The `context` argument is currently unused but could be used later
|
||||
* on to provide access to your own plugin so that the content script
|
||||
* and plugin can communicate.
|
||||
*
|
||||
* - Using the **optional** `assets` key you may specify assets such as JS or CSS that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured.
|
||||
* - The **required** `plugin` key is the actual Markdown-It plugin -
|
||||
* check the [official
|
||||
* doc](https://github.com/markdown-it/markdown-it) for more
|
||||
* information. The `options` parameter is of type
|
||||
* [RuleOptions](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml.ts),
|
||||
* which contains a number of options, mostly useful for Joplin's
|
||||
* internal code.
|
||||
*
|
||||
* To include a regular Markdown-It plugin, that doesn't make use of any Joplin-specific features, you would simply create a file such as this:
|
||||
* - Using the **optional** `assets` key you may specify assets such as
|
||||
* JS or CSS that should be loaded in the rendered HTML document.
|
||||
* Check for example the Joplin [Mermaid
|
||||
* plugin](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml/rules/mermaid.ts)
|
||||
* to see how the data should be structured.
|
||||
*
|
||||
* ## Passing messages from the content script to your plugin
|
||||
*
|
||||
* The application provides the following function to allow executing
|
||||
* commands from the rendered HTML code:
|
||||
*
|
||||
* `webviewApi.executeCommand(commandName, ...args)`
|
||||
*
|
||||
* So you can use this mechanism to pass messages from the note viewer
|
||||
* to your own plugin. To do so you would define a command, using
|
||||
* `joplin.commands.register`, then you would call this command using
|
||||
* the `webviewApi` object. See again [the
|
||||
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script)
|
||||
* to see how this can be done.
|
||||
*
|
||||
* ## Registering an existing Markdown-it plugin
|
||||
*
|
||||
* To include a regular Markdown-It plugin, that doesn't make use of
|
||||
* any Joplin-specific features, you would simply create a file such as
|
||||
* this:
|
||||
*
|
||||
* ```javascript
|
||||
* module.exports = {
|
||||
@ -371,7 +407,8 @@ export enum ContentScriptType {
|
||||
*/
|
||||
MarkdownItPlugin = 'markdownItPlugin',
|
||||
/**
|
||||
* Registers a new CodeMirror plugin, which should follow the template below.
|
||||
* Registers a new CodeMirror plugin, which should follow the template
|
||||
* below.
|
||||
*
|
||||
* ```javascript
|
||||
* module.exports = {
|
||||
@ -392,19 +429,42 @@ export enum ContentScriptType {
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* - The `context` argument is currently unused but could be used later on to provide access to your own plugin so that the content script and plugin can communicate.
|
||||
* - The `context` argument is currently unused but could be used later
|
||||
* on to provide access to your own plugin so that the content script
|
||||
* and plugin can communicate.
|
||||
*
|
||||
* - The `plugin` key is your CodeMirror plugin. This is where you can register new commands with CodeMirror or interact with the CodeMirror instance as needed.
|
||||
* - The `plugin` key is your CodeMirror plugin. This is where you can
|
||||
* register new commands with CodeMirror or interact with the
|
||||
* CodeMirror instance as needed.
|
||||
*
|
||||
* - The `codeMirrorResources` key is an array of CodeMirror resources that will be loaded and attached to the CodeMirror module. These are made up of addons, keymaps, and modes. For example, for a plugin that want's to enable clojure highlighting in code blocks. `codeMirrorResources` would be set to `['mode/clojure/clojure']`.
|
||||
* - The `codeMirrorResources` key is an array of CodeMirror resources
|
||||
* that will be loaded and attached to the CodeMirror module. These
|
||||
* are made up of addons, keymaps, and modes. For example, for a
|
||||
* plugin that want's to enable clojure highlighting in code blocks.
|
||||
* `codeMirrorResources` would be set to `['mode/clojure/clojure']`.
|
||||
*
|
||||
* - The `codeMirrorOptions` key contains all the [CodeMirror](https://codemirror.net/doc/manual.html#config) options that will be set or changed by this plugin. New options can alse be declared via [`CodeMirror.defineOption`](https://codemirror.net/doc/manual.html#defineOption), and then have their value set here. For example, a plugin that enables line numbers would set `codeMirrorOptions` to `{'lineNumbers': true}`.
|
||||
* - The `codeMirrorOptions` key contains all the
|
||||
* [CodeMirror](https://codemirror.net/doc/manual.html#config)
|
||||
* options that will be set or changed by this plugin. New options
|
||||
* can alse be declared via
|
||||
* [`CodeMirror.defineOption`](https://codemirror.net/doc/manual.html#defineOption),
|
||||
* and then have their value set here. For example, a plugin that
|
||||
* enables line numbers would set `codeMirrorOptions` to
|
||||
* `{'lineNumbers': true}`.
|
||||
*
|
||||
* - Using the **optional** `assets` key you may specify **only** CSS assets that should be loaded in the rendered HTML document. Check for example the Joplin [Mermaid plugin](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml/rules/mermaid.ts) to see how the data should be structured.
|
||||
* - Using the **optional** `assets` key you may specify **only** CSS
|
||||
* assets that should be loaded in the rendered HTML document. Check
|
||||
* for example the Joplin [Mermaid
|
||||
* plugin](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml/rules/mermaid.ts)
|
||||
* to see how the data should be structured.
|
||||
*
|
||||
* One of the `plugin`, `codeMirrorResources`, or `codeMirrorOptions` keys must be provided for the plugin to be valid. Having multiple or all provided is also okay.
|
||||
* One of the `plugin`, `codeMirrorResources`, or `codeMirrorOptions`
|
||||
* keys must be provided for the plugin to be valid. Having multiple or
|
||||
* all provided is also okay.
|
||||
*
|
||||
* See the [demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/codemirror_content_script) for an example of all these keys being used in one plugin.
|
||||
* See the [demo
|
||||
* plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/codemirror_content_script)
|
||||
* for an example of all these keys being used in one plugin.
|
||||
*/
|
||||
CodeMirrorPlugin = 'codeMirrorPlugin',
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user