Skip to content

Commit

Permalink
Release v1.3.0 (#12)
Browse files Browse the repository at this point in the history
* Update to latest API version + fixed vulnerabilities
* Updated plugin API to version v1.8.2 (`registerSettings`)
* Removed bundled font packages
* Make FavoriteDesc private for favorites.ts
* Do not trim search queries
* Use built-in clipboard functionality
  • Loading branch information
benji300 committed Aug 12, 2021
1 parent 1d0b5da commit 9bd4f85
Show file tree
Hide file tree
Showing 37 changed files with 454 additions and 6,314 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- None

## [1.3.0] - 2021-08-12

### Changed

- Updated plugin API to version v1.8.2 (`registerSettings`) to support app version v2.2.4 or newer
- Do not trim search queries (whitespaces before or after won't be removed)

### Removed

- Bundled font packages (FontAwesome, Roboto)
- Use built-in versions to decrease plugin size
- External `copy-to-clipboard` package
- Use of clipboard functionality provided by plugin API v2.1.5

## [1.2.1] - 2021-02-23

### Fixed
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Favorites is a plugin to extend the UX and UI of [Joplin's](https://joplinapp.or

It allows to save any notebook, note, to-do, tag, or search as favorite in an extra panel view for quick access.

> :warning: **CAUTION** - Requires Joplin **v1.6.5** or newer
> :warning: **CAUTION** - Requires Joplin **v2.1.5** or newer
## Features

Expand Down Expand Up @@ -160,6 +160,11 @@ You like this plugin as much as I do and it improves your daily work with Joplin

Then I would be very happy if you buy me a :beer: or :coffee: via [PayPal](https://www.paypal.com/donate?hosted_button_id=6FHDGK3PTNU22) :wink:

## Contributing

Contributions to this plugin are most welcome. Feel free to open a pull request or an issue.
Make sure to use conventional [commit messages](https://github.com/pvdlg/conventional-commit-types) if you're creating a pull request.

## Development

The npm package of the plugin can be found [here](https://www.npmjs.com/package/joplin-plugin-benji-favorites).
Expand Down
6 changes: 3 additions & 3 deletions api/Global.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
/**
* @ignore
*/
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;
get process(): any;
}
19 changes: 19 additions & 0 deletions api/Joplin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import JoplinContentScripts from './JoplinContentScripts';
import JoplinClipboard from './JoplinClipboard';
import JoplinWindow from './JoplinWindow';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
Expand All @@ -33,8 +35,12 @@ export default class Joplin {
private interop_;
private settings_;
private contentScripts_;
private clipboard_;
private window_;
constructor(implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get clipboard(): JoplinClipboard;
get window(): JoplinWindow;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;
get contentScripts(): JoplinContentScripts;
Expand All @@ -49,4 +55,17 @@ export default class Joplin {
get views(): JoplinViews;
get interop(): JoplinInterop;
get settings(): JoplinSettings;
/**
* It is not possible to bundle native packages with a plugin, because they
* need to work cross-platforms. Instead access to certain useful native
* packages is provided using this function.
*
* Currently these packages are available:
*
* - [sqlite3](https://www.npmjs.com/package/sqlite3)
* - [fs-extra](https://www.npmjs.com/package/fs-extra)
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/nativeModule)
*/
require(_path: string): any;
}
23 changes: 23 additions & 0 deletions api/JoplinClipboard.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default class JoplinClipboard {
private electronClipboard_;
private electronNativeImage_;
constructor(electronClipboard: any, electronNativeImage: any);
readText(): Promise<string>;
writeText(text: string): Promise<void>;
readHtml(): Promise<string>;
writeHtml(html: string): Promise<void>;
/**
* Returns the image in [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.
*/
readImage(): Promise<string>;
/**
* Takes an image in [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.
*/
writeImage(dataUrl: string): Promise<void>;
/**
* Returns the list available formats (mime types).
*
* For example [ 'text/plain', 'text/html' ]
*/
availableFormats(): Promise<string[]>;
}
28 changes: 28 additions & 0 deletions api/JoplinCommands.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ import { Command } from './types';
*
* To view what arguments are supported, you can open any of these files
* and look at the `execute()` command.
*
* ## Executing editor commands
*
* There might be a situation where you want to invoke editor commands
* without using a {@link JoplinContentScripts | contentScript}. For this
* reason Joplin provides the built in `editor.execCommand` command.
*
* `editor.execCommand` should work with any core command in both the
* [CodeMirror](https://codemirror.net/doc/manual.html#execCommand) and
* [TinyMCE](https://www.tiny.cloud/docs/api/tinymce/tinymce.editorcommands/#execcommand) editors,
* as well as most functions calls directly on a CodeMirror editor object (extensions).
*
* * [CodeMirror commands](https://codemirror.net/doc/manual.html#commands)
* * [TinyMCE core editor commands](https://www.tiny.cloud/docs/advanced/editor-command-identifiers/#coreeditorcommands)
*
* `editor.execCommand` supports adding arguments for the commands.
*
* ```typescript
* await joplin.commands.execute('editor.execCommand', {
* name: 'madeUpCommand', // CodeMirror and TinyMCE
* args: [], // CodeMirror and TinyMCE
* ui: false, // TinyMCE only
* value: '', // TinyMCE only
* });
* ```
*
* [View the example using the CodeMirror editor](https://github.com/laurent22/joplin/blob/dev/packages/app-cli/tests/support/plugins/codemirror_content_script/src/index.ts)
*
*/
export default class JoplinCommands {
/**
Expand Down
17 changes: 17 additions & 0 deletions api/JoplinPlugins.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,21 @@ export default class JoplinPlugins {
* @deprecated Use joplin.contentScripts.register()
*/
registerContentScript(type: ContentScriptType, id: string, scriptPath: string): Promise<void>;
/**
* Gets the plugin own data directory path. Use this to store any
* plugin-related data. Unlike [[installationDir]], any data stored here
* will be persisted.
*/
dataDir(): Promise<string>;
/**
* Gets the plugin installation directory. This can be used to access any
* asset that was packaged with the plugin. This directory should be
* considered read-only because any data you store here might be deleted or
* re-created at any time. To store new persistent data, use [[dataDir]].
*/
installationDir(): Promise<string>;
/**
* @deprecated Use joplin.require()
*/
require(_path: string): any;
}
9 changes: 8 additions & 1 deletion api/JoplinSettings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,18 @@ export default class JoplinSettings {
private get keyPrefix();
private namespacedKey;
/**
* Registers a new setting. Note that registering a setting item is dynamic and will be gone next time Joplin starts.
* Registers new settings.
* Note that registering a setting item is dynamic and will be gone next time Joplin starts.
* What it means is that you need to register the setting every time the plugin starts (for example in the onStart event).
* The setting value however will be preserved from one launch to the next so there is no risk that it will be lost even if for some
* reason the plugin fails to start at some point.
*/
registerSettings(settings: Record<string, SettingItem>): Promise<void>;
/**
* @deprecated Use joplin.settings.registerSettings()
*
* Registers a new setting.
*/
registerSetting(key: string, settingItem: SettingItem): Promise<void>;
/**
* Registers a new setting section. Like for registerSetting, it is dynamic and needs to be done every time the plugin starts.
Expand Down
9 changes: 8 additions & 1 deletion api/JoplinViewsDialogs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Plugin from '../Plugin';
import { ButtonSpec, ViewHandle, DialogResult } from './types';
/**
* Allows creating and managing dialogs. A dialog is modal window that
* contains a webview and a row of buttons. You can update the update the
* contains a webview and a row of buttons. You can update the
* webview using the `setHtml` method. Dialogs are hidden by default and
* you need to call `open()` to open them. Once the user clicks on a
* button, the `open` call will return an object indicating what button was
Expand Down Expand Up @@ -59,4 +59,11 @@ export default class JoplinViewsDialogs {
* Opens the dialog
*/
open(handle: ViewHandle): Promise<DialogResult>;
/**
* Toggle on whether to fit the dialog size to the content or not.
* When set to false, the dialog stretches to fill the application
* window.
* @default true
*/
setFitToContent(handle: ViewHandle, status: boolean): Promise<boolean>;
}
24 changes: 24 additions & 0 deletions api/JoplinWindow.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Plugin from '../Plugin';
export interface Implementation {
injectCustomStyles(elementId: string, cssFilePath: string): Promise<void>;
}
export default class JoplinWindow {
private plugin_;
private store_;
private implementation_;
constructor(implementation: Implementation, plugin: Plugin, store: any);
/**
* Loads a chrome CSS file. It will apply to the window UI elements, except
* for the note viewer. It is the same as the "Custom stylesheet for
* Joplin-wide app styles" setting. See the [Load CSS Demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/load_css)
* for an example.
*/
loadChromeCssFile(filePath: string): Promise<void>;
/**
* Loads a note CSS file. It will apply to the note viewer, as well as any
* exported or printed note. It is the same as the "Custom stylesheet for
* rendered Markdown" setting. See the [Load CSS Demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/load_css)
* for an example.
*/
loadNoteCssFile(filePath: string): Promise<void>;
}
2 changes: 1 addition & 1 deletion api/JoplinWorkspace.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class JoplinWorkspace {
*/
onNoteContentChange(callback: Function): Promise<void>;
/**
* Called when the content of a note changes.
* Called when the content of the current note changes.
*/
onNoteChange(handler: ItemChangeHandler): Promise<Disposable>;
/**
Expand Down
88 changes: 77 additions & 11 deletions api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ export interface Command {
execute(...args: any[]): Promise<any | void>;

/**
* Defines whether the command should be enabled or disabled, which in turns affects
* the enabled state of any associated button or menu item.
* Defines whether the command should be enabled or disabled, which in turns
* affects the enabled state of any associated button or menu item.
*
* The condition should be expressed as a "when-clause" (as in Visual Studio Code). It's a simple boolean expression that evaluates to
* `true` or `false`. It supports the following operators:
* The condition should be expressed as a "when-clause" (as in Visual Studio
* Code). It's a simple boolean expression that evaluates to `true` or
* `false`. It supports the following operators:
*
* Operator | Symbol | Example
* -- | -- | --
Expand All @@ -40,7 +41,15 @@ export interface Command {
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
* And | && | "oneNoteSelected && !inConflictFolder"
*
* Currently the supported context variables aren't documented, but you can [find the list here](https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts).
* Joplin, unlike VSCode, also supports parenthesis, which allows creating
* more complex expressions such as `cond1 || (cond2 && cond3)`. Only one
* level of parenthesis is possible (nested ones aren't supported).
*
* Currently the supported context variables aren't documented, but you can
* find the list below:
*
* - [Global When Clauses](https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts)
* - [Desktop app When Clauses](https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/services/commands/stateToWhenClauseContext.ts)
*
* Note: Commands are enabled by default unless you use this property.
*/
Expand Down Expand Up @@ -325,24 +334,81 @@ export enum SettingItemType {
Button = 6,
}

export enum AppType {
Desktop = 'desktop',
Mobile = 'mobile',
Cli = 'cli',
}

export enum SettingStorage {
Database = 1,
File = 2,
}

// Redefine a simplified interface to mask internal details
// and to remove function calls as they would have to be async.
export interface SettingItem {
value: any;
type: SettingItemType;
public: boolean;
label: string;

label: string;
description?: string;
isEnum?: boolean;

/**
* A public setting will appear in the Configuration screen and will be
* modifiable by the user. A private setting however will not appear there,
* and can only be changed programmatically. You may use this to store some
* values that you do not want to directly expose.
*/
public: boolean;

/**
* You would usually set this to a section you would have created
* specifically for the plugin.
*/
section?: string;
options?: any;
appTypes?: string[];

/**
* To create a setting with multiple options, set this property to `true`.
* That setting will render as a dropdown list in the configuration screen.
*/
isEnum?: boolean;

/**
* This property is required when `isEnum` is `true`. In which case, it
* should contain a map of value => label.
*/
options?: Record<any, any>;

/**
* Reserved property. Not used at the moment.
*/
appTypes?: AppType[];

/**
* Set this to `true` to store secure data, such as passwords. Any such
* setting will be stored in the system keychain if one is available.
*/
secure?: boolean;

/**
* An advanced setting will be moved under the "Advanced" button in the
* config screen.
*/
advanced?: boolean;

/**
* Set the min, max and step values if you want to restrict an int setting
* to a particular range.
*/
minimum?: number;
maximum?: number;
step?: number;

/**
* Either store the setting in the database or in settings.json. Defaults to database.
*/
storage?: SettingStorage;
}

export interface SettingSection {
Expand All @@ -369,7 +435,7 @@ export type Path = string[];
// Content Script types
// =================================================================

export type PostMessageHandler = (id: string, message: any)=> Promise<any>;
export type PostMessageHandler = (message: any)=> Promise<any>;

/**
* When a content script is initialised, it receives a `context` object.
Expand Down
Loading

0 comments on commit 9bd4f85

Please sign in to comment.