1
0
mirror of https://github.com/laurent22/joplin.git synced 2026-01-08 00:14:28 +02:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Laurent Cozic
9bba9a8ed6 Plugins: Fixed issue with toolbar button key not being unique 2020-11-20 16:19:57 +00:00
Laurent Cozic
3344e84c7c fix link 2020-11-20 15:52:08 +00:00
175 changed files with 3677 additions and 3961 deletions

View File

@@ -58,15 +58,105 @@ plugin_types/
readme/
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
Assets/TinyMCE/JoplinLists/src/main/ts/Main.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js.map
packages/app-cli/app/LinkSelector.d.ts
packages/app-cli/app/LinkSelector.js
packages/app-cli/app/LinkSelector.js.map
packages/app-cli/app/services/plugins/PluginRunner.d.ts
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/services/plugins/PluginRunner.js.map
packages/app-cli/tests/EnexToMd.d.ts
packages/app-cli/tests/EnexToMd.js
packages/app-cli/tests/EnexToMd.js.map
packages/app-cli/build/LinkSelector.d.ts
packages/app-cli/build/LinkSelector.js
packages/app-cli/build/LinkSelector.js.map
packages/app-cli/build/services/plugins/PluginRunner.d.ts
packages/app-cli/build/services/plugins/PluginRunner.js
packages/app-cli/build/services/plugins/PluginRunner.js.map
packages/app-cli/tests/InMemoryCache.d.ts
packages/app-cli/tests/InMemoryCache.js
packages/app-cli/tests/InMemoryCache.js.map

View File

@@ -126,10 +126,6 @@ module.exports = {
{
// enable the rule specifically for TypeScript files
'files': ['*.ts', '*.tsx'],
'parserOptions': {
// Required for @typescript-eslint/no-floating-promises
'project': './tsconfig.eslint.json',
},
'rules': {
// Warn only because it would make it difficult to convert JS classes to TypeScript, unless we
// make everything public which is not great. New code however should specify member accessibility.
@@ -156,7 +152,6 @@ module.exports = {
'requireLast': false,
},
}],
'@typescript-eslint/no-floating-promises': ['error'],
},
},
],

96
.gitignore vendored
View File

@@ -50,15 +50,105 @@ packages/tools/github_oauth_token.txt
lerna-debug.log
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
Assets/TinyMCE/JoplinLists/src/main/ts/Main.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js
Assets/TinyMCE/JoplinLists/src/main/ts/Main.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js
Assets/TinyMCE/JoplinLists/src/main/ts/Plugin.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/Indendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js
Assets/TinyMCE/JoplinLists/src/main/ts/actions/ToggleList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Api.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Commands.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Events.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js
Assets/TinyMCE/JoplinLists/src/main/ts/api/Settings.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Bookmark.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Delete.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/DlIndentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Keyboard.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/ListAction.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NodeType.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/NormalizeLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Range.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Selection.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/SplitList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/TextBlock.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/core/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ComposeList.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Entry.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Indentation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/JoplinListUtil.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ListsIndendation.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/NormalizeEntries.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/ParseLists.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js
Assets/TinyMCE/JoplinLists/src/main/ts/listModel/Util.js.map
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.d.ts
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js
Assets/TinyMCE/JoplinLists/src/main/ts/ui/Buttons.js.map
packages/app-cli/app/LinkSelector.d.ts
packages/app-cli/app/LinkSelector.js
packages/app-cli/app/LinkSelector.js.map
packages/app-cli/app/services/plugins/PluginRunner.d.ts
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/services/plugins/PluginRunner.js.map
packages/app-cli/tests/EnexToMd.d.ts
packages/app-cli/tests/EnexToMd.js
packages/app-cli/tests/EnexToMd.js.map
packages/app-cli/build/LinkSelector.d.ts
packages/app-cli/build/LinkSelector.js
packages/app-cli/build/LinkSelector.js.map
packages/app-cli/build/services/plugins/PluginRunner.d.ts
packages/app-cli/build/services/plugins/PluginRunner.js
packages/app-cli/build/services/plugins/PluginRunner.js.map
packages/app-cli/tests/InMemoryCache.d.ts
packages/app-cli/tests/InMemoryCache.js
packages/app-cli/tests/InMemoryCache.js.map

