You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-11 23:17:19 +02:00
Compare commits
25 Commits
v2.0.11
...
sync_batch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e81427a1f2 | ||
|
|
3b9c02e92d | ||
|
|
d73eab6f82 | ||
|
|
d698ea0c12 | ||
|
|
e04133cfc6 | ||
|
|
525ab01b9b | ||
|
|
0d33955fcd | ||
|
|
7f0b3fd718 | ||
|
|
65c3d01cc6 | ||
|
|
ac03c08f33 | ||
|
|
ea1d614f82 | ||
|
|
c682c8879c | ||
|
|
e8532441bc | ||
|
|
958e9163b6 | ||
|
|
1c597883ef | ||
|
|
15ce5cdd6e | ||
|
|
a38958ab7b | ||
|
|
232e0c937a | ||
|
|
479237d16f | ||
|
|
6ae0e84a1a | ||
|
|
71d567669b | ||
|
|
db39db45c5 | ||
|
|
6916b53c2e | ||
|
|
578550e824 | ||
|
|
240a624abd |
@@ -842,6 +842,9 @@ packages/lib/SyncTargetOneDrive.js.map
|
|||||||
packages/lib/Synchronizer.d.ts
|
packages/lib/Synchronizer.d.ts
|
||||||
packages/lib/Synchronizer.js
|
packages/lib/Synchronizer.js
|
||||||
packages/lib/Synchronizer.js.map
|
packages/lib/Synchronizer.js.map
|
||||||
|
packages/lib/TaskQueue.d.ts
|
||||||
|
packages/lib/TaskQueue.js
|
||||||
|
packages/lib/TaskQueue.js.map
|
||||||
packages/lib/commands/historyBackward.d.ts
|
packages/lib/commands/historyBackward.d.ts
|
||||||
packages/lib/commands/historyBackward.js
|
packages/lib/commands/historyBackward.js
|
||||||
packages/lib/commands/historyBackward.js.map
|
packages/lib/commands/historyBackward.js.map
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -828,6 +828,9 @@ packages/lib/SyncTargetOneDrive.js.map
|
|||||||
packages/lib/Synchronizer.d.ts
|
packages/lib/Synchronizer.d.ts
|
||||||
packages/lib/Synchronizer.js
|
packages/lib/Synchronizer.js
|
||||||
packages/lib/Synchronizer.js.map
|
packages/lib/Synchronizer.js.map
|
||||||
|
packages/lib/TaskQueue.d.ts
|
||||||
|
packages/lib/TaskQueue.js
|
||||||
|
packages/lib/TaskQueue.js.map
|
||||||
packages/lib/commands/historyBackward.d.ts
|
packages/lib/commands/historyBackward.d.ts
|
||||||
packages/lib/commands/historyBackward.js
|
packages/lib/commands/historyBackward.js
|
||||||
packages/lib/commands/historyBackward.js.map
|
packages/lib/commands/historyBackward.js.map
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ Three types of applications are available: for the **desktop** (Windows, macOS a
|
|||||||
|
|
||||||
Operating System | Download
|
Operating System | Download
|
||||||
---|---
|
---|---
|
||||||
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-Setup-1.8.5.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a>
|
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/Joplin-Setup-2.0.11.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a>
|
||||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-1.8.5.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a>
|
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/Joplin-2.0.11.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a>
|
||||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-1.8.5.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a>
|
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/Joplin-2.0.11.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a>
|
||||||
|
|
||||||
**On Windows**, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/JoplinPortable.exe'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
**On Windows**, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/JoplinPortable.exe'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
||||||
|
|
||||||
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
|
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,11 @@ services:
|
|||||||
- POSTGRES_PASSWORD=joplin
|
- POSTGRES_PASSWORD=joplin
|
||||||
- POSTGRES_USER=joplin
|
- POSTGRES_USER=joplin
|
||||||
- POSTGRES_DB=joplin
|
- POSTGRES_DB=joplin
|
||||||
|
|
||||||
|
# Use this to specify additional Postgres
|
||||||
|
# config parameters:
|
||||||
|
#
|
||||||
|
# command:
|
||||||
|
# - "postgres"
|
||||||
|
# - "-c"
|
||||||
|
# - "log_min_duration_statement=0"
|
||||||
|
|||||||
@@ -726,6 +726,11 @@ async function fetchAllNotes() {
|
|||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>conflict_original_id</td>
|
||||||
|
<td>text</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<td>body_html</td>
|
<td>body_html</td>
|
||||||
<td>text</td>
|
<td>text</td>
|
||||||
<td>Note body, in HTML format</td>
|
<td>Note body, in HTML format</td>
|
||||||
|
|||||||
@@ -405,6 +405,40 @@ https://github.com/laurent22/joplin/blob/dev/readme/changelog.md
|
|||||||
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>Joplin changelog<a name="joplin-changelog" href="#joplin-changelog" class="heading-anchor">🔗</a></h1>
|
<h1>Joplin changelog<a name="joplin-changelog" href="#joplin-changelog" class="heading-anchor">🔗</a></h1>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.11">v2.0.11</a> - 2021-06-16T17:55:49Z<a name="v2-0-11-https-github-com-laurent22-joplin-releases-tag-v2-0-11-2021-06-16t17-55-49z" href="#v2-0-11-https-github-com-laurent22-joplin-releases-tag-v2-0-11-2021-06-16t17-55-49z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Improved: Prevent sync process from being stuck when the download state of a resource is invalid (5c6fd93)</li>
|
||||||
|
<li>Fixed: Prevent app from crashing when loading a setting value that has been removed (<a href="https://github.com/laurent22/joplin/issues/5086">#5086</a>)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.10">v2.0.10</a> - 2021-06-16T07:58:29Z<a name="v2-0-10-https-github-com-laurent22-joplin-releases-tag-v2-0-10-2021-06-16t07-58-29z" href="#v2-0-10-https-github-com-laurent22-joplin-releases-tag-v2-0-10-2021-06-16t07-58-29z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Fixed: Ensure resources are decrypted when sharing a notebook with Joplin Server (<a href="https://github.com/laurent22/joplin/issues/5080">#5080</a>)</li>
|
||||||
|
<li>Fixed: Fixed user content URLs when sharing note via Joplin Server (2cf7067)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.9">v2.0.9</a> (Pre-release) - 2021-06-12T09:30:30Z<a name="v2-0-9-https-github-com-laurent22-joplin-releases-tag-v2-0-9-pre-release-2021-06-12t09-30-30z" href="#v2-0-9-https-github-com-laurent22-joplin-releases-tag-v2-0-9-pre-release-2021-06-12t09-30-30z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Improved: Conflict notes will now populate a new field with the ID of the conflict note. (<a href="https://github.com/laurent22/joplin/issues/5049">#5049</a> by <a href="https://github.com/Ahmad45123">@Ahmad45123</a>)</li>
|
||||||
|
<li>Improved: Expose prompt to plugins as a command (<a href="https://github.com/laurent22/joplin/issues/5058">#5058</a> by Nishant Mittal)</li>
|
||||||
|
<li>Improved: Filter out form elements from note body to prevent potential XSS (thanks to <a href="https://github.com/chinskiy">@chinskiy</a> for the PoC) (feaecf7)</li>
|
||||||
|
<li>Fixed: Wrong field removed in API search (<a href="https://github.com/laurent22/joplin/issues/5066">#5066</a> by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.8">v2.0.8</a> (Pre-release) - 2021-06-10T16:15:08Z<a name="v2-0-8-https-github-com-laurent22-joplin-releases-tag-v2-0-8-pre-release-2021-06-10t16-15-08z" href="#v2-0-8-https-github-com-laurent22-joplin-releases-tag-v2-0-8-pre-release-2021-06-10t16-15-08z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>New: Add "Retry all" button to sync status screen for items that could not be uploaded (ca487ad)</li>
|
||||||
|
<li>New: Add Joplin Cloud sync target (21ea325)</li>
|
||||||
|
<li>New: MacOS: add 'Hide Others' and 'Show All' menu items (<a href="https://github.com/laurent22/joplin/issues/5024">#5024</a> by Helmut K. C. Tessarek)</li>
|
||||||
|
<li>Improved: Allow passing arguments to commands in command palette (00dc1d8)</li>
|
||||||
|
<li>Improved: Allow restoring a deleted note from note history using command palette (5fd6571)</li>
|
||||||
|
<li>Improved: Improve search with Asian scripts (<a href="https://github.com/laurent22/joplin/issues/5018">#5018</a>) (<a href="https://github.com/laurent22/joplin/issues/4613">#4613</a> by <a href="https://github.com/mablin7">@mablin7</a>)</li>
|
||||||
|
<li>Improved: Improved Joplin Server error handling (95d7ccc)</li>
|
||||||
|
<li>Improved: Plugins: Support executing CodeMirror commands from plugins when using execCommand (<a href="https://github.com/laurent22/joplin/issues/5012">#5012</a> by <a href="https://github.com/CalebJohn">@CalebJohn</a>)</li>
|
||||||
|
<li>Improved: Recreate http agent when the protocol changes (<a href="https://github.com/laurent22/joplin/issues/5016">#5016</a> by Roman Musin)</li>
|
||||||
|
<li>Fixed: Certain resource paths could be corrupted when saved from the Rich Text editor (<a href="https://github.com/laurent22/joplin/issues/5034">#5034</a>)</li>
|
||||||
|
<li>Fixed: Ctrl+Clicking links in Rich Text editor was broken (regression) (e8a02c2)</li>
|
||||||
|
<li>Fixed: Incorrect list renumbering (<a href="https://github.com/laurent22/joplin/issues/4914">#4914</a>) (<a href="https://github.com/laurent22/joplin/issues/4877">#4877</a> by Austin Doupnik)</li>
|
||||||
|
<li>Fixed: Inline Katex gets broken when editing in Rich Text editor (<a href="https://github.com/laurent22/joplin/issues/5052">#5052</a>) (<a href="https://github.com/laurent22/joplin/issues/5025">#5025</a> by <a href="https://github.com/Subhra264">@Subhra264</a>)</li>
|
||||||
|
<li>Fixed: Items are filtered in the API search (<a href="https://github.com/laurent22/joplin/issues/5017">#5017</a>) (<a href="https://github.com/laurent22/joplin/issues/5007">#5007</a> by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||||
|
</ul>
|
||||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.4">v2.0.4</a> (Pre-release) - 2021-06-02T12:54:17Z<a name="v2-0-4-https-github-com-laurent22-joplin-releases-tag-v2-0-4-pre-release-2021-06-02t12-54-17z" href="#v2-0-4-https-github-com-laurent22-joplin-releases-tag-v2-0-4-pre-release-2021-06-02t12-54-17z" class="heading-anchor">🔗</a></h2>
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v2.0.4">v2.0.4</a> (Pre-release) - 2021-06-02T12:54:17Z<a name="v2-0-4-https-github-com-laurent22-joplin-releases-tag-v2-0-4-pre-release-2021-06-02t12-54-17z" href="#v2-0-4-https-github-com-laurent22-joplin-releases-tag-v2-0-4-pre-release-2021-06-02t12-54-17z" class="heading-anchor">🔗</a></h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Improved: Download plugins from GitHub release (8f6a475)</li>
|
<li>Improved: Download plugins from GitHub release (8f6a475)</li>
|
||||||
|
|||||||
@@ -405,6 +405,27 @@ https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md
|
|||||||
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>Joplin Android app changelog<a name="joplin-android-app-changelog" href="#joplin-android-app-changelog" class="heading-anchor">🔗</a></h1>
|
<h1>Joplin Android app changelog<a name="joplin-android-app-changelog" href="#joplin-android-app-changelog" class="heading-anchor">🔗</a></h1>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/android-v2.0.4">android-v2.0.4</a> - 2021-06-16T12:15:56Z<a name="android-v2-0-4-https-github-com-laurent22-joplin-releases-tag-android-v2-0-4-2021-06-16t12-15-56z" href="#android-v2-0-4-https-github-com-laurent22-joplin-releases-tag-android-v2-0-4-2021-06-16t12-15-56z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Improved: Prevent sync process from being stuck when the download state of a resource is invalid (5c6fd93)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/android-v2.0.3">android-v2.0.3</a> (Pre-release) - 2021-06-16T09:48:58Z<a name="android-v2-0-3-https-github-com-laurent22-joplin-releases-tag-android-v2-0-3-pre-release-2021-06-16t09-48-58z" href="#android-v2-0-3-https-github-com-laurent22-joplin-releases-tag-android-v2-0-3-pre-release-2021-06-16t09-48-58z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Improved: Verbose mode for synchronizer (4bbb3d1)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/android-v2.0.2">android-v2.0.2</a> - 2021-06-15T20:03:21Z<a name="android-v2-0-2-https-github-com-laurent22-joplin-releases-tag-android-v2-0-2-2021-06-15t20-03-21z" href="#android-v2-0-2-https-github-com-laurent22-joplin-releases-tag-android-v2-0-2-2021-06-15t20-03-21z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Improved: Conflict notes will now populate a new field with the ID of the conflict note. (#5049 by <a href="https://github.com/Ahmad45123">@Ahmad45123</a>)</li>
|
||||||
|
<li>Improved: Filter out form elements from note body to prevent potential XSS (thanks to Dmytro Vdovychinskiy for the PoC) (feaecf7)</li>
|
||||||
|
<li>Improved: Focus note editor where tapped instead of scrolling to the end (#4998) (#4216 by Roman Musin)</li>
|
||||||
|
<li>Improved: Improve search with Asian scripts (#5018) (#4613 by <a href="https://github.com/mablin7">@mablin7</a>)</li>
|
||||||
|
<li>Fixed: Fixed and improved alarm notifications (#4984) (#4912 by Roman Musin)</li>
|
||||||
|
<li>Fixed: Fixed opening URLs that contain non-alphabetical characters (#4494)</li>
|
||||||
|
<li>Fixed: Fixed user content URLs when sharing note via Joplin Server (2cf7067)</li>
|
||||||
|
<li>Fixed: Inline Katex gets broken when editing in Rich Text editor (#5052) (#5025 by <a href="https://github.com/Subhra264">@Subhra264</a>)</li>
|
||||||
|
<li>Fixed: Items are filtered in the API search (#5017) (#5007 by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||||
|
<li>Fixed: Wrong field removed in API search (#5066 by <a href="https://github.com/JackGruber">@JackGruber</a>)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="bottom-links">
|
<div class="bottom-links">
|
||||||
<a href="https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md">
|
<a href="https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md">
|
||||||
|
|||||||
@@ -405,6 +405,40 @@ https://github.com/laurent22/joplin/blob/dev/readme/changelog_server.md
|
|||||||
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"><img src="https://joplinapp.org/images/badges/Donate-PayPal-green.svg" alt="Donate using PayPal"></a> <a href="https://github.com/sponsors/laurent22/"><img src="https://joplinapp.org/images/badges/GitHub-Badge.svg" alt="Sponsor on GitHub"></a> <a href="https://www.patreon.com/joplin"><img src="https://joplinapp.org/images/badges/Patreon-Badge.svg" alt="Become a patron"></a> <a href="https://joplinapp.org/donate/#donations"><img src="https://joplinapp.org/images/badges/Donate-IBAN.svg" alt="Donate using IBAN"></a></p>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>Joplin Server Changelog<a name="joplin-server-changelog" href="#joplin-server-changelog" class="heading-anchor">🔗</a></h1>
|
<h1>Joplin Server Changelog<a name="joplin-server-changelog" href="#joplin-server-changelog" class="heading-anchor">🔗</a></h1>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.13">server-v2.0.13</a> - 2021-06-16T14:28:20Z<a name="server-v2-0-13-https-github-com-laurent22-joplin-releases-tag-server-v2-0-13-2021-06-16t14-28-20z" href="#server-v2-0-13-https-github-com-laurent22-joplin-releases-tag-server-v2-0-13-2021-06-16t14-28-20z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Improved: Allow creating a new user with no password, which must be set via email confirmation (1896549)</li>
|
||||||
|
<li>Improved: Allow creating a user with a specific account type from admin UI (ecd1602)</li>
|
||||||
|
<li>Fixed: Fixed error message when item is over the limit (ea65313)</li>
|
||||||
|
<li>Fixed: Fixed issue with user not being able to modify own profile (3c18190)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.12">server-v2.0.12</a> - 2021-06-15T16:24:42Z<a name="server-v2-0-12-https-github-com-laurent22-joplin-releases-tag-server-v2-0-12-2021-06-15t16-24-42z" href="#server-v2-0-12-https-github-com-laurent22-joplin-releases-tag-server-v2-0-12-2021-06-15t16-24-42z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Fixed: Fixed handling of user content URL (31121c8)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.11">server-v2.0.11</a> - 2021-06-15T11:41:41Z<a name="server-v2-0-11-https-github-com-laurent22-joplin-releases-tag-server-v2-0-11-2021-06-15t11-41-41z" href="#server-v2-0-11-https-github-com-laurent22-joplin-releases-tag-server-v2-0-11-2021-06-15t11-41-41z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>New: Add navbar on login and sign up page (7a3a208)</li>
|
||||||
|
<li>New: Added option to enable or disable stack traces (5614eb9)</li>
|
||||||
|
<li>Improved: Handle custom user content URLs (a36b13d)</li>
|
||||||
|
<li>Fixed: Fixed error when creating user (594084e)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.9-beta">server-v2.0.9-beta</a> (Pre-release) - 2021-06-11T16:49:05Z<a name="server-v2-0-9-beta-https-github-com-laurent22-joplin-releases-tag-server-v2-0-9-beta-pre-release-2021-06-11t16-49-05z" href="#server-v2-0-9-beta-https-github-com-laurent22-joplin-releases-tag-server-v2-0-9-beta-pre-release-2021-06-11t16-49-05z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>New: Add navbar on login and sign up page (7a3a208)</li>
|
||||||
|
<li>New: Added option to enable or disable stack traces (5614eb9)</li>
|
||||||
|
<li>Improved: Handle custom user content URLs (a36b13d)</li>
|
||||||
|
<li>Fixed: Fixed error when creating user (594084e)</li>
|
||||||
|
</ul>
|
||||||
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.6">server-v2.0.6</a> (Pre-release) - 2021-06-07T17:27:27Z<a name="server-v2-0-6-https-github-com-laurent22-joplin-releases-tag-server-v2-0-6-pre-release-2021-06-07t17-27-27z" href="#server-v2-0-6-https-github-com-laurent22-joplin-releases-tag-server-v2-0-6-pre-release-2021-06-07t17-27-27z" class="heading-anchor">🔗</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>New: Add Stripe integration (770af6a)</li>
|
||||||
|
<li>New: Add request duration to log (c8d7ecb)</li>
|
||||||
|
<li>New: Add terms and privacy page (db7b802)</li>
|
||||||
|
<li>New: Added way to disable signup page, and added links between signup and login pages (75d79f3)</li>
|
||||||
|
<li>Improved: Check share ID when uploading a note (3c41b45)</li>
|
||||||
|
<li>Improved: Load shared user content from correct domain (de45740)</li>
|
||||||
|
</ul>
|
||||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.5">server-v2.0.5</a> (Pre-release) - 2021-06-02T08:14:47Z<a name="server-v2-0-5-https-github-com-laurent22-joplin-releases-tag-server-v2-0-5-pre-release-2021-06-02t08-14-47z" href="#server-v2-0-5-https-github-com-laurent22-joplin-releases-tag-server-v2-0-5-pre-release-2021-06-02t08-14-47z" class="heading-anchor">🔗</a></h2>
|
<h2><a href="https://github.com/laurent22/joplin/releases/tag/server-v2.0.5">server-v2.0.5</a> (Pre-release) - 2021-06-02T08:14:47Z<a name="server-v2-0-5-https-github-com-laurent22-joplin-releases-tag-server-v2-0-5-pre-release-2021-06-02t08-14-47z" href="#server-v2-0-5-https-github-com-laurent22-joplin-releases-tag-server-v2-0-5-pre-release-2021-06-02t08-14-47z" class="heading-anchor">🔗</a></h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>New: Add version number on website (0ef7e98)</li>
|
<li>New: Add version number on website (0ef7e98)</li>
|
||||||
|
|||||||
@@ -424,19 +424,19 @@ https://github.com/laurent22/joplin/blob/dev/README.md
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Windows (32 and 64-bit)</td>
|
<td>Windows (32 and 64-bit)</td>
|
||||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-Setup-1.8.5.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a></td>
|
<td><a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/Joplin-Setup-2.0.11.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>macOS</td>
|
<td>macOS</td>
|
||||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-1.8.5.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a></td>
|
<td><a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/Joplin-2.0.11.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Linux</td>
|
<td>Linux</td>
|
||||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Joplin-1.8.5.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
<td><a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/Joplin-2.0.11.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p><strong>On Windows</strong>, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/JoplinPortable.exe'>Portable version</a>. The <a href="https://en.wikipedia.org/wiki/Portable_application">portable application</a> allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.</p>
|
<p><strong>On Windows</strong>, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v2.0.11/JoplinPortable.exe'>Portable version</a>. The <a href="https://en.wikipedia.org/wiki/Portable_application">portable application</a> allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.</p>
|
||||||
<p><strong>On Linux</strong>, the recommended way is to use the following installation script as it will handle the desktop icon too:</p>
|
<p><strong>On Linux</strong>, the recommended way is to use the following installation script as it will handle the desktop icon too:</p>
|
||||||
<pre><code style="word-break: break-all">wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash</code></pre>
|
<pre><code style="word-break: break-all">wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash</code></pre>
|
||||||
<h2>Mobile applications<a name="mobile-applications" href="#mobile-applications" class="heading-anchor">🔗</a></h2>
|
<h2>Mobile applications<a name="mobile-applications" href="#mobile-applications" class="heading-anchor">🔗</a></h2>
|
||||||
@@ -452,7 +452,7 @@ https://github.com/laurent22/joplin/blob/dev/README.md
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Android</td>
|
<td>Android</td>
|
||||||
<td><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></td>
|
<td><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></td>
|
||||||
<td>or download the APK file: <a href="https://github.com/laurent22/joplin-android/releases/download/android-v1.7.5/joplin-v1.7.5.apk">64-bit</a> <a href="https://github.com/laurent22/joplin-android/releases/download/android-v1.7.5/joplin-v1.7.5-32bit.apk">32-bit</a></td>
|
<td>or download the APK file: <a href="https://github.com/laurent22/joplin-android/releases/download/android-v2.0.4/joplin-v2.0.4.apk">64-bit</a> <a href="https://github.com/laurent22/joplin-android/releases/download/android-v2.0.4/joplin-v2.0.4-32bit.apk">32-bit</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>iOS</td>
|
<td>iOS</td>
|
||||||
@@ -774,6 +774,13 @@ Details:
|
|||||||
<p>For more information see <a href="https://joplinapp.org/plugins/">Plugins</a></p>
|
<p>For more information see <a href="https://joplinapp.org/plugins/">Plugins</a></p>
|
||||||
<h1>Searching<a name="searching" href="#searching" class="heading-anchor">🔗</a></h1>
|
<h1>Searching<a name="searching" href="#searching" class="heading-anchor">🔗</a></h1>
|
||||||
<p>Joplin implements the SQLite Full Text Search (FTS4) extension. It means the content of all the notes is indexed in real time and search queries return results very fast. Both <a href="https://www.sqlite.org/fts3.html#simple_fts_queries">Simple FTS Queries</a> and <a href="https://www.sqlite.org/fts3.html#full_text_index_queries">Full-Text Index Queries</a> are supported. See below for the list of supported queries:</p>
|
<p>Joplin implements the SQLite Full Text Search (FTS4) extension. It means the content of all the notes is indexed in real time and search queries return results very fast. Both <a href="https://www.sqlite.org/fts3.html#simple_fts_queries">Simple FTS Queries</a> and <a href="https://www.sqlite.org/fts3.html#full_text_index_queries">Full-Text Index Queries</a> are supported. See below for the list of supported queries:</p>
|
||||||
|
<p>One caveat of SQLite FTS is that it does not support languages which do not use Latin word boundaries (spaces, tabs, punctuation). To solve this issue, Joplin has a custom search mode, that does not use FTS, but still has all of its features (multi term search, filters, etc.). One of its drawbacks is that it can get slow on larger note collections. Also, the sorting of the results will be less accurate, as the ranking algorithm (BM25) is, for now, only implemented for FTS. Finally, in this mode there are no restrictions on using the <code>*</code> wildcard (<code>swim*</code>, <code>*swim</code> and <code>ast*rix</code> all work). This search mode is currently enabled if one of the following languages are detected:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Chinese</li>
|
||||||
|
<li>Japanese</li>
|
||||||
|
<li>Korean</li>
|
||||||
|
<li>Thai</li>
|
||||||
|
</ul>
|
||||||
<h2>Supported queries<a name="supported-queries" href="#supported-queries" class="heading-anchor">🔗</a></h2>
|
<h2>Supported queries<a name="supported-queries" href="#supported-queries" class="heading-anchor">🔗</a></h2>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -1032,21 +1039,21 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
|||||||
<td>Croatian (Hrvatska)</td>
|
<td>Croatian (Hrvatska)</td>
|
||||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po">hr_HR</a></td>
|
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po">hr_HR</a></td>
|
||||||
<td><a href="mailto:mail@milotype.de">Milo Ivir</a></td>
|
<td><a href="mailto:mail@milotype.de">Milo Ivir</a></td>
|
||||||
<td>96%</td>
|
<td>100%</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/></td>
|
<td><img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/></td>
|
||||||
<td>Czech (Česká republika)</td>
|
<td>Czech (Česká republika)</td>
|
||||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po">cs_CZ</a></td>
|
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po">cs_CZ</a></td>
|
||||||
<td><a href="mailto:lukas@aiya.cz">Lukas Helebrandt</a></td>
|
<td><a href="mailto:michal@stanke.cz">Michal Stanke</a></td>
|
||||||
<td>85%</td>
|
<td>100%</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/></td>
|
<td><img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/></td>
|
||||||
<td>Dansk (Danmark)</td>
|
<td>Dansk (Danmark)</td>
|
||||||
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po">da_DK</a></td>
|
<td><a href="https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po">da_DK</a></td>
|
||||||
<td>Mustafa Al-Dailemi (<a href="mailto:dailemi@hotmail.com">dailemi@hotmail.com</a>)Language-Team:</td>
|
<td>Mustafa Al-Dailemi (<a href="mailto:dailemi@hotmail.com">dailemi@hotmail.com</a>)Language-Team:</td>
|
||||||
<td>95%</td>
|
<td>99%</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/></td>
|
<td><img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/></td>
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
6,
|
6,
|
||||||
7,
|
7,
|
||||||
8,
|
8,
|
||||||
9
|
9,
|
||||||
|
10
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sync.upgradeState": {
|
"sync.upgradeState": {
|
||||||
@@ -99,14 +100,40 @@
|
|||||||
"sync.9.path": {
|
"sync.9.path": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "Joplin Cloud URL. Attention: If you change this location, make sure you copy all your content to it before syncing, otherwise all files will be removed! See the FAQ for more details: https://joplinapp.org/faq/"
|
"description": "Joplin Server URL. Attention: If you change this location, make sure you copy all your content to it before syncing, otherwise all files will be removed! See the FAQ for more details: https://joplinapp.org/faq/"
|
||||||
|
},
|
||||||
|
"sync.9.userContentPath": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"$comment": "private"
|
||||||
},
|
},
|
||||||
"sync.9.username": {
|
"sync.9.username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "Joplin Cloud email"
|
"description": "Joplin Server email"
|
||||||
},
|
},
|
||||||
"sync.9.password": {
|
"sync.9.password": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"description": "Joplin Server password",
|
||||||
|
"$comment": "private"
|
||||||
|
},
|
||||||
|
"sync.10.path": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "https://api.joplincloud.com",
|
||||||
|
"$comment": "private"
|
||||||
|
},
|
||||||
|
"sync.10.userContentPath": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "https://joplinusercontent.com",
|
||||||
|
"$comment": "private"
|
||||||
|
},
|
||||||
|
"sync.10.username": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"description": "Joplin Cloud email"
|
||||||
|
},
|
||||||
|
"sync.10.password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "Joplin Cloud password",
|
"description": "Joplin Cloud password",
|
||||||
@@ -147,6 +174,11 @@
|
|||||||
"default": "",
|
"default": "",
|
||||||
"$comment": "private"
|
"$comment": "private"
|
||||||
},
|
},
|
||||||
|
"sync.10.auth": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"$comment": "private"
|
||||||
|
},
|
||||||
"sync.1.context": {
|
"sync.1.context": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
@@ -192,6 +224,11 @@
|
|||||||
"default": "",
|
"default": "",
|
||||||
"$comment": "private"
|
"$comment": "private"
|
||||||
},
|
},
|
||||||
|
"sync.10.context": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"$comment": "private"
|
||||||
|
},
|
||||||
"sync.maxConcurrentConnections": {
|
"sync.maxConcurrentConnections": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 5,
|
"default": 5,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
2
packages/app-cli/package-lock.json
generated
2
packages/app-cli/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "joplin",
|
"name": "joplin",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -27,11 +27,12 @@
|
|||||||
2017,
|
2017,
|
||||||
2018,
|
2018,
|
||||||
2019,
|
2019,
|
||||||
2020
|
2020,
|
||||||
|
2021
|
||||||
],
|
],
|
||||||
"owner": "Laurent Cozic"
|
"owner": "Laurent Cozic"
|
||||||
},
|
},
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"joplin": "./main.js"
|
"joplin": "./main.js"
|
||||||
},
|
},
|
||||||
@@ -39,8 +40,8 @@
|
|||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/lib": "1.8",
|
"@joplin/lib": "2.0",
|
||||||
"@joplin/renderer": "1.8",
|
"@joplin/renderer": "2.0",
|
||||||
"aws-sdk": "^2.588.0",
|
"aws-sdk": "^2.588.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"compare-version": "^0.1.2",
|
"compare-version": "^0.1.2",
|
||||||
@@ -64,7 +65,7 @@
|
|||||||
"yargs-parser": "^7.0.0"
|
"yargs-parser": "^7.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@joplin/tools": "1.8",
|
"@joplin/tools": "2.0",
|
||||||
"@types/fs-extra": "^9.0.6",
|
"@types/fs-extra": "^9.0.6",
|
||||||
"@types/jest": "^26.0.15",
|
"@types/jest": "^26.0.15",
|
||||||
"@types/node": "^14.14.6",
|
"@types/node": "^14.14.6",
|
||||||
|
|||||||
3
packages/app-cli/tests/.gitignore
vendored
3
packages/app-cli/tests/.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
test data/
|
test data/
|
||||||
export/
|
export/
|
||||||
|
support/serverPerformances/testPerfCommands.txt
|
||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
17
packages/app-cli/tests/support/plugins/selected_text/api/JoplinInterop.d.ts
vendored
Normal file
17
packages/app-cli/tests/support/plugins/selected_text/api/JoplinInterop.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { ExportModule, ImportModule } from './types';
|
||||||
|
/**
|
||||||
|
* Provides a way to create modules to import external data into Joplin or to export notes into any arbitrary format.
|
||||||
|
*
|
||||||
|
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export)
|
||||||
|
*
|
||||||
|
* To implement an import or export module, you would simply define an object with various event handlers that are called
|
||||||
|
* by the application during the import/export process.
|
||||||
|
*
|
||||||
|
* See the documentation of the [[ExportModule]] and [[ImportModule]] for more information.
|
||||||
|
*
|
||||||
|
* You may also want to refer to the Joplin API documentation to see the list of properties for each item (note, notebook, etc.) - https://joplinapp.org/api/references/rest_api/
|
||||||
|
*/
|
||||||
|
export default class JoplinInterop {
|
||||||
|
registerExportModule(module: ExportModule): Promise<void>;
|
||||||
|
registerImportModule(module: ImportModule): Promise<void>;
|
||||||
|
}
|
||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -135,7 +135,9 @@ const pluginConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
// JSON files can also be required from scripts so we include this.
|
||||||
|
// https://github.com/joplin/plugin-bibtex/pull/2
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -167,7 +169,7 @@ const extraScriptConfig = Object.assign({}, baseConfig, {
|
|||||||
alias: {
|
alias: {
|
||||||
api: path.resolve(__dirname, 'api'),
|
api: path.resolve(__dirname, 'api'),
|
||||||
},
|
},
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
55
packages/app-cli/tests/support/serverPerformances/testPerf.sh
Executable file
55
packages/app-cli/tests/support/serverPerformances/testPerf.sh
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
ROOT_DIR="$SCRIPT_DIR/../../../../.."
|
||||||
|
|
||||||
|
COMMANDS=($(echo $1 | tr "," "\n"))
|
||||||
|
PROFILE_DIR=~/.config/joplindev-testperf
|
||||||
|
|
||||||
|
CMD_FILE="$SCRIPT_DIR/testPerfCommands.txt"
|
||||||
|
rm -f "$CMD_FILE"
|
||||||
|
touch "$CMD_FILE"
|
||||||
|
|
||||||
|
for CMD in "${COMMANDS[@]}"
|
||||||
|
do
|
||||||
|
if [[ $CMD == "createUsers" ]]; then
|
||||||
|
|
||||||
|
curl --data '{"action": "createTestUsers"}' -H 'Content-Type: application/json' http://api.joplincloud.local:22300/api/debug
|
||||||
|
|
||||||
|
# elif [[ $CMD == "createData" ]]; then
|
||||||
|
|
||||||
|
# echo 'mkbook "shared"' >> "$CMD_FILE"
|
||||||
|
# echo 'mkbook "other"' >> "$CMD_FILE"
|
||||||
|
# echo 'use "shared"' >> "$CMD_FILE"
|
||||||
|
# echo 'mknote "note 1"' >> "$CMD_FILE"
|
||||||
|
# echo 'mknote "note 2"' >> "$CMD_FILE"
|
||||||
|
|
||||||
|
elif [[ $CMD == "reset" ]]; then
|
||||||
|
|
||||||
|
USER_EMAIL="user1@example.com"
|
||||||
|
rm -rf "$PROFILE_DIR"
|
||||||
|
echo "config keychain.supported 0" >> "$CMD_FILE"
|
||||||
|
echo "config sync.target 9" >> "$CMD_FILE"
|
||||||
|
echo "config sync.9.path http://api.joplincloud.local:22300" >> "$CMD_FILE"
|
||||||
|
echo "config sync.9.username $USER_EMAIL" >> "$CMD_FILE"
|
||||||
|
echo "config sync.9.password 123456" >> "$CMD_FILE"
|
||||||
|
|
||||||
|
# elif [[ $CMD == "e2ee" ]]; then
|
||||||
|
|
||||||
|
# echo "e2ee enable --password 111111" >> "$CMD_FILE"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "Unknown command: $CMD"
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cd "$ROOT_DIR/packages/app-cli"
|
||||||
|
npm start -- --profile "$PROFILE_DIR" batch "$CMD_FILE"
|
||||||
|
npm start -- --profile "$PROFILE_DIR" import ~/Desktop/Joplin_17_06_2021.jex
|
||||||
|
npm start -- --profile "$PROFILE_DIR" sync
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Joplin Web Clipper [DEV]",
|
"name": "Joplin Web Clipper [DEV]",
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
||||||
"homepage_url": "https://joplinapp.org",
|
"homepage_url": "https://joplinapp.org",
|
||||||
"content_security_policy": "script-src 'self'; object-src 'self'",
|
"content_security_policy": "script-src 'self'; object-src 'self'",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/app-desktop",
|
"name": "@joplin/app-desktop",
|
||||||
"version": "2.0.11",
|
"version": "2.1.0",
|
||||||
"description": "Joplin for Desktop",
|
"description": "Joplin for Desktop",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ android {
|
|||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 2097635
|
versionCode 2097635
|
||||||
versionName "2.0.4"
|
versionName "2.1.0"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -492,7 +492,7 @@
|
|||||||
INFOPLIST_FILE = Joplin/Info.plist;
|
INFOPLIST_FILE = Joplin/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 12.0.2;
|
MARKETING_VERSION = 12.1.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
@@ -519,7 +519,7 @@
|
|||||||
INFOPLIST_FILE = Joplin/Info.plist;
|
INFOPLIST_FILE = Joplin/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 12.0.2;
|
MARKETING_VERSION = 12.1.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
@@ -666,7 +666,7 @@
|
|||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 12.0.2;
|
MARKETING_VERSION = 12.1.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||||
@@ -697,7 +697,7 @@
|
|||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 12.0.2;
|
MARKETING_VERSION = 12.1.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import SyncTargetJoplinServer from '@joplin/lib/SyncTargetJoplinServer';
|
|||||||
import SyncTargetJoplinCloud from '@joplin/lib/SyncTargetJoplinCloud';
|
import SyncTargetJoplinCloud from '@joplin/lib/SyncTargetJoplinCloud';
|
||||||
import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
|
import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
|
||||||
|
|
||||||
|
const VersionInfo = require('react-native-version-info').default;
|
||||||
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar, Linking, Platform } = require('react-native');
|
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar, Linking, Platform } = require('react-native');
|
||||||
|
|
||||||
import NetInfo from '@react-native-community/netinfo';
|
import NetInfo from '@react-native-community/netinfo';
|
||||||
@@ -426,7 +427,7 @@ async function initialize(dispatch: Function) {
|
|||||||
// require('@joplin/lib/ntpDate').setLogger(reg.logger());
|
// require('@joplin/lib/ntpDate').setLogger(reg.logger());
|
||||||
|
|
||||||
reg.logger().info('====================================');
|
reg.logger().info('====================================');
|
||||||
reg.logger().info(`Starting application ${Setting.value('appId')} (${Setting.value('env')})`);
|
reg.logger().info(`Starting application ${Setting.value('appId')} v${VersionInfo.appVersion} (${Setting.value('env')})`);
|
||||||
|
|
||||||
const dbLogger = new Logger();
|
const dbLogger = new Logger();
|
||||||
dbLogger.addTarget(TargetType.Database, { database: logDatabase, source: 'm' });
|
dbLogger.addTarget(TargetType.Database, { database: logDatabase, source: 'm' });
|
||||||
|
|||||||
2
packages/fork-htmlparser2/package-lock.json
generated
2
packages/fork-htmlparser2/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/fork-htmlparser2",
|
"name": "@joplin/fork-htmlparser2",
|
||||||
"version": "4.1.26",
|
"version": "4.1.27",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/fork-htmlparser2",
|
"name": "@joplin/fork-htmlparser2",
|
||||||
"description": "Fast & forgiving HTML/XML/RSS parser",
|
"description": "Fast & forgiving HTML/XML/RSS parser",
|
||||||
"version": "4.1.26",
|
"version": "4.1.27",
|
||||||
"author": "Felix Boehm <me@feedic.com>",
|
"author": "Felix Boehm <me@feedic.com>",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
|||||||
2
packages/fork-sax/package-lock.json
generated
2
packages/fork-sax/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/fork-sax",
|
"name": "@joplin/fork-sax",
|
||||||
"version": "1.2.30",
|
"version": "1.2.31",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@joplin/fork-sax",
|
"name": "@joplin/fork-sax",
|
||||||
"description": "An evented streaming XML parser in JavaScript",
|
"description": "An evented streaming XML parser in JavaScript",
|
||||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||||
"version": "1.2.30",
|
"version": "1.2.31",
|
||||||
"main": "lib/sax.js",
|
"main": "lib/sax.js",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ import { Command } from './types';
|
|||||||
*
|
*
|
||||||
* To view what arguments are supported, you can open any of these files
|
* To view what arguments are supported, you can open any of these files
|
||||||
* and look at the `execute()` command.
|
* 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 {
|
export default class JoplinCommands {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ export interface Command {
|
|||||||
execute(...args: any[]): Promise<any | void>;
|
execute(...args: any[]): Promise<any | void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines whether the command should be enabled or disabled, which in turns affects
|
* Defines whether the command should be enabled or disabled, which in turns
|
||||||
* the enabled state of any associated button or menu item.
|
* 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
|
* The condition should be expressed as a "when-clause" (as in Visual Studio
|
||||||
* `true` or `false`. It supports the following operators:
|
* Code). It's a simple boolean expression that evaluates to `true` or
|
||||||
|
* `false`. It supports the following operators:
|
||||||
*
|
*
|
||||||
* Operator | Symbol | Example
|
* Operator | Symbol | Example
|
||||||
* -- | -- | --
|
* -- | -- | --
|
||||||
@@ -40,7 +41,15 @@ export interface Command {
|
|||||||
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
|
||||||
* And | && | "oneNoteSelected && !inConflictFolder"
|
* 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.
|
* Note: Commands are enabled by default unless you use this property.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"id": "<%= pluginId %>",
|
"id": "<%= pluginId %>",
|
||||||
"app_min_version": "2.0",
|
"app_min_version": "2.1",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"name": "<%= pluginName %>",
|
"name": "<%= pluginName %>",
|
||||||
"description": "<%= pluginDescription %>",
|
"description": "<%= pluginDescription %>",
|
||||||
|
|||||||
2
packages/generator-joplin/package-lock.json
generated
2
packages/generator-joplin/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "generator-joplin",
|
"name": "generator-joplin",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "generator-joplin",
|
"name": "generator-joplin",
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"description": "Scaffolds out a new Joplin plugin",
|
"description": "Scaffolds out a new Joplin plugin",
|
||||||
"homepage": "https://github.com/laurent22/joplin/tree/dev/packages/generator-joplin",
|
"homepage": "https://github.com/laurent22/joplin/tree/dev/packages/generator-joplin",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -91,6 +91,23 @@ export default class JoplinServerApi {
|
|||||||
return _('Could not connect to Joplin Server. Please check the Synchronisation options in the config screen. Full error was:\n\n%s', msg);
|
return _('Could not connect to Joplin Server. Please check the Synchronisation options in the config screen. Full error was:\n\n%s', msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private hidePassword(o: any): any {
|
||||||
|
if (typeof o === 'string') {
|
||||||
|
try {
|
||||||
|
const output = JSON.parse(o);
|
||||||
|
if (!output) return o;
|
||||||
|
if (output.password) output.password = '******';
|
||||||
|
return JSON.stringify(output);
|
||||||
|
} catch (error) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const output = { ...o };
|
||||||
|
if (output.password) output.password = '******';
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private requestToCurl_(url: string, options: any) {
|
private requestToCurl_(url: string, options: any) {
|
||||||
const output = [];
|
const output = [];
|
||||||
output.push('curl');
|
output.push('curl');
|
||||||
@@ -99,11 +116,12 @@ export default class JoplinServerApi {
|
|||||||
if (options.headers) {
|
if (options.headers) {
|
||||||
for (const n in options.headers) {
|
for (const n in options.headers) {
|
||||||
if (!options.headers.hasOwnProperty(n)) continue;
|
if (!options.headers.hasOwnProperty(n)) continue;
|
||||||
output.push(`${'-H ' + '"'}${n}: ${options.headers[n]}"`);
|
const headerValue = n === 'X-API-AUTH' ? '******' : options.headers[n];
|
||||||
|
output.push(`${'-H ' + '"'}${n}: ${headerValue}"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.body) {
|
if (options.body) {
|
||||||
const serialized = typeof options.body !== 'string' ? JSON.stringify(options.body) : options.body;
|
const serialized = typeof options.body !== 'string' ? JSON.stringify(this.hidePassword(options.body)) : this.hidePassword(options.body);
|
||||||
output.push(`${'--data ' + '\''}${serialized}'`);
|
output.push(`${'--data ' + '\''}${serialized}'`);
|
||||||
}
|
}
|
||||||
output.push(`'${url}'`);
|
output.push(`'${url}'`);
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ import ResourceService from './services/ResourceService';
|
|||||||
import EncryptionService from './services/EncryptionService';
|
import EncryptionService from './services/EncryptionService';
|
||||||
import JoplinError from './JoplinError';
|
import JoplinError from './JoplinError';
|
||||||
import ShareService from './services/share/ShareService';
|
import ShareService from './services/share/ShareService';
|
||||||
|
import TaskQueue from './TaskQueue';
|
||||||
|
import { preUploadItems, serializeAndUploadItem } from './services/synchronizer/uploadUtils';
|
||||||
const { sprintf } = require('sprintf-js');
|
const { sprintf } = require('sprintf-js');
|
||||||
const TaskQueue = require('./TaskQueue');
|
|
||||||
const { Dirnames } = require('./services/synchronizer/utils/types');
|
const { Dirnames } = require('./services/synchronizer/utils/types');
|
||||||
|
|
||||||
interface RemoteItem {
|
interface RemoteItem {
|
||||||
@@ -169,7 +170,7 @@ export default class Synchronizer {
|
|||||||
if (report.deleteRemote) lines.push(_('Deleted remote items: %d.', report.deleteRemote));
|
if (report.deleteRemote) lines.push(_('Deleted remote items: %d.', report.deleteRemote));
|
||||||
if (report.fetchingTotal && report.fetchingProcessed) lines.push(_('Fetched items: %d/%d.', report.fetchingProcessed, report.fetchingTotal));
|
if (report.fetchingTotal && report.fetchingProcessed) lines.push(_('Fetched items: %d/%d.', report.fetchingProcessed, report.fetchingTotal));
|
||||||
if (report.cancelling && !report.completedTime) lines.push(_('Cancelling...'));
|
if (report.cancelling && !report.completedTime) lines.push(_('Cancelling...'));
|
||||||
if (report.completedTime) lines.push(_('Completed: %s', time.formatMsToLocal(report.completedTime)));
|
if (report.completedTime) lines.push(_('Completed: %s (%s)', time.formatMsToLocal(report.completedTime), `${Math.round((report.completedTime - report.startTime) / 1000)}s`));
|
||||||
if (this.reportHasErrors(report)) lines.push(_('Last error: %s', report.errors[report.errors.length - 1].toString().substr(0, 500)));
|
if (this.reportHasErrors(report)) lines.push(_('Last error: %s', report.errors[report.errors.length - 1].toString().substr(0, 500)));
|
||||||
|
|
||||||
return lines;
|
return lines;
|
||||||
@@ -225,6 +226,7 @@ export default class Synchronizer {
|
|||||||
if (n == 'starting') continue;
|
if (n == 'starting') continue;
|
||||||
if (n == 'finished') continue;
|
if (n == 'finished') continue;
|
||||||
if (n == 'state') continue;
|
if (n == 'state') continue;
|
||||||
|
if (n == 'startTime') continue;
|
||||||
if (n == 'completedTime') continue;
|
if (n == 'completedTime') continue;
|
||||||
this.logger().info(`${n}: ${report[n] ? report[n] : '-'}`);
|
this.logger().info(`${n}: ${report[n] ? report[n] : '-'}`);
|
||||||
}
|
}
|
||||||
@@ -356,6 +358,8 @@ export default class Synchronizer {
|
|||||||
|
|
||||||
const outputContext = Object.assign({}, lastContext);
|
const outputContext = Object.assign({}, lastContext);
|
||||||
|
|
||||||
|
this.progressReport_.startTime = time.unixMs();
|
||||||
|
|
||||||
this.dispatch({ type: 'SYNC_STARTED' });
|
this.dispatch({ type: 'SYNC_STARTED' });
|
||||||
eventManager.emit('syncStart');
|
eventManager.emit('syncStart');
|
||||||
|
|
||||||
@@ -386,6 +390,12 @@ export default class Synchronizer {
|
|||||||
// correctly so as to share/unshare the right items.
|
// correctly so as to share/unshare the right items.
|
||||||
await Folder.updateAllShareIds();
|
await Folder.updateAllShareIds();
|
||||||
|
|
||||||
|
const uploadQueue = new TaskQueue('syncUpload', this.logger());
|
||||||
|
|
||||||
|
const uploadItem = (path: string, content: any) => {
|
||||||
|
return this.apiCall('put', path, content);
|
||||||
|
};
|
||||||
|
|
||||||
let errorToThrow = null;
|
let errorToThrow = null;
|
||||||
let syncLock = null;
|
let syncLock = null;
|
||||||
|
|
||||||
@@ -437,6 +447,8 @@ export default class Synchronizer {
|
|||||||
const result = await BaseItem.itemsThatNeedSync(syncTargetId);
|
const result = await BaseItem.itemsThatNeedSync(syncTargetId);
|
||||||
const locals = result.items;
|
const locals = result.items;
|
||||||
|
|
||||||
|
await preUploadItems(uploadItem, uploadQueue, result.items.filter((it: any) => result.neverSyncedItemIds.includes(it.id)));
|
||||||
|
|
||||||
for (let i = 0; i < locals.length; i++) {
|
for (let i = 0; i < locals.length; i++) {
|
||||||
if (this.cancelling()) break;
|
if (this.cancelling()) break;
|
||||||
|
|
||||||
@@ -453,7 +465,7 @@ export default class Synchronizer {
|
|||||||
// (by setting an updated_time less than current time).
|
// (by setting an updated_time less than current time).
|
||||||
if (donePaths.indexOf(path) >= 0) throw new JoplinError(sprintf('Processing a path that has already been done: %s. sync_time was not updated? Remote item has an updated_time in the future?', path), 'processingPathTwice');
|
if (donePaths.indexOf(path) >= 0) throw new JoplinError(sprintf('Processing a path that has already been done: %s. sync_time was not updated? Remote item has an updated_time in the future?', path), 'processingPathTwice');
|
||||||
|
|
||||||
const remote: RemoteItem = await this.apiCall('stat', path);
|
const remote: RemoteItem = result.neverSyncedItemIds.includes(local.id) ? null : await this.apiCall('stat', path);
|
||||||
let action = null;
|
let action = null;
|
||||||
|
|
||||||
let reason = '';
|
let reason = '';
|
||||||
@@ -561,14 +573,15 @@ export default class Synchronizer {
|
|||||||
try {
|
try {
|
||||||
const remoteContentPath = resourceRemotePath(local.id);
|
const remoteContentPath = resourceRemotePath(local.id);
|
||||||
const result = await Resource.fullPathForSyncUpload(local);
|
const result = await Resource.fullPathForSyncUpload(local);
|
||||||
local = result.resource;
|
const resource = result.resource;
|
||||||
|
local = resource as any;
|
||||||
const localResourceContentPath = result.path;
|
const localResourceContentPath = result.path;
|
||||||
|
|
||||||
if (local.size >= 10 * 1000 * 1000) {
|
if (resource.size >= 10 * 1000 * 1000) {
|
||||||
this.logger().warn(`Uploading a large resource (resourceId: ${local.id}, size:${local.size} bytes) which may tie up the sync process.`);
|
this.logger().warn(`Uploading a large resource (resourceId: ${local.id}, size:${resource.size} bytes) which may tie up the sync process.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.apiCall('put', remoteContentPath, null, { path: localResourceContentPath, source: 'file', shareId: local.share_id });
|
await this.apiCall('put', remoteContentPath, null, { path: localResourceContentPath, source: 'file', shareId: resource.share_id });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isCannotSyncError(error)) {
|
if (isCannotSyncError(error)) {
|
||||||
await handleCannotSyncItem(ItemClass, syncTargetId, local, error.message);
|
await handleCannotSyncItem(ItemClass, syncTargetId, local, error.message);
|
||||||
@@ -584,8 +597,7 @@ export default class Synchronizer {
|
|||||||
let canSync = true;
|
let canSync = true;
|
||||||
try {
|
try {
|
||||||
if (this.testingHooks_.indexOf('notesRejectedByTarget') >= 0 && local.type_ === BaseModel.TYPE_NOTE) throw new JoplinError('Testing rejectedByTarget', 'rejectedByTarget');
|
if (this.testingHooks_.indexOf('notesRejectedByTarget') >= 0 && local.type_ === BaseModel.TYPE_NOTE) throw new JoplinError('Testing rejectedByTarget', 'rejectedByTarget');
|
||||||
const content = await ItemClass.serializeForSync(local);
|
await serializeAndUploadItem(uploadItem, uploadQueue, ItemClass, path, local);
|
||||||
await this.apiCall('put', path, content);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error && error.code === 'rejectedByTarget') {
|
if (error && error.code === 'rejectedByTarget') {
|
||||||
await handleCannotSyncItem(ItemClass, syncTargetId, local, error.message);
|
await handleCannotSyncItem(ItemClass, syncTargetId, local, error.message);
|
||||||
@@ -784,7 +796,7 @@ export default class Synchronizer {
|
|||||||
if (!BaseItem.isSystemPath(remote.path)) continue; // The delta API might return things like the .sync, .resource or the root folder
|
if (!BaseItem.isSystemPath(remote.path)) continue; // The delta API might return things like the .sync, .resource or the root folder
|
||||||
|
|
||||||
const loadContent = async () => {
|
const loadContent = async () => {
|
||||||
const task = await this.downloadQueue_.waitForResult(path); // await this.apiCall('get', path);
|
const task = await this.downloadQueue_.waitForResult(path);
|
||||||
if (task.error) throw task.error;
|
if (task.error) throw task.error;
|
||||||
if (!task.result) return null;
|
if (!task.result) return null;
|
||||||
return await BaseItem.unserialize(task.result);
|
return await BaseItem.unserialize(task.result);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const { setupDatabaseAndSynchronizer, sleep, switchClient } = require('./testing/test-utils.js');
|
const { setupDatabaseAndSynchronizer, sleep, switchClient } = require('./testing/test-utils.js');
|
||||||
const TaskQueue = require('./TaskQueue.js');
|
const TaskQueue = require('./TaskQueue').default;
|
||||||
|
|
||||||
describe('TaskQueue', function() {
|
describe('TaskQueue', function() {
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,38 @@
|
|||||||
const time = require('./time').default;
|
import time from './time';
|
||||||
const Setting = require('./models/Setting').default;
|
import Setting from './models/Setting';
|
||||||
const Logger = require('./Logger').default;
|
import Logger from './Logger';
|
||||||
|
|
||||||
class TaskQueue {
|
interface Task {
|
||||||
constructor(name) {
|
id: string;
|
||||||
this.waitingTasks_ = [];
|
callback: Function;
|
||||||
this.processingTasks_ = {};
|
}
|
||||||
this.processingQueue_ = false;
|
|
||||||
this.stopping_ = false;
|
interface TaskResult {
|
||||||
this.results_ = {};
|
id: string;
|
||||||
|
result: any;
|
||||||
|
error?: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class TaskQueue {
|
||||||
|
|
||||||
|
private waitingTasks_: Task[] = [];
|
||||||
|
private processingTasks_: Record<string, Task> = {};
|
||||||
|
private processingQueue_ = false;
|
||||||
|
private stopping_ = false;
|
||||||
|
private results_: Record<string, TaskResult> = {};
|
||||||
|
private name_: string;
|
||||||
|
private logger_: Logger;
|
||||||
|
|
||||||
|
constructor(name: string, logger: Logger = null) {
|
||||||
this.name_ = name;
|
this.name_ = name;
|
||||||
this.logger_ = new Logger();
|
this.logger_ = logger ? logger : new Logger();
|
||||||
}
|
}
|
||||||
|
|
||||||
concurrency() {
|
concurrency() {
|
||||||
return Setting.value('sync.maxConcurrentConnections');
|
return Setting.value('sync.maxConcurrentConnections');
|
||||||
}
|
}
|
||||||
|
|
||||||
push(id, callback) {
|
push(id: string, callback: Function) {
|
||||||
if (this.stopping_) throw new Error('Cannot push task when queue is stopping');
|
if (this.stopping_) throw new Error('Cannot push task when queue is stopping');
|
||||||
|
|
||||||
this.waitingTasks_.push({
|
this.waitingTasks_.push({
|
||||||
@@ -32,10 +47,10 @@ class TaskQueue {
|
|||||||
|
|
||||||
this.processingQueue_ = true;
|
this.processingQueue_ = true;
|
||||||
|
|
||||||
const completeTask = (task, result, error) => {
|
const completeTask = (task: Task, result: any, error: Error) => {
|
||||||
delete this.processingTasks_[task.id];
|
delete this.processingTasks_[task.id];
|
||||||
|
|
||||||
const r = {
|
const r: TaskResult = {
|
||||||
id: task.id,
|
id: task.id,
|
||||||
result: result,
|
result: result,
|
||||||
};
|
};
|
||||||
@@ -55,10 +70,10 @@ class TaskQueue {
|
|||||||
|
|
||||||
task
|
task
|
||||||
.callback()
|
.callback()
|
||||||
.then(result => {
|
.then((result: any) => {
|
||||||
completeTask(task, result, null);
|
completeTask(task, result, null);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error: Error) => {
|
||||||
if (!error) error = new Error('Unknown error');
|
if (!error) error = new Error('Unknown error');
|
||||||
completeTask(task, null, error);
|
completeTask(task, null, error);
|
||||||
});
|
});
|
||||||
@@ -67,29 +82,42 @@ class TaskQueue {
|
|||||||
this.processingQueue_ = false;
|
this.processingQueue_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isWaiting(taskId) {
|
isWaiting(taskId: string) {
|
||||||
return this.waitingTasks_.find(task => task.id === taskId);
|
return this.waitingTasks_.find(task => task.id === taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
isProcessing(taskId) {
|
isProcessing(taskId: string) {
|
||||||
return taskId in this.processingTasks_;
|
return taskId in this.processingTasks_;
|
||||||
}
|
}
|
||||||
|
|
||||||
isDone(taskId) {
|
isDone(taskId: string) {
|
||||||
return taskId in this.results_;
|
return taskId in this.results_;
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForResult(taskId) {
|
async waitForAll() {
|
||||||
if (!this.isWaiting(taskId) && !this.isProcessing(taskId) && !this.isDone(taskId)) throw new Error(`No such task: ${taskId}`);
|
return new Promise((resolve) => {
|
||||||
|
const checkIID = setInterval(() => {
|
||||||
|
if (this.waitingTasks_.length) return;
|
||||||
|
if (this.processingTasks_.length) return;
|
||||||
|
clearInterval(checkIID);
|
||||||
|
resolve(null);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
taskExists(taskId: string) {
|
||||||
|
return this.isWaiting(taskId) || this.isProcessing(taskId) || this.isDone(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
taskResult(taskId: string) {
|
||||||
|
if (!this.taskExists(taskId)) throw new Error(`No such task: ${taskId}`);
|
||||||
|
return this.results_[taskId];
|
||||||
|
}
|
||||||
|
|
||||||
|
async waitForResult(taskId: string) {
|
||||||
|
if (!this.taskExists(taskId)) throw new Error(`No such task: ${taskId}`);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// if (this.stopping_) {
|
|
||||||
// return {
|
|
||||||
// id: taskId,
|
|
||||||
// error: new JoplinError('Queue has been destroyed', 'destroyedQueue'),
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
const task = this.results_[taskId];
|
const task = this.results_[taskId];
|
||||||
if (task) return task;
|
if (task) return task;
|
||||||
await time.sleep(0.1);
|
await time.sleep(0.1);
|
||||||
@@ -120,7 +148,3 @@ class TaskQueue {
|
|||||||
return this.stopping_;
|
return this.stopping_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskQueue.CONCURRENCY = 5;
|
|
||||||
|
|
||||||
module.exports = TaskQueue;
|
|
||||||
@@ -18,6 +18,20 @@ export interface ItemsThatNeedDecryptionResult {
|
|||||||
items: any[];
|
items: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ItemThatNeedSync {
|
||||||
|
id: string;
|
||||||
|
sync_time: number;
|
||||||
|
type_: ModelType;
|
||||||
|
updated_time: number;
|
||||||
|
encryption_applied: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ItemsThatNeedSyncResult {
|
||||||
|
hasMore: boolean;
|
||||||
|
items: ItemThatNeedSync[];
|
||||||
|
neverSyncedItemIds: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export default class BaseItem extends BaseModel {
|
export default class BaseItem extends BaseModel {
|
||||||
|
|
||||||
public static encryptionService_: any = null;
|
public static encryptionService_: any = null;
|
||||||
@@ -583,7 +597,7 @@ export default class BaseItem extends BaseModel {
|
|||||||
throw new Error('Unreachable');
|
throw new Error('Unreachable');
|
||||||
}
|
}
|
||||||
|
|
||||||
static async itemsThatNeedSync(syncTarget: number, limit = 100) {
|
public static async itemsThatNeedSync(syncTarget: number, limit = 100): Promise<ItemsThatNeedSyncResult> {
|
||||||
const classNames = this.syncItemClassNames();
|
const classNames = this.syncItemClassNames();
|
||||||
|
|
||||||
for (let i = 0; i < classNames.length; i++) {
|
for (let i = 0; i < classNames.length; i++) {
|
||||||
@@ -660,12 +674,13 @@ export default class BaseItem extends BaseModel {
|
|||||||
changedItems = await ItemClass.modelSelectAll(sql);
|
changedItems = await ItemClass.modelSelectAll(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const neverSyncedItemIds = neverSyncedItem.map((it: any) => it.id);
|
||||||
const items = neverSyncedItem.concat(changedItems);
|
const items = neverSyncedItem.concat(changedItems);
|
||||||
|
|
||||||
if (i >= classNames.length - 1) {
|
if (i >= classNames.length - 1) {
|
||||||
return { hasMore: items.length >= limit, items: items };
|
return { hasMore: items.length >= limit, items: items, neverSyncedItemIds };
|
||||||
} else {
|
} else {
|
||||||
if (items.length) return { hasMore: true, items: items };
|
if (items.length) return { hasMore: true, items: items, neverSyncedItemIds };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
packages/lib/package-lock.json
generated
2
packages/lib/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/lib",
|
"name": "@joplin/lib",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/lib",
|
"name": "@joplin/lib",
|
||||||
"version": "2.0.2",
|
"version": "2.1.0",
|
||||||
"description": "Joplin Core library",
|
"description": "Joplin Core library",
|
||||||
"author": "Laurent Cozic",
|
"author": "Laurent Cozic",
|
||||||
"homepage": "",
|
"homepage": "",
|
||||||
@@ -25,11 +25,11 @@
|
|||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/fork-htmlparser2": "^4.1.26",
|
"@joplin/fork-htmlparser2": "^4.1.27",
|
||||||
"@joplin/fork-sax": "^1.2.30",
|
"@joplin/fork-sax": "^1.2.31",
|
||||||
"@joplin/renderer": "^1.8.2",
|
"@joplin/renderer": "^1.8.2",
|
||||||
"@joplin/turndown": "^4.0.48",
|
"@joplin/turndown": "^4.0.49",
|
||||||
"@joplin/turndown-plugin-gfm": "^1.0.30",
|
"@joplin/turndown-plugin-gfm": "^1.0.31",
|
||||||
"async-mutex": "^0.1.3",
|
"async-mutex": "^0.1.3",
|
||||||
"aws-sdk": "^2.588.0",
|
"aws-sdk": "^2.588.0",
|
||||||
"base-64": "^0.1.0",
|
"base-64": "^0.1.0",
|
||||||
|
|||||||
30
packages/lib/services/synchronizer/uploadUtils.ts
Normal file
30
packages/lib/services/synchronizer/uploadUtils.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { ModelType } from '../../BaseModel';
|
||||||
|
import BaseItem, { ItemThatNeedSync } from '../../models/BaseItem';
|
||||||
|
import TaskQueue from '../../TaskQueue';
|
||||||
|
|
||||||
|
type UploadItem = (path: string, content: any)=> Promise<any>;
|
||||||
|
|
||||||
|
export async function serializeAndUploadItem(uploadItem: UploadItem, uploadQueue: TaskQueue, ItemClass: any, path: string, local: ItemThatNeedSync) {
|
||||||
|
if (uploadQueue && uploadQueue.taskExists(path)) {
|
||||||
|
return uploadQueue.taskResult(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = await ItemClass.serializeForSync(local);
|
||||||
|
return uploadItem(path, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function preUploadItems(uploadItem: UploadItem, uploadQueue: TaskQueue, items: ItemThatNeedSync[]) {
|
||||||
|
for (const local of items) {
|
||||||
|
// For resources, additional logic is necessary - in particular the blob
|
||||||
|
// should be uploaded before the metadata, so we can't batch process.
|
||||||
|
if (local.type_ === ModelType.Resource) continue;
|
||||||
|
|
||||||
|
const ItemClass = BaseItem.itemClass(local);
|
||||||
|
const path = BaseItem.systemPath(local);
|
||||||
|
uploadQueue.push(path, async () => {
|
||||||
|
await serializeAndUploadItem(uploadItem, null, ItemClass, path, local);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await uploadQueue.waitForAll();
|
||||||
|
}
|
||||||
2
packages/plugin-repo-cli/package-lock.json
generated
2
packages/plugin-repo-cli/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/plugin-repo-cli",
|
"name": "@joplin/plugin-repo-cli",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/plugin-repo-cli",
|
"name": "@joplin/plugin-repo-cli",
|
||||||
"version": "2.0.2",
|
"version": "2.1.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
2
packages/renderer/package-lock.json
generated
2
packages/renderer/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/renderer",
|
"name": "@joplin/renderer",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/renderer",
|
"name": "@joplin/renderer",
|
||||||
"version": "2.0.2",
|
"version": "2.1.0",
|
||||||
"description": "The Joplin note renderer, used the mobile and desktop application",
|
"description": "The Joplin note renderer, used the mobile and desktop application",
|
||||||
"repository": "https://github.com/laurent22/joplin/tree/dev/packages/renderer",
|
"repository": "https://github.com/laurent22/joplin/tree/dev/packages/renderer",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@joplin/fork-htmlparser2": "^4.1.26",
|
"@joplin/fork-htmlparser2": "^4.1.27",
|
||||||
"font-awesome-filetypes": "^2.1.0",
|
"font-awesome-filetypes": "^2.1.0",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
"highlight.js": "^10.2.1",
|
"highlight.js": "^10.2.1",
|
||||||
|
|||||||
2
packages/server/package-lock.json
generated
2
packages/server/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/server",
|
"name": "@joplin/server",
|
||||||
"version": "2.0.13",
|
"version": "2.1.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@joplin/server",
|
"name": "@joplin/server",
|
||||||
"version": "2.0.13",
|
"version": "2.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start-dev": "nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",
|
"start-dev": "nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",
|
||||||
|
"devCreateDb": "node dist/app.js --env dev --create-db",
|
||||||
|
"devDropTables": "node dist/app.js --env dev --drop-tables",
|
||||||
|
"devDropDb": "node dist/app.js --env dev --drop-db",
|
||||||
"start": "node dist/app.js",
|
"start": "node dist/app.js",
|
||||||
"generateTypes": "rm -f db-buildTypes.sqlite && npm run start -- --migrate-db --env buildTypes && node dist/tools/generateTypes.js && mv db-buildTypes.sqlite schema.sqlite",
|
"generateTypes": "rm -f db-buildTypes.sqlite && npm run start -- --migrate-db --env buildTypes && node dist/tools/generateTypes.js && mv db-buildTypes.sqlite schema.sqlite",
|
||||||
"tsc": "tsc --project tsconfig.json",
|
"tsc": "tsc --project tsconfig.json",
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ const env: Env = argv.env as Env || Env.Prod;
|
|||||||
|
|
||||||
const defaultEnvVariables: Record<Env, EnvVariables> = {
|
const defaultEnvVariables: Record<Env, EnvVariables> = {
|
||||||
dev: {
|
dev: {
|
||||||
|
// To test with the Postgres database, uncomment DB_CLIENT below and
|
||||||
|
// comment out SQLITE_DATABASE. Then start the Postgres server using
|
||||||
|
// `docker-compose --file docker-compose.db-dev.yml up`
|
||||||
|
|
||||||
|
// DB_CLIENT: 'pg',
|
||||||
SQLITE_DATABASE: `${sqliteDefaultDir}/db-dev.sqlite`,
|
SQLITE_DATABASE: `${sqliteDefaultDir}/db-dev.sqlite`,
|
||||||
},
|
},
|
||||||
buildTypes: {
|
buildTypes: {
|
||||||
|
|||||||
@@ -94,7 +94,27 @@ export async function waitForConnection(dbConfig: DatabaseConfig): Promise<Conne
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function connectDb(dbConfig: DatabaseConfig): Promise<DbConnection> {
|
export async function connectDb(dbConfig: DatabaseConfig): Promise<DbConnection> {
|
||||||
return knex(makeKnexConfig(dbConfig));
|
const connection = knex(makeKnexConfig(dbConfig));
|
||||||
|
|
||||||
|
const debugSlowQueries = false;
|
||||||
|
|
||||||
|
if (debugSlowQueries) {
|
||||||
|
const startTimes: Record<string, number> = {};
|
||||||
|
|
||||||
|
const slowQueryDuration = 10;
|
||||||
|
|
||||||
|
connection.on('query', (data) => {
|
||||||
|
startTimes[data.__knexQueryUid] = Date.now();
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.on('query-response', (_response, data) => {
|
||||||
|
const duration = Date.now() - startTimes[data.__knexQueryUid];
|
||||||
|
if (duration < slowQueryDuration) return;
|
||||||
|
console.info(`SQL: ${data.sql} (${duration}ms)`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function disconnectDb(db: DbConnection) {
|
export async function disconnectDb(db: DbConnection) {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export default async function(ctx: AppContext) {
|
|||||||
stack: config().showErrorStackTraces ? error.stack : '',
|
stack: config().showErrorStackTraces ? error.stack : '',
|
||||||
owner: ctx.owner,
|
owner: ctx.owner,
|
||||||
},
|
},
|
||||||
|
title: 'Error',
|
||||||
};
|
};
|
||||||
ctx.response.body = await ctx.services.mustache.renderView(view);
|
ctx.response.body = await ctx.services.mustache.renderView(view);
|
||||||
} else { // JSON
|
} else { // JSON
|
||||||
|
|||||||
@@ -12,6 +12,18 @@ const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
|
|||||||
// Converts "root:/myfile.txt:" to "myfile.txt"
|
// Converts "root:/myfile.txt:" to "myfile.txt"
|
||||||
const extractNameRegex = /^root:\/(.*):$/;
|
const extractNameRegex = /^root:\/(.*):$/;
|
||||||
|
|
||||||
|
export interface SaveFromRawContentItem {
|
||||||
|
name: string;
|
||||||
|
body: Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SaveFromRawContentResultItem {
|
||||||
|
item: Item;
|
||||||
|
error: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SaveFromRawContentResult = Record<string, SaveFromRawContentResultItem>;
|
||||||
|
|
||||||
export interface PaginatedItems extends PaginatedResults {
|
export interface PaginatedItems extends PaginatedResults {
|
||||||
items: Item[];
|
items: Item[];
|
||||||
}
|
}
|
||||||
@@ -282,62 +294,122 @@ export default class ItemModel extends BaseModel<Item> {
|
|||||||
return this.itemToJoplinItem(raw);
|
return this.itemToJoplinItem(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async saveFromRawContent(user: User, name: string, buffer: Buffer, options: ItemSaveOption = null): Promise<Item> {
|
public async saveFromRawContent(user: User, rawContentItems: SaveFromRawContentItem[], options: ItemSaveOption = null): Promise<SaveFromRawContentResult> {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
const existingItem = await this.loadByName(user.id, name);
|
// In this function, first we process the input items, which may be
|
||||||
|
// serialized Joplin items or actual buffers (for resources) and convert
|
||||||
|
// them to database items. Once it's done those db items are saved in
|
||||||
|
// batch at the end.
|
||||||
|
|
||||||
const isJoplinItem = isJoplinItemName(name);
|
interface ItemToProcess {
|
||||||
let isNote = false;
|
item: Item;
|
||||||
|
error: Error;
|
||||||
const item: Item = {
|
resourceIds?: string[];
|
||||||
name,
|
isNote?: boolean;
|
||||||
};
|
joplinItem?: any;
|
||||||
|
|
||||||
let joplinItem: any = null;
|
|
||||||
|
|
||||||
let resourceIds: string[] = [];
|
|
||||||
|
|
||||||
if (isJoplinItem) {
|
|
||||||
joplinItem = await unserializeJoplinItem(buffer.toString());
|
|
||||||
isNote = joplinItem.type_ === ModelType.Note;
|
|
||||||
resourceIds = isNote ? linkedResourceIds(joplinItem.body) : [];
|
|
||||||
|
|
||||||
item.jop_id = joplinItem.id;
|
|
||||||
item.jop_parent_id = joplinItem.parent_id || '';
|
|
||||||
item.jop_type = joplinItem.type_;
|
|
||||||
item.jop_encryption_applied = joplinItem.encryption_applied || 0;
|
|
||||||
item.jop_share_id = joplinItem.share_id || '';
|
|
||||||
|
|
||||||
const joplinItemToSave = { ...joplinItem };
|
|
||||||
|
|
||||||
delete joplinItemToSave.id;
|
|
||||||
delete joplinItemToSave.parent_id;
|
|
||||||
delete joplinItemToSave.share_id;
|
|
||||||
delete joplinItemToSave.type_;
|
|
||||||
delete joplinItemToSave.encryption_applied;
|
|
||||||
|
|
||||||
item.content = Buffer.from(JSON.stringify(joplinItemToSave));
|
|
||||||
} else {
|
|
||||||
item.content = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingItem) item.id = existingItem.id;
|
const existingItems = await this.loadByNames(user.id, rawContentItems.map(i => i.name));
|
||||||
|
const itemsToProcess: Record<string, ItemToProcess> = {};
|
||||||
|
|
||||||
if (options.shareId) item.jop_share_id = options.shareId;
|
for (const rawItem of rawContentItems) {
|
||||||
|
try {
|
||||||
|
const isJoplinItem = isJoplinItemName(rawItem.name);
|
||||||
|
let isNote = false;
|
||||||
|
|
||||||
await this.models().user().checkMaxItemSizeLimit(user, buffer, item, joplinItem);
|
const item: Item = {
|
||||||
|
name: rawItem.name,
|
||||||
|
};
|
||||||
|
|
||||||
return this.withTransaction<Item>(async () => {
|
let joplinItem: any = null;
|
||||||
const savedItem = await this.saveForUser(user.id, item);
|
|
||||||
|
|
||||||
if (isNote) {
|
let resourceIds: string[] = [];
|
||||||
await this.models().itemResource().deleteByItemId(savedItem.id);
|
|
||||||
await this.models().itemResource().addResourceIds(savedItem.id, resourceIds);
|
if (isJoplinItem) {
|
||||||
|
joplinItem = await unserializeJoplinItem(rawItem.body.toString());
|
||||||
|
isNote = joplinItem.type_ === ModelType.Note;
|
||||||
|
resourceIds = isNote ? linkedResourceIds(joplinItem.body) : [];
|
||||||
|
|
||||||
|
item.jop_id = joplinItem.id;
|
||||||
|
item.jop_parent_id = joplinItem.parent_id || '';
|
||||||
|
item.jop_type = joplinItem.type_;
|
||||||
|
item.jop_encryption_applied = joplinItem.encryption_applied || 0;
|
||||||
|
item.jop_share_id = joplinItem.share_id || '';
|
||||||
|
|
||||||
|
const joplinItemToSave = { ...joplinItem };
|
||||||
|
|
||||||
|
delete joplinItemToSave.id;
|
||||||
|
delete joplinItemToSave.parent_id;
|
||||||
|
delete joplinItemToSave.share_id;
|
||||||
|
delete joplinItemToSave.type_;
|
||||||
|
delete joplinItemToSave.encryption_applied;
|
||||||
|
|
||||||
|
item.content = Buffer.from(JSON.stringify(joplinItemToSave));
|
||||||
|
} else {
|
||||||
|
item.content = rawItem.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingItem = existingItems.find(i => i.name === rawItem.name);
|
||||||
|
if (existingItem) item.id = existingItem.id;
|
||||||
|
|
||||||
|
if (options.shareId) item.jop_share_id = options.shareId;
|
||||||
|
|
||||||
|
await this.models().user().checkMaxItemSizeLimit(user, rawItem.body, item, joplinItem);
|
||||||
|
|
||||||
|
itemsToProcess[rawItem.name] = {
|
||||||
|
item: item,
|
||||||
|
error: null,
|
||||||
|
resourceIds,
|
||||||
|
isNote,
|
||||||
|
joplinItem,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
itemsToProcess[rawItem.name] = {
|
||||||
|
item: null,
|
||||||
|
error: error,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return savedItem;
|
const output: SaveFromRawContentResult = {};
|
||||||
|
|
||||||
|
await this.withTransaction(async () => {
|
||||||
|
for (const name of Object.keys(itemsToProcess)) {
|
||||||
|
const o = itemsToProcess[name];
|
||||||
|
|
||||||
|
if (o.error) {
|
||||||
|
output[name] = {
|
||||||
|
item: null,
|
||||||
|
error: o.error,
|
||||||
|
};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemToSave = o.item;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const savedItem = await this.saveForUser(user.id, itemToSave);
|
||||||
|
|
||||||
|
if (o.isNote) {
|
||||||
|
await this.models().itemResource().deleteByItemId(savedItem.id);
|
||||||
|
await this.models().itemResource().addResourceIds(savedItem.id, o.resourceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
output[name] = {
|
||||||
|
item: savedItem,
|
||||||
|
error: null,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
output[name] = {
|
||||||
|
item: null,
|
||||||
|
error: error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async validate(item: Item, options: ValidateOptions = {}): Promise<Item> {
|
protected async validate(item: Item, options: ValidateOptions = {}): Promise<Item> {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import BaseModel from './BaseModel';
|
|||||||
|
|
||||||
export default class TokenModel extends BaseModel<Token> {
|
export default class TokenModel extends BaseModel<Token> {
|
||||||
|
|
||||||
private tokenTtl_: number = 7 * 24 * 60 * 1000;
|
private tokenTtl_: number = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
public get tableName(): string {
|
public get tableName(): string {
|
||||||
return 'tokens';
|
return 'tokens';
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user