View File

@@ -91,7 +91,7 @@ Note that you should most likely always specify a scope because otherwise it wil
## TypeScript
The application was originally written in JavaScript, however it has slowly been migrated to [TypeScript](https://www.typescriptlang.org/). New classes and files should be written in TypeScript. All compiled files are generated next to the .ts or .tsx file. So for example, if there's a file "lib/MyClass.ts", there will be a generated "lib/MyClass.js" next to it. It is implemented that way as it requires minimal changes to integrate TypeScript in the existing JavaScript code base.
The application was originally written JavaScript, however it has slowly been migrated to [TypeScript](https://www.typescriptlang.org/). New classes and files should be written in TypeScript. All compiled files are generated next to the .ts or .tsx file. So for example, if there's a file "lib/MyClass.ts", there will be a generated "lib/MyClass.js" next to it. It is implemented that way as it requires minimal changes to integrate TypeScript in the existing JavaScript code base.
## Hot reload

View File

@@ -28,7 +28,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/
Operating System | Download | Alt. Download
-----------------|----------|----------------
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.4.11/joplin-v1.4.11.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.4.11/joplin-v1.4.11-32bit.apk)
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.3.13/joplin-v1.3.13.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.3.13/joplin-v1.3.13-32bit.apk)
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://joplinapp.org/images/BadgeIOS.png'/></a> | -
## Terminal application
@@ -402,14 +402,13 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
# Community
Name | Description
--- | ---
[Support Forum](https://discourse.joplinapp.org/) | This is the main place for general discussion about Joplin, user support, software development questions, and to discuss new features. Also where the latest beta versions are released and discussed.
[Sub-reddit](https://www.reddit.com/r/joplinapp/) | Also a good place to get help
[Discord server](https://discordapp.com/invite/d2HMPwE) | Our chat server
[Patreon page](https://www.patreon.com/joplin) |The latest news are often posted there
[Mastodon feed](https://mastodon.social/@joplinapp) | Follow us on Mastodon
[Twitter feed](https://twitter.com/joplinapp) | Follow us on Twitter
- For general discussion about Joplin, user support, software development questions, and to discuss new features, go to the [Joplin Forum](https://discourse.joplinapp.org/). It is possible to login with your GitHub account.
- Also see here for information about [the latest releases and general news](https://discourse.joplinapp.org/c/news).
- For bug reports go to the [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues). Please follow the template accordingly.
- Feature requests must not be opened on GitHub unless they have been discussed and accepted on the forum.
- The latest news are posted [on the Patreon page](https://www.patreon.com/joplin).
- You can also follow us on <a rel="me" href="https://mastodon.social/@joplinapp">the Mastodon feed</a> or [the Twitter feed](https://twitter.com/joplinapp).
- You can join the live community on [the JoplinApp discord server](https://discordapp.com/invite/d2HMPwE) to get help with Joplin or to discuss anything Joplin related.
# Contributing

View File

@@ -1,6 +1,6 @@
{
"name": "joplin",
"version": "1.4.7",
"version": "1.4.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -31,7 +31,7 @@
],
"owner": "Laurent Cozic"
},
"version": "1.4.9",
"version": "1.4.3",
"bin": {
"joplin": "./main.js"
},

View File

@@ -0,0 +1,67 @@
/* eslint-disable no-unused-vars */
const os = require('os');
const time = require('@joplin/lib/time').default;
const { filename } = require('@joplin/lib/path-utils');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js');
const Folder = require('@joplin/lib/models/Folder.js');
const Note = require('@joplin/lib/models/Note.js');
const BaseModel = require('@joplin/lib/BaseModel').default;
const shim = require('@joplin/lib/shim').default;
const { enexXmlToMd } = require('@joplin/lib/import-enex-md-gen.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('EnexToMd', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should convert from Enex to Markdown', asyncTest(async () => {
const basePath = `${__dirname}/enex_to_md`;
const files = await shim.fsDriver().readDirStats(basePath);
for (let i = 0; i < files.length; i++) {
const htmlFilename = files[i].path;
if (htmlFilename.indexOf('.html') < 0) continue;
const htmlPath = `${basePath}/${htmlFilename}`;
const mdPath = `${basePath}/${filename(htmlFilename)}.md`;
// if (htmlFilename !== 'multiline_inner_text.html') continue;
const html = await shim.fsDriver().readFile(htmlPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);
let actualMd = await enexXmlToMd(`<div>${html}</div>`, []);
if (os.EOL === '\r\n') {
expectedMd = expectedMd.replace(/\r\n/g, '\n');
actualMd = actualMd.replace(/\r\n/g, '\n');
}
if (actualMd !== expectedMd) {
console.info('');
console.info(`Error converting file: ${htmlFilename}`);
console.info('--------------------------------- Got:');
console.info(actualMd.split('\n'));
console.info('--------------------------------- Expected:');
console.info(expectedMd.split('\n'));
console.info('--------------------------------------------');
console.info('');
expect(false).toBe(true);
// return;
} else {
expect(true).toBe(true);
}
}
}));
});

View File

@@ -1,99 +0,0 @@
import { NoteEntity, ResourceEntity, TagEntity } from '@joplin/lib/services/database/types';
import shim from '@joplin/lib/shim';
const fs = require('fs-extra');
const os = require('os');
const { filename } = require('@joplin/lib/path-utils');
const { setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
const { enexXmlToMd } = require('@joplin/lib/import-enex-md-gen.js');
const { importEnex } = require('@joplin/lib/import-enex');
const Note = require('@joplin/lib/models/Note');
const Tag = require('@joplin/lib/models/Tag');
const Resource = require('@joplin/lib/models/Resource');
const enexSampleBaseDir = `${__dirname}/enex_to_md`;
describe('EnexToMd', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should convert ENEX content to Markdown', async () => {
const files = await shim.fsDriver().readDirStats(enexSampleBaseDir);
for (let i = 0; i < files.length; i++) {
const htmlFilename = files[i].path;
if (htmlFilename.indexOf('.html') < 0) continue;
const htmlPath = `${enexSampleBaseDir}/${htmlFilename}`;
const mdPath = `${enexSampleBaseDir}/${filename(htmlFilename)}.md`;
// if (htmlFilename !== 'multiline_inner_text.html') continue;
const html = await shim.fsDriver().readFile(htmlPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);
let actualMd = await enexXmlToMd(`<div>${html}</div>`, []);
if (os.EOL === '\r\n') {
expectedMd = expectedMd.replace(/\r\n/g, '\n');
actualMd = actualMd.replace(/\r\n/g, '\n');
}
if (actualMd !== expectedMd) {
console.info('');
console.info(`Error converting file: ${htmlFilename}`);
console.info('--------------------------------- Got:');
console.info(actualMd.split('\n'));
console.info('--------------------------------- Expected:');
console.info(expectedMd.split('\n'));
console.info('--------------------------------------------');
console.info('');
expect(false).toBe(true);
// return;
} else {
expect(true).toBe(true);
}
}
});
it('should import ENEX metadata', async () => {
const filePath = `${enexSampleBaseDir}/sample-enex.xml`;
await importEnex('', filePath);
const note: NoteEntity = (await Note.all())[0];
expect(note.title).toBe('Test Note for Export');
expect(note.body).toBe([
' Hello, World.',
'',
'![snapshot-DAE9FC15-88E3-46CF-B744-DA9B1B56EB57.jpg](:/3d0f4d01abc02cf8c4dc1c796df8c4b2)',
].join('\n'));
expect(note.created_time).toBe(1375217524000);
expect(note.updated_time).toBe(1376560800000);
expect(note.latitude).toBe('33.88394692');
expect(note.longitude).toBe('-117.91913551');
expect(note.altitude).toBe('96.0000');
expect(note.author).toBe('Brett Kelly');
const tag: TagEntity = (await Tag.tagsByNoteId(note.id))[0];
expect(tag.title).toBe('fake-tag');
const resource: ResourceEntity = (await Resource.all())[0];
expect(resource.id).toBe('3d0f4d01abc02cf8c4dc1c796df8c4b2');
const stat = await fs.stat(Resource.fullPath(resource));
expect(stat.size).toBe(277);
});
it('should handle invalid dates', async () => {
const filePath = `${enexSampleBaseDir}/invalid_date.enex`;
await importEnex('', filePath);
const note: NoteEntity = (await Note.all())[0];
expect(note.created_time).toBe(1521822724000); // 20180323T163204Z
expect(note.updated_time).toBe(1521822724000); // Because this date was invalid, it is set to the created time instead
});
});

View File

@@ -147,27 +147,27 @@ describe('MdToHtml', function() {
expect(result.html.trim()).toBe('<div id="rendered-md"><p>just <strong>testing</strong></p>\n</div>');
}));
// it('should render links correctly', asyncTest(async () => {
// const mdToHtml = newTestMdToHtml();
it('should render links correctly', asyncTest(async () => {
const mdToHtml = newTestMdToHtml();
// const testCases = [
// // None of these should result in a link
// ['https://example.com', 'https://example.com'],
// ['file://C:\\AUTOEXEC.BAT', 'file://C:\\AUTOEXEC.BAT'],
// ['example.com', 'example.com'],
// ['oo.ps', 'oo.ps'],
// ['test@example.com', 'test@example.com'],
const testCases = [
// None of these should result in a link
['https://example.com', 'https://example.com'],
['file://C:\\AUTOEXEC.BAT', 'file://C:\\AUTOEXEC.BAT'],
['example.com', 'example.com'],
['oo.ps', 'oo.ps'],
['test@example.com', 'test@example.com'],
// // Those should be converted to links
// ['<https://example.com>', '<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>https://example.com</a>'],
// ['[ok](https://example.com)', '<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>ok</a>'],
// ];
// Those should be converted to links
['<https://example.com>', '<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>https://example.com</a>'],
['[ok](https://example.com)', '<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>ok</a>'],
];
// for (const testCase of testCases) {
// const [input, expected] = testCase;
// const actual = await mdToHtml.render(input, null, { bodyOnly: true, plainResourceRendering: true });
// expect(actual.html).toBe(expected);
// }
// }));
for (const testCase of testCases) {
const [input, expected] = testCase;
const actual = await mdToHtml.render(input, null, { bodyOnly: true, plainResourceRendering: true });
expect(actual.html).toBe(expected);
}
}));
});

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
<en-export export-date="20201223T053642Z" application="Evernote" version="10.4.3">
<note>
<title>Fruit Tree Assessment</title>
<created>20180323T163204Z</created>
<updated>10101T000000Z</updated>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"
><en-note>Fruit Tree</en-note> ]]>
</content>
</note>
</en-export>

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
<en-export export-date="20130730T205637Z" application="Evernote" version="Evernote Mac">
<note>
<title>Test Note for Export</title>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">
Hello, World.
<div>
<br/>
</div>
<div>
<en-media alt="" type="image/jpeg" hash="dd7b6d285d09ec054e8cd6a3814ce093"/>
</div>
<div>
<br/>
</div>
</en-note>
]]>
</content>
<created>20130730T205204Z</created>
<updated>20130815T100000Z</updated>
<tag>fake-tag</tag>
<note-attributes>
<latitude>33.88394692352314</latitude>
<longitude>-117.9191355110099</longitude>
<altitude>96</altitude>
<author>Brett Kelly</author>
</note-attributes>
<resource>
<data encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdCIFhZ
WiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUhQ
kfeIGT/+uufk8DpM0gyVjGfmzkgetesnUoTHJ+5Cxn86zmv4/wB75EW+QHAPUH/P9Ky+s1rtrr/wfvOm
dBSamnq/xPKp/hpLKmS7x4OBjgn6elee6v4OuLJirRSHb/FtyG9s9u1fR0+oTiIRvGq7W4bpisfUGk1C
GVWtkIyM57n1rfDY+uqigtU76ffZkUsA6iajHZ6v/P8A4B//2Q==</data>
<mime>image/jpeg</mime>
<width>1280</width>
<height>720</height>
<resource-attributes>
<file-name>snapshot-DAE9FC15-88E3-46CF-B744-DA9B1B56EB57.jpg</file-name>
</resource-attributes>
</resource>
</note>
</en-export>

View File

@@ -105,11 +105,7 @@ describe('models_BaseItem', function() {
}));
it('should serialize and unserialize properties that contain new lines', asyncTest(async () => {
const sourceUrl = `
https://joplinapp.org/ \\n
`;
const note = await Note.save({ title: 'note', source_url: sourceUrl });
const note = await Note.save({ title: 'note', source_url: '\nhttps://joplinapp.org/\n' });
const noteBefore = await Note.load(note.id);
const serialized = await Note.serialize(noteBefore);
@@ -117,18 +113,4 @@ https://joplinapp.org/ \\n
expect(noteAfter).toEqual(noteBefore);
}));
it('should not serialize the note title and body', asyncTest(async () => {
const note = await Note.save({ title: 'my note', body: `one line
two line
three line \\n no escape` });
const noteBefore = await Note.load(note.id);
const serialized = await Note.serialize(noteBefore);
expect(serialized.indexOf(`my note
one line
two line
three line \\n no escape`)).toBe(0);
}));
});

View File

@@ -447,7 +447,7 @@ describe('services_SearchEngine', function() {
expect((await engine.search('title:bla 我是')).length).toBe(0);
// For non-alpha char, only the first field is looked at, the following ones are ignored
// expect((await engine.search('title:你好 title:hello')).length).toBe(1);
expect((await engine.search('title:你好 title:hello')).length).toBe(1);
}));
it('should parse normal query strings', asyncTest(async () => {

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -21,20 +21,6 @@ joplin.plugins.register({
},
});
await joplin.commands.register({
name: 'contextMenuCommandExample',
label: 'My Context Menu command',
execute: async (noteIds:string[]) => {
const notes = [];
for (const noteId of noteIds) {
notes.push(await joplin.data.get(['notes', noteId]));
}
const noteTitles = notes.map((note:any) => note.title);
alert('The following notes will be processed:\n\n' + noteTitles.join(', '));
},
});
// Commands that return a result and take argument can only be used
// programmatically, so it's not necessary to set a label and icon.
await joplin.commands.register({
@@ -54,8 +40,6 @@ joplin.plugins.register({
await joplin.views.menuItems.create('myMenuItem1', 'testCommand1', MenuItemLocation.Tools, { accelerator: 'CmdOrCtrl+Alt+Shift+B' });
await joplin.views.menuItems.create('myMenuItem2', 'testCommand2', MenuItemLocation.Tools);
await joplin.views.menuItems.create('contextMenuItem1', 'contextMenuCommandExample', MenuItemLocation.NoteListContextMenu);
console.info('Running command with arguments...');
const result = await joplin.commands.execute('commandWithResult', 'abcd', 123);
console.info('Result was: ' + result);

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -20,4 +20,4 @@
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -23,4 +23,4 @@
"dependencies": {
"uslug": "^1.0.4"
}
}
}

View File

@@ -1,7 +1,6 @@
document.addEventListener('click', event => {
const element = event.target;
if (element.className === 'toc-item-link') {
console.debug('TOC Plugin Webview: Sending scrollToHash message', element.dataset.slug);
webviewApi.postMessage({
name: 'scrollToHash',
hash: element.dataset.slug,

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -1,12 +1,13 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
import Logger from '../../../Logger';
/**
* @ignore
*/
export default class Global {
private joplin_;
private requireWhiteList_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
private requireWhiteList;
require(filePath: string): any;

View File

@@ -7,6 +7,7 @@ import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import Logger from '../../../Logger';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
@@ -31,7 +32,7 @@ export default class Joplin {
private views_;
private interop_;
private settings_;
constructor(implementation: any, plugin: Plugin, store: any);
constructor(logger: Logger, implementation: any, plugin: Plugin, store: any);
get data(): JoplinData;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;

View File

@@ -1,11 +1,13 @@
import Plugin from '../Plugin';
import Logger from '../../../Logger';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private logger;
private plugin;
constructor(plugin: Plugin);
constructor(logger: Logger, plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.

View File

@@ -6,7 +6,7 @@
"dist": "webpack",
"postinstall": "npm run dist"
},
"keywords": {},
"keywords": [],
"license": "MIT",
"devDependencies": {
"@types/node": "^14.0.14",
@@ -23,4 +23,4 @@
"dependencies": {
"left-pad": "^1.3.0"
}
}
}

View File

@@ -16,13 +16,6 @@ function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`)
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) {
// Usually means there's an error, which is going to be printed by
// webpack
console.info('Plugin archive was not created because the "dist" directory is empty');
return;
}
fs.removeSync(destPath);
tar.create(
@@ -45,8 +38,6 @@ const manifestPath = `${srcDir}/manifest.json`;
const manifest = readManifest(manifestPath);
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
fs.removeSync(distDir);
module.exports = {
mode: 'production',
entry: './src/index.ts',

View File

@@ -150,16 +150,8 @@ class Bridge {
const folders = await this.folderTree();
this.dispatch({ type: 'FOLDERS_SET', folders: folders.items ? folders.items : folders });
let tags = [];
for (let page = 1; page < 10000; page++) {
const result = await this.clipperApiExec('GET', 'tags', { page: page, order_by: 'title', order_dir: 'ASC' });
const resultTags = result.items ? result.items : result;
const hasMore = ('has_more' in result) && result.has_more;
tags = tags.concat(resultTags);
if (!hasMore) break;
}
this.dispatch({ type: 'TAGS_SET', tags: tags });
const tags = await this.clipperApiExec('GET', 'tags');
this.dispatch({ type: 'TAGS_SET', tags: tags.items ? tags.items : tags });
bridge().restoreState();
return;

View File

@@ -156,7 +156,7 @@ export default class InteropServiceHelper {
if (Array.isArray(path)) path = path[0];
void CommandService.instance().execute('showModalMessage', _('Exporting to "%s" as "%s" format. Please wait...', path, module.format));
CommandService.instance().execute('showModalMessage', _('Exporting to "%s" as "%s" format. Please wait...', path, module.format));
const exportOptions: ExportOptions = {};
exportOptions.path = path;
@@ -177,7 +177,7 @@ export default class InteropServiceHelper {
bridge().showErrorMessageBox(_('Could not export notes: %s', error.message));
}
void CommandService.instance().execute('hideModalMessage');
CommandService.instance().execute('hideModalMessage');
}
}

View File

@@ -424,7 +424,7 @@ class Application extends BaseApplication {
const contextMenu = Menu.buildFromTemplate([
{ label: _('Open %s', app.electronApp().name), click: () => { app.window().show(); } },
{ type: 'separator' },
{ label: _('Quit'), click: () => { void app.quit(); } },
{ label: _('Quit'), click: () => { app.quit(); } },
]);
app.createTray(contextMenu);
}
@@ -664,7 +664,7 @@ class Application extends BaseApplication {
this.updateTray();
shim.setTimeout(() => {
void AlarmService.garbageCollect();
AlarmService.garbageCollect();
}, 1000 * 60 * 60);
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
@@ -676,12 +676,12 @@ class Application extends BaseApplication {
ResourceService.runInBackground();
if (Setting.value('env') === 'dev') {
void AlarmService.updateAllNotifications();
AlarmService.updateAllNotifications();
} else {
reg.scheduleSync(1000).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.
void AlarmService.updateAllNotifications();
AlarmService.updateAllNotifications();
DecryptionWorker.instance().scheduleStart();
});

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>

View File

@@ -11,7 +11,7 @@ export const declaration: CommandDeclaration = {
export const runtime = (): CommandRuntime => {
return {
execute: async () => {
void bridge().openItem(Setting.value('profileDir'));
bridge().openItem(Setting.value('profileDir'));
},
};
};

View File

@@ -18,7 +18,7 @@ export const runtime = (): CommandRuntime => {
try {
const note = await Note.load(noteId);
void ExternalEditWatcher.instance().openAndWatch(note);
ExternalEditWatcher.instance().openAndWatch(note);
} catch (error) {
bridge().showErrorMessageBox(_('Error opening note in editor: %s', error.message));
}

View File

@@ -13,7 +13,7 @@ export const runtime = (): CommandRuntime => {
return {
execute: async (context: CommandContext, noteId: string = null) => {
noteId = noteId || stateUtils.selectedNoteId(context.state);
void ExternalEditWatcher.instance().stopWatching(noteId);
ExternalEditWatcher.instance().stopWatching(noteId);
},
enabledCondition: 'oneNoteSelected',
};

View File

@@ -17,9 +17,9 @@ export const runtime = (): CommandRuntime => {
if (!noteId) return;
if (context.state.watchedNoteFiles.includes(noteId)) {
void CommandService.instance().execute('stopExternalEditing', noteId);
CommandService.instance().execute('stopExternalEditing', noteId);
} else {
void CommandService.instance().execute('startExternalEditing', noteId);
CommandService.instance().execute('startExternalEditing', noteId);
}
},
enabledCondition: 'oneNoteSelected',

View File

@@ -696,7 +696,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
const needRestartComp: any = this.state.needRestart ? (
<div style={{ ...theme.textStyle, padding: 10, paddingLeft: 24, backgroundColor: theme.warningBackgroundColor, color: theme.color }}>
{this.restartMessage()}
<a style={{ ...theme.urlStyle, marginLeft: 10 }} href="#" onClick={() => { void this.restartApp(); }}>{_('Restart now')}</a>
<a style={{ ...theme.urlStyle, marginLeft: 10 }} href="#" onClick={() => { this.restartApp(); }}>{_('Restart now')}</a>
</div>
) : null;

View File

@@ -86,7 +86,7 @@ const useKeymap = (): [
}
}
void saveKeymap();
saveKeymap();
}, [keymapItems, mustSave]);
return [keymapItems, keymapError, overrideKeymapItems, setAccelerator, resetAccelerator];

View File

@@ -30,7 +30,6 @@ import { themeStyle } from '@joplin/lib/theme';
import validateLayout from '../ResizableLayout/utils/validateLayout';
import iterateItems from '../ResizableLayout/utils/iterateItems';
import removeItem from '../ResizableLayout/utils/removeItem';
import Logger from '@joplin/lib/Logger';
const { connect } = require('react-redux');
const { PromptDialog } = require('../PromptDialog.min.js');
@@ -39,8 +38,6 @@ const PluginManager = require('@joplin/lib/services/PluginManager');
const EncryptionService = require('@joplin/lib/services/EncryptionService');
const ipcRenderer = require('electron').ipcRenderer;
const logger = Logger.create('MainScreen');
interface LayerModalState {
visible: boolean;
message: string;
@@ -333,7 +330,7 @@ class MainScreenComponent extends React.Component<Props, State> {
layoutModeListenerKeyDown(event: any) {
if (event.key !== 'Escape') return;
if (!this.props.layoutMoveMode) return;
void CommandService.instance().execute('toggleLayoutMoveMode');
CommandService.instance().execute('toggleLayoutMoveMode');
}
componentDidMount() {
@@ -567,7 +564,6 @@ class MainScreenComponent extends React.Component<Props, State> {
}
userWebview_message(event: any) {
logger.debug('Got message (WebView => Plugin) (2)', event);
PluginService.instance().pluginById(event.pluginId).viewController(event.viewId).emitMessage(event);
}

View File

@@ -18,9 +18,9 @@ export const runtime = (comp: any): CommandRuntime => {
onClose: async (answer: any) => {
if (answer) {
if (noteType === 'note' || noteType === 'todo') {
void CommandService.instance().execute('newNote', answer.value, noteType === 'todo');
CommandService.instance().execute('newNote', answer.value, noteType === 'todo');
} else {
void CommandService.instance().execute('insertText', TemplateUtils.render(answer.value));
CommandService.instance().execute('insertText', TemplateUtils.render(answer.value));
}
}

View File

@@ -18,7 +18,7 @@ export const runtime = (comp: any): CommandRuntime => {
noteId: noteId,
visible: true,
onRevisionLinkClick: () => {
void CommandService.instance().execute('showRevisions');
CommandService.instance().execute('showRevisions');
},
},
});

View File

@@ -112,7 +112,7 @@ function useMenu(props: Props) {
const [modulesLastChangeTime, setModulesLastChangeTime] = useState(Date.now());
const onMenuItemClick = useCallback((commandName: string) => {
void CommandService.instance().execute(commandName);
CommandService.instance().execute(commandName);
}, []);
const onImportModuleClick = useCallback(async (module: Module, moduleSource: string) => {
@@ -134,7 +134,7 @@ function useMenu(props: Props) {
const modalMessage = _('Importing from "%s" as "%s" format. Please wait...', path, module.format);
void CommandService.instance().execute('showModalMessage', modalMessage);
CommandService.instance().execute('showModalMessage', modalMessage);
const importOptions = {
path,
@@ -145,7 +145,7 @@ function useMenu(props: Props) {
return `${key}: ${status[key]}`;
});
void CommandService.instance().execute('showModalMessage', `${modalMessage}\n\n${statusStrings.join('\n')}`);
CommandService.instance().execute('showModalMessage', `${modalMessage}\n\n${statusStrings.join('\n')}`);
},
onError: console.warn,
destinationFolderId: !module.isNoteArchive && moduleSource === 'file' ? props.selectedFolderId : null,
@@ -159,7 +159,7 @@ function useMenu(props: Props) {
bridge().showErrorMessageBox(error.message);
}
void CommandService.instance().execute('hideModalMessage');
CommandService.instance().execute('hideModalMessage');
}, [props.selectedFolderId]);
const onMenuItemClickRef = useRef(null);
@@ -177,7 +177,7 @@ function useMenu(props: Props) {
const quitMenuItem = {
label: _('Quit'),
accelerator: keymapService.getAccelerator('quit'),
click: () => { void bridge().electronApp().quit(); },
click: () => { bridge().electronApp().quit(); },
};
const sortNoteFolderItems = (type: string) => {
@@ -284,23 +284,23 @@ function useMenu(props: Props) {
templateItems.push({
label: _('Create note from template'),
click: () => {
void CommandService.instance().execute('selectTemplate', 'note');
CommandService.instance().execute('selectTemplate', 'note');
},
}, {
label: _('Create to-do from template'),
click: () => {
void CommandService.instance().execute('selectTemplate', 'todo');
CommandService.instance().execute('selectTemplate', 'todo');
},
}, {
label: _('Insert template'),
accelerator: keymapService.getAccelerator('insertTemplate'),
click: () => {
void CommandService.instance().execute('selectTemplate');
CommandService.instance().execute('selectTemplate');
},
}, {
label: _('Open template directory'),
click: () => {
void bridge().openItem(Setting.value('templateDir'));
bridge().openItem(Setting.value('templateDir'));
},
}, {
label: _('Refresh templates'),

Some files were not shown because too many files have changed in this diff Show More