1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-09-05 20:56:22 +02:00

Compare commits

..

389 Commits

Author SHA1 Message Date
Laurent Cozic
7683284352 Android 3.0.2 2024-04-15 19:17:10 +01:00
Laurent Cozic
e84ea8ab04 Desktop release v3.0.3 2024-04-15 18:47:03 +01:00
Henry Heino
b638056150 Mobile: Support description banners on plugin-registered settings screens (#10286) 2024-04-15 18:18:22 +01:00
Henry Heino
ff86c253d3 Mobile: Support accepting Joplin Cloud shares (#10300) 2024-04-15 18:17:34 +01:00
Henry Heino
86d9f7e1cb Chore: Mobile: Remove no-longer-necessary Icon warning workaround (#10301) 2024-04-15 18:16:24 +01:00
Henry Heino
385fe7bbe0 Desktop: Fixes #10067: Fix dragging notebooks to the toplevel notebook (#10302) 2024-04-15 18:15:45 +01:00
Henry Heino
313587097a Server: Decrease maximum email and full_name sizes (#10303) 2024-04-15 18:15:29 +01:00
Henry Heino
8393ccc7f8 Chore: Desktop: Use stronger types in Sidebar.tsx (#10305) 2024-04-15 18:15:18 +01:00
Henry Heino
e3ba605592 Chore: Fixes #10306: Remove unnecessary initial commit in default plugins build (#10308) 2024-04-15 18:14:47 +01:00
Henry Heino
035557de9f Desktop: Allow creating plugins that process pasted text in the beta editor (#10310) 2024-04-15 18:14:38 +01:00
Sy Sagar
97ff2b51f1 Docs: build for wsl/linux based system. (#10312)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-04-15 18:14:21 +01:00
Henry Heino
87f7fb6841 Mobile: Fixes #10313: Fix error on retry or ignore attachment too large error (#10314) 2024-04-15 18:13:41 +01:00
github-actions[bot]
9fe31544f7 @SySagar has signed the CLA in laurent22/joplin#10312 2024-04-15 05:50:29 +00:00
Laurent Cozic
89dfbe3ec1 Server: Optimize delta change query to prevent timeouts on large datasets 2024-04-13 14:44:50 +01:00
github-actions[bot]
0c640c5e77 @totikom has signed the CLA in laurent22/joplin#10307 2024-04-12 17:17:16 +00:00
github-actions[bot]
a3eec19b32 @G0maa has signed the CLA in laurent22/joplin#10298 2024-04-11 11:57:26 +00:00
Henry Heino
c0c3b4d23e Mobile: Plugins: Fix event listener memory leak when disabling/uninstalling plugins (#10280)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-04-11 09:04:47 +01:00
Henry Heino
1812587970 Chore: Fixes #10285: Fix failing tarExtract test (#10295) 2024-04-11 08:43:39 +01:00
Henry Heino
1bb724fe0e Android: Fix plugin card titles are clipped (#10296) 2024-04-11 08:37:20 +01:00
Henry Heino
346f49fa66 Chore: Improve types for mobile and desktop themeStyle (#10297) 2024-04-11 08:35:20 +01:00
Henry Heino
55d25308f8 Chore: Refactor warning banner out of ScreenHeader into a separate file (#10268) 2024-04-10 15:31:04 +01:00
Fabio Neto
514a8cf841 Desktop: Fixes #9970: Focus is lost when the hyperlink modal is cancelled (#10258)
Signed-off-by: Fabio Neto <fabiogvdneto@tecnico.ulisboa.pt>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-04-10 15:30:22 +01:00
pedr
837826ea4f Server: Improve log quality by increasing specificity of error (#10287) 2024-04-10 11:40:12 +01:00
Henry Heino
681d1d67f3 Mobile: Resolves #10288: Show plugin versions in settings (#10289) 2024-04-10 11:39:18 +01:00
Henry Heino
d2f3252de2 Desktop: Allow marking sync errors as ignored in "sync status" (#10290) 2024-04-10 11:38:23 +01:00
pedr
859d3e867e Desktop, Mobile: Fixes #10292: Email to note address not presented in configuration screen before synchronisation (#10293) 2024-04-10 11:37:00 +01:00
Henry Heino
238683e36f Desktop: Fix "open profile directory" shows a warning message (#10294) 2024-04-10 11:35:35 +01:00
Henry Heino
2ae08ff46e Mobile: Support importing from JEX files (#10269) 2024-04-08 17:57:01 +01:00
Pratyay Roy
ce672915da Mobile: Resolves #10207: display recommended plugin alert (#10281) 2024-04-08 14:52:07 +01:00
Henry Heino
a2071bfed2 Chore: Mobile: Plugin settings screen: Improve accessibility and tests (#10267) 2024-04-08 12:36:40 +01:00
Henry Heino
03c3feef16 Mobile: Resolves #10245: Allow marking items as "ignored" in sync status (#10261) 2024-04-08 12:35:57 +01:00
Self Not Found
b3f4414026 CI: Bump action versions (#10265) 2024-04-07 14:42:50 +01:00
Henry Heino
04c6863d7f Mobile: Fixes #10270: Fix dropdowns invisble when opening settings by clicking "synchronize" (#10271) 2024-04-07 14:38:51 +01:00
Arda Kılıçdağı
b678e2fb5d Turkish translations updated (#10277) 2024-04-07 14:38:24 +01:00
Laurent Cozic
1179de7c36 Destkop, Cli, Mobile: Resolves #6173: Do not repeat failed requests with ENOTFOUND error 2024-04-07 11:29:30 +01:00
Henry Heino
58ca1a938b Chore: Refactor EventManager to use stronger types (#10272) 2024-04-06 18:08:16 +01:00
Liffindra Angga Zaaldian
9713034f18 Update Indonesian translations (#10276) 2024-04-06 18:04:50 +01:00
Laurent Cozic
28b8818c4d Chore: Disabled not very useful test that can fail easily as we add more sort fields 2024-04-05 12:19:57 +01:00
Laurent Cozic
2e2a2b3193 Tools: Implement @typescript-eslint/no-explicit-any rule 2024-04-05 12:16:49 +01:00
Laurent Cozic
42900bcc66 Desktop: Fixed sorting labels 2024-04-05 10:41:14 +01:00
Laurent Cozic
ce451c5850 Desktop: Resolves #5819: Allow sorting by due date and completion date in detailed note list 2024-04-05 10:34:05 +01:00
Laurent Cozic
5b4477f7bd Desktop: Fixed rendering of alarm time in detailed note list 2024-04-05 10:32:52 +01:00
github-actions[bot]
660ebcfc77 @AliceHincu has signed the CLA in laurent22/joplin#10222 2024-04-04 20:04:18 +00:00
Laurent Cozic
86872fb07c Chore: Fix dic 2024-04-04 15:37:07 +01:00
Cyrus Yip
c55bb95950 Doc: add InfiniCLOUD to WebDAV section (#10266) 2024-04-04 12:45:04 +01:00
Laurent Cozic
d613d1ab4e Tools: Switch from "docker-compose" to "docker compose" 2024-04-04 12:43:35 +01:00
github-actions[bot]
cd5d648eec @CyrusYip has signed the CLA in laurent22/joplin#10266 2024-04-04 11:41:47 +00:00
Henry Heino
384b17738a Mobile: Plugin API: Fix error when calling plugins.dataDir (#10262) 2024-04-04 12:10:59 +01:00
Henry Heino
500c8facdb Mobile: Plugin API: Fix crash when a plugin registers an enum setting with no default (#10263) 2024-04-04 12:10:13 +01:00
cagnusmarlsen
6f76fe728f Desktop: Fixes #10182: Detailed note list doesn't follow preferred date and time formats (#10204) 2024-04-04 11:38:38 +01:00
github-actions[bot]
2488dd3806 @jaibal1152 has signed the CLA in laurent22/joplin#10260 2024-04-03 18:13:28 +00:00
Self Not Found
9d3cccdf71 Mobile: Show sync version and client id in More Info (#10254) 2024-04-03 19:04:16 +01:00
Henry Heino
8dc75efc4c Desktop: Security: Make attachment and file links safer (#10250) 2024-04-03 18:57:52 +01:00
Henry Heino
7caed19a32 Mobile: Plugin API: Improve support for the Kanban and similar plugins (#10247) 2024-04-03 18:56:54 +01:00
Henry Heino
a301470ac5 Mobile: Default to tab indentation for consistency with desktop platforms (#10242) 2024-04-03 18:54:34 +01:00
Henry Heino
f899c97c4c Mobile,Desktop: Resolves #10206: Allow marking a plugin as mobile-only or desktop-only (#10229) 2024-04-03 18:51:09 +01:00
Daniel Nunes
8630c8e630 Desktop: Fixes #9950: Link pased in RTE editor is not underlined until switch to another note (#10202) 2024-04-03 18:43:30 +01:00
github-actions[bot]
29daec2c07 @fabiogvdneto has signed the CLA in laurent22/joplin#10258 2024-04-03 17:42:28 +00:00
Janhavi Alekar
ce3a28de70 Desktop: Fixes #10025: Toggle external editing button overlaps with bold button. (#10069) 2024-04-03 18:29:22 +01:00
pedr
1e6cc11868 Desktop, Mobile, Cli: Avoid unnecessary requests if Joplin Cloud credentials are empty (#10256) 2024-04-03 15:43:22 +01:00
github-actions[bot]
3e0f6994a1 @henriqueeapsilva has signed the CLA in laurent22/joplin#10257 2024-04-03 14:15:55 +00:00
ihan1004
c10e617870 All: Translation: Update ko.po (#10239) 2024-04-01 15:08:56 -04:00
github-actions[bot]
cade585292 @RafaR13 has signed the CLA in laurent22/joplin#10246 2024-04-01 18:59:05 +00:00
Laurent Cozic
f60e105d77 Desktop: Fixes #10108: When creating a note or to-do, focus is not set correctly 2024-04-01 16:51:47 +01:00
Laurent Cozic
b622f9b938 Chore: Fixed naming 2024-04-01 16:47:50 +01:00
Laurent Cozic
00084c5798 Desktop, Mobile: Improve focus handling 2024-04-01 15:34:22 +01:00
Laurent Cozic
554fb7026a Chore: Remove old note list files 2024-04-01 14:19:48 +01:00
Laurent Cozic
04a6c36b5c Chore: Fixed populateDatabase tool 2024-04-01 13:44:07 +01:00
Joplin Bot
adbf819cc0 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-04-01 00:41:42 +00:00
github-actions[bot]
3062f83367 @Wr4th100 has signed the CLA in laurent22/joplin#10228 2024-03-29 15:43:55 +00:00
Henry Heino
bdb2e588f3 iOS: Resolves #10154: Allow installing recommended plugins (#10223) 2024-03-29 12:40:54 +00:00
Henry Heino
688d807eee Mobile: Fixes #10188: Fix "new note" button is shown in the trash notebook (#10227) 2024-03-29 12:11:15 +00:00
Henry Heino
06aa64016f Desktop: Resolves #9794: Plugin API: Add support for loading PDFs with the imaging API (#10177) 2024-03-27 18:53:24 +00:00
github-actions[bot]
06c7c132b8 @Aitchessbee has signed the CLA in laurent22/joplin#10220 2024-03-27 11:34:22 +00:00
github-actions[bot]
fcb837ca99 @thisisnihal has signed the CLA in laurent22/joplin#10217 2024-03-26 18:17:15 +00:00
Mohamad Ashraf
7f34afcaea Desktop: Fixes#10196: Added hover effect to detailed renderer (#10213) 2024-03-26 14:05:40 +00:00
Mohammad Ashouri
876fa324e5 All: Update farsi/persian translation fa.po (#10181) 2024-03-26 11:47:26 +00:00
Mohamad Ashraf
f781183250 Desktop: Fixes #10078: Fixed auto scrolling with moving a note (#10193) 2024-03-26 11:45:15 +00:00
Henry Heino
c1ae449ce2 Android,Desktop: Plugin API: Fix unable to require @codemirror/search (#10205) 2024-03-26 11:36:30 +00:00
Henry Heino
c4aa18a63e Doc: Mark several desktop-only plugin API features as "desktop-only" (#10208) 2024-03-26 11:36:15 +00:00
Henry Heino
27b86fbb00 Android: Plugin API: Support clipboard.availableFormats (#10209) 2024-03-26 11:36:04 +00:00
Henry Heino
569c6d8479 Tools: Fix build failures when compiled .js files are out-of-date (#10210) 2024-03-26 11:35:30 +00:00
Henry Heino
d3e2d3fc4a Android: Plugins: Autohide the plugin panel toggle in toolbar to increase size for notebook dropdown (#10212) 2024-03-26 11:35:15 +00:00
github-actions[bot]
9b5ee63638 @DarkFalc0n has signed the CLA in laurent22/joplin#10215 2024-03-26 10:56:22 +00:00
Joplin Bot
dee68681f5 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-26 00:37:42 +00:00
Laurent Cozic
f85db1496e Desktop: Fixed error when exporting certain notes that contain plugin content 2024-03-25 12:52:06 +00:00
Henry Heino
0839b0314e Desktop: Upgrade the built-in Backup plugin to version 1.4.1 (#10197) 2024-03-25 11:40:44 +00:00
Henry Heino
40dbb8bd7f Android: Toggle plugin panels using a button in the toolbar (#10180) 2024-03-25 11:39:48 +00:00
Edward Jiles
2de5c1bbf8 Mobile, Desktop: Make tables horizontally scrollable (#10161)
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
2024-03-25 11:27:48 +00:00
github-actions[bot]
20edc63785 @Mohamad-Shiro has signed the CLA in laurent22/joplin#10193 2024-03-23 23:05:37 +00:00
Meow
b936f9ba7c All: Bump @codemirror/view version. (#10174) 2024-03-23 15:03:59 +00:00
Henry Heino
a5419e61d5 Doc: Plugin API: Document how to add support for the Rich Text Editor to a renderer plugin (#10178) 2024-03-23 14:41:17 +00:00
Henry Heino
ec4d4141ef Doc: Plugin API: Update editor content script documentation to include information about the mobile and beta editors (#10179) 2024-03-23 14:40:14 +00:00
Henry Heino
b5a16f756a Chore: Mobile: Migrate the tags dialog to TypeScript (#10185) 2024-03-23 14:21:37 +00:00
github-actions[bot]
0331d2a8db @kartiksaxena532 has signed the CLA in laurent22/joplin#10187 2024-03-23 13:19:45 +00:00
Joplin Bot
79eedcf6a6 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-22 00:37:51 +00:00
Laurent Cozic
0715340dc0 Android 3.0.1 2024-03-21 18:28:16 +00:00
Laurent Cozic
a59ad20bd5 Desktop release v3.0.2 2024-03-21 15:51:26 +00:00
Laurent Cozic
e3de158d18 Tools: Fixed building macOS app on CI 2024-03-21 15:51:01 +00:00
Laurent Cozic
e9514e742b Desktop release v3.0.1 2024-03-21 14:55:18 +00:00
Henry Heino
d2c060cd97 Chore: Mobile: Fix note viewer startup error (#10164) 2024-03-21 10:50:44 +00:00
Henry Heino
57fc70cec1 Mobile: Plugins: Fix warning after reloading plugins (#10165) 2024-03-21 10:50:32 +00:00
Henry Heino
180f52dab2 Mobile: Fixes #10166: Fix clicking on a link results in a blank screen (#10168) 2024-03-21 10:48:35 +00:00
Henry Heino
0c6df3dd73 Mobile: Fixes #10170, #8779: Fix shared data lost if Joplin is closed immediately after receiving a share (#10171) 2024-03-21 10:45:54 +00:00
github-actions[bot]
b29bf7de5d @itzTheMeow has signed the CLA in laurent22/joplin#10174 2024-03-21 01:12:20 +00:00
Henry Heino
382f0d8218 Mobile: Fixes #10172: Fix trash folder sometimes has wrong icon (#10173) 2024-03-21 01:09:01 +00:00
Joplin Bot
55d72a8f68 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-20 12:20:52 +00:00
cagnusmarlsen
e9ebd845b9 Desktop: Fixes #10077: Special characters in notebooks and tags are not sorted alphabetically (#10085)
Co-authored-by: Martin Dörfelt <martin.d@andix.de>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-20 11:17:46 +00:00
pedr
ea29cf4e13 Clipper, Desktop: Prevent race condition when download limit is reached (#10124) 2024-03-20 11:11:57 +00:00
Henry Heino
d260d0efce Mobile: Fixes #10130: Improve note editor performance when quickly entering text (#10134) 2024-03-20 11:02:10 +00:00
Henry Heino
e92f89df99 Android: Add support for renderer plugins (#10135) 2024-03-20 11:01:09 +00:00
Henry Heino
44e8950f1b Android: Fixes #10152: Fix broken plugin API: editor.execCommand (#10153) 2024-03-20 10:58:42 +00:00
Siddhant Paritosh Rao
32141d4e23 Mobile: Fixes #10143: Shows only the real folders in the dropdown of parent folders. (#10147) 2024-03-20 10:53:36 +00:00
Henry Heino
7d068cfb87 Android: Allow debugging plugins (#10156) 2024-03-20 10:52:58 +00:00
Henry Heino
9c3e751ebc Server: Avoid logging automated resource deletions (#10157) 2024-03-20 10:52:42 +00:00
Henry Heino
eecad1aefc Desktop: Resolves #8931: Improve support for plugins in the Rich Text Editor (implement webviewApi.postMesage) (#10158) 2024-03-20 10:52:29 +00:00
Laurent Cozic
eb06ac673b Revert "Desktop: Fixes #10036: Applied font family and font size to RTE (#10102)"
This reverts commit 85d98f5254.

Reason: Introducing too many issues, some of them know, some of them unknown.
2024-03-20 10:50:11 +00:00
ERYpTION
5e2c54f2ad All: Translation: Update da_DK.po (#10127)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-18 23:57:08 -04:00
Joplin Bot
15649c89f1 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-18 18:16:55 +00:00
Laurent Cozic
42483a4d46 Tools: Improve getting GitHub name for git-changelog 2024-03-18 18:11:19 +00:00
Laurent Cozic
56b010ba0e Merge branch 'release-2.14' into dev 2024-03-18 16:03:58 +00:00
Laurent Cozic
cfd98e3a4d Desktop release v2.14.20 2024-03-18 16:01:54 +00:00
Laurent Cozic
40db753417 Deskop, Cli: Fixes #10125: ENEX does not import correctly when title of note matches the name of the attachment 2024-03-18 16:00:39 +00:00
Laurent Cozic
3d2c100fe9 Desktop: Fixes #10097: Fix OCR not working for certain languages 2024-03-18 12:16:17 +00:00
Laurent Cozic
fd4d7ead43 Merge branch 'release-2.14' into dev 2024-03-18 10:17:39 +00:00
Laurent Cozic
073df50244 lock file 2024-03-18 09:11:32 +00:00
Laurent Cozic
6973734d5b Doc: Fixed sponsors 2024-03-17 11:59:46 +00:00
Laurent Cozic
b44b30124c Doc: Added documentation for the Joplin Cloud "custom banner" feature 2024-03-17 11:52:02 +00:00
Laurent Cozic
60f447dd49 Doc: Added documentation for the Joplin Cloud "custom banner" feature 2024-03-17 11:51:10 +00:00
Ton Hoang Nguyen (Bill)
7638bdf171 Desktop: Resolves #9984: Allow 'All Notes' to have 'Toggle own sort order' (#10021)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-16 09:16:42 +00:00
github-actions[bot]
9dc480e8d1 @chaNcharge has signed the CLA in laurent22/joplin#10137 2024-03-16 06:37:23 +00:00
Laurent Cozic
c2dbb9606f Doc: Updated sponsors 2024-03-15 15:43:01 +00:00
github-actions[bot]
a40c3b792e @7adidaz has signed the CLA in laurent22/joplin#10128 2024-03-15 11:48:06 +00:00
Henry Heino
08aa2ae939 Android: Fixes #10122: Fix screen reader touch-to-focus broken on note list and note viewer pages (#10123) 2024-03-15 10:16:16 +00:00
Abdelrrahman Elhaddad
85d98f5254 Desktop: Fixes #10036: Applied font family and font size to RTE (#10102) 2024-03-15 09:30:45 +00:00
Khương Duy
310a90744a Desktop: Fixes #10060: Fix "New note" button rendering when startup with Trash can selected. (#10076) 2024-03-15 09:29:24 +00:00
Henry Heino
b3ec92a57e Mobile: Add support for plugin panels and dialogs (#10121) 2024-03-14 19:04:32 +00:00
Siddhant Paritosh Rao
b9eb4522f5 Mobile: Resolves #10092: Added empty trash option on long pressing the trash folder (#10120) 2024-03-14 18:42:58 +00:00
Henry Heino
04298f0eba Mobile: Fix note editor's settings and plugins updated on every keystroke (#10116) 2024-03-14 18:42:22 +00:00
Henry Heino
a53a8d67a1 Mobile: Fix plugin API memory leak (#10115) 2024-03-14 18:42:13 +00:00
Henry Heino
6467bf0fc1 Desktop: Link "browse all plugins" to joplinapp.org/plugins (#10113) 2024-03-14 18:40:47 +00:00
Henry Heino
4ac0cdf556 Chore: Add RemoteMessenger documentation to plugin technical spec (#10112) 2024-03-14 18:39:27 +00:00
Henry Heino
3e34f150b8 Desktop: Upgrade to Electron 29 (#10110) 2024-03-14 18:39:02 +00:00
Henry Heino
e72cce0d07 Clipper: Improve support for future versions of Chrome (upgrade to manifest version 3) (#10109) 2024-03-14 18:38:20 +00:00
Henry Heino
78b8839ae3 CLI: Resolves #10090: Allow deleting notes and notebooks permanently (#10107)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-14 18:38:07 +00:00
Henry Heino
49cd17e520 Chore: Allow disabling deletion logging (#10105) 2024-03-14 18:34:11 +00:00
Henry Heino
c16ce1c434 Desktop,Mobile: Resolves #10073, #10080: Fix conflicts notebook doesn't work with the trash feature (#10104) 2024-03-14 18:30:49 +00:00
Laurent Cozic
8eea3953f3 Update translations 2024-03-14 09:52:40 +00:00
Laurent Cozic
8cb9c08bcb Cli: Clarify that the "restore" command is to restore items from the trash 2024-03-12 18:20:49 +00:00
Laurent Cozic
bc7a0fa095 Chore: Disable OCR language file caching on dev to fix bug 2024-03-12 17:40:53 +00:00
Laurent Cozic
298549e51a Update dictionary 2024-03-12 17:35:50 +00:00
Siddhant Paritosh Rao
da393f6c34 Mobile: Fixes #10065: New note button crashes app when there are no notebooks (#10087) 2024-03-11 15:22:26 +00:00
pedr
8bdac6ffbf Mobile: Change Joplin Cloud login process to allow MFA via browser (#9776) 2024-03-11 15:17:23 +00:00
Henry Heino
55cafb8891 Android: Add support for Markdown editor plugins (#10086)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-11 15:02:15 +00:00
Henry Heino
238468ddaa Chore: Joplin generator: Remove @joplin/lib dev dependency from generated projects (#10075) 2024-03-11 10:11:07 +00:00
Laurent Cozic
b152732d7f Tools: Build doc on CI (#10100) 2024-03-11 10:06:55 +00:00
pedr
56dde88003 Cli: Change Joplin Cloud login process (#9722) 2024-03-11 09:58:54 +00:00
pedr
9e0a0468b2 Chore: Make resource creation from files faster by executing them in parallel (#9952) 2024-03-11 09:39:57 +00:00
Laurent Cozic
e203397f89 Doc: Fixed links 2024-03-10 23:59:48 +00:00
github-actions[bot]
3e22041672 @danimnunes has signed the CLA in laurent22/joplin#10099 2024-03-10 16:44:05 +00:00
Arda Kılıçdağı
0d018a8d7a All: Translation: Update tr_TR.po (#10098) 2024-03-09 23:08:01 -05:00
Henry Heino
c3954d7326 Chore: Fix spelling error (#10096) 2024-03-09 21:14:19 +00:00
Henry Heino
d7401d70a7 Chore: Mobile: Migrate global-style.js to TypeScript (#10091) 2024-03-09 11:15:13 +00:00
Henry Heino
bae16f7a65 Desktop: Fixes #10082: Fix text not shown in plugin message boxes (#10084) 2024-03-09 11:05:38 +00:00
Henry Heino
25cd5affca Chore: Apply changes from mobile plugins to lib/ and app-desktop/ (#10079) 2024-03-09 11:03:57 +00:00
Henry Heino
91004f5714 Desktop: Fixes #10020: Beta markdown editor: Support overriding built-in keyboard shortcuts (#10022) 2024-03-09 10:49:28 +00:00
Henry Heino
c35085d1d5 Desktop: Improve beta editor support for the Rich Markdown plugin (#9935) 2024-03-09 10:48:22 +00:00
pedr
17a8ce5010 Api: Add capability of limiting downloads (#9788) 2024-03-09 10:45:21 +00:00
pedr
4d8fcff6d5 Desktop: Change Joplin Cloud login process to allow MFA via browser (#9445)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-09 10:35:54 +00:00
Henry Heino
75cb639ed2 Cli,Desktop,Mobile: Resolves #9465: Log user actions (deletions) (#9585) 2024-03-09 10:33:05 +00:00
github-actions[bot]
3222b620b9 @AdarshSajwan2003 has signed the CLA in laurent22/joplin#10093 2024-03-08 19:59:55 +00:00
Joplin Bot
d7a0d74c4d Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-08 12:19:09 +00:00
github-actions[bot]
52810c51f5 @Sidd-R has signed the CLA in laurent22/joplin#10087 2024-03-08 02:14:22 +00:00
github-actions[bot]
1b96a16586 @ab-elhaddad has signed the CLA in laurent22/joplin#10083 2024-03-07 19:35:54 +00:00
Laurent Cozic
971c4e5e84 Desktop release v2.14.19 2024-03-07 10:01:48 +00:00
Henry Heino
9ef0a504ec Desktop: Re-enable UNC links (#10071) 2024-03-07 10:01:27 +00:00
github-actions[bot]
e59211deea @khuongduy354 has signed the CLA in laurent22/joplin#10076 2024-03-07 07:01:48 +00:00
Laurent Cozic
3177729663 Desktop release v2.14.18 2024-03-06 16:02:00 +00:00
github-actions[bot]
70c7804a43 @Amit91848 has signed the CLA in laurent22/joplin#10070 2024-03-06 15:59:21 +00:00
Radith Samarakoon
c40682f16f Desktop: Resolves #9981: Fix Vim keymap error with beta editor (#10049) 2024-03-06 14:13:57 +00:00
Henry Heino
406c778cfd Desktop: Fixes #10062: Fix pasting images from the rich text editor into the rich text editor (#10064) 2024-03-06 14:13:24 +00:00
Henry Heino
9d17ab429d Chore: Mobile: Update fsDriver in preparation for mobile plugins (#10066) 2024-03-06 10:03:11 +00:00
Henry Heino
20f8bb76f7 Desktop: Resolves #9927: Beta editor: Fix search results not highlighted (#9928) 2024-03-06 09:53:07 +00:00
cagnusmarlsen
5e4c35a18f Desktop: Fixes #9960: Creating a profile changes the language of Joplin (#10038) 2024-03-05 18:09:23 +00:00
NightKnight
9a6484c488 Tools: Fix packages\lib\fsDriver.test.ts test file on Windows (#10053) 2024-03-05 18:08:47 +00:00
Henry Heino
1dfebf5ed3 iOS: Fixes #10047: Allow pasting URLs copied from the share sheet (#10048) 2024-03-05 16:57:18 +00:00
Marph
be2f4d3d79 Desktop: Configure RTE to handle the first table row as header (#10059) 2024-03-05 16:52:43 +00:00
Laurent Cozic
a1cea6776f Desktop: Fixes #10058: OCR does not start when German language is selected 2024-03-05 16:36:27 +00:00
Laurent Cozic
3c10282848 Doc: Set blog page title to "News" 2024-03-05 14:14:31 +00:00
Laurent Cozic
d9a16b5c0f Desktop: Fixes #10050: Fixed OCR memory leak when processing PDF documents 2024-03-05 11:42:54 +00:00
github-actions[bot]
28c7268f82 @JanhaviAlekar has signed the CLA in laurent22/joplin#10055 2024-03-05 10:54:43 +00:00
github-actions[bot]
3eab87ae69 @Deadreyo has signed the CLA in laurent22/joplin#10053 2024-03-05 08:45:27 +00:00
Laurent Cozic
9acbac6613 Desktop: Fixed sizing of new note buttons 2024-03-04 12:12:42 +00:00
Henry Heino
9a10cd4bec Desktop: Fixes #10023: Beta editor plugins: Fix opening and closing settings can break some plugins with legacy code (#10024) 2024-03-04 10:34:33 +00:00
Radith Samarakoon
5aba1e38a2 Desktop: Resolves #9998: Fixed text wrapping in Spellcheck button (#10005) 2024-03-04 10:33:39 +00:00
Michael Sorens
b812027281 Doc: Update on synchronization (#9721)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-03-04 10:23:39 +00:00
Henry Heino
dfc08da40c Desktop,Mobile: Resolves #10031: Upgrade CodeMirror 6 packages (#10032) 2024-03-04 10:20:06 +00:00
Laurent Cozic
f5f47f3c08 Merge branch 'release-2.14' into dev 2024-03-04 09:31:37 +00:00
Laurent Cozic
8d5ee36745 Desktop: Fixes #10044: Certain RTE menu items are not visible in dark mode 2024-03-04 09:25:51 +00:00
github-actions[bot]
7068670554 @chenrui333 has signed the CLA in laurent22/joplin#10039 2024-03-02 22:13:36 +00:00
Laurent Cozic
6e3162f92f Tools: Always run all checks on CI 2024-03-02 17:59:42 +00:00
Mr-Kanister
6494b74d0c Desktop: Fixes #9453: Improve visibility of selected note in OLED dark theme (#10026) 2024-03-02 16:04:38 +00:00
Sagnik Mandal
d26d9f16d9 Desktop: Fixes #10007: Fixed Toggle Comment & Delete/Duplicate/Sort Line Options in Beta Editor (#10016) 2024-03-02 15:58:15 +00:00
Henry Heino
4c6969b17d Chore: Plugin API: Rename CodeMirrorContentScriptModule to MarkdownEditorContentScriptModule (#10015) 2024-03-02 15:57:40 +00:00
Sagnik Mandal
9a2a251eec Desktop: Fixes #9985: Filter Sync Target Info Logs (#10014) 2024-03-02 15:57:29 +00:00
Henry Heino
f6c7213f69 Desktop: Resolves #9890: Fix hiding the note preview pane is very slow for large notes (#10006) 2024-03-02 15:55:35 +00:00
Henry Heino
4827d0bf92 Desktop: Fixes #9982: Show focus indicator when navigating with keyboard (#9989) 2024-03-02 15:54:16 +00:00
pedr
f0f6590312 Desktop: Fixes #9919: Command palette not showing note title (#9961) 2024-03-02 15:53:46 +00:00
Henry Heino
fa83d48141 Chore: Plugin generator: Update types (#10010) 2024-03-02 15:53:10 +00:00
cagnusmarlsen
c409160ad7 Desktop: Resolves #9980: Support Ctrl+Enter keyboard shortcut (Cmd+Enter on MacOS) (#10003) 2024-03-02 15:52:55 +00:00
pedr
ff1f1b190e Desktop: Fixes #9264: Preserve indentation from plain text when pasting on Rich Text Editor (#9828) 2024-03-02 15:43:38 +00:00
Laurent Cozic
53d5cf55bc Desktop: Add support for multiple columns note list (#9924) 2024-03-02 15:29:18 +00:00
Laurent Cozic
f19b1c5364 All: Resolves #483: Add trash folder (#9671) 2024-03-02 14:25:27 +00:00
Joplin Bot
07fbd547dc Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-02 12:16:54 +00:00
Laurent Cozic
cb540a5abb Chore: Setup new release 3.0 2024-03-02 11:04:23 +00:00
github-actions[bot]
a7b303259c @GuptTmay has signed the CLA in laurent22/joplin#10035 2024-03-02 06:25:15 +00:00
Joplin Bot
ee181c1fd6 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-02 06:17:18 +00:00
Joplin Bot
2e8fc99c5c Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-02 00:36:16 +00:00
Laurent Cozic
4a78cd2564 Merge branch 'release-2.14' into dev 2024-03-01 19:10:39 +00:00
Laurent Cozic
95e42c4ca7 CLI v2.14.1 2024-03-01 19:10:10 +00:00
Laurent Cozic
98bb0250f2 Lock file 2024-03-01 19:07:01 +00:00
Laurent Cozic
5aba5e544d Releasing sub-packages 2024-03-01 19:06:13 +00:00
Laurent Cozic
0ca36bbf66 Doc: Add news item for release 2.14 2024-03-01 18:44:00 +00:00
Joplin Bot
5d3034d418 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-01 18:16:00 +00:00
Laurent Cozic
438dddda6e iOS 12.14.6 2024-03-01 18:05:20 +00:00
Laurent Cozic
8bd6132398 Update translations 2024-03-01 18:04:19 +00:00
Laurent Cozic
d1c6c0622b Tools: Fix spelling regex 2024-03-01 18:04:02 +00:00
ERYpTION
bd5b3feabe All: Translation: Update da_DK.po (#10029) 2024-03-01 04:29:15 -05:00
Joplin Bot
22f4d19dd1 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-03-01 00:40:46 +00:00
Laurent Cozic
a86f859b42 Tools: Fixed order of release notes posted to forum 2024-02-29 19:45:48 +00:00
Laurent Cozic
4bef8aa632 Tools: Only process supported files with spellchecker 2024-02-28 14:26:52 +00:00
Laurent Cozic
40ae03c438 Tools: Add info link when spelling mistake check fails 2024-02-27 14:22:26 +00:00
Laurent Cozic
afedc53354 Tools: Improve error message and suggested command when checkIgnoredFiles pre-commit hook fails 2024-02-27 11:46:02 +00:00
Laurent Cozic
0d5bca20d3 lock file 2024-02-27 11:34:47 +00:00
github-actions[bot]
f254255ba5 @criticic has signed the CLA in laurent22/joplin#10014 2024-02-27 11:30:31 +00:00
Laurent Cozic
fc1c1a3c20 Tools: Remove message "add --no-verify to bypass" when pre-commit fails 2024-02-27 11:18:16 +00:00
Wesley D
3c31b2bc38 Doc: Change macOS and Linux symlink suggestion (#10009) 2024-02-27 10:20:58 +00:00
Najam Ul Saqib
b4cc6803e7 Doc: Fix a minor issue in comment (#10011) 2024-02-27 10:17:55 +00:00
github-actions[bot]
2ac7997c07 @njmulsqb has signed the CLA in laurent22/joplin#10011 2024-02-27 07:04:55 +00:00
Joplin Bot
0055345689 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-27 00:36:49 +00:00
github-actions[bot]
f43f5c0a34 @WesleyDavid has signed the CLA in laurent22/joplin#10009 2024-02-26 21:03:49 +00:00
Laurent Cozic
dee66ec6ad Android 2.14.9 2024-02-26 20:12:05 +00:00
Laurent Cozic
094175c067 Desktop release v2.14.17 2024-02-26 19:28:48 +00:00
Laurent Cozic
e5a643e796 Desktop, Mobile: Fixes #9996: Sort notebooks in a case-insensitive way 2024-02-26 19:27:29 +00:00
Laurent Cozic
ef9a1daf18 Doc: Update sponsors.json 2024-02-26 19:06:58 +00:00
github-actions[bot]
9035fe67a4 @RadCod3 has signed the CLA in laurent22/joplin#10005 2024-02-26 17:41:15 +00:00
Laurent Cozic
fc1da80086 Tools: Trying to fix lint-staged 2024-02-26 17:29:11 +00:00
Laurent Cozic
d5ac7c6bc0 Tools: Run pre-commit hook tasks in parallel 2024-02-26 17:11:11 +00:00
Laurent Cozic
28fd9c3039 Tools: Spellcheck Markdown documents (#10004) 2024-02-26 16:53:48 +00:00
github-actions[bot]
83599234a9 @cagnusmarlsen has signed the CLA in laurent22/joplin#10003 2024-02-26 14:10:19 +00:00
Joplin Bot
c2e49ebb2b Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-26 12:19:13 +00:00
Ton Hoang Nguyen (Bill)
64684dc896 Desktop: Fixes #7834: Merged shorthand variants of spellcheck languages (#9983) 2024-02-26 10:27:34 +00:00
Laurent Cozic
0b63ba1a28 Update translations 2024-02-26 10:23:31 +00:00
Laurent Cozic
47f95cb294 Chore: Implement cSpell to detect spelling mistakes in codebase (#10001)
Co-authored-by: Helmut K. C. Tessarek <tessarek@evermeet.cx>
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
2024-02-26 10:16:23 +00:00
Joplin Bot
69cbd45782 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-26 06:17:02 +00:00
ihan1004
31368f3148 All: Translation: Update ko_KO.po (#9999) 2024-02-25 22:08:20 -05:00
github-actions[bot]
1fb1d4714c @ihan1004 has signed the CLA in laurent22/joplin#9999 2024-02-26 03:01:12 +00:00
Liffindra Angga Zaaldian
69e591c01d All: Translation: Update id_ID.po (#9995) 2024-02-25 21:21:24 -05:00
qx100
2bc0d5e8e7 All: Translation: Update zh_CN.po (#9991) 2024-02-25 21:18:53 -05:00
Ikko Eltociear Ashimine
57c182b9a4 Chore: Fix typo (#10000) 2024-02-25 19:37:13 +00:00
github-actions[bot]
ac721cf8f4 @eltociear has signed the CLA in laurent22/joplin#10000 2024-02-25 15:49:50 +00:00
Joplin Bot
935f90422f Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-25 12:17:49 +00:00
Laurent Cozic
c308f858f1 Doc: Update sponsors 2024-02-25 10:15:07 +00:00
Andy Piper
5ce5edf7ba Generator: update manifest.json to include promo tile (#9993) 2024-02-25 09:52:12 +00:00
github-actions[bot]
16594eaae3 @findrakecil has signed the CLA in laurent22/joplin#9995 2024-02-25 07:48:59 +00:00
github-actions[bot]
1548eab677 @Sanket-0510 has signed the CLA in laurent22/joplin#9994 2024-02-25 07:34:20 +00:00
github-actions[bot]
ae9c8f27da @andypiper has signed the CLA in laurent22/joplin#9993 2024-02-24 18:30:37 +00:00
Henry Heino
ea6b704754 Mobile: Fixes #9521: Note editor: Support older WebView versions (#9986) 2024-02-24 11:40:48 +00:00
Henry Heino
ff62bd8ff7 iOS: Fixes #8557: Fix white flash when editing notes in dark mode (#9987) 2024-02-24 11:39:21 +00:00
github-actions[bot]
774d924abd @tecc has signed the CLA in laurent22/joplin#9988 2024-02-23 21:45:52 +00:00
github-actions[bot]
9a115c9e93 @HahaBill has signed the CLA in laurent22/joplin#9983 2024-02-23 14:31:00 +00:00
Joplin Bot
9f5109aed7 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-23 12:19:24 +00:00
Laurent Cozic
dd04a39f3b Android 2.14.8 2024-02-22 22:44:56 +00:00
Laurent Cozic
514123d2b6 Desktop release v2.14.16 2024-02-22 21:34:08 +00:00
Henry Heino
fbeaf31a14 Desktop: Plugins: Allow commands registered within the beta markdown editor to take arguments (#9963) 2024-02-22 21:30:48 +00:00
Henry Heino
e5e191110c Desktop: Resolves #9857: Back up to a subdirectory of the home directory by default (#9942) 2024-02-22 21:30:21 +00:00
Henry Heino
836e23c082 Desktop: Security: Disallow UNC file links (#9979) 2024-02-22 21:29:16 +00:00
Henry Heino
4c5e708977 Desktop: Beta editor plugin API: Fix plugins unable to require nodeJS modules (#9968) 2024-02-22 15:39:46 +00:00
Henry Heino
1b846fca90 Doc: Plugins: Add CodeMirror 6 plugin tutorial (#9933) 2024-02-22 15:38:15 +00:00
Henry Heino
f1a833ef21 Desktop: Resolves #9964: Beta editor plugins: Allow fixing conflicts between plugins that add autocompletions (#9965) 2024-02-22 15:36:27 +00:00
Henry Heino
4a61ff2df3 Desktop: Fixes #9966: Beta editor plugins: Fix newlines break content scripts (#9967) 2024-02-22 15:36:10 +00:00
Henry Heino
2e3783f1c6 Mobile,Desktop: Fixes #9971: Fix auto-indentation in some types of code blocks (#9972) 2024-02-22 15:35:54 +00:00
Laurent Cozic
de03679be0 Doc: Redirect to official GSoC repo 2024-02-22 15:03:26 +00:00
Laurent Cozic
5820f63ea6 Desktop, Mobile: Immediately sort notes after toggling a checkbox 2024-02-19 23:09:34 +00:00
Laurent Cozic
bfc31127af Tools: Automatically generate pre-release post for Android and iOS 2024-02-19 22:50:10 +00:00
Joplin Bot
d1db799b5c Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-19 12:19:27 +00:00
Laurent Cozic
5a30a790ca iOS 12.14.5 2024-02-19 10:47:14 +00:00
Laurent Cozic
ab8f1492b1 Android 2.14.7 2024-02-19 10:45:14 +00:00
Laurent Cozic
7cfe9bb4b6 Desktop release v2.14.15 2024-02-19 10:34:23 +00:00
pedr
563b9d8f71 Desktop: #9870: Fixed command palette not properly showing non-latin-characters (#9916) 2024-02-19 10:31:14 +00:00
Henry Heino
2aea7fcc25 Desktop: Fixes #9932: Fix only one CodeMirror 6 content script loaded per plugin (#9934) 2024-02-19 10:29:37 +00:00
Henry Heino
e2a79c16c1 Desktop: Fixes #9953: Rich text editor: Fix context menu not shown in some cases (#9954) 2024-02-19 10:04:54 +00:00
Henry Heino
2d0a53eaca Desktop: CodeMirror 6 plugin API: Improve ability to register custom commands (#9956) 2024-02-19 10:04:20 +00:00
Laurent Cozic
0b2bb80bb8 Desktop: Fixes #9958: Highlight partial matches in search results 2024-02-19 10:01:54 +00:00
Joplin Bot
f378662196 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-17 12:17:23 +00:00
Joplin Bot
6588adbfe0 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-17 06:15:45 +00:00
Jonatan
7ae9f30922 All: Translation: Update sv.po (#9943) 2024-02-16 14:03:30 -05:00
Laurent Cozic
1cfbf000d6 Desktop: Fixes #9944: GotoAnything does not return all the results in some cases 2024-02-16 17:40:51 +00:00
Mr-Kanister
7f50cb9787 All: Translation: Update de_DE.po (#9947) 2024-02-15 22:39:00 -05:00
Henry Heino
7dbbcb06b5 Chore: Docs: Update Joplin versions on release cycle page (#9946) 2024-02-16 00:01:48 +00:00
github-actions[bot]
4b520222ed @peterwilli has signed the CLA in laurent22/joplin#9940 2024-02-14 20:08:58 +00:00
Joplin Bot
d4b32d3a91 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-13 18:16:21 +00:00
Vladimir Fedorchuk
9aaea7fb69 All: Improving translation into Russian. (#9925) 2024-02-13 15:54:26 +00:00
Henry Heino
6e1331e580 Chore: Remove generated .js files from version control (#9930) 2024-02-13 15:33:46 +00:00
Laurent Cozic
9f81f4cc49 Doc: Update sponsors 2024-02-13 15:08:10 +00:00
github-actions[bot]
530375f221 @fedorch has signed the CLA in laurent22/joplin#9925 2024-02-12 20:38:32 +00:00
Joplin Bot
640174b7cd Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-12 18:14:40 +00:00
renovate[bot]
279416b66d Update dependency tar-stream to v3.1.7 (#9918)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 18:08:10 +00:00
renovate[bot]
9602323e0f Update dependency pm2 to v5.3.1 (#9917)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 18:08:04 +00:00
Laurent Cozic
115eb5defb Desktop, Cli, Mobile: Migrate profile in preparation for trash feature 2024-02-12 15:02:52 +00:00
Laurent Cozic
012fe0fb44 Chore: Prevent database schema generation script from adding extra spaces 2024-02-12 14:51:07 +00:00
Max Patiiuk
771ada0184 Clipper: handle tables with captions (#9910) 2024-02-12 14:44:50 +00:00
Henry Heino
cb21a91fac Mobile: Fixes #9905: Fix full text search broken on Android 7 and earlier (#9914) 2024-02-12 14:43:01 +00:00
Joplin Bot
3000afca49 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-11 00:41:05 +00:00
Laurent Cozic
b7189d57f2 Update renovate.json5 2024-02-10 18:20:59 +00:00
Laurent Cozic
e5d53b6276 Update renovate.json5 2024-02-10 17:00:44 +00:00
Laurent Cozic
ecb6ac3554 Desktop release v2.14.14 2024-02-10 15:24:47 +00:00
Laurent Cozic
1b27e4c07d Revert "Update dependency sqlite3 to v5.1.7 (#9837)"
This reverts commit eefde7baba.

Trying to fix https://github.com/laurent22/joplin/issues/9922
2024-02-10 15:24:33 +00:00
Joplin Bot
4151c65fc2 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-10 00:35:52 +00:00
Laurent Cozic
c626386ebd iOS 12.14.4 2024-02-09 13:34:00 +00:00
Laurent Cozic
7dfa3137c4 lock file 2024-02-09 12:47:22 +00:00
Laurent Cozic
0f9da943cd Android 2.14.6 2024-02-09 12:45:52 +00:00
Laurent Cozic
485a685e5a Desktop release v2.14.13 2024-02-09 12:21:37 +00:00
Joplin Bot
3a0b180487 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-09 12:19:03 +00:00
Laurent Cozic
605233c572 Ignore Renovate package 2024-02-09 12:17:30 +00:00
Max Patiiuk
37344fe718 Doc: use correct package names for turndown (#9882)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-09 12:16:41 +00:00
Max Patiiuk
f74570b403 Doc: explain how to get TypeScript typings (#9883)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-09 12:16:18 +00:00
renovate[bot]
13f907e7f1 Update dependency nodemon to v3.0.3 (#9895)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:15:35 +00:00
renovate[bot]
f2ee35c82a Update dependency react-native-share to v10.0.2 (#9897)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:15:26 +00:00
renovate[bot]
29d4a026e2 Update dependency react-native-localize to v3.0.6 (#9896)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:15:21 +00:00
renovate[bot]
c7e312e959 Update dependency node-mocks-http to v1.14.1 (#9894)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:15:14 +00:00
renovate[bot]
e6a811e259 Update dependency @react-native-community/netinfo to v11.2.1 (#9898)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:14:59 +00:00
renovate[bot]
5408dd71d3 Update dependency koa to v2.15.0 (#9899)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:14:46 +00:00
renovate[bot]
edc8865e50 Update dependency moment to v2.30.1 (#9900)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-09 12:14:30 +00:00
Max Patiiuk
a80fea9c4b Chore: fix cache memory leak in turndown (#9886)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-09 12:12:45 +00:00
pedr
92c85ca07c Mobile: Fixes #9475: Increase space available for Notebook icon (#9877)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-09 12:11:51 +00:00
Henry Heino
296d586b04 Mobile,Desktop,Cli: Improve search engine error handling when preparing text for search (#9871)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-09 12:11:08 +00:00
Laurent Cozic
6f0fd4219e Desktop: Make OCR results available to search immediately after completion 2024-02-09 11:56:23 +00:00
renovate[bot]
35fe392058 Update dependency async-mutex to v0.4.1 (#9893)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-08 23:36:08 +00:00
renovate[bot]
61f8a2afd3 Update dependency @types/react to v18.2.48 (#9892)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-08 23:33:13 +00:00
Henry Heino
347ba9bb38 Mobile: Fixes #9858: Fix deeply-nested subnotebook titles invisible in the folder dropdown (#9906) 2024-02-08 23:17:17 +00:00
Henry Heino
802f6c462e Desktop: Fixes #9891: Don't rerender markdown notes when the note preview pane is hidden (#9901) 2024-02-08 22:49:29 +00:00
Henry Heino
39b44ff439 Desktop: Disable built-in copy of Simple Backup by default in Joplin Portable (#9907) 2024-02-08 22:48:39 +00:00
Henry Heino
627b830739 Desktop: Fix mermaid save button partially hidden behind graph (#9888) 2024-02-08 18:41:19 +00:00
Laurent Cozic
d58185afe0 Chore: Add more debug info when assets cannot be unloaded 2024-02-08 18:14:08 +00:00
Laurent Cozic
0b3a5a431d Desktop, Mobile, Cli: Fixes #9694: Correctly search HTML-entity encoded text 2024-02-08 18:14:07 +00:00
Henry Heino
c54603025b Chore: Desktop: Fixes #9873: Fix Playwright test failure due to image not visible (#9874) 2024-02-08 16:56:12 +00:00
Henry Heino
debd8a6ebe Chore: Remove .gitignored file from version control (#9872) 2024-02-08 16:55:48 +00:00
Henry Heino
d614d40cfd Desktop: Fixes #9868: Fix markdown (frontmatter) notes that start with a UTF-8 BOM aren't imporetd correctly (#9875) 2024-02-08 16:55:34 +00:00
Henry Heino
628877147e Mobile: Fixes #9863: Fix share to Joplin when only "All notes" has been opened (#9876)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-08 16:54:23 +00:00
pedr
c163491371 Desktop: Fixes #9763: Suppress random error that happens during desktop shutdown (#9878)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-08 16:51:32 +00:00
Laurent Cozic
16d77bfa10 Doc: Documented Sentry integration 2024-02-08 14:51:24 +00:00
Laurent Cozic
11e1a49b5c Desktop: Fixes #9607: Copied and pasted text from Firefox to RTE does not include images 2024-02-08 13:06:18 +00:00
Laurent Cozic
b1877fcd0d Desktop: Speed up pasting text and images in Rich Text Editor 2024-02-08 12:51:31 +00:00
Laurent Cozic
4b7f0bfbb9 fixed test 2024-02-08 11:57:30 +00:00
github-actions[bot]
2f06697aa2 @maxpatiiuk has signed the CLA in laurent22/joplin#9882 2024-02-08 03:53:06 +00:00
Laurent Cozic
07aba918a0 Desktop: Disable initial Sentry request when crash auto-upload is disabled 2024-02-07 18:05:13 +00:00
Henry Heino
01ec640bdb Chore: Refactor string-utils to TypeScript (#9869) 2024-02-07 14:16:54 +00:00
renovate[bot]
c1e5adf658 Update dependency @types/node to v18.19.8 (#9866)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 02:35:16 +00:00
Henry Heino
a364f66d4b Android: Fixes #7974: Fix regression: Crash when opening appearance/sync settings on some devices (#9864) 2024-02-06 16:27:12 +00:00
Henry Heino
a906e73b22 Desktop: PDF search text: Remove NULL characters early to avoid possible sync issues (#9862) 2024-02-06 16:24:00 +00:00
Henry Heino
8b9ce9ec72 Desktop: Fixes #9855: Allow using editor commands in the command palette (#9861) 2024-02-06 16:20:15 +00:00
Henry Heino
e462881502 MacOS: Resolves #9488: Add "Window" menu to toolbar on MacOS (#9859) 2024-02-06 16:19:52 +00:00
Laurent Cozic
0e8f0a2dc1 Update translations 2024-02-06 16:15:34 +00:00
renovate[bot]
2252a06a50 Update dependency @types/node-fetch to v2.6.11 (#9865)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-06 15:50:38 +00:00
Cristi
6ecc478402 Translated text in ro.po and rename file to ro_RO.po (#9717)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-02-06 15:49:12 +00:00
Laurent Cozic
da06383458 Doc: Add GSoC 2024 folder 2024-02-05 12:09:37 +00:00
renovate[bot]
a56c78db8b Update dependency @types/node to v18.19.7 (#9853)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-05 05:06:10 +00:00
Henry Heino
6ebc7993be Desktop: Fixes #9832: Fix user-installed versions of built-in plugins can't access resources in some cases (#9849) 2024-02-03 20:28:47 +01:00
renovate[bot]
b8243e5518 Update dependency react-native-share to v10 (#9848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:28:32 +01:00
renovate[bot]
a5a4aaf765 Update dependency @react-native-community/netinfo to v11 (#9846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:28:03 +01:00
renovate[bot]
0f793a4cf0 Update dependency react-native-safe-area-context to v4.8.2 (#9844)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:27:24 +01:00
renovate[bot]
ce11761dc9 Update dependency react-native-document-picker to v9.1.0 (#9843)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:27:10 +01:00
renovate[bot]
437b3bbfe8 Update dependency node-mocks-http to v1.14.0 (#9842)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:26:55 +01:00
renovate[bot]
6dbfa6e4d8 Update dependency @react-native-community/slider to v4.5.0 (#9840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:26:29 +01:00
renovate[bot]
3451133fd7 Update dependency @js-draw/material-icons to v1.16.1 (#9839)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:26:16 +01:00
renovate[bot]
1932187e0f Update dependency style-loader to v3.3.4 (#9838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:26:10 +01:00
renovate[bot]
eefde7baba Update dependency sqlite3 to v5.1.7 (#9837)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:26:04 +01:00
renovate[bot]
a225c11822 Update dependency sharp to v0.33.2 (#9836)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:25:44 +01:00
renovate[bot]
b35246cd64 Update dependency react-native-paper to v5.11.7 (#9835)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:25:37 +01:00
renovate[bot]
4289c08538 Update dependency react-native-localize to v3.0.5 (#9834)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:25:30 +01:00
renovate[bot]
b58ca5095c Update dependency follow-redirects to v1.15.5 (#9833)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:25:21 +01:00
renovate[bot]
a2e5125335 Update dependency js-draw to v1.16.1 (#9841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-03 20:25:08 +01:00
Joplin Bot
7938eab6e2 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-02-03 12:18:52 +00:00
renovate[bot]
b322ff247c Update dependency sass to v1.69.7 (#9741)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 23:49:16 +00:00
Laurent Cozic
fc8fadce2b Update renovate.json5 2024-02-03 00:37:54 +01:00
Laurent Cozic
9485c323d1 iOS 12.14.3 2024-02-03 00:35:09 +01:00
renovate[bot]
40749cabff Update dependency react-native-webview to v13.6.4 (#9773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 23:29:59 +00:00
renovate[bot]
cddd8213d5 Update dependency ldapts to v7.0.8 (#9790)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 23:26:34 +00:00
1284 changed files with 95415 additions and 50380 deletions

View File

@@ -52,7 +52,7 @@ packages/app-desktop/packageInfo.js
packages/app-desktop/services/electron-context-menu.js
packages/app-desktop/vendor/lib/
packages/app-mobile/android
packages/app-mobile/components/NoteEditor/**/*.bundle.js
packages/app-mobile/**/*.bundle.js
packages/app-mobile/ios
packages/app-mobile/lib/rnInjectedJs/
packages/app-mobile/locales
@@ -109,7 +109,10 @@ packages/app-cli/app/command-mkbook.test.js
packages/app-cli/app/command-mkbook.js
packages/app-cli/app/command-mv.js
packages/app-cli/app/command-ren.js
packages/app-cli/app/command-restore.js
packages/app-cli/app/command-rmbook.test.js
packages/app-cli/app/command-rmbook.js
packages/app-cli/app/command-rmnote.test.js
packages/app-cli/app/command-rmnote.js
packages/app-cli/app/command-set.js
packages/app-cli/app/command-settingschema.js
@@ -117,6 +120,7 @@ packages/app-cli/app/command-sync.js
packages/app-cli/app/command-testing.js
packages/app-cli/app/command-use.js
packages/app-cli/app/command-version.js
packages/app-cli/app/gui/FolderListWidget.js
packages/app-cli/app/gui/StatusBarWidget.js
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/setupCommand.js
@@ -143,6 +147,7 @@ packages/app-desktop/bridge.js
packages/app-desktop/checkForUpdates.js
packages/app-desktop/commands/copyDevCommand.js
packages/app-desktop/commands/editProfileConfig.js
packages/app-desktop/commands/emptyTrash.js
packages/app-desktop/commands/exportFolders.js
packages/app-desktop/commands/exportNotes.js
packages/app-desktop/commands/focusElement.js
@@ -168,8 +173,6 @@ packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.test.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.js
packages/app-desktop/gui/Dialog.js
packages/app-desktop/gui/DialogButtonRow.js
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
@@ -188,6 +191,7 @@ packages/app-desktop/gui/IconButton.js
packages/app-desktop/gui/ImportScreen.js
packages/app-desktop/gui/ItemList.js
packages/app-desktop/gui/JoplinCloudConfigScreen.js
packages/app-desktop/gui/JoplinCloudLoginScreen.js
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.js
packages/app-desktop/gui/KeymapConfig/styles/index.js
@@ -217,10 +221,13 @@ packages/app-desktop/gui/MainScreen/commands/openItem.js
packages/app-desktop/gui/MainScreen/commands/openNote.js
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.js
packages/app-desktop/gui/MainScreen/commands/openTag.js
packages/app-desktop/gui/MainScreen/commands/permanentlyDeleteNote.js
packages/app-desktop/gui/MainScreen/commands/print.js
packages/app-desktop/gui/MainScreen/commands/renameFolder.js
packages/app-desktop/gui/MainScreen/commands/renameTag.js
packages/app-desktop/gui/MainScreen/commands/resetLayout.js
packages/app-desktop/gui/MainScreen/commands/restoreFolder.js
packages/app-desktop/gui/MainScreen/commands/restoreNote.js
packages/app-desktop/gui/MainScreen/commands/revealResourceFile.js
packages/app-desktop/gui/MainScreen/commands/search.js
packages/app-desktop/gui/MainScreen/commands/setTags.js
@@ -230,6 +237,7 @@ packages/app-desktop/gui/MainScreen/commands/showNoteProperties.js
packages/app-desktop/gui/MainScreen/commands/showPrompt.js
packages/app-desktop/gui/MainScreen/commands/showShareFolderDialog.js
packages/app-desktop/gui/MainScreen/commands/showShareNoteDialog.js
packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.test.js
packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.js
packages/app-desktop/gui/MainScreen/commands/toggleEditors.js
packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js
@@ -247,26 +255,30 @@ packages/app-desktop/gui/Navigator.js
packages/app-desktop/gui/NoteContentPropertiesDialog.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/normalizeAccelerator.test.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/normalizeAccelerator.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.test.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearch.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useExternalPlugins.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinMode.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useLineSorting.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useListIdent.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearchExtension.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearchHandler.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollHandler.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useStyles.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useWebviewIpcMessage.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/Editor.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useCursorUtils.test.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useCursorUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useExternalPlugins.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useJoplinCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useJoplinMode.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useLineSorting.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useListIdent.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useScrollUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/PlainEditor/PlainEditor.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
@@ -278,6 +290,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/shouldPasteResources.
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/types.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useWebViewApi.js
packages/app-desktop/gui/NoteEditor/NoteEditor.js
packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
@@ -309,9 +322,7 @@ packages/app-desktop/gui/NoteEditor/utils/useNoteSearchBar.js
packages/app-desktop/gui/NoteEditor/utils/usePluginServiceRegistration.js
packages/app-desktop/gui/NoteEditor/utils/useSearchMarkers.js
packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.js
packages/app-desktop/gui/NoteList/NoteList.js
packages/app-desktop/gui/NoteList/NoteList2.js
packages/app-desktop/gui/NoteList/NoteListSource.js
packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js
packages/app-desktop/gui/NoteList/commands/index.js
packages/app-desktop/gui/NoteList/utils/canManuallySortNotes.js
@@ -328,9 +339,18 @@ packages/app-desktop/gui/NoteList/utils/useVisibleRange.js
packages/app-desktop/gui/NoteListControls/NoteListControls.js
packages/app-desktop/gui/NoteListControls/commands/focusSearch.js
packages/app-desktop/gui/NoteListControls/commands/index.js
packages/app-desktop/gui/NoteListItem.js
packages/app-desktop/gui/NoteListHeader/NoteListHeader.js
packages/app-desktop/gui/NoteListHeader/NoteListHeaderItem.js
packages/app-desktop/gui/NoteListHeader/types.js
packages/app-desktop/gui/NoteListHeader/useDragAndDrop.test.js
packages/app-desktop/gui/NoteListHeader/useDragAndDrop.js
packages/app-desktop/gui/NoteListHeader/utils/getColumnTitle.js
packages/app-desktop/gui/NoteListHeader/utils/useContextMenu.js
packages/app-desktop/gui/NoteListHeader/utils/validateColumns.test.js
packages/app-desktop/gui/NoteListHeader/utils/validateColumns.js
packages/app-desktop/gui/NoteListItem/NoteListItem.js
packages/app-desktop/gui/NoteListItem/utils/getNoteTitleHtml.js
packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.test.js
packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.js
packages/app-desktop/gui/NoteListItem/utils/types.js
packages/app-desktop/gui/NoteListItem/utils/useItemElement.js
@@ -345,6 +365,7 @@ packages/app-desktop/gui/NoteSearchBar.js
packages/app-desktop/gui/NoteStatusBar.js
packages/app-desktop/gui/NoteTextViewer.js
packages/app-desktop/gui/NoteToolbar/NoteToolbar.js
packages/app-desktop/gui/NotyfContext.js
packages/app-desktop/gui/OneDriveLoginScreen.js
packages/app-desktop/gui/PasswordInput/PasswordInput.js
packages/app-desktop/gui/PdfViewer.js
@@ -389,6 +410,7 @@ packages/app-desktop/gui/ToolbarBase.js
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
packages/app-desktop/gui/ToolbarButton/styles/index.js
packages/app-desktop/gui/ToolbarSpace.js
packages/app-desktop/gui/TrashNotification/TrashNotification.js
packages/app-desktop/gui/dialogs.js
packages/app-desktop/gui/hooks/useEffectDebugger.js
packages/app-desktop/gui/hooks/useImperativeHandlerDebugger.js
@@ -404,6 +426,7 @@ packages/app-desktop/gui/style/StyledMessage.js
packages/app-desktop/gui/style/StyledTextInput.js
packages/app-desktop/gui/utils/NoteListUtils.js
packages/app-desktop/gui/utils/convertToScreenCoordinates.js
packages/app-desktop/gui/utils/dragAndDrop.js
packages/app-desktop/gui/utils/loadScript.js
packages/app-desktop/gulpfile.js
packages/app-desktop/integration-tests/main.spec.js
@@ -437,7 +460,6 @@ packages/app-desktop/services/plugins/hooks/useThemeCss.js
packages/app-desktop/services/plugins/hooks/useViewIsReady.js
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js
packages/app-desktop/services/restart.js
packages/app-desktop/services/share/invitationRespond.js
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.test.js
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
@@ -451,10 +473,17 @@ packages/app-desktop/utils/7zip/pathToBundled7Zip.js
packages/app-desktop/utils/checkForUpdatesUtils.test.js
packages/app-desktop/utils/checkForUpdatesUtils.js
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
packages/app-desktop/utils/isSafeToOpen.test.js
packages/app-desktop/utils/isSafeToOpen.js
packages/app-desktop/utils/markupLanguageUtils.js
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
packages/app-desktop/utils/restartInSafeModeFromMain.js
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/commands/index.js
packages/app-mobile/commands/openItem.js
packages/app-mobile/commands/openNote.js
packages/app-mobile/commands/scrollToHash.js
packages/app-mobile/commands/util/goToNote.js
packages/app-mobile/components/ActionButton.js
packages/app-mobile/components/BackButtonDialogBox.js
packages/app-mobile/components/CameraView.js
@@ -465,14 +494,24 @@ packages/app-mobile/components/ExtendedWebView.js
packages/app-mobile/components/FolderPicker.js
packages/app-mobile/components/Icon.js
packages/app-mobile/components/Modal.js
packages/app-mobile/components/ModalDialog.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.test.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/noteBodyViewerBundle.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/types.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/addPluginAssets.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/makeResourceModel.js
packages/app-mobile/components/NoteBodyViewer/hooks/useContentScripts.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.test.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRenderer.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRerenderHandler.js
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
packages/app-mobile/components/NoteBodyViewer/types.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.js
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/autosave.js
@@ -494,17 +533,25 @@ packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useActionButto
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useHeaderButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useInlineFormattingButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useListButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/usePluginButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.js
packages/app-mobile/components/NoteEditor/NoteEditor.test.js
packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/commandDeclarations.js
packages/app-mobile/components/NoteEditor/hooks/useCodeMirrorPlugins.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.test.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.js
packages/app-mobile/components/NoteEditor/hooks/useKeyboardVisible.js
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteList.js
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
packages/app-mobile/components/ScreenHeader.js
packages/app-mobile/components/ScreenHeader/WarningBanner.test.js
packages/app-mobile/components/ScreenHeader/WarningBanner.js
packages/app-mobile/components/ScreenHeader/WarningBox.js
packages/app-mobile/components/ScreenHeader/index.js
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/TextInput.js
@@ -515,15 +562,20 @@ packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/getResponsiveValue.test.js
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/global-style.js
packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen/FileSystemPathSelector.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportDebugReportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteImportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/TaskButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/exportAllFolders.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/exportDebugReport.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/exportProfile.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/makeImportExportCacheDirectory.js
packages/app-mobile/components/screens/ConfigScreen/SectionDescription.js
packages/app-mobile/components/screens/ConfigScreen/SectionHeader.js
packages/app-mobile/components/screens/ConfigScreen/SectionSelector.js
packages/app-mobile/components/screens/ConfigScreen/SettingComponent.js
@@ -531,16 +583,59 @@ packages/app-mobile/components/screens/ConfigScreen/SettingItem.js
packages/app-mobile/components/screens/ConfigScreen/SettingsButton.js
packages/app-mobile/components/screens/ConfigScreen/SettingsToggle.js
packages/app-mobile/components/screens/ConfigScreen/configScreenStyles.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/ActionButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/index.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginToggle.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginUploadButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/newRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/pluginServiceSetup.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/openWebsiteForPlugin.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/types.js
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
packages/app-mobile/components/screens/LogScreen.js
packages/app-mobile/components/screens/Note.js
packages/app-mobile/components/screens/NoteTagsDialog.js
packages/app-mobile/components/screens/Notes.js
packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
packages/app-mobile/components/screens/ShareManager/IncomingShareItem.js
packages/app-mobile/components/screens/ShareManager/index.test.js
packages/app-mobile/components/screens/ShareManager/index.js
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/search.js
packages/app-mobile/components/screens/status.js
packages/app-mobile/components/side-menu-content.js
packages/app-mobile/components/voiceTyping/VoiceTypingDialog.js
packages/app-mobile/gulpfile.js
packages/app-mobile/plugins/PlatformImplementation.js
packages/app-mobile/plugins/PluginRunner/PluginRunner.js
packages/app-mobile/plugins/PluginRunner/PluginRunnerWebView.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/initializeDialogWebView.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/initializePluginBackgroundIframe.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/pluginRunnerBackgroundPage.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/startStopPlugin.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/getFormData.test.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/getFormData.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/makeSandboxedIframe.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/reportUnhandledErrors.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/wrapConsoleLog.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginDialogManager.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginDialogWebView.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginPanelViewer.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginUserWebView.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useDialogMessenger.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useDialogSize.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useViewInfos.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useWebViewSetup.js
packages/app-mobile/plugins/PluginRunner/types.js
packages/app-mobile/plugins/PluginRunner/utils/createOnLogHandler.js
packages/app-mobile/plugins/hooks/usePlugin.js
packages/app-mobile/plugins/loadPlugins.js
packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
@@ -557,14 +652,29 @@ packages/app-mobile/utils/ShareExtension.js
packages/app-mobile/utils/ShareUtils.test.js
packages/app-mobile/utils/ShareUtils.js
packages/app-mobile/utils/TlsUtils.js
packages/app-mobile/utils/appDefaultState.js
packages/app-mobile/utils/autodetectTheme.js
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/createRootStyle.js
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/fs-driver/constants.js
packages/app-mobile/utils/fs-driver/fs-driver-rn.js
packages/app-mobile/utils/fs-driver/runOnDeviceTests.js
packages/app-mobile/utils/fs-driver/tarCreate.js
packages/app-mobile/utils/fs-driver/tarExtract.test.js
packages/app-mobile/utils/fs-driver/tarExtract.js
packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
packages/app-mobile/utils/initializeCommandService.js
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
packages/app-mobile/utils/pickDocument.js
packages/app-mobile/utils/polyfills/bufferPolyfill.js
packages/app-mobile/utils/polyfills/index.js
packages/app-mobile/utils/setupNotifications.js
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/showMessageBox.js
packages/app-mobile/utils/testing/createMockReduxStore.js
packages/app-mobile/utils/types.js
packages/default-plugins/build.js
packages/default-plugins/buildDefaultPlugins.js
@@ -574,6 +684,7 @@ packages/default-plugins/utils/getCurrentCommitHash.js
packages/default-plugins/utils/getPathToPatchFileFor.js
packages/default-plugins/utils/readRepositoryJson.js
packages/default-plugins/utils/waitForCliInput.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5BuiltInOptions.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.js
packages/editor/CodeMirror/CodeMirror5Emulation/Decorator.js
@@ -582,12 +693,20 @@ packages/editor/CodeMirror/CodeMirrorControl.js
packages/editor/CodeMirror/configFromSettings.js
packages/editor/CodeMirror/createEditor.test.js
packages/editor/CodeMirror/createEditor.js
packages/editor/CodeMirror/editorCommands/duplicateLine.test.js
packages/editor/CodeMirror/editorCommands/duplicateLine.js
packages/editor/CodeMirror/editorCommands/editorCommands.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.test.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.test.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.js
packages/editor/CodeMirror/editorCommands/supportsCommand.js
packages/editor/CodeMirror/editorCommands/swapLine.test.js
packages/editor/CodeMirror/editorCommands/swapLine.js
packages/editor/CodeMirror/getScrollFraction.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/allLanguages.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/defaultLanguage.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/lookUpLanguage.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
@@ -600,13 +719,17 @@ packages/editor/CodeMirror/markdown/markdownMathParser.test.js
packages/editor/CodeMirror/markdown/markdownMathParser.js
packages/editor/CodeMirror/markdown/markdownReformatter.test.js
packages/editor/CodeMirror/markdown/markdownReformatter.js
packages/editor/CodeMirror/markdown/syntaxHighlightingLanguages.js
packages/editor/CodeMirror/pluginApi/PluginLoader.js
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.js
packages/editor/CodeMirror/testUtil/createEditorControl.js
packages/editor/CodeMirror/testUtil/createEditorSettings.js
packages/editor/CodeMirror/testUtil/createTestEditor.js
packages/editor/CodeMirror/testUtil/forceFullParse.js
packages/editor/CodeMirror/testUtil/loadLanguages.js
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
packages/editor/CodeMirror/testUtil/typeText.js
packages/editor/CodeMirror/theme.js
packages/editor/CodeMirror/util/isInSyntaxNode.js
packages/editor/CodeMirror/util/setupVim.js
@@ -632,6 +755,7 @@ packages/generator-joplin/generators/app/templates/api/noteListType.js
packages/generator-joplin/generators/app/templates/api/types.js
packages/generator-joplin/generators/app/templates/api_index.js
packages/generator-joplin/generators/app/templates/src/index.js
packages/generator-joplin/tools/updateCategories.js
packages/htmlpack/src/index.js
packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.js
@@ -671,15 +795,22 @@ packages/lib/commands/openMasterPasswordDialog.js
packages/lib/commands/synchronize.js
packages/lib/components/EncryptionConfigScreen/utils.js
packages/lib/components/shared/config/config-shared.js
packages/lib/components/shared/config/plugins/types.js
packages/lib/components/shared/config/plugins/useOnDeleteHandler.js
packages/lib/components/shared/config/plugins/useOnInstallHandler.test.js
packages/lib/components/shared/config/plugins/useOnInstallHandler.js
packages/lib/components/shared/config/shouldShowMissingPasswordWarning.test.js
packages/lib/components/shared/config/shouldShowMissingPasswordWarning.js
packages/lib/components/shared/note-screen-shared.js
packages/lib/components/shared/reduxSharedMiddleware.js
packages/lib/components/shared/side-menu-shared.test.js
packages/lib/components/shared/side-menu-shared.js
packages/lib/database-driver-better-sqlite.js
packages/lib/database.js
packages/lib/debug/DebugService.js
packages/lib/determineBaseAppDirs.js
packages/lib/dom.js
packages/lib/downloadController.js
packages/lib/errorUtils.js
packages/lib/errors.js
packages/lib/eventManager.js
@@ -696,6 +827,7 @@ packages/lib/geolocation-node.js
packages/lib/hooks/useAsyncEffect.js
packages/lib/hooks/useElementSize.js
packages/lib/hooks/useEventListener.js
packages/lib/hooks/usePrevious.js
packages/lib/htmlUtils.test.js
packages/lib/htmlUtils.js
packages/lib/htmlUtils2.test.js
@@ -740,11 +872,17 @@ packages/lib/models/Tag.test.js
packages/lib/models/Tag.js
packages/lib/models/dateTimeFormats.test.js
packages/lib/models/settings/FileHandler.js
packages/lib/models/settings/settingValidations.test.js
packages/lib/models/settings/settingValidations.js
packages/lib/models/utils/getCollator.js
packages/lib/models/utils/getConflictFolderId.js
packages/lib/models/utils/isItemId.js
packages/lib/models/utils/itemCanBeEncrypted.js
packages/lib/models/utils/onFolderDrop.test.js
packages/lib/models/utils/onFolderDrop.js
packages/lib/models/utils/paginatedFeed.js
packages/lib/models/utils/paginationToSql.js
packages/lib/models/utils/readOnly.test.js
packages/lib/models/utils/readOnly.js
packages/lib/models/utils/resourceUtils.js
packages/lib/models/utils/types.js
@@ -774,6 +912,7 @@ packages/lib/services/KvStore.js
packages/lib/services/MigrationService.js
packages/lib/services/NavService.js
packages/lib/services/PostMessageService.js
packages/lib/services/ReportService.test.js
packages/lib/services/ReportService.js
packages/lib/services/ResourceEditWatcher/index.js
packages/lib/services/ResourceEditWatcher/reducer.js
@@ -800,6 +939,8 @@ packages/lib/services/database/migrations/42.js
packages/lib/services/database/migrations/43.js
packages/lib/services/database/migrations/44.js
packages/lib/services/database/migrations/45.js
packages/lib/services/database/migrations/46.js
packages/lib/services/database/migrations/47.js
packages/lib/services/database/migrations/index.js
packages/lib/services/database/sqlStringToLines.js
packages/lib/services/database/types.js
@@ -839,6 +980,7 @@ packages/lib/services/interop/InteropService_Importer_Raw.js
packages/lib/services/interop/Module.test.js
packages/lib/services/interop/Module.js
packages/lib/services/interop/types.js
packages/lib/services/joplinCloudUtils.js
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
packages/lib/services/keychain/KeychainService.js
packages/lib/services/keychain/KeychainServiceDriver.dummy.js
@@ -847,6 +989,12 @@ packages/lib/services/keychain/KeychainServiceDriver.node.js
packages/lib/services/keychain/KeychainServiceDriverBase.js
packages/lib/services/noteList/defaultLeftToRightListRenderer.js
packages/lib/services/noteList/defaultListRenderer.js
packages/lib/services/noteList/defaultMultiColumnsRenderer.js
packages/lib/services/noteList/depNameToNoteProp.js
packages/lib/services/noteList/renderTemplate.test.js
packages/lib/services/noteList/renderTemplate.js
packages/lib/services/noteList/renderViewProps.test.js
packages/lib/services/noteList/renderViewProps.js
packages/lib/services/noteList/renderers.js
packages/lib/services/ocr/OcrDriverBase.js
packages/lib/services/ocr/OcrService.test.js
@@ -892,6 +1040,13 @@ packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js
packages/lib/services/plugins/reducer.js
packages/lib/services/plugins/utils/createViewHandle.js
packages/lib/services/plugins/utils/executeSandboxCall.js
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
packages/lib/services/plugins/utils/getPluginSettingValue.js
packages/lib/services/plugins/utils/isCompatible/index.test.js
packages/lib/services/plugins/utils/isCompatible/index.js
packages/lib/services/plugins/utils/isCompatible/minVersionForPlatform.js
packages/lib/services/plugins/utils/isCompatible/types.js
packages/lib/services/plugins/utils/loadContentScripts.js
packages/lib/services/plugins/utils/makeListener.js
packages/lib/services/plugins/utils/manifestFromObject.js
@@ -899,6 +1054,8 @@ packages/lib/services/plugins/utils/mapEventHandlersToIds.js
packages/lib/services/plugins/utils/types.js
packages/lib/services/plugins/utils/validatePluginId.test.js
packages/lib/services/plugins/utils/validatePluginId.js
packages/lib/services/plugins/utils/validatePluginPlatforms.test.js
packages/lib/services/plugins/utils/validatePluginPlatforms.js
packages/lib/services/plugins/utils/validatePluginVersion.test.js
packages/lib/services/plugins/utils/validatePluginVersion.js
packages/lib/services/profileConfig/index.test.js
@@ -914,6 +1071,7 @@ packages/lib/services/rest/actionApi.desktop.js
packages/lib/services/rest/routes/auth.js
packages/lib/services/rest/routes/events.test.js
packages/lib/services/rest/routes/events.js
packages/lib/services/rest/routes/folders.test.js
packages/lib/services/rest/routes/folders.js
packages/lib/services/rest/routes/master_keys.js
packages/lib/services/rest/routes/notes.test.js
@@ -945,6 +1103,7 @@ packages/lib/services/search/gotoAnythingStyleQuery.js
packages/lib/services/search/queryBuilder.js
packages/lib/services/share/ShareService.test.js
packages/lib/services/share/ShareService.js
packages/lib/services/share/invitationRespond.js
packages/lib/services/share/reducer.js
packages/lib/services/spellChecker/SpellCheckerService.js
packages/lib/services/spellChecker/SpellCheckerServiceDriverBase.js
@@ -982,8 +1141,22 @@ packages/lib/services/synchronizer/utils/handleSyncStartupOperation.js
packages/lib/services/synchronizer/utils/resourceRemotePath.js
packages/lib/services/synchronizer/utils/syncDeleteStep.js
packages/lib/services/synchronizer/utils/types.js
packages/lib/services/trash/emptyTrash.test.js
packages/lib/services/trash/emptyTrash.js
packages/lib/services/trash/getTrashFolderId.js
packages/lib/services/trash/index.test.js
packages/lib/services/trash/index.js
packages/lib/services/trash/isTrashableItem.js
packages/lib/services/trash/permanentlyDeleteOldItems.test.js
packages/lib/services/trash/permanentlyDeleteOldItems.js
packages/lib/services/trash/restoreItems.test.js
packages/lib/services/trash/restoreItems.js
packages/lib/shim-init-node.js
packages/lib/shim.js
packages/lib/string-utils.test.js
packages/lib/string-utils.js
packages/lib/testing/share/makeMockShareInvitation.js
packages/lib/testing/share/mockShareService.js
packages/lib/testing/syncTargetUtils.js
packages/lib/testing/test-utils-synchronizer.js
packages/lib/testing/test-utils.js
@@ -999,9 +1172,24 @@ packages/lib/themes/solarizedLight.js
packages/lib/themes/type.js
packages/lib/time.js
packages/lib/types.js
packages/lib/utils/ActionLogger.test.js
packages/lib/utils/ActionLogger.js
packages/lib/utils/credentialFiles.js
packages/lib/utils/focusHandler.js
packages/lib/utils/ipc/RemoteMessenger.test.js
packages/lib/utils/ipc/RemoteMessenger.js
packages/lib/utils/ipc/TestMessenger.js
packages/lib/utils/ipc/WindowMessenger.js
packages/lib/utils/ipc/types.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.test.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.test.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js
packages/lib/utils/userFetcher.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/utils/webDAVUtils.js
@@ -1069,6 +1257,7 @@ packages/renderer/MdToHtml/rules/link_open.js
packages/renderer/MdToHtml/rules/mermaid.js
packages/renderer/MdToHtml/rules/sanitize_html.js
packages/renderer/MdToHtml/rules/source_map.js
packages/renderer/MdToHtml/rules/tableHorizontallyScrollable.js
packages/renderer/MdToHtml/setupLinkify.js
packages/renderer/MdToHtml/validateLinks.js
packages/renderer/assetsToHeaders.js
@@ -1100,6 +1289,7 @@ packages/tools/packageJsonLint.js
packages/tools/postPreReleasesToForum.js
packages/tools/release-android.js
packages/tools/release-cli.js
packages/tools/release-clipper.js
packages/tools/release-electron.js
packages/tools/release-ios.js
packages/tools/release-plugin-repo-cli.js

View File

@@ -101,6 +101,19 @@ module.exports = {
'no-unneeded-ternary': 'error',
'github/array-foreach': ['error'],
'no-restricted-properties': ['error',
{
'property': 'focus',
'message': 'Please use focusHandler::focus() instead',
},
{
'property': 'blur',
'message': 'Please use focusHandler::blur() instead',
},
],
'@typescript-eslint/no-explicit-any': ['error'],
// -------------------------------
// Formatting
// -------------------------------
@@ -253,7 +266,7 @@ module.exports = {
selector: 'enumMember',
format: null,
'filter': {
'regex': '^(GET|POST|PUT|DELETE|PATCH|HEAD|SQLite|PostgreSQL|ASC|DESC|E2EE|OR|AND|UNION|INTERSECT|EXCLUSION|INCLUSION|EUR|GBP|USD|SJCL.*)$',
'regex': '^(GET|POST|PUT|DELETE|PATCH|HEAD|SQLite|PostgreSQL|ASC|DESC|E2EE|OR|AND|UNION|INTERSECT|EXCLUSION|INCLUSION|EUR|GBP|USD|SJCL.*|iOS)$',
'match': true,
},
},

View File

@@ -20,6 +20,6 @@ If it's not related to any platform (such as a translation, change to the docume
Then please append the issue that you've addressed or fixed. Use "Resolves #123" for new features or improvements and "Fixes #123" for bug fixes.
AND PLEASE READ THE GUIDE: https://github.com/laurent22/joplin/blob/dev/CONTRIBUTING.md
AND PLEASE READ THE GUIDE: https://github.com/laurent22/joplin/blob/dev/readme/dev/index.md
-->
-->

View File

@@ -90,7 +90,7 @@ if [ "$RUN_TESTS" == "1" ]; then
# On Linux, we run the Joplin Server tests using PostgreSQL
if [ "$IS_LINUX" == "1" ]; then
echo "Running Joplin Server tests using PostgreSQL..."
sudo docker-compose --file docker-compose.db-dev.yml up -d
sudo docker compose --file docker-compose.db-dev.yml up -d
cmdResult=$?
if [ $cmdResult -ne 0 ]; then
exit $cmdResult
@@ -141,15 +141,13 @@ fi
# for Linux only is sufficient.
# =============================================================================
if [ "$IS_PULL_REQUEST" == "1" ]; then
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Validating translations..."
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Validating translations..."
node packages/tools/validate-translation.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
node packages/tools/validate-translation.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
@@ -179,15 +177,13 @@ fi
# See coding_style.md
# =============================================================================
if [ "$IS_PULL_REQUEST" == "1" ]; then
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Checking for files that should have been ignored..."
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Checking for files that should have been ignored..."
node packages/tools/checkIgnoredFiles.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
node packages/tools/checkIgnoredFiles.js
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
@@ -196,11 +192,27 @@ fi
# =============================================================================
if [ "$RUN_TESTS" == "1" ]; then
echo "Step: Check that the website still builds..."
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Check that the website still builds..."
mkdir -p ../joplin-website/docs
ll ../joplin-website/docs/api/references/plugin_api
SKIP_SPONSOR_PROCESSING=1 yarn buildWebsite
mkdir -p ../joplin-website/docs
CROWDIN_PERSONAL_TOKEN="$CROWDIN_PERSONAL_TOKEN" yarn crowdinDownload
SKIP_SPONSOR_PROCESSING=1 yarn buildWebsite
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult
fi
fi
fi
# =============================================================================
# Spellchecking
# =============================================================================
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Spellchecking..."
yarn spellcheck --all
testResult=$?
if [ $testResult -ne 0 ]; then
exit $testResult

View File

@@ -28,7 +28,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'

View File

@@ -20,8 +20,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: olegtarasov/get-tag@v2.1
- uses: actions/setup-node@v2
- uses: olegtarasov/get-tag@v2.1.3
- uses: actions/setup-node@v4
with:
# We need to pin the version to 18.15, because 18.16+ fails with this error:
# https://github.com/facebook/react-native/issues/36440
@@ -40,7 +40,7 @@ jobs:
brew install pango
# See github-action-main.yml for explanation
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'

View File

@@ -9,7 +9,7 @@ jobs:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v4
- uses: actions/stale@v9
with:
# Use this to do a dry run from a pull request
# debug-only: true

View File

@@ -82,8 +82,8 @@ jobs:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
- uses: actions/checkout@v4
- uses: olegtarasov/get-tag@v2.1
- uses: actions/setup-node@v2
- uses: olegtarasov/get-tag@v2.1.3
- uses: actions/setup-node@v4
with:
# We need to pin the version to 18.15, because 18.16+ fails with this error:
# https://github.com/facebook/react-native/issues/36440
@@ -109,7 +109,7 @@ jobs:
# Python to an earlier version.
# Fixes error `ModuleNotFoundError: No module named 'distutils'`
# Ref: https://github.com/nodejs/node-gyp/issues/2869
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
@@ -127,6 +127,7 @@ jobs:
BUILD_SEQUENCIAL: 1
SERVER_REPOSITORY: joplin/server
SERVER_TAG_PREFIX: server
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
run: |
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"
@@ -182,7 +183,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'yarn'

228
.gitignore vendored
View File

@@ -89,7 +89,10 @@ packages/app-cli/app/command-mkbook.test.js
packages/app-cli/app/command-mkbook.js
packages/app-cli/app/command-mv.js
packages/app-cli/app/command-ren.js
packages/app-cli/app/command-restore.js
packages/app-cli/app/command-rmbook.test.js
packages/app-cli/app/command-rmbook.js
packages/app-cli/app/command-rmnote.test.js
packages/app-cli/app/command-rmnote.js
packages/app-cli/app/command-set.js
packages/app-cli/app/command-settingschema.js
@@ -97,6 +100,7 @@ packages/app-cli/app/command-sync.js
packages/app-cli/app/command-testing.js
packages/app-cli/app/command-use.js
packages/app-cli/app/command-version.js
packages/app-cli/app/gui/FolderListWidget.js
packages/app-cli/app/gui/StatusBarWidget.js
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/setupCommand.js
@@ -123,6 +127,7 @@ packages/app-desktop/bridge.js
packages/app-desktop/checkForUpdates.js
packages/app-desktop/commands/copyDevCommand.js
packages/app-desktop/commands/editProfileConfig.js
packages/app-desktop/commands/emptyTrash.js
packages/app-desktop/commands/exportFolders.js
packages/app-desktop/commands/exportNotes.js
packages/app-desktop/commands/focusElement.js
@@ -148,8 +153,6 @@ packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.test.js
packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.js
packages/app-desktop/gui/Dialog.js
packages/app-desktop/gui/DialogButtonRow.js
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
@@ -168,6 +171,7 @@ packages/app-desktop/gui/IconButton.js
packages/app-desktop/gui/ImportScreen.js
packages/app-desktop/gui/ItemList.js
packages/app-desktop/gui/JoplinCloudConfigScreen.js
packages/app-desktop/gui/JoplinCloudLoginScreen.js
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.js
packages/app-desktop/gui/KeymapConfig/styles/index.js
@@ -197,10 +201,13 @@ packages/app-desktop/gui/MainScreen/commands/openItem.js
packages/app-desktop/gui/MainScreen/commands/openNote.js
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.js
packages/app-desktop/gui/MainScreen/commands/openTag.js
packages/app-desktop/gui/MainScreen/commands/permanentlyDeleteNote.js
packages/app-desktop/gui/MainScreen/commands/print.js
packages/app-desktop/gui/MainScreen/commands/renameFolder.js
packages/app-desktop/gui/MainScreen/commands/renameTag.js
packages/app-desktop/gui/MainScreen/commands/resetLayout.js
packages/app-desktop/gui/MainScreen/commands/restoreFolder.js
packages/app-desktop/gui/MainScreen/commands/restoreNote.js
packages/app-desktop/gui/MainScreen/commands/revealResourceFile.js
packages/app-desktop/gui/MainScreen/commands/search.js
packages/app-desktop/gui/MainScreen/commands/setTags.js
@@ -210,6 +217,7 @@ packages/app-desktop/gui/MainScreen/commands/showNoteProperties.js
packages/app-desktop/gui/MainScreen/commands/showPrompt.js
packages/app-desktop/gui/MainScreen/commands/showShareFolderDialog.js
packages/app-desktop/gui/MainScreen/commands/showShareNoteDialog.js
packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.test.js
packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.js
packages/app-desktop/gui/MainScreen/commands/toggleEditors.js
packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js
@@ -227,26 +235,30 @@ packages/app-desktop/gui/Navigator.js
packages/app-desktop/gui/NoteContentPropertiesDialog.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/normalizeAccelerator.test.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/normalizeAccelerator.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.test.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearch.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useExternalPlugins.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinMode.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useLineSorting.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useListIdent.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearchExtension.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearchHandler.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollHandler.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useStyles.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/useWebviewIpcMessage.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/Editor.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useCursorUtils.test.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useCursorUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useExternalPlugins.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useJoplinCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useJoplinMode.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useLineSorting.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useListIdent.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useScrollUtils.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/PlainEditor/PlainEditor.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
@@ -258,6 +270,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/shouldPasteResources.
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/types.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useWebViewApi.js
packages/app-desktop/gui/NoteEditor/NoteEditor.js
packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
@@ -289,9 +302,7 @@ packages/app-desktop/gui/NoteEditor/utils/useNoteSearchBar.js
packages/app-desktop/gui/NoteEditor/utils/usePluginServiceRegistration.js
packages/app-desktop/gui/NoteEditor/utils/useSearchMarkers.js
packages/app-desktop/gui/NoteEditor/utils/useWindowCommandHandler.js
packages/app-desktop/gui/NoteList/NoteList.js
packages/app-desktop/gui/NoteList/NoteList2.js
packages/app-desktop/gui/NoteList/NoteListSource.js
packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js
packages/app-desktop/gui/NoteList/commands/index.js
packages/app-desktop/gui/NoteList/utils/canManuallySortNotes.js
@@ -308,9 +319,18 @@ packages/app-desktop/gui/NoteList/utils/useVisibleRange.js
packages/app-desktop/gui/NoteListControls/NoteListControls.js
packages/app-desktop/gui/NoteListControls/commands/focusSearch.js
packages/app-desktop/gui/NoteListControls/commands/index.js
packages/app-desktop/gui/NoteListItem.js
packages/app-desktop/gui/NoteListHeader/NoteListHeader.js
packages/app-desktop/gui/NoteListHeader/NoteListHeaderItem.js
packages/app-desktop/gui/NoteListHeader/types.js
packages/app-desktop/gui/NoteListHeader/useDragAndDrop.test.js
packages/app-desktop/gui/NoteListHeader/useDragAndDrop.js
packages/app-desktop/gui/NoteListHeader/utils/getColumnTitle.js
packages/app-desktop/gui/NoteListHeader/utils/useContextMenu.js
packages/app-desktop/gui/NoteListHeader/utils/validateColumns.test.js
packages/app-desktop/gui/NoteListHeader/utils/validateColumns.js
packages/app-desktop/gui/NoteListItem/NoteListItem.js
packages/app-desktop/gui/NoteListItem/utils/getNoteTitleHtml.js
packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.test.js
packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.js
packages/app-desktop/gui/NoteListItem/utils/types.js
packages/app-desktop/gui/NoteListItem/utils/useItemElement.js
@@ -325,6 +345,7 @@ packages/app-desktop/gui/NoteSearchBar.js
packages/app-desktop/gui/NoteStatusBar.js
packages/app-desktop/gui/NoteTextViewer.js
packages/app-desktop/gui/NoteToolbar/NoteToolbar.js
packages/app-desktop/gui/NotyfContext.js
packages/app-desktop/gui/OneDriveLoginScreen.js
packages/app-desktop/gui/PasswordInput/PasswordInput.js
packages/app-desktop/gui/PdfViewer.js
@@ -369,6 +390,7 @@ packages/app-desktop/gui/ToolbarBase.js
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
packages/app-desktop/gui/ToolbarButton/styles/index.js
packages/app-desktop/gui/ToolbarSpace.js
packages/app-desktop/gui/TrashNotification/TrashNotification.js
packages/app-desktop/gui/dialogs.js
packages/app-desktop/gui/hooks/useEffectDebugger.js
packages/app-desktop/gui/hooks/useImperativeHandlerDebugger.js
@@ -384,6 +406,7 @@ packages/app-desktop/gui/style/StyledMessage.js
packages/app-desktop/gui/style/StyledTextInput.js
packages/app-desktop/gui/utils/NoteListUtils.js
packages/app-desktop/gui/utils/convertToScreenCoordinates.js
packages/app-desktop/gui/utils/dragAndDrop.js
packages/app-desktop/gui/utils/loadScript.js
packages/app-desktop/gulpfile.js
packages/app-desktop/integration-tests/main.spec.js
@@ -417,7 +440,6 @@ packages/app-desktop/services/plugins/hooks/useThemeCss.js
packages/app-desktop/services/plugins/hooks/useViewIsReady.js
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js
packages/app-desktop/services/restart.js
packages/app-desktop/services/share/invitationRespond.js
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.test.js
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
@@ -431,10 +453,17 @@ packages/app-desktop/utils/7zip/pathToBundled7Zip.js
packages/app-desktop/utils/checkForUpdatesUtils.test.js
packages/app-desktop/utils/checkForUpdatesUtils.js
packages/app-desktop/utils/checkForUpdatesUtilsTestData.js
packages/app-desktop/utils/isSafeToOpen.test.js
packages/app-desktop/utils/isSafeToOpen.js
packages/app-desktop/utils/markupLanguageUtils.js
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
packages/app-desktop/utils/restartInSafeModeFromMain.js
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/commands/index.js
packages/app-mobile/commands/openItem.js
packages/app-mobile/commands/openNote.js
packages/app-mobile/commands/scrollToHash.js
packages/app-mobile/commands/util/goToNote.js
packages/app-mobile/components/ActionButton.js
packages/app-mobile/components/BackButtonDialogBox.js
packages/app-mobile/components/CameraView.js
@@ -445,14 +474,24 @@ packages/app-mobile/components/ExtendedWebView.js
packages/app-mobile/components/FolderPicker.js
packages/app-mobile/components/Icon.js
packages/app-mobile/components/Modal.js
packages/app-mobile/components/ModalDialog.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.test.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/noteBodyViewerBundle.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/types.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/addPluginAssets.js
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/makeResourceModel.js
packages/app-mobile/components/NoteBodyViewer/hooks/useContentScripts.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.test.js
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRenderer.js
packages/app-mobile/components/NoteBodyViewer/hooks/useRerenderHandler.js
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
packages/app-mobile/components/NoteBodyViewer/types.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.js
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.js
packages/app-mobile/components/NoteEditor/ImageEditor/autosave.js
@@ -474,17 +513,25 @@ packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useActionButto
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useHeaderButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useInlineFormattingButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useListButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/usePluginButtons.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.js
packages/app-mobile/components/NoteEditor/NoteEditor.test.js
packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/commandDeclarations.js
packages/app-mobile/components/NoteEditor/hooks/useCodeMirrorPlugins.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.test.js
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.js
packages/app-mobile/components/NoteEditor/hooks/useKeyboardVisible.js
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteList.js
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
packages/app-mobile/components/ScreenHeader.js
packages/app-mobile/components/ScreenHeader/WarningBanner.test.js
packages/app-mobile/components/ScreenHeader/WarningBanner.js
packages/app-mobile/components/ScreenHeader/WarningBox.js
packages/app-mobile/components/ScreenHeader/index.js
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/TextInput.js
@@ -495,15 +542,20 @@ packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/getResponsiveValue.test.js
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/global-style.js
packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen/FileSystemPathSelector.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportDebugReportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteImportButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/TaskButton.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/exportAllFolders.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/exportDebugReport.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/exportProfile.js
packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/utils/makeImportExportCacheDirectory.js
packages/app-mobile/components/screens/ConfigScreen/SectionDescription.js
packages/app-mobile/components/screens/ConfigScreen/SectionHeader.js
packages/app-mobile/components/screens/ConfigScreen/SectionSelector.js
packages/app-mobile/components/screens/ConfigScreen/SettingComponent.js
@@ -511,16 +563,59 @@ packages/app-mobile/components/screens/ConfigScreen/SettingItem.js
packages/app-mobile/components/screens/ConfigScreen/SettingsButton.js
packages/app-mobile/components/screens/ConfigScreen/SettingsToggle.js
packages/app-mobile/components/screens/ConfigScreen/configScreenStyles.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/ActionButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/index.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginStates.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginToggle.js
packages/app-mobile/components/screens/ConfigScreen/plugins/PluginUploadButton.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.test.js
packages/app-mobile/components/screens/ConfigScreen/plugins/SearchPlugins.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/newRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/plugins/testUtils/pluginServiceSetup.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/openWebsiteForPlugin.js
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
packages/app-mobile/components/screens/ConfigScreen/types.js
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
packages/app-mobile/components/screens/LogScreen.js
packages/app-mobile/components/screens/Note.js
packages/app-mobile/components/screens/NoteTagsDialog.js
packages/app-mobile/components/screens/Notes.js
packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
packages/app-mobile/components/screens/ShareManager/IncomingShareItem.js
packages/app-mobile/components/screens/ShareManager/index.test.js
packages/app-mobile/components/screens/ShareManager/index.js
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/search.js
packages/app-mobile/components/screens/status.js
packages/app-mobile/components/side-menu-content.js
packages/app-mobile/components/voiceTyping/VoiceTypingDialog.js
packages/app-mobile/gulpfile.js
packages/app-mobile/plugins/PlatformImplementation.js
packages/app-mobile/plugins/PluginRunner/PluginRunner.js
packages/app-mobile/plugins/PluginRunner/PluginRunnerWebView.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/initializeDialogWebView.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/initializePluginBackgroundIframe.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/pluginRunnerBackgroundPage.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/startStopPlugin.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/getFormData.test.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/getFormData.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/makeSandboxedIframe.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/reportUnhandledErrors.js
packages/app-mobile/plugins/PluginRunner/backgroundPage/utils/wrapConsoleLog.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginDialogManager.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginDialogWebView.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginPanelViewer.js
packages/app-mobile/plugins/PluginRunner/dialogs/PluginUserWebView.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useDialogMessenger.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useDialogSize.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useViewInfos.js
packages/app-mobile/plugins/PluginRunner/dialogs/hooks/useWebViewSetup.js
packages/app-mobile/plugins/PluginRunner/types.js
packages/app-mobile/plugins/PluginRunner/utils/createOnLogHandler.js
packages/app-mobile/plugins/hooks/usePlugin.js
packages/app-mobile/plugins/loadPlugins.js
packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
@@ -537,14 +632,29 @@ packages/app-mobile/utils/ShareExtension.js
packages/app-mobile/utils/ShareUtils.test.js
packages/app-mobile/utils/ShareUtils.js
packages/app-mobile/utils/TlsUtils.js
packages/app-mobile/utils/appDefaultState.js
packages/app-mobile/utils/autodetectTheme.js
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/createRootStyle.js
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/fs-driver/constants.js
packages/app-mobile/utils/fs-driver/fs-driver-rn.js
packages/app-mobile/utils/fs-driver/runOnDeviceTests.js
packages/app-mobile/utils/fs-driver/tarCreate.js
packages/app-mobile/utils/fs-driver/tarExtract.test.js
packages/app-mobile/utils/fs-driver/tarExtract.js
packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
packages/app-mobile/utils/initializeCommandService.js
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
packages/app-mobile/utils/pickDocument.js
packages/app-mobile/utils/polyfills/bufferPolyfill.js
packages/app-mobile/utils/polyfills/index.js
packages/app-mobile/utils/setupNotifications.js
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/showMessageBox.js
packages/app-mobile/utils/testing/createMockReduxStore.js
packages/app-mobile/utils/types.js
packages/default-plugins/build.js
packages/default-plugins/buildDefaultPlugins.js
@@ -554,6 +664,7 @@ packages/default-plugins/utils/getCurrentCommitHash.js
packages/default-plugins/utils/getPathToPatchFileFor.js
packages/default-plugins/utils/readRepositoryJson.js
packages/default-plugins/utils/waitForCliInput.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5BuiltInOptions.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.js
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.js
packages/editor/CodeMirror/CodeMirror5Emulation/Decorator.js
@@ -562,12 +673,20 @@ packages/editor/CodeMirror/CodeMirrorControl.js
packages/editor/CodeMirror/configFromSettings.js
packages/editor/CodeMirror/createEditor.test.js
packages/editor/CodeMirror/createEditor.js
packages/editor/CodeMirror/editorCommands/duplicateLine.test.js
packages/editor/CodeMirror/editorCommands/duplicateLine.js
packages/editor/CodeMirror/editorCommands/editorCommands.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.test.js
packages/editor/CodeMirror/editorCommands/insertLineAfter.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.test.js
packages/editor/CodeMirror/editorCommands/sortSelectedLines.js
packages/editor/CodeMirror/editorCommands/supportsCommand.js
packages/editor/CodeMirror/editorCommands/swapLine.test.js
packages/editor/CodeMirror/editorCommands/swapLine.js
packages/editor/CodeMirror/getScrollFraction.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/allLanguages.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/defaultLanguage.js
packages/editor/CodeMirror/markdown/codeBlockLanguages/lookUpLanguage.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
@@ -580,13 +699,17 @@ packages/editor/CodeMirror/markdown/markdownMathParser.test.js
packages/editor/CodeMirror/markdown/markdownMathParser.js
packages/editor/CodeMirror/markdown/markdownReformatter.test.js
packages/editor/CodeMirror/markdown/markdownReformatter.js
packages/editor/CodeMirror/markdown/syntaxHighlightingLanguages.js
packages/editor/CodeMirror/pluginApi/PluginLoader.js
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
packages/editor/CodeMirror/pluginApi/customEditorCompletion.js
packages/editor/CodeMirror/testUtil/createEditorControl.js
packages/editor/CodeMirror/testUtil/createEditorSettings.js
packages/editor/CodeMirror/testUtil/createTestEditor.js
packages/editor/CodeMirror/testUtil/forceFullParse.js
packages/editor/CodeMirror/testUtil/loadLanguages.js
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
packages/editor/CodeMirror/testUtil/typeText.js
packages/editor/CodeMirror/theme.js
packages/editor/CodeMirror/util/isInSyntaxNode.js
packages/editor/CodeMirror/util/setupVim.js
@@ -612,6 +735,7 @@ packages/generator-joplin/generators/app/templates/api/noteListType.js
packages/generator-joplin/generators/app/templates/api/types.js
packages/generator-joplin/generators/app/templates/api_index.js
packages/generator-joplin/generators/app/templates/src/index.js
packages/generator-joplin/tools/updateCategories.js
packages/htmlpack/src/index.js
packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.js
@@ -651,15 +775,22 @@ packages/lib/commands/openMasterPasswordDialog.js
packages/lib/commands/synchronize.js
packages/lib/components/EncryptionConfigScreen/utils.js
packages/lib/components/shared/config/config-shared.js
packages/lib/components/shared/config/plugins/types.js
packages/lib/components/shared/config/plugins/useOnDeleteHandler.js
packages/lib/components/shared/config/plugins/useOnInstallHandler.test.js
packages/lib/components/shared/config/plugins/useOnInstallHandler.js
packages/lib/components/shared/config/shouldShowMissingPasswordWarning.test.js
packages/lib/components/shared/config/shouldShowMissingPasswordWarning.js
packages/lib/components/shared/note-screen-shared.js
packages/lib/components/shared/reduxSharedMiddleware.js
packages/lib/components/shared/side-menu-shared.test.js
packages/lib/components/shared/side-menu-shared.js
packages/lib/database-driver-better-sqlite.js
packages/lib/database.js
packages/lib/debug/DebugService.js
packages/lib/determineBaseAppDirs.js
packages/lib/dom.js
packages/lib/downloadController.js
packages/lib/errorUtils.js
packages/lib/errors.js
packages/lib/eventManager.js
@@ -676,6 +807,7 @@ packages/lib/geolocation-node.js
packages/lib/hooks/useAsyncEffect.js
packages/lib/hooks/useElementSize.js
packages/lib/hooks/useEventListener.js
packages/lib/hooks/usePrevious.js
packages/lib/htmlUtils.test.js
packages/lib/htmlUtils.js
packages/lib/htmlUtils2.test.js
@@ -720,11 +852,17 @@ packages/lib/models/Tag.test.js
packages/lib/models/Tag.js
packages/lib/models/dateTimeFormats.test.js
packages/lib/models/settings/FileHandler.js
packages/lib/models/settings/settingValidations.test.js
packages/lib/models/settings/settingValidations.js
packages/lib/models/utils/getCollator.js
packages/lib/models/utils/getConflictFolderId.js
packages/lib/models/utils/isItemId.js
packages/lib/models/utils/itemCanBeEncrypted.js
packages/lib/models/utils/onFolderDrop.test.js
packages/lib/models/utils/onFolderDrop.js
packages/lib/models/utils/paginatedFeed.js
packages/lib/models/utils/paginationToSql.js
packages/lib/models/utils/readOnly.test.js
packages/lib/models/utils/readOnly.js
packages/lib/models/utils/resourceUtils.js
packages/lib/models/utils/types.js
@@ -754,6 +892,7 @@ packages/lib/services/KvStore.js
packages/lib/services/MigrationService.js
packages/lib/services/NavService.js
packages/lib/services/PostMessageService.js
packages/lib/services/ReportService.test.js
packages/lib/services/ReportService.js
packages/lib/services/ResourceEditWatcher/index.js
packages/lib/services/ResourceEditWatcher/reducer.js
@@ -780,6 +919,8 @@ packages/lib/services/database/migrations/42.js
packages/lib/services/database/migrations/43.js
packages/lib/services/database/migrations/44.js
packages/lib/services/database/migrations/45.js
packages/lib/services/database/migrations/46.js
packages/lib/services/database/migrations/47.js
packages/lib/services/database/migrations/index.js
packages/lib/services/database/sqlStringToLines.js
packages/lib/services/database/types.js
@@ -819,6 +960,7 @@ packages/lib/services/interop/InteropService_Importer_Raw.js
packages/lib/services/interop/Module.test.js
packages/lib/services/interop/Module.js
packages/lib/services/interop/types.js
packages/lib/services/joplinCloudUtils.js
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
packages/lib/services/keychain/KeychainService.js
packages/lib/services/keychain/KeychainServiceDriver.dummy.js
@@ -827,6 +969,12 @@ packages/lib/services/keychain/KeychainServiceDriver.node.js
packages/lib/services/keychain/KeychainServiceDriverBase.js
packages/lib/services/noteList/defaultLeftToRightListRenderer.js
packages/lib/services/noteList/defaultListRenderer.js
packages/lib/services/noteList/defaultMultiColumnsRenderer.js
packages/lib/services/noteList/depNameToNoteProp.js
packages/lib/services/noteList/renderTemplate.test.js
packages/lib/services/noteList/renderTemplate.js
packages/lib/services/noteList/renderViewProps.test.js
packages/lib/services/noteList/renderViewProps.js
packages/lib/services/noteList/renderers.js
packages/lib/services/ocr/OcrDriverBase.js
packages/lib/services/ocr/OcrService.test.js
@@ -872,6 +1020,13 @@ packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js
packages/lib/services/plugins/reducer.js
packages/lib/services/plugins/utils/createViewHandle.js
packages/lib/services/plugins/utils/executeSandboxCall.js
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
packages/lib/services/plugins/utils/getPluginSettingValue.js
packages/lib/services/plugins/utils/isCompatible/index.test.js
packages/lib/services/plugins/utils/isCompatible/index.js
packages/lib/services/plugins/utils/isCompatible/minVersionForPlatform.js
packages/lib/services/plugins/utils/isCompatible/types.js
packages/lib/services/plugins/utils/loadContentScripts.js
packages/lib/services/plugins/utils/makeListener.js
packages/lib/services/plugins/utils/manifestFromObject.js
@@ -879,6 +1034,8 @@ packages/lib/services/plugins/utils/mapEventHandlersToIds.js
packages/lib/services/plugins/utils/types.js
packages/lib/services/plugins/utils/validatePluginId.test.js
packages/lib/services/plugins/utils/validatePluginId.js
packages/lib/services/plugins/utils/validatePluginPlatforms.test.js
packages/lib/services/plugins/utils/validatePluginPlatforms.js
packages/lib/services/plugins/utils/validatePluginVersion.test.js
packages/lib/services/plugins/utils/validatePluginVersion.js
packages/lib/services/profileConfig/index.test.js
@@ -894,6 +1051,7 @@ packages/lib/services/rest/actionApi.desktop.js
packages/lib/services/rest/routes/auth.js
packages/lib/services/rest/routes/events.test.js
packages/lib/services/rest/routes/events.js
packages/lib/services/rest/routes/folders.test.js
packages/lib/services/rest/routes/folders.js
packages/lib/services/rest/routes/master_keys.js
packages/lib/services/rest/routes/notes.test.js
@@ -925,6 +1083,7 @@ packages/lib/services/search/gotoAnythingStyleQuery.js
packages/lib/services/search/queryBuilder.js
packages/lib/services/share/ShareService.test.js
packages/lib/services/share/ShareService.js
packages/lib/services/share/invitationRespond.js
packages/lib/services/share/reducer.js
packages/lib/services/spellChecker/SpellCheckerService.js
packages/lib/services/spellChecker/SpellCheckerServiceDriverBase.js
@@ -962,8 +1121,22 @@ packages/lib/services/synchronizer/utils/handleSyncStartupOperation.js
packages/lib/services/synchronizer/utils/resourceRemotePath.js
packages/lib/services/synchronizer/utils/syncDeleteStep.js
packages/lib/services/synchronizer/utils/types.js
packages/lib/services/trash/emptyTrash.test.js
packages/lib/services/trash/emptyTrash.js
packages/lib/services/trash/getTrashFolderId.js
packages/lib/services/trash/index.test.js
packages/lib/services/trash/index.js
packages/lib/services/trash/isTrashableItem.js
packages/lib/services/trash/permanentlyDeleteOldItems.test.js
packages/lib/services/trash/permanentlyDeleteOldItems.js
packages/lib/services/trash/restoreItems.test.js
packages/lib/services/trash/restoreItems.js
packages/lib/shim-init-node.js
packages/lib/shim.js
packages/lib/string-utils.test.js
packages/lib/string-utils.js
packages/lib/testing/share/makeMockShareInvitation.js
packages/lib/testing/share/mockShareService.js
packages/lib/testing/syncTargetUtils.js
packages/lib/testing/test-utils-synchronizer.js
packages/lib/testing/test-utils.js
@@ -979,9 +1152,24 @@ packages/lib/themes/solarizedLight.js
packages/lib/themes/type.js
packages/lib/time.js
packages/lib/types.js
packages/lib/utils/ActionLogger.test.js
packages/lib/utils/ActionLogger.js
packages/lib/utils/credentialFiles.js
packages/lib/utils/focusHandler.js
packages/lib/utils/ipc/RemoteMessenger.test.js
packages/lib/utils/ipc/RemoteMessenger.js
packages/lib/utils/ipc/TestMessenger.js
packages/lib/utils/ipc/WindowMessenger.js
packages/lib/utils/ipc/types.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.test.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.test.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js
packages/lib/utils/userFetcher.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/utils/webDAVUtils.js
@@ -1049,6 +1237,7 @@ packages/renderer/MdToHtml/rules/link_open.js
packages/renderer/MdToHtml/rules/mermaid.js
packages/renderer/MdToHtml/rules/sanitize_html.js
packages/renderer/MdToHtml/rules/source_map.js
packages/renderer/MdToHtml/rules/tableHorizontallyScrollable.js
packages/renderer/MdToHtml/setupLinkify.js
packages/renderer/MdToHtml/validateLinks.js
packages/renderer/assetsToHeaders.js
@@ -1080,6 +1269,7 @@ packages/tools/packageJsonLint.js
packages/tools/postPreReleasesToForum.js
packages/tools/release-android.js
packages/tools/release-cli.js
packages/tools/release-clipper.js
packages/tools/release-electron.js
packages/tools/release-ios.js
packages/tools/release-plugin-repo-cli.js

View File

@@ -0,0 +1,33 @@
diff --git a/lib/runner/index.js b/lib/runner/index.js
index 87e3b3957619728e3ed1ca61e2d83df1c49f928f..6d5ab905415da0577341c8f5b67d4806adcf7549 100644
--- a/lib/runner/index.js
+++ b/lib/runner/index.js
@@ -68,15 +68,19 @@ function run([, scriptPath, hookName = '', HUSKY_GIT_PARAMS], getStdinFn = get_s
return 0;
}
catch (err) {
- const noVerifyMessage = [
- 'commit-msg',
- 'pre-commit',
- 'pre-rebase',
- 'pre-push'
- ].includes(hookName)
- ? '(add --no-verify to bypass)'
- : '(cannot be bypassed with --no-verify due to Git specs)';
- console.log(`husky > ${hookName} hook failed ${noVerifyMessage}`);
+ // We do not want to print this "add --no-verify to bypass" message because that's
+ // literally what some developers do instead of trying to fix the errors.
+
+ // const noVerifyMessage = [
+ // 'commit-msg',
+ // 'pre-commit',
+ // 'pre-rebase',
+ // 'pre-push'
+ // ].includes(hookName)
+ // ? '(add --no-verify to bypass)'
+ // : '(cannot be bypassed with --no-verify due to Git specs)';
+
+ console.log(`husky > ${hookName} hook failed (Please fix the errors listed above and try again)`);
return err.code;
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,4 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Sat, 27 Jan 2024 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Sat, 27 Jan 2024 00:00:00 GMT</pubDate><item><title><![CDATA[Support for new plugin metadata]]></title><description><![CDATA[<p>The plugin manifest now supports new properties to better describe and present your plugins on Joplin Plugins website. Those are the <code>icons</code>, <code>categories</code>, <code>screenshots</code> and <code>promo_tile</code> properties.</p>
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Fri, 01 Mar 2024 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Fri, 01 Mar 2024 00:00:00 GMT</pubDate><item><title><![CDATA[What's new in Joplin 2.14]]></title><description><![CDATA[<h2>OCR<a name="ocr" href="#ocr" class="heading-anchor">🔗</a></h2>
<p>Optical Character Recognition (OCR) in Joplin enables the transformation of text-containing images into machine-readable text formats. From this version you can enable OCR in the Configuration screen under the &quot;General&quot; section. Once activated, Joplin scans images and PDFs, extracting text data for searchability.</p>
<p>While OCR search is available on both desktop and mobile apps, document scanning is limited to the desktop due to resource demands. For more information head to the <a href="https://joplinapp.org/help/apps/ocr">OCR official documentation</a>!</p>
<h2>Bundled plugins<a name="bundled-plugins" href="#bundled-plugins" class="heading-anchor">🔗</a></h2>
<p>Joplin will now bundle high quality plugins that we feel will benefit most users. With this version we include the great <a href="https://github.com/JackGruber/joplin-plugin-backup">Backup plugin</a> by JackGruber. This will provide another layer of safety when using Joplin as by default it will automatically backup your notes in a &quot;JoplinBackup&quot; folder in your home directory.</p>
<p>Note that, just like any other plugin, you can change the plugin configuration or even disable it from the settings.</p>
<h2>ENEX importer<a name="enex-importer" href="#enex-importer" class="heading-anchor">🔗</a></h2>
<p>As usual in recent version, there are plenty of improvements to the <a href="https://joplinapp.org/help/apps/import_export#importing-from-evernote">Joplin ENEX importer</a>. Besides the various fixes and enhancement to support this format, we've added a few useful features:</p>
<h3>Restore note links after importing an ENEX file<a name="restore-note-links-after-importing-an-enex-file" href="#restore-note-links-after-importing-an-enex-file" class="heading-anchor">🔗</a></h3>
<p>Evernote Export files do not include the necessary information to reliably restore the links between notes, so for a long time this feature was not supported by the importer.</p>
<p>Now however Joplin will try to guess what note is linked to what other note based on the note title, which in many cases will give the expected result. But not always - when that happens, and Joplin cannot detect the link target, the application leaves the original Evernote link. That way you can manually restore it yourself or at least find back what the note was linked to.</p>
<h3>Import a directory of ENEX files<a name="import-a-directory-of-enex-files" href="#import-a-directory-of-enex-files" class="heading-anchor">🔗</a></h3>
<p>It is notoriously difficult to export data from Evernote because, among other issues, you can only export one notebook at a time, which is an obvious problems when you have dozens of notebooks. Unfortunately we cannot improve this part of the process since this up to Evernote, however we now make it easier to import all these notebook files by adding support for importing a folder of ENEX files. To use this feature, go to File &gt; Import, and select one of the &quot;ENEX (Directory)&quot; options.</p>
<p>This will process all the ENEX files in that directory and create a notebook in Joplin for each of them.</p>
<h2>Beta Markdown editor<a name="beta-markdown-editor" href="#beta-markdown-editor" class="heading-anchor">🔗</a></h2>
<p>This version features further improvements to the new Markdown editor based on <a href="https://codemirror.net/">CodeMirror 6</a>. The goal eventually is to be able to use the same editor on both the desktop and mobile application (which already uses CodeMirror 6), which will allow a more consistent user experience across devices.</p>
<p>Plugin support has also been improved in this version - plugin authors can now write native CodeMirror 6 extensions using the plugin API. For more information check the documentation on <a href="https://joplinapp.org/help/api/tutorials/cm6_plugin/">how to create a Markdown plugin</a>!</p>
<p>Another benefit of this new editor is that, in a future version, it will allow us to support plugins on the mobile application since a plugin written for the desktop app will work on mobile too. There are several other advantages that Henry <a href="https://discourse.joplinapp.org/t/pre-release-v2-13-is-now-available-updated-18-11-2023/32697/12?u=laurent">listed in this forum post</a>.</p>
<h2>Rich text editor improvements<a name="rich-text-editor-improvements" href="#rich-text-editor-improvements" class="heading-anchor">🔗</a></h2>
<p>We continue making improvements to the Rich Text Editor (RTE) in particular to improve interoperability with other applications, such as LibreOffice, Office or web browsers, as well as better handling of copy and paste.</p>
<p>Another notable addition is support for setting colours, which was a frequently asked feature. To use the feature, select it from the &quot;...&quot; button in the toolbar. Note that once applied the colours will work in the Markdown editor too!</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20240301-rte-colors.png" alt=""></p>
<p>See below for the full list of RTE changes:</p>
<ul>
<li>Fixed: Rich text editor: Fix context menu not shown in some cases</li>
<li>Improved: Speed up pasting text and images in Rich Text Editor</li>
<li>Fixed: Fix drag-and-drop of images and text in the rich text editor</li>
<li>Fixed: Fix images with SVG data URLs corrupted in the rich text editor</li>
<li>Fixed: Pasting rich text in the RTE sometimes result in invalid markup</li>
<li>Fixed: Rich text editor: Fix newline behavior in new notes</li>
<li>Improved: Add support for changing text colors in rich text editor</li>
<li>Fixed: Fix HTML resource links lost when editing notes in the rich text editor</li>
<li>Fixed: Fix code blocks with blank lines break tables in the rich text editor</li>
<li>Fixed: Copied and pasted text from Firefox to RTE does not include images</li>
<li>Fixed: Pasting rich text in the RTE sometimes result in invalid markup</li>
<li>Fixed: Fixed copying and pasting an image from Chrome in RTE</li>
</ul>
<h1>Full changelog<a name="full-changelog" href="#full-changelog" class="heading-anchor">🔗</a></h1>
<p>This is just an overview of the main features. The full changelog is available there:</p>
<ul>
<li>Desktop: <a href="https://joplinapp.org/help/about/changelog/desktop">https://joplinapp.org/help/about/changelog/desktop</a></li>
<li>Android: <a href="https://joplinapp.org/help/about/changelog/android/">https://joplinapp.org/help/about/changelog/android/</a></li>
<li>iOS: <a href="https://joplinapp.org/help/about/changelog/ios/">https://joplinapp.org/help/about/changelog/ios/</a></li>
</ul>
]]></description><link>https://joplinapp.org/news/20240301-release-2-14</link><guid isPermaLink="false">20240301-release-2-14</guid><pubDate>Fri, 01 Mar 2024 00:00:00 GMT</pubDate><twitter-text>What&apos;s new in Joplin 2.14</twitter-text></item><item><title><![CDATA[Support for new plugin metadata]]></title><description><![CDATA[<p>The plugin manifest now supports new properties to better describe and present your plugins on Joplin Plugins website. Those are the <code>icons</code>, <code>categories</code>, <code>screenshots</code> and <code>promo_tile</code> properties.</p>
<h2>Icon<a name="icon" href="#icon" class="heading-anchor">🔗</a></h2>
<p>This is the icon that will be used in various plugin pages, including in your main plugin page. It will be shown on the main result page too. If not provided, a default icon will be displayed instead.</p>
<h2>Category<a name="category" href="#category" class="heading-anchor">🔗</a></h2>
@@ -353,15 +397,4 @@ sys 0m38.013s</p>
]]></description><link>https://joplinapp.org/news/20220522-gsoc-contributors</link><guid isPermaLink="false">20220522-gsoc-contributors</guid><pubDate>Sun, 22 May 2022 00:00:00 GMT</pubDate><twitter-text>Joplin received 6 Contributor Projects for GSoC 2022! Welcome to our new contributors who will be working on these projects over summer!</twitter-text></item><item><title><![CDATA[GSoC "Contributor Proposals" phase is starting now!]]></title><description><![CDATA[<p>The &quot;Contributor Proposals&quot; phase of GSoC 2022 is starting today! If you would like to be a contributor, now is the time to choose your project idea, write your proposal, and upload it to <a href="https://summerofcode.withgoogle.com/">https://summerofcode.withgoogle.com/</a></p>
<p>When it's done, please also let us know by posting an update on your forum introduction post.</p>
<p>If you haven't created a pull request yet, it's still time to create one. Doing so will greatly increase your chances of being selected!</p>
]]></description><link>https://joplinapp.org/news/20220405-gsoc-contributor-proposals</link><guid isPermaLink="false">20220405-gsoc-contributor-proposals</guid><pubDate>Tue, 05 Apr 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin participates in Google Summer of Code 2022!]]></title><description><![CDATA[<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220308-gsoc-banner.png" alt=""></p>
<p>For the third year, Joplin has been selected as a <strong>Google Summer of Code</strong> mentor organisation! We look forward to start working with the contributors on some great new projects. This year's main themes are:</p>
<ul>
<li><strong>Mobile and tablet development</strong> - we want to improve the mobile/tablet application on iOS and Android.</li>
<li><strong>Plugin and external apps</strong> - leverage the Joplin API to create plugins and external apps.</li>
<li>And of course contributors are welcome to suggest their own ideas.</li>
</ul>
<p>Our full idea list is available here: <a href="https://joplinapp.org/help/dev/gsoc/gsoc2022/ideas">GSoC 2022 idea list</a></p>
<p>In the coming month (<strong>March 7 - April 3</strong>), contributors will start getting involved in the forum and start discussing project ideas with the mentors and community. It's also a good time to start looking at Joplin's source code, perhaps work on fixing bugs or implement small features to get familiar with the source code, and to show us your skills.</p>
<p>One difference with previous years is that anyone, not just students, are allowed to participate.</p>
<p>Additionally, last year Google only allowed smaller projects, while this year they allow again small and large projects, so we've indicated this in the idea list - the small ones are <strong>175 hours</strong>, and the large ones <strong>350 hours</strong>.</p>
]]></description><link>https://joplinapp.org/news/20220308-gsoc2022-start</link><guid isPermaLink="false">20220308-gsoc2022-start</guid><pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
]]></description><link>https://joplinapp.org/news/20220405-gsoc-contributor-proposals</link><guid isPermaLink="false">20220405-gsoc-contributor-proposals</guid><pubDate>Tue, 05 Apr 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>

View File

@@ -31,7 +31,7 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
# Sponsors
<!-- SPONSORS-ORG -->
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&amp;mtm_kwd=joplinapp&amp;mtm_source=joplinapp-webseite&amp;mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a> <a href="https://citricsheep.com"><img title="Citric Sheep" width="256" src="https://joplinapp.org/images/sponsors/CitricSheep.png"/></a> <a href="https://sorted.travel/?utm_source=joplinapp "><img title="Sorted Travel" width="256" src="https://joplinapp.org/images/sponsors/SortedTravel.png"/></a> <a href="https://celebian.com "><img title="Celebian" width="256" src="https://joplinapp.org/images/sponsors/Celebian.png"/></a>
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&amp;mtm_kwd=joplinapp&amp;mtm_source=joplinapp-webseite&amp;mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a> <a href="https://citricsheep.com"><img title="Citric Sheep" width="256" src="https://joplinapp.org/images/sponsors/CitricSheep.png"/></a> <a href="https://sorted.travel/?utm_source=joplinapp"><img title="Sorted Travel" width="256" src="https://joplinapp.org/images/sponsors/SortedTravel.png"/></a> <a href="https://celebian.com"><img title="Celebian" width="256" src="https://joplinapp.org/images/sponsors/Celebian.png"/></a> <a href="https://bestkru.com"><img title="BestKru" width="256" src="https://joplinapp.org/images/sponsors/BestKru.png"/></a>
<!-- SPONSORS-ORG -->
* * *
@@ -39,11 +39,12 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
<!-- SPONSORS-GITHUB -->
| | | | |
| :---: | :---: | :---: | :---: |
| <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[avanderberg](https://github.com/avanderberg) | <img width="50" src="https://avatars2.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) | <img width="50" src="https://avatars2.githubusercontent.com/u/2793530?s=96&v=4"/></br>[CyberXZT](https://github.com/CyberXZT) | <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[dbrandonjohnson](https://github.com/dbrandonjohnson) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/14873877?s=96&v=4"/></br>[dchecks](https://github.com/dchecks) | <img width="50" src="https://avatars2.githubusercontent.com/u/56287?s=96&v=4"/></br>[fats](https://github.com/fats) | <img width="50" src="https://avatars2.githubusercontent.com/u/8030470?s=96&v=4"/></br>[Galliver7](https://github.com/Galliver7) | <img width="50" src="https://avatars2.githubusercontent.com/u/64712218?s=96&v=4"/></br>[Hegghammer](https://github.com/Hegghammer) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/1310474?s=96&v=4"/></br>[jknowles](https://github.com/jknowles) | <img width="50" src="https://avatars2.githubusercontent.com/u/11947658?s=96&v=4"/></br>[KentBrockman](https://github.com/KentBrockman) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/126279083?s=96&v=4"/></br>[matmoly](https://github.com/matmoly) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/4560672?s=96&v=4"/></br>[mu88](https://github.com/mu88) | <img width="50" src="https://avatars2.githubusercontent.com/u/31054972?s=96&v=4"/></br>[saarantras](https://github.com/saarantras) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/327998?s=96&v=4"/></br>[sif](https://github.com/sif) | <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) | <img width="50" src="https://avatars2.githubusercontent.com/u/333944?s=96&v=4"/></br>[tateisu](https://github.com/tateisu) | |
| <img width="50" src="https://avatars2.githubusercontent.com/u/97193607?s=96&v=4"/></br>[Akhil-CM](https://github.com/Akhil-CM) | <img width="50" src="https://avatars2.githubusercontent.com/u/552452?s=96&v=4"/></br>[andypiper](https://github.com/andypiper) | <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[avanderberg](https://github.com/avanderberg) | <img width="50" src="https://avatars2.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/2793530?s=96&v=4"/></br>[CyberXZT](https://github.com/CyberXZT) | <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[dbrandonjohnson](https://github.com/dbrandonjohnson) | <img width="50" src="https://avatars2.githubusercontent.com/u/14873877?s=96&v=4"/></br>[dchecks](https://github.com/dchecks) | <img width="50" src="https://avatars2.githubusercontent.com/u/56287?s=96&v=4"/></br>[fats](https://github.com/fats) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/8030470?s=96&v=4"/></br>[Galliver7](https://github.com/Galliver7) | <img width="50" src="https://avatars2.githubusercontent.com/u/64712218?s=96&v=4"/></br>[Hegghammer](https://github.com/Hegghammer) | <img width="50" src="https://avatars2.githubusercontent.com/u/2583421?s=96&v=4"/></br>[jamesandariese](https://github.com/jamesandariese) | <img width="50" src="https://avatars2.githubusercontent.com/u/1310474?s=96&v=4"/></br>[jknowles](https://github.com/jknowles) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/11947658?s=96&v=4"/></br>[KentBrockman](https://github.com/KentBrockman) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) | <img width="50" src="https://avatars2.githubusercontent.com/u/126279083?s=96&v=4"/></br>[matmoly](https://github.com/matmoly) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/4560672?s=96&v=4"/></br>[mu88](https://github.com/mu88) | <img width="50" src="https://avatars2.githubusercontent.com/u/31054972?s=96&v=4"/></br>[saarantras](https://github.com/saarantras) | <img width="50" src="https://avatars2.githubusercontent.com/u/327998?s=96&v=4"/></br>[sif](https://github.com/sif) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) | <img width="50" src="https://avatars2.githubusercontent.com/u/333944?s=96&v=4"/></br>[tateisu](https://github.com/tateisu) | | |
<!-- SPONSORS-GITHUB -->
# Community

View File

@@ -1,7 +1,13 @@
{
"version": "0.2",
"language": "en_GB",
"ignoreRegExpList": [
"\\[.*?\\]\\(https:\\/\\/github.com\\/.*?\\)",
"by .*?\\)",
"\\| (.*?) \\| \\d+%"
],
"ignorePaths": [
"**/*.d.ts",
"**/*.min.*",
"**/*.svg",
"/_mydocs",
@@ -11,7 +17,10 @@
"/Assets",
"/packages/app-cli/app/fuzzing.js",
"/packages/app-cli/build",
"/packages/app-cli/tests/enex_to_md/",
"/packages/app-cli/tests/html_to_md/",
"/packages/app-cli/tests/support",
"/packages/app-cli/tests/sync",
"/packages/app-cli/tests/test data",
"/packages/app-cli/tests/tmp",
"/packages/app-clipper/content_scripts/JSDOMParser.js",
@@ -20,14 +29,24 @@
"/packages/app-clipper/popup/build/js/0.chunk.js",
"/packages/app-clipper/popup/build/js/bundle.js",
"/packages/app-clipper/popup/build/js/main.chunk.js",
"/packages/app-clipper/popup/build/js/main.chunk.js",
"/packages/app-clipper/popup/config",
"/packages/app-desktop/build/",
"/packages/app-desktop/utils/checkForUpdatesUtilsTestData.ts",
"/packages/app-desktop/vendor/",
"/packages/app-mobile/ios/Pods/",
"/packages/app-mobile/lib/rnInjectedJs",
"/packages/app-mobile/pluginAssets",
"/packages/app-mobile/utils/fs-driver/runOnDeviceTests.ts",
"/packages/default-plugins/plugin-sources/",
"/packages/doc-builder/build",
"/packages/doc-builder/help/",
"/packages/doc-builder/i18n/",
"/packages/doc-builder/news/",
"/packages/fork-sax/examples",
"/packages/fork-sax/lib/sax.js",
"/packages/fork-sax/test",
"/packages/fork-uslug",
"/packages/generator-joplin/generators/app/templates/api/",
"/packages/lib/locales",
"/packages/lib/mime-utils-types.js",
"/packages/lib/parameters.js",
@@ -36,919 +55,38 @@
"/packages/lib/services/joplinServer/personalizedUserContentBaseUrl.ts",
"/packages/lib/vendor",
"/packages/lib/welcomeAssets.js",
"/packages/renderer/highlight.ts",
"/packages/server/src/utils/testing/randomWords.ts",
"/packages/turndown-plugin-gfm/config",
"/packages/turndown/config",
"/readme/_i18n",
"/readme/about/changelog/desktop.md",
"/readme/i18n",
"cspell.json",
"node_modules"
],
"words": [
"aàáâãäåāą",
"AÀÁÂÃÄÅĀĄ",
"abbrev",
"ABCDEFGHIJ",
"Abhishek",
"Abkhazian",
"accel",
"accum",
"actualkeyword",
"adata",
"advlist",
"AGSFE",
"Aland",
"Åland",
"alertbanner",
"Allaire",
"alse",
"altool",
"aman",
"ambrt",
"Amharic",
"amothc",
"andrejilderda",
"anki",
"Antarctique",
"antarctiques",
"Antártico",
"anymore",
"apidoc",
"appiconset",
"applewebkit",
"approot",
"arableague",
"Aragonés",
"ARITIM",
"armeabi",
"asterix",
"atest",
"atestb",
"attribname",
"attribvalue",
"authcode",
"autocompleteitem",
"autocompleter",
"Autocompleter",
"AUTOEXEC",
"autohide",
"Avenir",
"Ayiti",
"azamah",
"Azərbaycan",
"backoff",
"Bangla",
"Bêafrîka",
"beforeinput",
"België",
"Belgien",
"Belgique",
"Bénin",
"Bhutani",
"bibtex",
"Bihari",
"Bislama",
"blabla",
"blablablabla",
"boohay",
"Bosna",
"Bouvet",
"Bouvetøya",
"browserslist",
"bthqu",
"btns",
"Bulibiya",
"bullist",
"bulma",
"Byelorussian",
"calebjohn",
"Calédonie",
"Caligraphic",
"callsites",
"Cameroun",
"cantdothat",
"Capslock",
"cardcontainer",
"cardimage",
"cardmenuitem",
"cardtext",
"Caribisch",
"CAUTOEXEC",
"cçćč",
"CÇĆČ",
"cdataend",
"cdatastart",
"cdot",
"ceaf",
"centrafricaine",
"Centrafrican",
"Česká",
"changedtitle",
"charcodes",
"checkboxclick",
"checkmark",
"chemfive",
"choiceitem",
"chromedriver",
"chromeframe",
"chromeos",
"Città",
"Cmds",
"codepoint",
"colorinput",
"colorpicker",
"colorswatch",
"colspan",
"committerdate",
"commmmmand",
"commonmark",
"COMMONMARK",
"Comores",
"compositionend",
"compositionstart",
"compositionupdate",
"conflicter",
"contenteditable",
"contextform",
"contextformbutton",
"contextformtogglebutton",
"contextkey",
"contexttoolbar",
"continuelist",
"Contrl",
"Conv",
"convo",
"copytags",
"cozic",
"Cozic",
"createdb",
"Creds",
"Crna",
"cronspec",
"cros",
"crypted",
"Curaçao",
"curso",
"customeditor",
"customkeymap",
"cyingfan",
"d'Ivoire",
"Danmark",
"Dansk",
"dataimg",
"datauri",
"Datauri",
"datetime",
"Datetime",
"davris",
"dbuuid",
"DDTHH",
"deflist",
"deinit",
"Démocratique",
"deselector",
"deuxième",
"dflt",
"dialogbox",
"dialogs",
"Dialogs",
"DIALOGS",
"Distill",
"dists",
"docid",
"docsize",
"doctypes",
"doesnotwork",
"doesntexist",
"doesntlookright",
"domelementtype",
"domhandler",
"Dominicana",
"domutils",
"DONATELINKS",
"downarrow",
"dragdrop",
"draggesture",
"dünn",
"dylib",
"dynamiclib",
"ecuatorial",
"eèéêëěēę",
"EÈÉÊËĚĒĘ",
"Eesti",
"effet",
"efgh",
"égalité",
"Éire",
"elem",
"elementpath",
"elems",
"ellipsize",
"ELOCKED",
"encryptable",
"endregion",
"enex",
"Enex",
"ENEX",
"enumber",
"eqeqeq",
"équatoriale",
"Erro",
"errorish",
"escapeplus",
"eslintignore",
"España",
"étiquette",
"EUNSPECIFIED",
"eventname",
"evermeet",
"evernote",
"Evernote",
"execa",
"expando",
"expirable",
"Expirable",
"expval",
"Færøerne",
"Fahrräder",
"FAILSAFE",
"fallbacks",
"fancymenuitem",
"fancytype",
"favorites",
"Fiber",
"filepicker",
"folderid",
"foldl",
"fontawesome",
"fontface",
"forall",
"forcewake",
"Føroyar",
"fortawesome",
"française",
"françaises",
"Gabuutih",
"gedit",
"geoip",
"Geoip",
"geoloc",
"geoplugin",
"getlastmodified",
"gettext",
"githubusercontent",
"Gora",
"gotchas",
"gradlew",
"Grønland",
"grouptoolbarbutton",
"Gruber",
"gsoc",
"gttest",
"Guåhån",
"guarentee",
"guarentees",
"Guiena",
"Guiné",
"Guinée",
"gulpfile",
"Guyane",
"gvim",
"Haïti",
"hanlder",
"Hausa",
"headerless",
"Heisenbug",
"Hercegovina",
"hift",
"highjack",
"highlited",
"historyhas",
"HMRKG",
"hoge",
"homenote",
"hotfolder",
"Howver",
"hpagent",
"Hrvatska",
"htmlentities",
"htmlfile",
"htmlpack",
"htmlpanel",
"ʻĀirani",
"icns",
"iconset",
"iconutil",
"Iforgot",
"iframes",
"ihack",
"iife",
"iìíîïī",
"IÌÍÎÏĪ",
"ijkl",
"imagelink",
"imagetools",
"immer",
"iname",
"Incl",
"infint",
"inflim",
"infty",
"inputi",
"inserttable",
"Interlingue",
"Interp",
"interupting",
"Inteval",
"Inuktitut",
"Inupiak",
"Invididual",
"IOERR",
"Ionicons",
"IPHONEOS",
"ipify",
"ipwhois",
"iscompleted",
"Ísland",
"Italiano",
"Itoophiyaa",
"itsgone",
"itunes",
"Jabuuti",
"jackgruber",
"joeattardi",
"jopext",
"joplinapp",
"JOPLINAPP",
"joplincloud",
"joplindev",
"JOPLINMOD",
"joplintest",
"jsbundles",
"justtesting",
"Kalaallit",
"kalba",
"kanban",
"Kashmiri",
"katex",
"keychain",
"keycodes",
"keymaps",
"keytar",
"Kibris",
"Kinyarwanda",
"Kirundi",
"Ködörösêse",
"Komori",
"Kpck",
"Kūki",
"Laothian",
"lastmod",
"Latvija",
"lcov",
"leaft",
"leftarrow",
"leftequilibrium",
"leftrightarrow",
"Lettish",
"Lëtzebuerg",
"Levithan",
"Liban",
"libz",
"Lietuva",
"Lietuvių",
"lineheight",
"Lingala",
"linkg",
"linkurl",
"listbox",
"listfile",
"listpreview",
"loglevel",
"longclick",
"longpress",
"longpresscancel",
"looooooong",
"ltrim",
"Luxemburg",
"Maarten",
"Madagasikara",
"Magyarország",
"majax",
"Mardown",
"markdowncalc",
"Maroc",
"MASTERKEY",
"matchinfo",
"mathchoice",
"mathjax",
"Mathjax",
"MATHJAX",
"mathllap",
"mathml",
"mathrlap",
"mathrm",
"Mauritanie",
"Maxiumm",
"Mayen",
"mchem",
"mechanim",
"mediumtext",
"menubutton",
"mergeff",
"Metadatas",
"México",
"mhchem",
"middlewares",
"migth",
"mkbook",
"MKCOL",
"mkdirp",
"mknote",
"mktodo",
"MMYY",
"modifié",
"monokai",
"MONOSPACE",
"msgctxt",
"msgfmt",
"msgmerge",
"msgstr",
"msleep",
"mtext",
"mult",
"multicursor",
"multimarkdown",
"multimd",
"multistatus",
"multitable",
"mybucket",
"mydir",
"myfile",
"mynote",
"myplugin",
"mytag",
"mytaga",
"mytagb",
"mytagc",
"mytagd",
"mytest",
"mytoken",
"myvalue",
"nanoid",
"Neaus",
"Nederlands",
"nestedmenuitem",
"newone",
"Nextcloud",
"njstrace",
"nñňń",
"NÑŇŃ",
"NOCASE",
"nodechange",
"nodir",
"noexpand",
"nojs",
"nolongershared",
"nonlatin",
"NONLATIN",
"Noreg",
"Norge",
"nospecialcharacters",
"notanumber",
"notarization",
"notetags",
"Notif",
"notindexed",
"notthere",
"nounce",
"Nounce",
"Nounces",
"npmignore",
"numadd",
"numbersareok",
"numdec",
"numdiv",
"numlist",
"Numlock",
"nummult",
"numsub",
"Nunaat",
"obelix",
"odata",
"ohno",
"OHNO",
"oldppk",
"onattribdata",
"onattribend",
"onattribname",
"onattribute",
"oncdata",
"oncdataend",
"oncdatastart",
"onclosetag",
"oncomment",
"oncommentend",
"ondeclaration",
"onedrive",
"onelink",
"onformat",
"onmatch",
"onopentag",
"onopentagend",
"onopentagname",
"onparserinit",
"onprocessinginstruction",
"onselfclosingtag",
"ontext",
"oòóôõöøō",
"OÒÓÔÕÖØŌ",
"opentag",
"opentagname",
"Opptionn",
"orignal",
"Oromo",
"Österreich",
"otherpackage",
"outdented",
"overidding",
"overriden",
"padd",
"pandoc",
"paperclip",
"passthrough",
"Päth",
"Pbuild",
"pbxproj",
"pcmag",
"pcnalx",
"pddv",
"Pehr",
"Percents",
"père",
"Perú",
"pfff",
"PGPASSWORD",
"pidfile",
"PLUGINLEGACY",
"pocount",
"Polska",
"Polski",
"Polynésie",
"Português",
"Potoczny's",
"powerpoint",
"Prakash",
"precommit",
"pred",
"preg",
"prerelease",
"Prerelease",
"presigner",
"prettycron",
"pricetag",
"Príncipe",
"privkey",
"processinginstruction",
"programatically",
"propfind",
"PROPFIND",
"propname",
"propstat",
"protcol",
"pseudoclass",
"pseudos",
"Pushto",
"quot",
"qwer",
"raisebox",
"rbga",
"readerable",
"Readerable",
"READERABLE",
"Redownload",
"reencrypt",
"reencrypted",
"Reencrypting",
"reencrypts",
"regexes",
"Regexs",
"Relavent",
"relayouted",
"rels",
"renamings",
"renderered",
"Renderered",
"República",
"republika",
"République",
"requestheaders",
"resourcetype",
"resynced",
"Rhaeto",
"rightarrow",
"rightequilibrium",
"rightleftarrows",
"rightleftharpoons",
"rmbook",
"rmnote",
"rmusin",
"rnfs",
"RNFS",
"robocopy",
"Roboto",
"România",
"roule",
"rowid",
"ROWID",
"ROWIDs",
"rowspan",
"rseidelsohn",
"rtrim",
"safeext",
"salut",
"Sangho",
"sasss",
"SAVEPOINT",
"schtroumpf",
"Schweiz",
"Scrolllock",
"scrollmap",
"seafdav",
"Seafile",
"searchengine",
"searchlimit",
"SEARCHOVERLAY",
"securerandom",
"segdir",
"selectbox",
"Sénégal",
"Serializers",
"setext",
"settingschema",
"shantanugoel",
"sharee",
"Shiftt",
"Shoft",
"shouldntendwithit",
"shouldstartwiththis",
"Shqip",
"Shqipëria",
"Sicen",
"simplemath",
"Siswati",
"sizeinput",
"SJCL",
"Slovenčina",
"Slovenija",
"Slovensko",
"softbreaks",
"Solarised",
"SOLARIZED",
"someid",
"somewhereelse",
"sourceurl",
"SPACEBAR",
"spaceno",
"Spacify",
"spdfgh",
"spellfix",
"sphemy",
"splitbutton",
"sprintf",
"sqlts",
"srcfolder",
"SSSZ",
"starttls",
"Starttls",
"stepsize",
"stevenlevithan",
"stex",
"stilltryingtohack",
"strack",
"Stringifiable",
"subdir",
"subl",
"Suomi",
"Sūriyya",
"Svenska",
"Sverige",
"svgs",
"Svizra",
"Svizzera",
"synclock",
"synclog",
"syswide",
"syswidecas",
"taboverride",
"tabpanel",
"taga",
"tagb",
"tagc",
"Tajik",
"takesover",
"targetfolder",
"Tchad",
"Teardown",
"termi",
"termutils",
"Terres",
"Tessarek",
"tessus",
"Testb",
"testcreate",
"testexportfolder",
"testingconnection",
"testingkeychain",
"testunit",
"texify",
"Texify",
"textareas",
"textexportnote",
"textstyle",
"thaaaaaaan",
"thatsok",
"thatsreallylongthatsreallylongthatsreallylongthats",
"thatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylong",
"Thevenard",
"thisisfine",
"Thmmss",
"Tiếng",
"Tigrinya",
"tiiitlllle",
"tinymce",
"titi",
"titletitle",
"tkwidget",
"tkwidgets",
"Todos",
"togglebutton",
"togglemenuitem",
"toolip",
"tooshort",
"treymo",
"tripledash",
"tsmerge",
"Tsonga",
"tttest",
"Tunisie",
"Türkçe",
"Türkiye",
"Türkmenistan",
"turndown",
"Turndown",
"TWCO",
"typeahead",
"Typora",
"tzip",
"uastring",
"uglifycss",
"uglifyjs",
"Uighur",
"unconflicted",
"underbrace",
"Undos",
"unescaping",
"unhighlighted",
"unixlike",
"unmocked",
"unserialize",
"unserialized",
"unserializes",
"unserializing",
"unshares",
"unsharing",
"unusued",
"uparrow",
"uphy",
"urlconverter",
"urlinput",
"userchrome",
"usercontent",
"userstyle",
"uslug",
"Ustd",
"utems",
"uuidgen",
"uuidv",
"uùúûüůū",
"UÙÚÛÜŮŪ",
"valign",
"Valign",
"vars",
"Vars",
"Vaticano",
"vers",
"verylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongid",
"veryverylongclientidveryverylongclientidveryverylongclientidveryverylongclientid",
"veryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitle",
"Việt",
"viewbox",
"Volapuk",
"Volívia",
"votearrow",
"webclipper",
"webdav",
"webfonts",
"whitespaces",
"widder",
"Wifi",
"Withflags",
"Wolof",
"WONTFIX",
"wrongclienttype",
"wrongpassword",
"wrongtype",
"Wuliwya",
"wxyz",
"xcallbackurl",
"xcassets",
"xcodeproj",
"xcrun",
"xgettext",
"xlink",
"xzvf",
"yarg",
"yosay",
"yufzkns",
"YYYYMMDDTHH",
"zxcvbn",
"zžżź",
"ZŽŻŹ",
"Ελλάδα",
"Ελληνικά",
"Κύπρος",
"Агентство",
"Антарктике",
"Беларусь",
"България",
"Гора",
"језик",
"Казахстан",
"Киргизия",
"Книги",
"Кыргызстан",
"Қазақстан",
"Македонија",
"Молдавия",
"Монгол",
"номер",
"рейтер",
"Рейтер",
"Россия",
"Русский",
"Северна",
"сообщило",
"СООБЩИЛО",
"Србија",
"српски",
"Україна",
"Црна",
"საქართველო",
"Հայաստան",
"ישראל",
"עיברית",
"إرتريا",
"اسلامي",
"اسلامی",
"افغانستان",
"الأُرْدُن",
"الإمارات",
"البحرين",
"الجزائر",
"السعودية",
"السودان",
"الصومال",
"العراق",
"العربيّة",
"ﺍﻟﻘﻤﺮي",
"الكويت",
"المتّحدة",
"المغرب",
"اليَمَن",
"ایران",
"پاکستان",
"تشاد",
"تونس",
"جمهوری",
"جيبوتي",
"دولة",
"دولتدولت",
"سلطنة",
"سوريا",
"عُمان",
"لبنان",
"ليبيا",
"موريتانيا",
"ⵍⵎⵖⵔⵉⴱ",
"ኢትዮጵያ",
"ኤርትራ",
"भारत",
"গণপ্রজাতন্ত্রী",
"লাদেশ",
"இலங்கை",
"ලංකා",
"คือค",
"คือคนไทย",
"ประเทศไทย",
"ປະຊາຊົນລາວ",
"မြန်မာ",
"កម្ពុជា"
]
"dictionaryDefinitions": [
{
"name": "dictionary1",
"path": "packages/tools/cspell/dictionary1.txt"
},
{
"name": "dictionary2",
"path": "packages/tools/cspell/dictionary2.txt"
},
{
"name": "dictionary3",
"path": "packages/tools/cspell/dictionary3.txt"
},
{
"name": "dictionary4",
"path": "packages/tools/cspell/dictionary4.txt"
}
],
"dictionaries": [
"dictionary1",
"dictionary2",
"dictionary3",
"dictionary4"
]
}

View File

@@ -14,3 +14,22 @@ module.exports = () => {
global.console = jestConsole;
});
};
// jsdom extensions
if (typeof document !== 'undefined') {
// Prevents the CodeMirror error "getClientRects is undefined".
// See https://github.com/jsdom/jsdom/issues/3002#issue-652790925
document.createRange = () => {
const range = new Range();
range.getBoundingClientRect = jest.fn();
range.getClientRects = () => {
return {
length: 0,
item: () => null,
[Symbol.iterator]: jest.fn(),
};
};
return range;
};
}

View File

@@ -186,6 +186,8 @@
"packages/doc-builder/help": true,
"packages/doc-builder/news": true,
"packages/doc-builder/i18n": true,
"packages/doc-builder/.docusaurus": true,
"packages/doc-builder/static/images": true,
"readme/i18n": true,
"packages/app-cli/**/*.*~": true,
"packages/app-cli/**/*.mo": true,

View File

@@ -1,19 +1,27 @@
module.exports = {
// Don't compile when committing as it will process all TS files in the
// monorepo, which is too slow. Errors should be checked during development
// using `npm run watch`.
// # About TypeScript compilation
//
// Don't compile when committing as it will process all TS files in the monorepo, which is too
// slow. Errors should be checked during development using `yarn watch`.
//
// Or if we add this back, we could do something like this:
// https://stackoverflow.com/a/44748041/561309
//
// The script would check where the TS file is located, then use the right
// tsconfig.json file along with the tsconfig override.
// The script would check where the TS file is located, then use the right tsconfig.json file
// along with the tsconfig override.
//
// '**/*.ts?(x)': () => 'npm run tsc',
'*.{js,jsx,ts,tsx}': [
'yarn checkIgnoredFiles',
// 'yarn checkLibPaths',
'yarn packageJsonLint',
'yarn linter-precommit',
],
// # Running tasks in parallel
//
// lint-staged does not allow running concurrent tasks for the same extension, because multiple
// tasks might modify the same files. This doesn't apply to us because only one task modifies
// files (the linter task) while others only notify about errors. So to go around this we add
// this fake extension "task?" to make lint-staged think those are different extension tasks
// that can run in parallel.
//
// See https://github.com/lint-staged/lint-staged/issues/934#issuecomment-743299357
'*.{js,jsx,ts,tsx,task1}': 'yarn checkIgnoredFiles',
'*.{js,jsx,ts,tsx,task2}': 'yarn spellcheck',
'*.{js,jsx,ts,tsx,task3}': 'yarn packageJsonLint',
'*.{js,jsx,ts,tsx,task4}': 'yarn linter-precommit',
'*.{md,mdx}': 'yarn spellcheck',
};

View File

@@ -29,7 +29,6 @@
"crowdin": "crowdin",
"crowdinDownload": "crowdin download",
"crowdinUpload": "crowdin upload",
"cspell": "cspell",
"dependencyTree": "madge",
"generateTypes": "node packages/tools/generate-database-types",
"linkChecker": "linkchecker https://joplinapp.org/ && linkchecker --check-extern https://joplinapp.org/api/references/plugin_api/classes/joplin.html",
@@ -65,7 +64,7 @@
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
"pre-commit": "yarn lint-staged"
}
},
"devDependencies": {
@@ -97,7 +96,7 @@
"eslint-plugin-github": "4.10.1",
"http-server": "14.1.1",
"node-gyp": "9.4.1",
"nodemon": "3.0.2"
"nodemon": "3.0.3"
},
"packageManager": "yarn@3.6.4",
"resolutions": {
@@ -108,6 +107,8 @@
"react-native@0.71.10": "patch:react-native@npm%3A0.71.10#./.yarn/patches/react-native-animation-fix/react-native-npm-0.71.10-f9c32562d8.patch",
"nanoid": "patch:nanoid@npm%3A3.3.7#./.yarn/patches/nanoid-npm-3.3.7-98824ba130.patch",
"pdfjs-dist": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"@react-native-community/slider@4.4.4": "patch:@react-native-community/slider@npm%3A4.4.4#./.yarn/patches/@react-native-community-slider-npm-4.4.4-d78e472f48.patch"
"@react-native-community/slider": "patch:@react-native-community/slider@npm%3A4.4.4#./.yarn/patches/@react-native-community-slider-npm-4.4.4-d78e472f48.patch",
"husky": "patch:husky@npm%3A3.1.0#./.yarn/patches/husky-npm-3.1.0-5cc13e4e34.patch",
"chokidar@^2.0.0": "3.5.3"
}
}

View File

@@ -41,6 +41,7 @@ class LinkSelector {
const newLinkStore: LinkStoreEntry[] = [];
const lines: string[] = renderedText.split('\n');
for (let i = 0; i < lines.length; i++) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const r = (lines[i] as any).matchAll(this.linkRegex_);
const matches = [...r];
// eslint-disable-next-line github/array-foreach -- Old code before rule was applied
@@ -63,12 +64,14 @@ class LinkSelector {
this.linkStore_ = this.findLinks(this.renderedText_);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public updateNote(textWidget: any): void {
this.noteId_ = textWidget.noteId;
this.scrollTop_ = textWidget.scrollTop_;
this.updateText(textWidget.renderedText_);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public scrollWidget(textWidget: any): void {
if (this.currentLinkIndex_ === null) return;
@@ -94,6 +97,7 @@ class LinkSelector {
return;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public changeLink(textWidget: any, offset: number): void | null {
if (textWidget.noteId !== this.noteId_) {
this.updateNote(textWidget);
@@ -124,6 +128,7 @@ class LinkSelector {
return;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public openLink(textWidget: any): void {
if (textWidget.noteId !== this.noteId_) return;
if (textWidget.renderedText_ !== this.renderedText_) return;

View File

@@ -31,7 +31,7 @@ const WindowWidget = require('tkwidgets/WindowWidget.js');
const NoteWidget = require('./gui/NoteWidget.js');
const ResourceServer = require('./ResourceServer.js');
const NoteMetadataWidget = require('./gui/NoteMetadataWidget.js');
const FolderListWidget = require('./gui/FolderListWidget.js');
const FolderListWidget = require('./gui/FolderListWidget').default;
const NoteListWidget = require('./gui/NoteListWidget.js');
const StatusBarWidget = require('./gui/StatusBarWidget').default;
const ConsoleWidget = require('./gui/ConsoleWidget.js');
@@ -441,6 +441,7 @@ class AppGui {
if (cmd === 'activate') {
const w = this.widget('mainWindow').focusedWidget;
if (w.name === 'folderList') {
// eslint-disable-next-line no-restricted-properties
this.widget('noteList').focus();
} else if (w.name === 'noteList' || w.name === 'noteText') {
this.processPromptCommand('edit $n');

View File

@@ -1,461 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const BaseApplication_1 = require("@joplin/lib/BaseApplication");
const folders_screen_utils_js_1 = require("@joplin/lib/folders-screen-utils.js");
const ResourceService_1 = require("@joplin/lib/services/ResourceService");
const BaseModel_1 = require("@joplin/lib/BaseModel");
const Folder_1 = require("@joplin/lib/models/Folder");
const BaseItem_1 = require("@joplin/lib/models/BaseItem");
const Note_1 = require("@joplin/lib/models/Note");
const Tag_1 = require("@joplin/lib/models/Tag");
const Setting_1 = require("@joplin/lib/models/Setting");
const registry_js_1 = require("@joplin/lib/registry.js");
const path_utils_1 = require("@joplin/lib/path-utils");
const utils_1 = require("@joplin/utils");
const locale_1 = require("@joplin/lib/locale");
const fs_extra_1 = require("fs-extra");
const RevisionService_1 = require("@joplin/lib/services/RevisionService");
const shim_1 = require("@joplin/lib/shim");
const setupCommand_1 = require("./setupCommand");
const { cliUtils } = require('./cli-utils.js');
const Cache = require('@joplin/lib/Cache');
const { splitCommandBatch } = require('@joplin/lib/string-utils');
class Application extends BaseApplication_1.default {
constructor() {
super(...arguments);
this.commands_ = {};
this.commandMetadata_ = null;
this.activeCommand_ = null;
this.allCommandsLoaded_ = false;
this.gui_ = null;
this.cache_ = new Cache();
}
gui() {
return this.gui_;
}
commandStdoutMaxWidth() {
return this.gui().stdoutMaxWidth();
}
guessTypeAndLoadItem(pattern, options = null) {
return __awaiter(this, void 0, void 0, function* () {
let type = BaseModel_1.default.TYPE_NOTE;
if (pattern.indexOf('/') === 0) {
type = BaseModel_1.default.TYPE_FOLDER;
pattern = pattern.substr(1);
}
return this.loadItem(type, pattern, options);
});
}
loadItem(type, pattern, options = null) {
return __awaiter(this, void 0, void 0, function* () {
const output = yield this.loadItems(type, pattern, options);
if (output.length > 1) {
// output.sort((a, b) => { return a.user_updated_time < b.user_updated_time ? +1 : -1; });
// let answers = { 0: _('[Cancel]') };
// for (let i = 0; i < output.length; i++) {
// answers[i + 1] = output[i].title;
// }
// Not really useful with new UI?
throw new Error((0, locale_1._)('More than one item match "%s". Please narrow down your query.', pattern));
// let msg = _('More than one item match "%s". Please select one:', pattern);
// const response = await cliUtils.promptMcq(msg, answers);
// if (!response) return null;
// return output[response - 1];
}
else {
return output.length ? output[0] : null;
}
});
}
loadItems(type, pattern, options = null) {
return __awaiter(this, void 0, void 0, function* () {
if (type === 'folderOrNote') {
const folders = yield this.loadItems(BaseModel_1.default.TYPE_FOLDER, pattern, options);
if (folders.length)
return folders;
return yield this.loadItems(BaseModel_1.default.TYPE_NOTE, pattern, options);
}
pattern = pattern ? pattern.toString() : '';
if (type === BaseModel_1.default.TYPE_FOLDER && (pattern === Folder_1.default.conflictFolderTitle() || pattern === Folder_1.default.conflictFolderId()))
return [Folder_1.default.conflictFolder()];
if (!options)
options = {};
const parent = options.parent ? options.parent : app().currentFolder();
const ItemClass = BaseItem_1.default.itemClass(type);
if (type === BaseModel_1.default.TYPE_NOTE && pattern.indexOf('*') >= 0) {
// Handle it as pattern
if (!parent)
throw new Error((0, locale_1._)('No notebook selected.'));
return yield Note_1.default.previews(parent.id, { titlePattern: pattern });
}
else {
// Single item
let item = null;
if (type === BaseModel_1.default.TYPE_NOTE) {
if (!parent)
throw new Error((0, locale_1._)('No notebook has been specified.'));
item = yield ItemClass.loadFolderNoteByField(parent.id, 'title', pattern);
}
else {
item = yield ItemClass.loadByTitle(pattern);
}
if (item)
return [item];
item = yield ItemClass.load(pattern); // Load by id
if (item)
return [item];
if (pattern.length >= 2) {
return yield ItemClass.loadByPartialId(pattern);
}
}
return [];
});
}
setupCommand(cmd) {
return (0, setupCommand_1.default)(cmd, (t) => this.stdout(t), () => this.store(), () => this.gui());
}
stdout(text) {
return this.gui().stdout(text);
}
exit(code = 0) {
const _super = Object.create(null, {
exit: { get: () => super.exit }
});
return __awaiter(this, void 0, void 0, function* () {
const doExit = () => __awaiter(this, void 0, void 0, function* () {
this.gui().exit();
yield _super.exit.call(this, code);
});
// Give it a few seconds to cancel otherwise exit anyway
shim_1.default.setTimeout(() => __awaiter(this, void 0, void 0, function* () {
yield doExit();
}), 5000);
if (yield registry_js_1.reg.syncTarget().syncStarted()) {
this.stdout((0, locale_1._)('Cancelling background synchronisation... Please wait.'));
const sync = yield registry_js_1.reg.syncTarget().synchronizer();
yield sync.cancel();
}
yield doExit();
});
}
commands(uiType = null) {
if (!this.allCommandsLoaded_) {
// eslint-disable-next-line github/array-foreach -- Old code before rule was applied
(0, fs_extra_1.readdirSync)(__dirname).forEach(path => {
if (path.indexOf('command-') !== 0)
return;
if (path.endsWith('.test.js'))
return;
const ext = (0, path_utils_1.fileExtension)(path);
if (ext !== 'js')
return;
const CommandClass = require(`./${path}`);
let cmd = new CommandClass();
if (!cmd.enabled())
return;
cmd = this.setupCommand(cmd);
this.commands_[cmd.name()] = cmd;
});
this.allCommandsLoaded_ = true;
}
if (uiType !== null) {
const temp = {};
for (const n in this.commands_) {
if (!this.commands_.hasOwnProperty(n))
continue;
const c = this.commands_[n];
if (!c.supportsUi(uiType))
continue;
temp[n] = c;
}
return temp;
}
return this.commands_;
}
commandNames() {
return __awaiter(this, void 0, void 0, function* () {
const metadata = yield this.commandMetadata();
const output = [];
for (const n in metadata) {
if (!metadata.hasOwnProperty(n))
continue;
output.push(n);
}
return output;
});
}
commandMetadata() {
return __awaiter(this, void 0, void 0, function* () {
if (this.commandMetadata_)
return this.commandMetadata_;
let output = yield this.cache_.getItem('metadata');
if (output) {
this.commandMetadata_ = output;
return Object.assign({}, this.commandMetadata_);
}
const commands = this.commands();
output = {};
for (const n in commands) {
if (!commands.hasOwnProperty(n))
continue;
const cmd = commands[n];
output[n] = cmd.metadata();
}
yield this.cache_.setItem('metadata', output, 1000 * 60 * 60 * 24);
this.commandMetadata_ = output;
return Object.assign({}, this.commandMetadata_);
});
}
hasGui() {
return this.gui() && !this.gui().isDummy();
}
findCommandByName(name) {
if (this.commands_[name])
return this.commands_[name];
let CommandClass = null;
try {
CommandClass = require(`${__dirname}/command-${name}.js`);
}
catch (error) {
if (error.message && error.message.indexOf('Cannot find module') >= 0) {
const e = new Error((0, locale_1._)('No such command: %s', name));
e.type = 'notFound';
throw e;
}
else {
throw error;
}
}
let cmd = new CommandClass();
cmd = this.setupCommand(cmd);
this.commands_[name] = cmd;
return this.commands_[name];
}
dummyGui() {
return {
isDummy: () => {
return true;
},
prompt: (initialText = '', promptString = '', options = null) => {
return cliUtils.prompt(initialText, promptString, options);
},
showConsole: () => { },
maximizeConsole: () => { },
stdout: (text) => {
// eslint-disable-next-line no-console
console.info(text);
},
fullScreen: () => { },
exit: () => { },
showModalOverlay: () => { },
hideModalOverlay: () => { },
stdoutMaxWidth: () => {
return 100;
},
forceRender: () => { },
termSaveState: () => { },
termRestoreState: () => { },
};
}
execCommand(argv) {
return __awaiter(this, void 0, void 0, function* () {
if (!argv.length)
return this.execCommand(['help']);
// reg.logger().debug('execCommand()', argv);
const commandName = argv[0];
this.activeCommand_ = this.findCommandByName(commandName);
let outException = null;
try {
if (this.gui().isDummy() && !this.activeCommand_.supportsUi('cli'))
throw new Error((0, locale_1._)('The command "%s" is only available in GUI mode', this.activeCommand_.name()));
const cmdArgs = cliUtils.makeCommandArgs(this.activeCommand_, argv);
yield this.activeCommand_.action(cmdArgs);
}
catch (error) {
outException = error;
}
this.activeCommand_ = null;
if (outException)
throw outException;
});
}
currentCommand() {
return this.activeCommand_;
}
loadKeymaps() {
return __awaiter(this, void 0, void 0, function* () {
const defaultKeyMap = [
{ keys: [':'], type: 'function', command: 'enter_command_line_mode' },
{ keys: ['TAB'], type: 'function', command: 'focus_next' },
{ keys: ['SHIFT_TAB'], type: 'function', command: 'focus_previous' },
{ keys: ['UP'], type: 'function', command: 'move_up' },
{ keys: ['DOWN'], type: 'function', command: 'move_down' },
{ keys: ['PAGE_UP'], type: 'function', command: 'page_up' },
{ keys: ['PAGE_DOWN'], type: 'function', command: 'page_down' },
{ keys: ['ENTER'], type: 'function', command: 'activate' },
{ keys: ['DELETE', 'BACKSPACE'], type: 'function', command: 'delete' },
{ keys: ['n'], type: 'function', command: 'next_link' },
{ keys: ['b'], type: 'function', command: 'previous_link' },
{ keys: ['o'], type: 'function', command: 'open_link' },
{ keys: [' '], type: 'prompt', command: 'todo toggle $n' },
{ keys: ['tc'], type: 'function', command: 'toggle_console' },
{ keys: ['tm'], type: 'function', command: 'toggle_metadata' },
{ keys: ['ti'], type: 'function', command: 'toggle_ids' },
{ keys: ['/'], type: 'prompt', command: 'search ""', cursorPosition: -2 },
{ keys: ['mn'], type: 'prompt', command: 'mknote ""', cursorPosition: -2 },
{ keys: ['mt'], type: 'prompt', command: 'mktodo ""', cursorPosition: -2 },
{ keys: ['mb'], type: 'prompt', command: 'mkbook ""', cursorPosition: -2 },
{ keys: ['yn'], type: 'prompt', command: 'cp $n ""', cursorPosition: -2 },
{ keys: ['dn'], type: 'prompt', command: 'mv $n ""', cursorPosition: -2 },
];
// Filter the keymap item by command so that items in keymap.json can override
// the default ones.
const itemsByCommand = {};
for (let i = 0; i < defaultKeyMap.length; i++) {
itemsByCommand[defaultKeyMap[i].command] = defaultKeyMap[i];
}
const filePath = `${Setting_1.default.value('profileDir')}/keymap.json`;
if (yield (0, fs_extra_1.pathExists)(filePath)) {
try {
let configString = yield (0, fs_extra_1.readFile)(filePath, 'utf-8');
configString = configString.replace(/^\s*\/\/.*/, ''); // Strip off comments
const keymap = JSON.parse(configString);
for (let keymapIndex = 0; keymapIndex < keymap.length; keymapIndex++) {
const item = keymap[keymapIndex];
itemsByCommand[item.command] = item;
}
}
catch (error) {
let msg = error.message ? error.message : '';
msg = `Could not load keymap ${filePath}\n${msg}`;
error.message = msg;
throw error;
}
}
const output = [];
for (const n in itemsByCommand) {
if (!itemsByCommand.hasOwnProperty(n))
continue;
output.push(itemsByCommand[n]);
}
// Map reserved shortcuts to their equivalent key
// https://github.com/cronvel/terminal-kit/issues/101
for (let i = 0; i < output.length; i++) {
const newKeys = output[i].keys.map(k => {
k = k.replace(/CTRL_H/g, 'BACKSPACE');
k = k.replace(/CTRL_I/g, 'TAB');
k = k.replace(/CTRL_M/g, 'ENTER');
return k;
});
output[i].keys = newKeys;
}
return output;
});
}
commandList(argv) {
return __awaiter(this, void 0, void 0, function* () {
if (argv.length && argv[0] === 'batch') {
const commands = [];
const commandLines = splitCommandBatch(yield (0, fs_extra_1.readFile)(argv[1], 'utf-8'));
for (const commandLine of commandLines) {
if (!commandLine.trim())
continue;
const splitted = (0, utils_1.splitCommandString)(commandLine.trim());
commands.push(splitted);
}
return commands;
}
else {
return [argv];
}
});
}
// We need this special case here because by the time the `version` command
// runs, the keychain has already been setup.
checkIfKeychainEnabled(argv) {
return argv.indexOf('version') < 0;
}
start(argv) {
const _super = Object.create(null, {
start: { get: () => super.start }
});
return __awaiter(this, void 0, void 0, function* () {
const keychainEnabled = this.checkIfKeychainEnabled(argv);
argv = yield _super.start.call(this, argv, { keychainEnabled });
cliUtils.setStdout((object) => {
return this.stdout(object);
});
this.initRedux();
// If we have some arguments left at this point, it's a command
// so execute it.
if (argv.length) {
this.gui_ = this.dummyGui();
this.currentFolder_ = yield Folder_1.default.load(Setting_1.default.value('activeFolderId'));
yield this.applySettingsSideEffects();
try {
const commands = yield this.commandList(argv);
for (const command of commands) {
yield this.execCommand(command);
}
}
catch (error) {
if (this.showStackTraces_) {
console.error(error);
}
else {
// eslint-disable-next-line no-console
console.info(error.message);
}
process.exit(1);
}
yield Setting_1.default.saveAll();
// Need to call exit() explicitly, otherwise Node wait for any timeout to complete
// https://stackoverflow.com/questions/18050095
process.exit(0);
}
else {
// Otherwise open the GUI
const keymap = yield this.loadKeymaps();
const AppGui = require('./app-gui.js');
this.gui_ = new AppGui(this, this.store(), keymap);
this.gui_.setLogger(this.logger());
yield this.gui_.start();
// Since the settings need to be loaded before the store is created, it will never
// receive the SETTING_UPDATE_ALL even, which mean state.settings will not be
// initialised. So we manually call dispatchUpdateAll() to force an update.
Setting_1.default.dispatchUpdateAll();
yield (0, folders_screen_utils_js_1.refreshFolders)((action) => this.store().dispatch(action));
const tags = yield Tag_1.default.allWithNotes();
ResourceService_1.default.runInBackground();
RevisionService_1.default.instance().runInBackground();
this.dispatch({
type: 'TAG_UPDATE_ALL',
items: tags,
});
this.store().dispatch({
type: 'FOLDER_SELECT',
id: Setting_1.default.value('activeFolderId'),
});
this.startRotatingLogMaintenance(Setting_1.default.value('profileDir'));
}
});
}
}
let application_ = null;
function app() {
if (application_)
return application_;
application_ = new Application();
return application_;
}
exports.default = app;
//# sourceMappingURL=app.js.map

View File

@@ -22,10 +22,14 @@ const { splitCommandBatch } = require('@joplin/lib/string-utils');
class Application extends BaseApplication {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private commands_: Record<string, any> = {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private commandMetadata_: any = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private activeCommand_: any = null;
private allCommandsLoaded_ = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private gui_: any = null;
private cache_ = new Cache();
@@ -37,6 +41,7 @@ class Application extends BaseApplication {
return this.gui().stdoutMaxWidth();
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async guessTypeAndLoadItem(pattern: string, options: any = null) {
let type = BaseModel.TYPE_NOTE;
if (pattern.indexOf('/') === 0) {
@@ -46,6 +51,7 @@ class Application extends BaseApplication {
return this.loadItem(type, pattern, options);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async loadItem(type: ModelType | 'folderOrNote', pattern: string, options: any = null) {
const output = await this.loadItems(type, pattern, options);
@@ -70,6 +76,7 @@ class Application extends BaseApplication {
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async loadItems(type: ModelType | 'folderOrNote', pattern: string, options: any = null): Promise<(FolderEntity | NoteEntity)[]> {
if (type === 'folderOrNote') {
const folders: FolderEntity[] = await this.loadItems(BaseModel.TYPE_FOLDER, pattern, options);
@@ -95,7 +102,7 @@ class Application extends BaseApplication {
let item = null;
if (type === BaseModel.TYPE_NOTE) {
if (!parent) throw new Error(_('No notebook has been specified.'));
item = await ItemClass.loadFolderNoteByField(parent.id, 'title', pattern);
item = await (ItemClass as typeof Note).loadFolderNoteByField(parent.id, 'title', pattern);
} else {
item = await ItemClass.loadByTitle(pattern);
}
@@ -160,6 +167,7 @@ class Application extends BaseApplication {
}
if (uiType !== null) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const temp: Record<string, any> = {};
for (const n in this.commands_) {
if (!this.commands_.hasOwnProperty(n)) continue;
@@ -219,6 +227,7 @@ class Application extends BaseApplication {
CommandClass = require(`${__dirname}/command-${name}.js`);
} catch (error) {
if (error.message && error.message.indexOf('Cannot find module') >= 0) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const e: any = new Error(_('No such command: %s', name));
e.type = 'notFound';
throw e;
@@ -238,6 +247,7 @@ class Application extends BaseApplication {
isDummy: () => {
return true;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
prompt: (initialText = '', promptString = '', options: any = null) => {
return cliUtils.prompt(initialText, promptString, options);
},
@@ -260,6 +270,7 @@ class Application extends BaseApplication {
};
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async execCommand(argv: string[]): Promise<any> {
if (!argv.length) return this.execCommand(['help']);
// reg.logger().debug('execCommand()', argv);
@@ -307,6 +318,7 @@ class Application extends BaseApplication {
{ keys: ['tc'], type: 'function', command: 'toggle_console' },
{ keys: ['tm'], type: 'function', command: 'toggle_metadata' },
{ keys: ['ti'], type: 'function', command: 'toggle_ids' },
{ keys: ['r'], type: 'prompt', command: 'restore $n' },
{ keys: ['/'], type: 'prompt', command: 'search ""', cursorPosition: -2 },
{ keys: ['mn'], type: 'prompt', command: 'mknote ""', cursorPosition: -2 },
{ keys: ['mt'], type: 'prompt', command: 'mktodo ""', cursorPosition: -2 },
@@ -389,6 +401,7 @@ class Application extends BaseApplication {
argv = await super.start(argv, { keychainEnabled });
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
cliUtils.setStdout((object: any) => {
return this.stdout(object);
});
@@ -438,6 +451,7 @@ class Application extends BaseApplication {
// initialised. So we manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
await refreshFolders((action: any) => this.store().dispatch(action));
const tags = await Tag.allWithNotes();

View File

@@ -3,14 +3,18 @@ import { reg } from '@joplin/lib/registry.js';
export default class BaseCommand {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
protected stdout_: any = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
protected prompt_: any = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
protected dispatcher_: any;
public usage(): string {
throw new Error('Usage not defined');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public encryptionCheck(item: any) {
if (item && item.encryption_applied) throw new Error(_('Cannot change encrypted item'));
}
@@ -19,6 +23,7 @@ export default class BaseCommand {
throw new Error('Description not defined');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async action(_args: any) {
throw new Error('Action not defined');
}
@@ -31,6 +36,7 @@ export default class BaseCommand {
return this.compatibleUis().indexOf(ui) >= 0;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public options(): any[] {
return [];
}
@@ -59,6 +65,7 @@ export default class BaseCommand {
this.dispatcher_ = fn;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public dispatch(action: any) {
if (!this.dispatcher_) throw new Error('Dispatcher not defined');
return this.dispatcher_(action);
@@ -78,6 +85,7 @@ export default class BaseCommand {
this.prompt_ = fn;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async prompt(message: string, options: any = null) {
if (!this.prompt_) throw new Error('Prompt is undefined');
return await this.prompt_(message, options);

View File

@@ -37,6 +37,7 @@ class Command extends BaseCommand {
return markdownUtils.createMarkdownTable(headers, tableFields);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const models = [
{
@@ -82,7 +83,7 @@ class Command extends BaseCommand {
lines.push('## Authorisation');
lines.push('');
lines.push('To prevent unauthorised applications from accessing the API, the calls must be authentified. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.');
lines.push('To prevent unauthorised applications from accessing the API, the calls must be authenticated. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.');
lines.push('');
lines.push('This would be an example of valid cURL call using a token:');
lines.push('');
@@ -149,7 +150,7 @@ class Command extends BaseCommand {
lines.push('');
lines.push('```shell\ncurl http://localhost:41184/notes?order_by=updated_time&order_dir=ASC&limit=10&page=2\n```');
lines.push('');
lines.push('Eventually you will get some results that do not contain an "has_more" paramater, at which point you will have retrieved all the results');
lines.push('Eventually you will get some results that do not contain an "has_more" parameter, at which point you will have retrieved all the results');
lines.push('');
lines.push('As an example the pseudo-code below could be used to fetch all the notes:');
lines.push('');
@@ -199,7 +200,7 @@ async function fetchAllNotes() {
lines.push('## Item type IDs');
lines.push('');
lines.push('Item type IDs might be refered to in certain object you will retrieve from the API. This is the correspondance between name and ID:');
lines.push('Item type IDs might be referred to in certain objects you will retrieve from the API. This is the correspondence between name and ID:');
lines.push('');
lines.push('Name | Value');
lines.push('---- | -----');
@@ -400,6 +401,11 @@ async function fetchAllNotes() {
lines.push('Remove the tag from the note.');
lines.push('');
}
if (model.type === BaseModel.TYPE_NOTE || model.type === BaseModel.TYPE_FOLDER) {
lines.push(`By default, the ${singular} will be moved **to the trash**. To permanently delete it, add the query parameter \`permanent=1\``);
lines.push('');
}
}
{

View File

@@ -13,6 +13,7 @@ class Command extends BaseCommand {
return _('Attaches the given file to the note.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const title = args['note'];

View File

@@ -18,6 +18,7 @@ class Command extends BaseCommand {
return [['-v, --verbose', _('Displays the complete information about note.')]];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const title = args['note'];

View File

@@ -27,6 +27,7 @@ class Command extends BaseCommand {
return new Promise<void>((resolve, reject) => {
// being defensive and not attempting to settle twice
let isSettled = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const chunks: any = [];
inputStream.on('readable', () => {
@@ -67,6 +68,7 @@ class Command extends BaseCommand {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const verbose = args.options.verbose;
const isExport = args.options.export;
@@ -91,6 +93,7 @@ class Command extends BaseCommand {
keys.sort();
if (isExport) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const resultObj = keys.reduce<Record<string, any>>((acc, key) => {
const value = Setting.value(key);
if (!verbose && !value) return acc;

View File

@@ -13,6 +13,7 @@ class Command extends BaseCommand {
return _('Duplicates the notes matching <note> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
let folder = null;
if (args['notebook']) {

View File

@@ -15,6 +15,7 @@ class Command extends BaseCommand {
return _('Marks a to-do as done.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public static async handleAction(commandInstance: BaseCommand, args: any, isCompleted: boolean) {
const note: NoteEntity = await app().loadItem(BaseModel.TYPE_NOTE, args.note);
commandInstance.encryptionCheck(note);
@@ -31,6 +32,7 @@ class Command extends BaseCommand {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
await Command.handleAction(this, args, true);
}

View File

@@ -2,6 +2,7 @@ import BaseCommand from './base-command';
import Folder from '@joplin/lib/models/Folder';
import Note from '@joplin/lib/models/Note';
import Tag from '@joplin/lib/models/Tag';
import { FolderEntity, NoteEntity } from '@joplin/lib/services/database/types';
class Command extends BaseCommand {
public override usage() {
@@ -17,7 +18,7 @@ class Command extends BaseCommand {
}
public override async action() {
let items = [];
let items: (NoteEntity | FolderEntity)[] = [];
const folders = await Folder.all();
for (let i = 0; i < folders.length; i++) {
const folder = folders[i];

View File

@@ -30,9 +30,11 @@ class Command extends BaseCommand {
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async action(args: any) {
const options = args.options;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const askForMasterKey = async (error: any) => {
const masterKeyId = error.masterKeyId;
const password = await this.prompt(_('Enter master password:'), { type: 'string', secure: true });

View File

@@ -17,6 +17,7 @@ class Command extends BaseCommand {
return _('Edit note.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
let tempFilePath: string|null = null;

View File

@@ -24,6 +24,7 @@ class Command extends BaseCommand {
return [['--format <format>', _('Destination format: %s', formats.join(', '))], ['--note <note>', _('Exports only the given note.')], ['--notebook <notebook>', _('Exports only the given notebook.')]];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const exportOptions: ExportOptions = {};
exportOptions.path = args.path;
@@ -35,10 +36,12 @@ class Command extends BaseCommand {
if (args.options.note) {
const notes = await app().loadItems(BaseModel.TYPE_NOTE, args.options.note, { parent: app().currentFolder() });
if (!notes.length) throw new Error(_('Cannot find "%s".', args.options.note));
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
exportOptions.sourceNoteIds = notes.map((n: any) => n.id);
} else if (args.options.notebook) {
const folders = await app().loadItems(BaseModel.TYPE_FOLDER, args.options.notebook);
if (!folders.length) throw new Error(_('Cannot find "%s".', args.options.notebook));
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
exportOptions.sourceFolderIds = folders.map((n: any) => n.id);
}

View File

@@ -13,6 +13,7 @@ class Command extends BaseCommand {
return _('Displays a geolocation URL for the note.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const title = args['note'];

View File

@@ -29,6 +29,7 @@ class Command extends BaseCommand {
return output;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const stdoutWidth = app().commandStdoutMaxWidth();

View File

@@ -30,6 +30,7 @@ class Command extends BaseCommand {
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);

View File

@@ -7,6 +7,7 @@ import Setting from '@joplin/lib/models/Setting';
import Note from '@joplin/lib/models/Note';
const { sprintf } = require('sprintf-js');
import time from '@joplin/lib/time';
import { NoteEntity } from '@joplin/lib/services/database/types';
const { cliUtils } = require('./cli-utils.js');
class Command extends BaseCommand {
@@ -33,11 +34,13 @@ class Command extends BaseCommand {
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const pattern = args['note-pattern'];
let items = [];
const options = args.options;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const queryOptions: any = {};
if (options.limit) queryOptions.limit = options.limit;
if (options.sort) {
@@ -71,7 +74,7 @@ class Command extends BaseCommand {
let hasTodos = false;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.is_todo) {
if ((item as NoteEntity).is_todo) {
hasTodos = true;
break;
}
@@ -103,8 +106,8 @@ class Command extends BaseCommand {
}
if (hasTodos) {
if (item.is_todo) {
row.push(sprintf('[%s]', item.todo_completed ? 'X' : ' '));
if ((item as NoteEntity).is_todo) {
row.push(sprintf('[%s]', (item as NoteEntity).todo_completed ? 'X' : ' '));
} else {
row.push(' ');
}

View File

@@ -43,6 +43,7 @@ class Command extends BaseCommand {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async action(args: any) {
const targetFolder = args.options.parent;

View File

@@ -14,6 +14,7 @@ class Command extends BaseCommand {
return _('Moves the given <item> to [notebook]');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const pattern = args['item'];
const destination = args['notebook'];

View File

@@ -14,6 +14,7 @@ class Command extends BaseCommand {
return _('Renames the given <item> (note or notebook) to <name>.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const pattern = args['item'];
const name = args['name'];

View File

@@ -0,0 +1,27 @@
import BaseCommand from './base-command';
import app from './app';
import { _ } from '@joplin/lib/locale';
import restoreItems from '@joplin/lib/services/trash/restoreItems';
class Command extends BaseCommand {
public override usage() {
return 'restore <pattern>';
}
public override description() {
return _('Restore the items matching <pattern> from the trash.');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const pattern = args['pattern'];
const items = await app().loadItems('folderOrNote', pattern);
if (!items.length) throw new Error(_('Cannot find "%s".', pattern));
const ids = items.map(n => n.id);
await restoreItems(items[0].type_, ids, { useRestoreFolder: true });
}
}
module.exports = Command;

View File

@@ -0,0 +1,81 @@
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
import Folder from '@joplin/lib/models/Folder';
import Note from '@joplin/lib/models/Note';
const Command = require('./command-rmbook');
const setUpCommand = () => {
const command = setupCommandForTesting(Command);
const promptMock = jest.fn(() => true);
command.setPrompt(promptMock);
return { command, promptMock };
};
describe('command-rmbook', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
await setupApplication();
});
it('should ask before moving to the trash', async () => {
await Folder.save({ title: 'folder1' });
const { command, promptMock } = setUpCommand();
await command.action({ 'notebook': 'folder1', options: {} });
expect(promptMock).toHaveBeenCalledTimes(1);
const folder1 = await Folder.loadByTitle('folder1');
expect(folder1.deleted_time).not.toBeFalsy();
expect((await Note.allItemsInTrash()).folderIds).toHaveLength(1);
});
it('cancelling a prompt should prevent deletion', async () => {
await Folder.save({ title: 'folder1' });
const { command, promptMock } = setUpCommand();
promptMock.mockImplementation(() => false);
await command.action({ 'notebook': 'folder1', options: {} });
expect((await Note.allItemsInTrash()).folderIds).toHaveLength(0);
});
it('should not prompt when the force flag is given', async () => {
const { id: folder1Id } = await Folder.save({ title: 'folder1' });
const { id: folder2Id } = await Folder.save({ title: 'folder2', parent_id: folder1Id });
const { command, promptMock } = setUpCommand();
await command.action({ 'notebook': 'folder1', options: { force: true } });
expect(promptMock).toHaveBeenCalledTimes(0);
expect((await Note.allItemsInTrash()).folderIds.includes(folder1Id)).toBe(true);
expect((await Note.allItemsInTrash()).folderIds.includes(folder2Id)).toBe(true);
});
it('should support permanent deletion', async () => {
const { id: folder1Id } = await Folder.save({ title: 'folder1' });
const { id: folder2Id } = await Folder.save({ title: 'folder2' });
const { command, promptMock } = setUpCommand();
await command.action({ 'notebook': 'folder1', options: { permanent: true, force: true } });
expect(promptMock).not.toHaveBeenCalled();
// Should be permanently deleted.
expect((await Note.allItemsInTrash()).folderIds.includes(folder1Id)).toBe(false);
expect(await Folder.load(folder1Id, { includeDeleted: true })).toBe(undefined);
// folder2 should not be deleted
expect(await Folder.load(folder2Id, { includeDeleted: false })).toBeTruthy();
// Should prompt before deleting
await command.action({ 'notebook': 'folder2', options: { permanent: true } });
expect(promptMock).toHaveBeenCalled();
expect(await Folder.load(folder2Id, { includeDeleted: false })).toBeUndefined();
});
});

View File

@@ -3,6 +3,7 @@ import app from './app';
import { _ } from '@joplin/lib/locale';
import Folder from '@joplin/lib/models/Folder';
import BaseModel from '@joplin/lib/BaseModel';
import { substrWithEllipsis } from '@joplin/lib/string-utils';
class Command extends BaseCommand {
public override usage() {
@@ -14,19 +15,32 @@ class Command extends BaseCommand {
}
public override options() {
return [['-f, --force', _('Deletes the notebook without asking for confirmation.')]];
return [
['-f, --force', _('Deletes the notebook without asking for confirmation.')],
['-p, --permanent', _('Permanently deletes the notebook, skipping the trash.')],
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const pattern = args['notebook'];
const force = args.options && args.options.force === true;
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
if (!folder) throw new Error(_('Cannot find "%s".', pattern));
const ok = force ? true : await this.prompt(_('Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.'), { booleanAnswerDefault: 'n' });
const permanent = args.options?.permanent === true || !!folder.deleted_time;
const ellipsizedFolderTitle = substrWithEllipsis(folder.title, 0, 32);
let msg;
if (permanent) {
msg = _('Permanently delete notebook "%s"?\n\nAll notes and sub-notebooks within this notebook will be permanently deleted.', ellipsizedFolderTitle);
} else {
msg = _('Move notebook "%s" to the trash?\n\nAll notes and sub-notebooks within this notebook will also be moved to the trash.', ellipsizedFolderTitle);
}
const ok = force ? true : await this.prompt(msg, { booleanAnswerDefault: 'n' });
if (!ok) return;
await Folder.delete(folder.id);
await Folder.delete(folder.id, { toTrash: !permanent, sourceDescription: 'rmbook command' });
}
}

View File

@@ -0,0 +1,57 @@
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
import Note from '@joplin/lib/models/Note';
import Folder from '@joplin/lib/models/Folder';
import app from './app';
import { getTrashFolderId } from '@joplin/lib/services/trash';
const Command = require('./command-rmnote');
const setUpCommand = () => {
const command = setupCommandForTesting(Command);
const promptMock = jest.fn(() => true);
command.setPrompt(promptMock);
return { command, promptMock };
};
const createTestNote = async () => {
const folder = await Folder.save({ title: 'folder' });
app().switchCurrentFolder(folder);
return await Note.save({ title: 'note1', parent_id: folder.id });
};
describe('command-rmnote', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
await setupApplication();
});
it('should move to the trash by default, without prompting', async () => {
const { id: noteId } = await createTestNote();
const { command, promptMock } = setUpCommand();
await command.action({ 'note-pattern': 'note1', options: {} });
expect(promptMock).not.toHaveBeenCalled();
expect((await Note.allItemsInTrash()).noteIds.includes(noteId)).toBe(true);
});
it('should permanently delete trashed items by default, with prompting', async () => {
const { id: noteId } = await createTestNote();
const { command, promptMock } = setUpCommand();
// Should not prompt when deleting from a folder
await command.action({ 'note-pattern': 'note1', options: {} });
expect(promptMock).toHaveBeenCalledTimes(0);
// Should prompt when deleting from trash
app().switchCurrentFolder(await Folder.load(getTrashFolderId()));
await command.action({ 'note-pattern': 'note1', options: {} });
expect(promptMock).toHaveBeenCalledTimes(1);
expect(await Note.load(noteId, { includeDeleted: true })).toBe(undefined);
});
});

View File

@@ -2,7 +2,8 @@ import BaseCommand from './base-command';
import app from './app';
import { _ } from '@joplin/lib/locale';
import Note from '@joplin/lib/models/Note';
import BaseModel from '@joplin/lib/BaseModel';
import BaseModel, { DeleteOptions } from '@joplin/lib/BaseModel';
import { NoteEntity } from '@joplin/lib/services/database/types';
class Command extends BaseCommand {
public override usage() {
@@ -14,20 +15,41 @@ class Command extends BaseCommand {
}
public override options() {
return [['-f, --force', _('Deletes the notes without asking for confirmation.')]];
return [
['-f, --force', _('Deletes the notes without asking for confirmation.')],
['-p, --permanent', _('Deletes notes permanently, skipping the trash.')],
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const pattern = args['note-pattern'];
const force = args.options && args.options.force === true;
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
const notes: NoteEntity[] = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
if (!notes.length) throw new Error(_('Cannot find "%s".', pattern));
const ok = force ? true : await this.prompt(notes.length > 1 ? _('%d notes match this pattern. Delete them?', notes.length) : _('Delete note?'), { booleanAnswerDefault: 'n' });
let ok = true;
if (!force && notes.length > 1) {
ok = await this.prompt(_('%d notes match this pattern. Delete them?', notes.length), { booleanAnswerDefault: 'n' });
}
const permanent = (args.options?.permanent === true) || notes.every(n => !!n.deleted_time);
if (!force && permanent) {
const message = (
notes.length === 1 ? _('This will permanently delete the note "%s". Continue?', notes[0].title) : _('%d notes will be permanently deleted. Continue?', notes.length)
);
ok = await this.prompt(message, { booleanAnswerDefault: 'n' });
}
if (!ok) return;
const ids = notes.map((n: any) => n.id);
await Note.batchDelete(ids);
const ids = notes.map(n => n.id);
const options: DeleteOptions = {
toTrash: !permanent,
sourceDescription: 'rmnote',
};
await Note.batchDelete(ids, options);
}
}

View File

@@ -22,6 +22,7 @@ class Command extends BaseCommand {
return _('Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s', s.join(', '));
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const title = args['note'];
const propName = args['name'];
@@ -36,6 +37,7 @@ class Command extends BaseCommand {
const timestamp = Date.now();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const newNote: any = {
id: notes[i].id,
type_: notes[i].type_,

View File

@@ -35,7 +35,9 @@ class Command extends BaseCommand {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async action(args: any) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const schema: Record<string, any> = {
title: 'JSON schema for Joplin setting files',
'$id': Setting.schemaUrl,
@@ -52,6 +54,7 @@ class Command extends BaseCommand {
const type = settingTypeToSchemaType(md.type);
if (!type) continue;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const props: Record<string, any> = {};
props.type = type;
props.default = md.value;
@@ -61,6 +64,7 @@ class Command extends BaseCommand {
if (md.description && md.description('desktop')) description.push(md.description('desktop'));
if (description.length) props.description = description.join('. ');
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
if (md.isEnum) props.enum = Object.keys(md.options()).map((v: any) => Setting.formatValue(key, v));
if ('minimum' in md) props.minimum = md.minimum;
if ('maximum' in md) props.maximum = md.maximum;

View File

@@ -14,12 +14,18 @@ const { cliUtils } = require('./cli-utils.js');
const md5 = require('md5');
import * as locker from 'proper-lockfile';
import { pathExists, writeFile } from 'fs-extra';
import { checkIfLoginWasSuccessful, generateApplicationConfirmUrl } from '@joplin/lib/services/joplinCloudUtils';
import Logger from '@joplin/utils/Logger';
import { uuidgen } from '@joplin/lib/uuid';
const logger = Logger.create('command-sync');
class Command extends BaseCommand {
private syncTargetId_: number = null;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
private releaseLockFn_: Function = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private oneDriveApiUtils_: any = null;
public usage() {
@@ -54,6 +60,7 @@ class Command extends BaseCommand {
// OneDrive
this.oneDriveApiUtils_ = new OneDriveApiNodeUtils(syncTarget.api());
const auth = await this.oneDriveApiUtils_.oauthDance({
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
log: (...s: any[]) => {
return this.stdout(...s);
},
@@ -84,9 +91,36 @@ class Command extends BaseCommand {
Setting.setValue(`sync.${this.syncTargetId_}.auth`, response.access_token);
api.setAuthToken(response.access_token);
return true;
} else if (syncTargetMd.name === 'joplinCloud') {
const applicationAuthId = uuidgen();
const checkForCredentials = async () => {
try {
const applicationAuthUrl = `${Setting.value('sync.10.path')}/api/application_auth/${applicationAuthId}`;
const response = await checkIfLoginWasSuccessful(applicationAuthUrl);
if (response && response.success) {
return response;
}
return null;
} catch (error) {
logger.error(error);
throw error;
}
};
this.stdout(_('To allow Joplin to synchronise with Joplin Cloud, please login using this URL:'));
const confirmUrl = `${Setting.value('sync.10.website')}/applications/${applicationAuthId}/confirm`;
const urlWithClient = await generateApplicationConfirmUrl(confirmUrl);
this.stdout(urlWithClient);
const authorized = await this.prompt(_('Have you authorised the application login in the above URL?'), { booleanAnswerDefault: 'y' });
if (!authorized) return false;
const result = await checkForCredentials();
if (!result) return false;
return true;
}
this.stdout(_('Not authentified with %s. Please provide any missing credentials.', syncTargetMd.label));
this.stdout(_('Not authenticated with %s. Please provide any missing credentials.', syncTargetMd.label));
return false;
}
@@ -101,6 +135,7 @@ class Command extends BaseCommand {
return !!this.oneDriveApiUtils_;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async action(args: any) {
this.releaseLockFn_ = null;
@@ -149,7 +184,9 @@ class Command extends BaseCommand {
const sync = await syncTarget.synchronizer();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const options: any = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
onProgress: (report: any) => {
const lines = Synchronizer.reportToLines(report);
if (lines.length) cliUtils.redraw(lines.join(' '));

View File

@@ -6,11 +6,13 @@ import populateDatabase from '@joplin/lib/services/debug/populateDatabase';
import { readCredentialFile } from '@joplin/lib/utils/credentialFiles';
import JoplinServerApi from '@joplin/lib/JoplinServerApi';
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
function randomElement(array: any[]): any {
if (!array.length) return null;
return array[Math.floor(Math.random() * array.length)];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
function itemCount(args: any) {
const count = Number(args.arg0);
if (!count || isNaN(count)) throw new Error('Note count must be specified');
@@ -30,6 +32,7 @@ class Command extends BaseCommand {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public options(): any[] {
return [
['--folder-count <count>', 'Folders to create'],
@@ -40,6 +43,7 @@ class Command extends BaseCommand {
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async action(args: any) {
const { command, options } = args;
@@ -53,6 +57,7 @@ class Command extends BaseCommand {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const promises: any[] = [];
if (command === 'createRandomNotes') {
@@ -85,7 +90,7 @@ class Command extends BaseCommand {
for (let i = 0; i < noteCount; i++) {
const noteId = randomElement(noteIds);
promises.push(Note.delete(noteId));
promises.push(Note.delete(noteId, { sourceDescription: 'command-testing' }));
}
}

View File

@@ -16,6 +16,7 @@ class Command extends BaseCommand {
return ['cli'];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public override async action(args: any) {
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args['notebook']);
if (!folder) throw new Error(_('Cannot find "%s".', args['notebook']));

View File

@@ -1,16 +1,20 @@
const Folder = require('@joplin/lib/models/Folder').default;
const Tag = require('@joplin/lib/models/Tag').default;
const BaseModel = require('@joplin/lib/BaseModel').default;
import Folder from '@joplin/lib/models/Folder';
import Tag from '@joplin/lib/models/Tag';
import BaseModel from '@joplin/lib/BaseModel';
import Setting from '@joplin/lib/models/Setting';
import { _ } from '@joplin/lib/locale';
import { FolderEntity } from '@joplin/lib/services/database/types';
import { getDisplayParentId, getTrashFolderId } from '@joplin/lib/services/trash';
const ListWidget = require('tkwidgets/ListWidget.js');
const Setting = require('@joplin/lib/models/Setting').default;
const _ = require('@joplin/lib/locale')._;
class FolderListWidget extends ListWidget {
constructor() {
export default class FolderListWidget extends ListWidget {
private folders_: FolderEntity[] = [];
public constructor() {
super();
this.tags_ = [];
this.folders_ = [];
this.searches_ = [];
this.selectedFolderId_ = null;
this.selectedTagId_ = null;
@@ -21,7 +25,8 @@ class FolderListWidget extends ListWidget {
this.trimItemTitle = false;
this.showIds = false;
this.itemRenderer = item => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
this.itemRenderer = (item: any) => {
const output = [];
if (item === '-') {
output.push('-'.repeat(this.innerWidth));
@@ -33,13 +38,13 @@ class FolderListWidget extends ListWidget {
}
output.push(Folder.displayTitle(item));
if (Setting.value('showNoteCounts')) {
if (Setting.value('showNoteCounts') && !item.deleted_time && item.id !== getTrashFolderId()) {
let noteCount = item.note_count;
// Subtract children note_count from parent folder.
if (this.folderHasChildren_(this.folders, item.id)) {
for (let i = 0; i < this.folders.length; i++) {
if (this.folders[i].parent_id === item.id) {
noteCount -= this.folders[i].note_count;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
noteCount -= (this.folders[i] as any).note_count;
}
}
}
@@ -56,113 +61,122 @@ class FolderListWidget extends ListWidget {
};
}
folderDepth(folders, folderId) {
public folderDepth(folders: FolderEntity[], folderId: string) {
let output = 0;
while (true) {
const folder = BaseModel.byId(folders, folderId);
if (!folder || !folder.parent_id) return output;
const folderParentId = getDisplayParentId(folder, folders.find(f => f.id === folder.parent_id));
if (!folder || !folderParentId) return output;
output++;
folderId = folder.parent_id;
folderId = folderParentId;
}
}
get selectedFolderId() {
public get selectedFolderId() {
return this.selectedFolderId_;
}
set selectedFolderId(v) {
public set selectedFolderId(v) {
this.selectedFolderId_ = v;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
get selectedSearchId() {
public get selectedSearchId() {
return this.selectedSearchId_;
}
set selectedSearchId(v) {
public set selectedSearchId(v) {
this.selectedSearchId_ = v;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
get selectedTagId() {
public get selectedTagId() {
return this.selectedTagId_;
}
set selectedTagId(v) {
public set selectedTagId(v) {
this.selectedTagId_ = v;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
get notesParentType() {
public get notesParentType() {
return this.notesParentType_;
}
set notesParentType(v) {
public set notesParentType(v) {
this.notesParentType_ = v;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
get searches() {
public get searches() {
return this.searches_;
}
set searches(v) {
public set searches(v) {
this.searches_ = v;
this.updateItems_ = true;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
get tags() {
public get tags() {
return this.tags_;
}
set tags(v) {
public set tags(v) {
this.tags_ = v;
this.updateItems_ = true;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
get folders() {
public get folders() {
return this.folders_;
}
set folders(v) {
public set folders(v) {
this.folders_ = v;
this.updateItems_ = true;
this.updateIndexFromSelectedItemId();
this.invalidate();
}
toggleShowIds() {
public toggleShowIds() {
this.showIds = !this.showIds;
this.invalidate();
}
folderHasChildren_(folders, folderId) {
public folderHasChildren_(folders: FolderEntity[], folderId: string) {
for (let i = 0; i < folders.length; i++) {
const folder = folders[i];
if (folder.parent_id === folderId) return true;
const folderParentId = getDisplayParentId(folder, folders.find(f => f.id === folder.parent_id));
if (folderParentId === folderId) return true;
}
return false;
}
render() {
public render() {
if (this.updateItems_) {
this.logger().debug('Rebuilding items...', this.notesParentType, this.selectedJoplinItemId, this.selectedSearchId);
const wasSelectedItemId = this.selectedJoplinItemId;
const previousParentType = this.notesParentType;
let newItems = [];
const orderFolders = parentId => {
this.logger().info('FFFFFFFFFFFFF', JSON.stringify(this.folders, null, 4));
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
let newItems: any[] = [];
const orderFolders = (parentId: string) => {
this.logger().info('PARENT', parentId);
for (let i = 0; i < this.folders.length; i++) {
const f = this.folders[i];
const folderParentId = f.parent_id ? f.parent_id : '';
const originalParent = this.folders_.find(f => f.id === f.parent_id);
const folderParentId = getDisplayParentId(f, originalParent); // f.parent_id ? f.parent_id : '';
this.logger().info('FFF', f.title, folderParentId);
if (folderParentId === parentId) {
newItems.push(f);
if (this.folderHasChildren_(this.folders, f.id)) orderFolders(f.id);
@@ -192,7 +206,7 @@ class FolderListWidget extends ListWidget {
super.render();
}
get selectedJoplinItemId() {
public get selectedJoplinItemId() {
if (!this.notesParentType) return '';
if (this.notesParentType === 'Folder') return this.selectedFolderId;
if (this.notesParentType === 'Tag') return this.selectedTagId;
@@ -200,17 +214,15 @@ class FolderListWidget extends ListWidget {
throw new Error(`Unknown parent type: ${this.notesParentType}`);
}
get selectedJoplinItem() {
public get selectedJoplinItem() {
const id = this.selectedJoplinItemId;
const index = this.itemIndexByKey('id', id);
return this.itemAt(index);
}
updateIndexFromSelectedItemId(itemId = null) {
public updateIndexFromSelectedItemId(itemId: string = null) {
if (itemId === null) itemId = this.selectedJoplinItemId;
const index = this.itemIndexByKey('id', itemId);
this.currentIndex = index >= 0 ? index : 0;
}
}
module.exports = FolderListWidget;

View File

@@ -27,6 +27,7 @@ export default class StatusBarWidget extends BaseWidget {
this.invalidate();
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async prompt(initialText = '', promptString: any = null, options: any = null) {
if (this.promptState_) throw new Error('Another prompt already active');
if (promptString === null) promptString = ':';
@@ -86,6 +87,7 @@ export default class StatusBarWidget extends BaseWidget {
// const textStyle = this.promptActive ? (s) => s : chalk.bgBlueBright.white;
// const textStyle = (s) => s;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const textStyle = this.promptActive ? (s: any) => s : chalk.gray;
this.term.drawHLine(this.absoluteInnerX, this.absoluteInnerY, this.innerWidth, textStyle(' '));
@@ -106,6 +108,7 @@ export default class StatusBarWidget extends BaseWidget {
const isSecurePrompt = !!this.promptState_.secure;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const options: any = {
cancelable: true,
history: this.history,
@@ -118,6 +121,7 @@ export default class StatusBarWidget extends BaseWidget {
if ('cursorPosition' in this.promptState_) options.cursorPosition = this.promptState_.cursorPosition;
if (isSecurePrompt) options.echoChar = true;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
this.inputEventEmitter_ = this.term.inputField(options, (error: any, input: any) => {
let resolveResult = null;
const resolveFn = this.promptState_.resolve;

View File

@@ -8,14 +8,17 @@ import uuid from '@joplin/lib/uuid';
const sandboxProxy = require('@joplin/lib/services/plugins/sandboxProxy');
function createConsoleWrapper(pluginId: string) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const wrapper: any = {};
for (const n in console) {
// eslint-disable-next-line no-console
if (!console.hasOwnProperty(n)) continue;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
wrapper[n] = (...args: any[]) => {
const newArgs = args.slice();
newArgs.splice(0, 0, `Plugin "${pluginId}":`);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
return (console as any)[n](...newArgs);
};
}
@@ -33,6 +36,7 @@ function createConsoleWrapper(pluginId: string) {
export default class PluginRunner extends BasePluginRunner {
private eventHandlers_: EventHandlers = {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private activeSandboxCalls_: any = {};
public constructor() {
@@ -41,12 +45,14 @@ export default class PluginRunner extends BasePluginRunner {
this.eventHandler = this.eventHandler.bind(this);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private async eventHandler(eventHandlerId: string, args: any[]) {
const cb = this.eventHandlers_[eventHandlerId];
return cb(...args);
}
private newSandboxProxy(pluginId: string, sandbox: Global) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const target = async (path: string, args: any[]) => {
const callId = `${pluginId}::${path}::${uuid.createNano()}`;
this.activeSandboxCalls_[callId] = true;

View File

@@ -1,11 +1,12 @@
import { _ } from '@joplin/lib/locale';
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any -- Old code before rule was applied, Old code before rule was applied
export default (cmd: any, stdout: Function, store: Function, gui: Function) => {
cmd.setStdout((text: string) => {
return stdout(text);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
cmd.setDispatcher((action: any) => {
if (store()) {
return store().dispatch(action);
@@ -14,6 +15,7 @@ export default (cmd: any, stdout: Function, store: Function, gui: Function) => {
}
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
cmd.setPrompt(async (message: string, options: any) => {
if (!options) options = {};
if (!options.type) options.type = 'boolean';

View File

@@ -3,7 +3,7 @@ import Folder from '@joplin/lib/models/Folder';
import BaseCommand from '../base-command';
import setupCommand from '../setupCommand';
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any -- Old code before rule was applied, Old code before rule was applied
export const setupCommandForTesting = (CommandClass: any, stdout: Function = null): BaseCommand => {
const command = new CommandClass();
setupCommand(command, stdout, null, null);

View File

@@ -35,15 +35,15 @@
],
"owner": "Laurent Cozic"
},
"version": "2.14.0",
"version": "3.0.0",
"bin": "./main.js",
"engines": {
"node": ">=10.0.0"
},
"dependencies": {
"@joplin/lib": "~2.14",
"@joplin/renderer": "~2.14",
"@joplin/utils": "~2.14",
"@joplin/lib": "~3.0",
"@joplin/renderer": "~3.0",
"@joplin/utils": "~3.0",
"aws-sdk": "2.1340.0",
"chalk": "4.1.2",
"compare-version": "0.1.2",
@@ -57,7 +57,7 @@
"proper-lockfile": "4.1.2",
"read-chunk": "2.1.0",
"server-destroy": "1.0.1",
"sharp": "0.33.1",
"sharp": "0.33.2",
"sprintf-js": "1.1.3",
"sqlite3": "5.1.6",
"string-padding": "1.0.2",
@@ -70,10 +70,10 @@
"yargs-parser": "21.1.1"
},
"devDependencies": {
"@joplin/tools": "~2.14",
"@joplin/tools": "~3.0",
"@types/fs-extra": "11.0.4",
"@types/jest": "29.5.8",
"@types/node": "18.19.6",
"@types/node": "18.19.8",
"@types/proper-lockfile": "^4.1.2",
"gulp": "4.0.2",
"jest": "29.7.0",

View File

@@ -22,6 +22,7 @@ describe('HtmlToMd', () => {
// if (htmlFilename.indexOf('image_preserve_size') !== 0) continue;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const htmlToMdOptions: any = {};
if (htmlFilename === 'anchor_local.html') {

View File

@@ -4,6 +4,7 @@ import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/
import shim from '@joplin/lib/shim';
const { themeStyle } = require('@joplin/lib/theme');
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
function newTestMdToHtml(options: any = null) {
options = {
ResourceModel: {
@@ -37,6 +38,7 @@ describe('MdToHtml', () => {
// if (mdFilename !== 'sanitize_9.md') continue;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const mdToHtmlOptions: any = {
bodyOnly: true,
};
@@ -86,6 +88,7 @@ describe('MdToHtml', () => {
}));
it('should return enabled plugin assets', (async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const pluginOptions: any = {};
const pluginNames = MdToHtml.pluginNames();

View File

@@ -7,9 +7,10 @@
<updated>20231224T151443Z</updated>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div><a href="evernote:///view/5223870/s49/9cd5e810-fa03-429a-8194-ab847f2f1ab2/c99d9e01-ca35-4c75-ba63-f0c0ef97787d/" rel="noopener noreferrer" rev="en_rl_none">Note 2</a><a href="evernote:///view/5223870/s49/9cd5e810-fa03-429a-8194-ab847f2f1ab2/c99d9e01-ca35-4c75-ba63-f0c0ef97787d/" rel="noopener noreferrer" rev="en_rl_none">Note 3</a></div></en-note> ]]>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div><a href="evernote:///view/5223870/s49/9cd5e810-fa03-429a-8194-ab847f2f1ab2/c99d9e01-ca35-4c75-ba63-f0c0ef97787d/">Note 2</a><a href="evernote:///view/5223870/s49/9cd5e810-fa03-429a-8194-ab847f2f1ab2/c99d9e01-ca35-4c75-ba63-f0c0ef97787d/">Note 3</a></div></en-note> ]]>
</content>
</note>
<note>
<title>Note 2</title>
<created>20160730T111759Z</created>
@@ -19,15 +20,37 @@
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div>Testing</div></en-note> ]]>
</content>
</note>
<note>
<title>Note 3</title>
<created>20160730T111759Z</created>
<updated>20160730T111807Z</updated>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div><a href="evernote:///view/5223870/s49/9cd5e810-fa03-429a-8194-ab847f2f1ab2/c99d9e01-ca35-4c75-ba63-f0c0ef97787d/" rel="noopener noreferrer" rev="en_rl_none">Ambiguous note</a></div></en-note> ]]>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div><a href="evernote:///view/5223870/s49/9cd5e810-fa03-429a-8194-ab847f2f1ab2/c99d9e01-ca35-4c75-ba63-f0c0ef97787d/">Ambiguous note</a></div></en-note> ]]>
</content>
</note>
<note>
<title>Note 4</title>
<created>20160730T111759Z</created>
<updated>20160730T111807Z</updated>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div><a href="https://joplinapp.org">Note 5</a></div></en-note> ]]>
</content>
</note>
<note>
<title>Note 5</title>
<created>20160730T111759Z</created>
<updated>20160730T111807Z</updated>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div></div></en-note> ]]>
</content>
</note>
<note>
<title>Ambiguous note</title>
<created>20160730T111759Z</created>
@@ -37,6 +60,7 @@
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div>Testing</div></en-note> ]]>
</content>
</note>
<note>
<title>Ambiguous note</title>
<created>20160730T111759Z</created>

View File

@@ -0,0 +1,15 @@
<table>
<caption>Caption</caption>
<tbody>
<tr>
<th>Row 1, Column 1</th>
<th>Row 1, Column 2</th>
<th>Row 1, Column 3</th>
</tr>
<tr>
<th>Row 2, Column 1</th>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,6 @@
Caption
| | | |
| --- | --- | --- |
| Row 1, Column 1 | Row 1, Column 2 | Row 1, Column 3 |
| Row 2, Column 1 | Row 2, Column 2 | Row 2, Column 3 |

View File

@@ -0,0 +1,19 @@
<table>
<colgroup>
<col />
<col span="2" class="test" />
<col span="2" class="test2" />
</colgroup>
<tbody>
<tr>
<th>Row 1, Column 1</th>
<th>Row 1, Column 2</th>
<th>Row 1, Column 3</th>
</tr>
<tr>
<th>Row 2, Column 1</th>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,4 @@
| | | |
| --- | --- | --- |
| Row 1, Column 1 | Row 1, Column 2 | Row 1, Column 3 |
| Row 2, Column 1 | Row 2, Column 2 | Row 2, Column 3 |

View File

@@ -0,0 +1,20 @@
<div class="joplin-table-wrapper">
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>No</td>
<td>header</td>
</tr>
<tr>
<td>And no</td>
<td>surprises</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -0,0 +1,4 @@
| | |
| --- | --- |
| No | header |
| And no | surprises |

View File

@@ -0,0 +1,16 @@
<div class="joplin-table-wrapper">
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Some paragraph<br class="jop-noMdConv"/><br class="jop-noMdConv"/>inside a table cell</td>
<td>Second column</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -0,0 +1,3 @@
| | |
| --- | --- |
| Some paragraph<br><br>inside a table cell | Second column |

View File

@@ -5,6 +5,7 @@ import shim from '@joplin/lib/shim';
import Setting from '@joplin/lib/models/Setting';
import { db, setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
function describeIfCompatible(name: string, fn: any, elseFn: any) {
if (['win32', 'darwin'].includes(shim.platformName())) {
return describe(name, fn);
@@ -52,7 +53,7 @@ describeIfCompatible('services_KeychainService', () => {
}));
it('should delete db settings if they have been saved in keychain', (async () => {
// First save some secure settings and make sure it ends up in the databse
// First save some secure settings and make sure it ends up in the database
KeychainService.instance().enabled = false;
Setting.setValue('sync.5.password', 'password');

View File

@@ -7,7 +7,7 @@ import Setting from '@joplin/lib/models/Setting';
import * as fs from 'fs-extra';
import Note from '@joplin/lib/models/Note';
import Folder from '@joplin/lib/models/Folder';
import { expectNotThrow, setupDatabaseAndSynchronizer, switchClient, expectThrow, createTempDir, supportDir } from '@joplin/lib/testing/test-utils';
import { expectNotThrow, setupDatabaseAndSynchronizer, switchClient, expectThrow, createTempDir, supportDir, mockMobilePlatform } from '@joplin/lib/testing/test-utils';
import { newPluginScript } from '../../testUtils';
const testPluginDir = `${supportDir}/plugins`;
@@ -82,6 +82,7 @@ describe('services_PluginService', () => {
const allFolders = await Folder.all();
expect(allFolders.length).toBe(2);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
expect(allFolders.map((f: any) => f.title).sort().join(', ')).toBe('multi - simple1, multi - simple2');
}));
@@ -262,6 +263,68 @@ describe('services_PluginService', () => {
}
}));
it.each([
{
manifestPlatforms: ['desktop'],
isDesktop: true,
appVersion: '3.0.0',
shouldRun: true,
},
{
manifestPlatforms: ['desktop'],
isDesktop: false,
appVersion: '3.0.6',
shouldRun: false,
},
{
manifestPlatforms: ['desktop', 'mobile'],
isDesktop: false,
appVersion: '3.0.6',
shouldRun: true,
},
{
manifestPlatforms: [],
isDesktop: false,
appVersion: '3.0.8',
shouldRun: true,
},
])('should enable and disable plugins depending on what platform(s) they support (case %#: %j)', async ({ manifestPlatforms, isDesktop, appVersion, shouldRun }) => {
const pluginScript = `
/* joplin-manifest:
{
"id": "org.joplinapp.plugins.PluginTest",
"manifest_version": 1,
"app_min_version": "1.0.0",
"platforms": ${JSON.stringify(manifestPlatforms)},
"name": "JS Bundle test",
"version": "1.0.0"
}
*/
joplin.plugins.register({
onStart: async function() { },
});
`;
let resetPlatformMock = () => {};
if (!isDesktop) {
resetPlatformMock = mockMobilePlatform('android').reset;
}
try {
const service = newPluginService(appVersion);
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
if (shouldRun) {
await expect(service.runPlugin(plugin)).resolves.toBeUndefined();
} else {
await expect(service.runPlugin(plugin)).rejects.toThrow(/disabled/);
}
} finally {
resetPlatformMock();
}
});
it('should install a plugin', (async () => {
const service = newPluginService();
const pluginPath = `${testPluginDir}/jpl_test/org.joplinapp.FirstJplPlugin.jpl`;

View File

@@ -1,9 +1,14 @@
import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi';
import { AppType } from '@joplin/lib/models/Setting';
import RepositoryApi, { AppInfo, InstallMode } from '@joplin/lib/services/plugins/RepositoryApi';
import shim from '@joplin/lib/shim';
import { setupDatabaseAndSynchronizer, switchClient, supportDir, createTempDir } from '@joplin/lib/testing/test-utils';
import { remove } from 'fs-extra';
async function newRepoApi(): Promise<RepositoryApi> {
const repo = new RepositoryApi(`${supportDir}/pluginRepo`, await createTempDir());
let tempDirs: string[] = [];
async function newRepoApi(appInfo: AppInfo = { type: AppType.Desktop, version: '3.0.0' }): Promise<RepositoryApi> {
const tempDir = await createTempDir();
tempDirs.push(tempDir);
const repo = new RepositoryApi(`${supportDir}/pluginRepo`, tempDir, appInfo, InstallMode.Default);
await repo.initialize();
return repo;
}
@@ -14,6 +19,12 @@ describe('services_plugins_RepositoryApi', () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
});
afterEach(async () => {
for (const tempDir of tempDirs) {
await remove(tempDir);
}
tempDirs = [];
});
it('should get the manifests', (async () => {
const api = await newRepoApi();
@@ -27,9 +38,10 @@ describe('services_plugins_RepositoryApi', () => {
{
const results = await api.search('to');
expect(results.length).toBe(2);
expect(results.length).toBe(3);
expect(!!results.find(m => m.id === 'joplin.plugin.ambrt.backlinksToNote')).toBe(true);
expect(!!results.find(m => m.id === 'org.joplinapp.plugins.ToggleSidebars')).toBe(true);
expect(!!results.find(m => m.id === 'org.joplinapp.plugins.AbcSheetMusic')).toBe(true);
}
{
@@ -45,13 +57,14 @@ describe('services_plugins_RepositoryApi', () => {
expect(await shim.fsDriver().exists(pluginPath)).toBe(true);
}));
it('should tell if a plugin can be updated', (async () => {
const api = await newRepoApi();
expect(await api.pluginCanBeUpdated('org.joplinapp.plugins.ToggleSidebars', '1.0.0', '3.0.0')).toBe(true);
expect(await api.pluginCanBeUpdated('org.joplinapp.plugins.ToggleSidebars', '1.0.0', '1.0.0')).toBe(false);
expect(await api.pluginCanBeUpdated('org.joplinapp.plugins.ToggleSidebars', '1.0.2', '3.0.0')).toBe(false);
expect(await api.pluginCanBeUpdated('does.not.exist', '1.0.0', '3.0.0')).toBe(false);
it.each([
{ id: 'org.joplinapp.plugins.ToggleSidebars', installedVersion: '1.0.0', appVersion: '3.0.0', shouldBeUpdatable: true },
{ id: 'org.joplinapp.plugins.ToggleSidebars', installedVersion: '1.0.0', appVersion: '1.0.0', shouldBeUpdatable: false },
{ id: 'org.joplinapp.plugins.ToggleSidebars', installedVersion: '1.0.2', appVersion: '3.0.0', shouldBeUpdatable: false },
{ id: 'does.not.exist', installedVersion: '1.0.0', appVersion: '3.0.0', shouldBeUpdatable: false },
])('should tell if a plugin can be updated (case %#)', (async ({ id, installedVersion, appVersion, shouldBeUpdatable }) => {
const api = await newRepoApi({ version: appVersion, type: AppType.Desktop });
expect(await api.pluginCanBeUpdated(id, installedVersion)).toBe(shouldBeUpdatable);
}));
});

View File

@@ -2,6 +2,7 @@ import Setting from '@joplin/lib/models/Setting';
import { waitForFolderCount, setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } from '@joplin/lib/testing/test-utils';
import Folder from '@joplin/lib/models/Folder';
import { newPluginScript, newPluginService } from '../../../testUtils';
import eventManager, { EventName } from '@joplin/lib/eventManager';
describe('JoplinSettings', () => {
@@ -66,6 +67,38 @@ describe('JoplinSettings', () => {
await service.destroy();
});
test('should de-register settings change listeners when a plugin is unloaded', async () => {
const service = newPluginService();
const pluginScript = newPluginScript(`
joplin.plugins.register({
onStart: async function() {
await joplin.settings.registerSettings({
'test-setting': {
value: 1234,
type: 1,
public: false,
label: 'Test',
}
});
// Register 8 listeners to improve test reliability in the case
// where listeners are added/removed from other sources.
for (let i = 0; i < 8; i++) {
await joplin.settings.onChange((event) => { });
}
},
});
`);
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
await service.runPlugin(plugin);
const listenerCounter = eventManager.listenerCounter_(EventName.SettingsChange);
plugin.onUnload();
expect(listenerCounter.getCountRemoved()).toBeGreaterThanOrEqual(8);
});
test('should allow registering multiple settings', async () => {
const service = newPluginService();

View File

@@ -4,6 +4,7 @@ import Note from '@joplin/lib/models/Note';
import Folder from '@joplin/lib/models/Folder';
import ItemChange from '@joplin/lib/models/ItemChange';
import { newPluginScript, newPluginService } from '../../../testUtils';
import eventManager, { EventName } from '@joplin/lib/eventManager';
describe('JoplinWorkspace', () => {
@@ -17,6 +18,7 @@ describe('JoplinWorkspace', () => {
});
test('should listen to noteChange events', async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const appState: Record<string, any> = {
selectedNoteIds: [],
};
@@ -49,6 +51,7 @@ describe('JoplinWorkspace', () => {
const folder = (await Folder.all())[0];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const result: any = JSON.parse(folder.title);
expect(result.id).toBe(note.id);
@@ -79,4 +82,33 @@ describe('JoplinWorkspace', () => {
expect(modFolder.title).toBe('changedtitle');
});
test('should remove event listeners when plugins are unloaded', async () => {
const service = newPluginService();
const pluginScript = newPluginScript(`
joplin.plugins.register({
onStart: async () => {
// Register each listener 8 times to improve test reliability -- it's possible
// for listeners for the same events to be added/removed by other sources.
for (let i = 0; i < 8; i++) {
await joplin.workspace.onNoteChange(async (event) => { });
await joplin.workspace.onResourceChange(async (event) => { });
await joplin.workspace.filterEditorContextMenu(async (event) => { });
}
}
})
`);
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
await service.runPlugin(plugin);
const itemChangeListenerCounter = eventManager.listenerCounter_(EventName.ItemChange);
const resourceChangeListenerCounter = eventManager.listenerCounter_(EventName.ResourceChange);
plugin.onUnload();
expect(itemChangeListenerCounter.getCountRemoved()).toBeGreaterThanOrEqual(8);
expect(resourceChangeListenerCounter.getCountRemoved()).toBeGreaterThanOrEqual(8);
await service.destroy();
});
});

View File

@@ -4,8 +4,9 @@ import { checkThrow, setupDatabaseAndSynchronizer, supportDir, switchClient } fr
import PluginService, { defaultPluginSetting, DefaultPluginsInfo } from '@joplin/lib/services/plugins/PluginService';
import Setting from '@joplin/lib/models/Setting';
const testDefaultPluginsDir = `${supportDir}/testDefaultPlugins`;
function newPluginService(appVersion = '1.4') {
function newPluginService(appVersion = '2.4') {
const runner = new PluginRunner();
const service = new PluginService();
service.initialize(
@@ -35,8 +36,7 @@ describe('defaultPluginsUtils', () => {
await switchClient(1);
});
it('should load default plugins when nor previously installed', (async () => {
const testPluginDir = `${supportDir}/testDefaultPlugins`;
it('should load default plugins when not previously installed', (async () => {
Setting.setValue('installedDefaultPlugins', []);
const service = newPluginService('2.1');
@@ -47,7 +47,9 @@ describe('defaultPluginsUtils', () => {
expect(pluginSettings[pluginId]).toBeFalsy();
}
const pluginPathsAndNewSettings = await getDefaultPluginPathsAndSettings(testPluginDir, defaultPluginsInfo, pluginSettings);
const pluginPathsAndNewSettings = await getDefaultPluginPathsAndSettings(
testDefaultPluginsDir, defaultPluginsInfo, pluginSettings, service,
);
for (const pluginId of pluginsId) {
expect(
@@ -57,7 +59,6 @@ describe('defaultPluginsUtils', () => {
}));
it('should keep already created default plugins disabled with previous default plugins installed', (async () => {
const testPluginDir = `${supportDir}/testDefaultPlugins`;
Setting.setValue('installedDefaultPlugins', ['org.joplinapp.plugins.ToggleSidebars']);
Setting.setValue('plugins.states', {
'org.joplinapp.plugins.ToggleSidebars': { ...defaultPluginSetting(), enabled: false },
@@ -66,7 +67,7 @@ describe('defaultPluginsUtils', () => {
const service = newPluginService('2.1');
const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
const pluginPathsAndNewSettings = await getDefaultPluginPathsAndSettings(testPluginDir, defaultPluginsInfo, pluginSettings);
const pluginPathsAndNewSettings = await getDefaultPluginPathsAndSettings(testDefaultPluginsDir, defaultPluginsInfo, pluginSettings, service);
// Should still be disabled
expect(
@@ -171,6 +172,34 @@ describe('defaultPluginsUtils', () => {
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe('initial-path');
});
it('should support disabled-by-default plugins', async () => {
const service = newPluginService();
const plugin = await service.loadPluginFromJsBundle('', sampleJsBundlePlugin);
plugin.builtIn = false;
await service.runPlugin(plugin);
const defaultPluginsInfo: DefaultPluginsInfo = {
'joplin.plugin.ambrt.backlinksToNote': {
enabled: false,
},
'org.joplinapp.plugins.ToggleSidebars': {},
};
Setting.setValue('installedDefaultPlugins', []);
const { pluginSettings } = await getDefaultPluginPathsAndSettings(
testDefaultPluginsDir, defaultPluginsInfo, {}, service,
);
expect(pluginSettings).toMatchObject({
'joplin.plugin.ambrt.backlinksToNote': {
enabled: false,
deleted: false,
},
'org.joplinapp.plugins.ToggleSidebars': defaultPluginSetting(),
});
});
it('should not throw error on missing setting key', async () => {
const service = newPluginService();
@@ -202,4 +231,34 @@ describe('defaultPluginsUtils', () => {
await service.destroy();
});
// Only returning not-yet-loaded plugins prevents non-default versions of built-in plugins
// from being overwritten by PluginService.
it('getDefaultPluginPathsAndSettings should return only plugins that haven\'t been loaded', async () => {
const service = newPluginService();
const testPluginId = 'org.joplinapp.plugins.ToggleSidebars';
const testPluginPath = `${supportDir}/pluginRepo/plugins/${testPluginId}/plugin.jpl`;
const pluginSettings = {
[testPluginId]: defaultPluginSetting(),
};
await service.loadAndRunPlugins([testPluginPath], pluginSettings, { devMode: false, builtIn: false });
// Should be running
expect(service.isPluginLoaded(testPluginId)).toBe(true);
const testDefaultPluginsInfo = {
[testPluginId]: {},
'joplin.plugin.ambrt.backlinksToNote': {},
};
const { pluginPaths } = await getDefaultPluginPathsAndSettings(
testDefaultPluginsDir, testDefaultPluginsInfo, pluginSettings, service,
);
// Should only return plugins that aren't loaded.
expect(pluginPaths).toHaveLength(1);
expect(pluginPaths[0]).toContain('joplin.plugin.ambrt.backlinksToNote');
});
});

View File

@@ -11,11 +11,13 @@ describe('services_plugins_sandboxProxy', () => {
it('should create a new sandbox proxy', (async () => {
interface Result {
path: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
args: any[];
}
const results: Result[] = [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const target: any = (path: string, args: any[]) => {
results.push({ path, args });
};
@@ -34,11 +36,13 @@ describe('services_plugins_sandboxProxy', () => {
it('should allow importing a namespace', (async () => {
interface Result {
path: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
args: any[];
}
const results: Result[] = [];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const target: any = (path: string, args: any[]) => {
results.push({ path, args });
};

View File

@@ -16,6 +16,7 @@
"manifest_version": 1,
"id": "org.joplinapp.plugins.ToggleSidebars",
"app_min_version": "1.6",
"platforms": ["desktop"],
"version": "1.0.2",
"name": "Note list and side bar toggle buttons",
"description": "Adds buttons to toggle note list and sidebar",
@@ -25,5 +26,43 @@
"_publish_hash": "sha256:e0d833b7ef1bb8f02ee4cb861ef1989621358c45a5614911071302dc0527a3b4",
"_publish_commit": "dev:1b5b2342fc25717b77ad9f1627c1a334e5bbae54",
"_npm_package_name": "@joplin/joplin-plugin-toggle-sidebars"
},
"org.joplinapp.plugins.AbcSheetMusic": {
"manifest_version": 1,
"id": "org.joplinapp.plugins.AbcSheetMusic",
"app_min_version": "2.13.5",
"version": "1.0.5",
"name": "ABC Sheet Music Plugin",
"description": "Turns ABC text notation into sheet music",
"author": "Laurent Cozic",
"homepage_url": "https://github.com/joplin/plugin-abc-sheet-music",
"repository_url": "https://github.com/joplin/plugin-abc-sheet-music",
"category": "viewer",
"keywords": [
"sheet music",
"abc",
"notation"
],
"screenshots": [
{
"src": "images/PeacherineRag.png"
},
{
"src": "images/Tablature.png"
}
],
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
},
"promo_tile": {
"src": "images/promo_tile.png"
},
"_publish_hash": "sha256:94a13d4833affbc949ba60174ab77419aa02b0777563a796f7480206b73a864b",
"_publish_commit": "master:2b128c7a21f010e9937a112e0cf1fb5c03f9ca75",
"_npm_package_name": "joplin-plugin-abc-sheet-music",
"_recommended": true
}
}

View File

@@ -0,0 +1,37 @@
{
"manifest_version": 1,
"id": "org.joplinapp.plugins.AbcSheetMusic",
"app_min_version": "2.13.5",
"version": "1.0.5",
"name": "ABC Sheet Music Plugin",
"description": "Turns ABC text notation into sheet music",
"author": "Laurent Cozic",
"homepage_url": "https://github.com/joplin/plugin-abc-sheet-music",
"repository_url": "https://github.com/joplin/plugin-abc-sheet-music",
"category": "viewer",
"keywords": [
"sheet music",
"abc",
"notation"
],
"screenshots": [
{
"src": "images/PeacherineRag.png"
},
{
"src": "images/Tablature.png"
}
],
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
},
"promo_tile": {
"src": "images/promo_tile.png"
},
"_publish_hash": "sha256:94a13d4833affbc949ba60174ab77419aa02b0777563a796f7480206b73a864b",
"_publish_commit": "master:2b128c7a21f010e9937a112e0cf1fb5c03f9ca75",
"_npm_package_name": "joplin-plugin-abc-sheet-music"
}

View File

@@ -2,6 +2,7 @@
"manifest_version": 1,
"id": "org.joplinapp.plugins.ToggleSidebars",
"app_min_version": "1.6",
"platforms": ["desktop"],
"version": "1.0.2",
"name": "Note list and side bar toggle buttons",
"description": "Adds buttons to toggle note list and sidebar",

View File

@@ -0,0 +1,3 @@
dist/
node_modules/
publish/

View File

@@ -0,0 +1,8 @@
*.md
!README.md
/*.jpl
/api
/src
/dist
tsconfig.json
webpack.config.js

View File

@@ -0,0 +1,78 @@
# Plugin development
This documentation describes how to create a plugin, and how to work with the plugin builder framework and API.
## Installation
First, install [Yeoman](http://yeoman.io) and generator-joplin using [npm](https://www.npmjs.com/) (we assume you have pre-installed [node.js](https://nodejs.org/)).
```bash
npm install -g yo@4.3.1
npm install -g generator-joplin
```
Then generate your new project:
```bash
yo --node-package-manager npm joplin
```
## Structure
The main two files you will want to look at are:
- `/src/index.ts`, which contains the entry point for the plugin source code.
- `/src/manifest.json`, which is the plugin manifest. It contains information such as the plugin a name, version, etc.
The file `/plugin.config.json` could also be useful if you intend to use [external scripts](#external-script-files), such as content scripts or webview scripts.
## Building the plugin
The plugin is built using Webpack, which creates the compiled code in `/dist`. A JPL archive will also be created at the root, which can use to distribute the plugin.
To build the plugin, simply run `npm run dist`.
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
## Updating the manifest version number
You can run `npm run updateVersion` to bump the patch part of the version number, so for example 1.0.3 will become 1.0.4. This script will update both the package.json and manifest.json version numbers so as to keep them in sync.
## Publishing the plugin
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
- In `package.json`, the keywords include "joplin-plugin".
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
## Updating the plugin framework
To update the plugin framework, run `npm run update`.
In general this command tries to do the right thing - in particular it's going to merge the changes in package.json and .gitignore instead of overwriting. It will also leave "/src" as well as README.md untouched.
The file that may cause problem is "webpack.config.js" because it's going to be overwritten. For that reason, if you want to change it, consider creating a separate JavaScript file and include it in webpack.config.js. That way, when you update, you only have to restore the line that include your file.
## External script files
By default, the compiler (webpack) is going to compile `src/index.ts` only (as well as any file it imports), and any other file will simply be copied to the plugin package. In some cases this is sufficient, however if you have [content scripts](https://joplinapp.org/api/references/plugin_api/classes/joplincontentscripts.html) or [webview scripts](https://joplinapp.org/api/references/plugin_api/classes/joplinviewspanels.html#addscript) you might want to compile them too, in particular in these two cases:
- The script is a TypeScript file - in which case it has to be compiled to JavaScript.
- The script requires modules you've added to package.json. In that case, the script, whether JS or TS, must be compiled so that the dependencies are bundled with the JPL file.
To get such an external script file to compile, you need to add it to the `extraScripts` array in `plugin.config.json`. The path you add should be relative to /src. For example, if you have a file in "/src/webviews/index.ts", the path should be set to "webviews/index.ts". Once compiled, the file will always be named with a .js extension. So you will get "webviews/index.js" in the plugin package, and that's the path you should use to reference the file.
## More information
- [Joplin Plugin API](https://joplinapp.org/api/references/plugin_api/classes/joplin.html)
- [Joplin Data API](https://joplinapp.org/help/api/references/rest_api)
- [Joplin Plugin Manifest](https://joplinapp.org/api/references/plugin_manifest/)
- Ask for help on the [forum](https://discourse.joplinapp.org/) or our [Discord channel](https://discord.gg/VSj7AFHvpq)
## License
MIT © Laurent Cozic

View File

@@ -0,0 +1,5 @@
# Joplin Plugin
This is an example plugin that supports **both** CodeMirror5 and CodeMirror6.
See https://joplinapp.org/help/api/tutorials/cm6_plugin for the relevant tutorial.

View File

@@ -0,0 +1,14 @@
import Plugin from '../Plugin';
import Joplin from './Joplin';
/**
* @ignore
*/
/**
* @ignore
*/
export default class Global {
private joplin_;
constructor(implementation: any, plugin: Plugin, store: any);
get joplin(): Joplin;
get process(): any;
}

View File

@@ -0,0 +1,74 @@
import Plugin from '../Plugin';
import JoplinData from './JoplinData';
import JoplinPlugins from './JoplinPlugins';
import JoplinWorkspace from './JoplinWorkspace';
import JoplinFilters from './JoplinFilters';
import JoplinCommands from './JoplinCommands';
import JoplinViews from './JoplinViews';
import JoplinInterop from './JoplinInterop';
import JoplinSettings from './JoplinSettings';
import JoplinContentScripts from './JoplinContentScripts';
import JoplinClipboard from './JoplinClipboard';
import JoplinWindow from './JoplinWindow';
import BasePlatformImplementation from '../BasePlatformImplementation';
import JoplinImaging from './JoplinImaging';
/**
* This is the main entry point to the Joplin API. You can access various services using the provided accessors.
*
* The API is now relatively stable and in general maintaining backward compatibility is a top priority, so you shouldn't except much breakages.
*
* If a breaking change ever becomes needed, best effort will be done to:
*
* - Deprecate features instead of removing them, so as to give you time to fix the issue;
* - Document breaking changes in the changelog;
*
* So if you are developing a plugin, please keep an eye on the changelog as everything will be in there with information about how to update your code.
*/
export default class Joplin {
private data_;
private plugins_;
private imaging_;
private workspace_;
private filters_;
private commands_;
private views_;
private interop_;
private settings_;
private contentScripts_;
private clipboard_;
private window_;
private implementation_;
constructor(implementation: BasePlatformImplementation, plugin: Plugin, store: any);
get data(): JoplinData;
get clipboard(): JoplinClipboard;
get imaging(): JoplinImaging;
get window(): JoplinWindow;
get plugins(): JoplinPlugins;
get workspace(): JoplinWorkspace;
get contentScripts(): JoplinContentScripts;
/**
* @ignore
*
* Not sure if it's the best way to hook into the app
* so for now disable filters.
*/
get filters(): JoplinFilters;
get commands(): JoplinCommands;
get views(): JoplinViews;
get interop(): JoplinInterop;
get settings(): JoplinSettings;
/**
* It is not possible to bundle native packages with a plugin, because they
* need to work cross-platforms. Instead access to certain useful native
* packages is provided using this function.
*
* Currently these packages are available:
*
* - [sqlite3](https://www.npmjs.com/package/sqlite3)
* - [fs-extra](https://www.npmjs.com/package/fs-extra)
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/nativeModule)
*/
require(_path: string): any;
versionInfo(): Promise<import("./types").VersionInfo>;
}

View File

@@ -0,0 +1,23 @@
export default class JoplinClipboard {
private electronClipboard_;
private electronNativeImage_;
constructor(electronClipboard: any, electronNativeImage: any);
readText(): Promise<string>;
writeText(text: string): Promise<void>;
readHtml(): Promise<string>;
writeHtml(html: string): Promise<void>;
/**
* Returns the image in [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.
*/
readImage(): Promise<string>;
/**
* Takes an image in [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.
*/
writeImage(dataUrl: string): Promise<void>;
/**
* Returns the list available formats (mime types).
*
* For example [ 'text/plain', 'text/html' ]
*/
availableFormats(): Promise<string[]>;
}

View File

@@ -0,0 +1,89 @@
import { Command } from './types';
/**
* This class allows executing or registering new Joplin commands. Commands
* can be executed or associated with
* {@link JoplinViewsToolbarButtons | toolbar buttons} or
* {@link JoplinViewsMenuItems | menu items}.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command)
*
* ## Executing Joplin's internal commands
*
* It is also possible to execute internal Joplin's commands which, as of
* now, are not well documented. You can find the list directly on GitHub
* though at the following locations:
*
* * [Main screen commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/MainScreen/commands)
* * [Global commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/commands)
* * [Editor commands](https://github.com/laurent22/joplin/tree/dev/packages/app-desktop/gui/NoteEditor/editorCommandDeclarations.ts)
*
* To view what arguments are supported, you can open any of these files
* and look at the `execute()` command.
*
* ## Executing editor commands
*
* There might be a situation where you want to invoke editor commands
* without using a {@link JoplinContentScripts | contentScript}. For this
* reason Joplin provides the built in `editor.execCommand` command.
*
* `editor.execCommand` should work with any core command in both the
* [CodeMirror](https://codemirror.net/doc/manual.html#execCommand) and
* [TinyMCE](https://www.tiny.cloud/docs/api/tinymce/tinymce.editorcommands/#execcommand) editors,
* as well as most functions calls directly on a CodeMirror editor object (extensions).
*
* * [CodeMirror commands](https://codemirror.net/doc/manual.html#commands)
* * [TinyMCE core editor commands](https://www.tiny.cloud/docs/advanced/editor-command-identifiers/#coreeditorcommands)
*
* `editor.execCommand` supports adding arguments for the commands.
*
* ```typescript
* await joplin.commands.execute('editor.execCommand', {
* name: 'madeUpCommand', // CodeMirror and TinyMCE
* args: [], // CodeMirror and TinyMCE
* ui: false, // TinyMCE only
* value: '', // TinyMCE only
* });
* ```
*
* [View the example using the CodeMirror editor](https://github.com/laurent22/joplin/blob/dev/packages/app-cli/tests/support/plugins/codemirror_content_script/src/index.ts)
*
*/
export default class JoplinCommands {
/**
* <span class="platform-desktop">desktop</span> Executes the given
* command.
*
* The command can take any number of arguments, and the supported
* arguments will vary based on the command. For custom commands, this
* is the `args` passed to the `execute()` function. For built-in
* commands, you can find the supported arguments by checking the links
* above.
*
* ```typescript
* // Create a new note in the current notebook:
* await joplin.commands.execute('newNote');
*
* // Create a new sub-notebook under the provided notebook
* // Note: internally, notebooks are called "folders".
* await joplin.commands.execute('newFolder', "SOME_FOLDER_ID");
* ```
*/
execute(commandName: string, ...args: any[]): Promise<any | void>;
/**
* <span class="platform-desktop">desktop</span> Registers a new command.
*
* ```typescript
* // Register a new commmand called "testCommand1"
*
* await joplin.commands.register({
* name: 'testCommand1',
* label: 'My Test Command 1',
* iconName: 'fas fa-music',
* execute: () => {
* alert('Testing plugin command 1');
* },
* });
* ```
*/
register(command: Command): Promise<void>;
}

View File

@@ -0,0 +1,40 @@
import Plugin from '../Plugin';
import { ContentScriptType } from './types';
export default class JoplinContentScripts {
private plugin;
constructor(plugin: Plugin);
/**
* Registers a new content script. Unlike regular plugin code, which runs in
* a separate process, content scripts run within the main process code and
* thus allow improved performances and more customisations in specific
* cases. It can be used for example to load a Markdown or editor plugin.
*
* Note that registering a content script in itself will do nothing - it
* will only be loaded in specific cases by the relevant app modules (eg.
* the Markdown renderer or the code editor). So it is not a way to inject
* and run arbitrary code in the app, which for safety and performance
* reasons is not supported.
*
* The plugin generator provides a way to build any content script you might
* want to package as well as its dependencies. See the [Plugin Generator
* doc](https://github.com/laurent22/joplin/blob/dev/packages/generator-joplin/README.md)
* for more information.
*
* * [View the renderer demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script)
* * [View the editor demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/codemirror_content_script)
*
* See also the [postMessage demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/post_messages)
*
* @param type Defines how the script will be used. See the type definition for more information about each supported type.
* @param id A unique ID for the content script.
* @param scriptPath Must be a path relative to the plugin main script. For example, if your file content_script.js is next to your index.ts file, you would set `scriptPath` to `"./content_script.js`.
*/
register(type: ContentScriptType, id: string, scriptPath: string): Promise<void>;
/**
* Listens to a messages sent from the content script using postMessage().
* See {@link ContentScriptType} for more information as well as the
* [postMessage
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/post_messages)
*/
onMessage(contentScriptId: string, callback: any): Promise<void>;
}

View File

@@ -0,0 +1,73 @@
import { ModelType } from '../../../BaseModel';
import Plugin from '../Plugin';
import { Path } from './types';
/**
* This module provides access to the Joplin data API: https://joplinapp.org/help/api/references/rest_api
* This is the main way to retrieve data, such as notes, notebooks, tags, etc.
* or to update them or delete them.
*
* This is also what you would use to search notes, via the `search` endpoint.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/simple)
*
* In general you would use the methods in this class as if you were using a REST API. There are four methods that map to GET, POST, PUT and DELETE calls.
* And each method takes these parameters:
*
* * `path`: This is an array that represents the path to the resource in the form `["resouceName", "resourceId", "resourceLink"]` (eg. ["tags", ":id", "notes"]). The "resources" segment is the name of the resources you want to access (eg. "notes", "folders", etc.). If not followed by anything, it will refer to all the resources in that collection. The optional "resourceId" points to a particular resources within the collection. Finally, an optional "link" can be present, which links the resource to a collection of resources. This can be used in the API for example to retrieve all the notes associated with a tag.
* * `query`: (Optional) The query parameters. In a URL, this is the part after the question mark "?". In this case, it should be an object with key/value pairs.
* * `data`: (Optional) Applies to PUT and POST calls only. The request body contains the data you want to create or modify, for example the content of a note or folder.
* * `files`: (Optional) Used to create new resources and associate them with files.
*
* Please refer to the [Joplin API documentation](https://joplinapp.org/help/api/references/rest_api) for complete details about each call. As the plugin runs within the Joplin application **you do not need an authorisation token** to use this API.
*
* For example:
*
* ```typescript
* // Get a note ID, title and body
* const noteId = 'some_note_id';
* const note = await joplin.data.get(['notes', noteId], { fields: ['id', 'title', 'body'] });
*
* // Get all folders
* const folders = await joplin.data.get(['folders']);
*
* // Set the note body
* await joplin.data.put(['notes', noteId], null, { body: "New note body" });
*
* // Create a new note under one of the folders
* await joplin.data.post(['notes'], null, { body: "my new note", title: "some title", parent_id: folders[0].id });
* ```
*/
export default class JoplinData {
private api_;
private pathSegmentRegex_;
private plugin;
constructor(plugin: Plugin);
private serializeApiBody;
private pathToString;
get(path: Path, query?: any): Promise<any>;
post(path: Path, query?: any, body?: any, files?: any[]): Promise<any>;
put(path: Path, query?: any, body?: any, files?: any[]): Promise<any>;
delete(path: Path, query?: any): Promise<any>;
itemType(itemId: string): Promise<ModelType>;
resourcePath(resourceId: string): Promise<string>;
/**
* Gets an item user data. User data are key/value pairs. The `key` can be any
* arbitrary string, while the `value` can be of any type supported by
* [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)
*
* User data is synchronised across devices, and each value wil be merged based on their timestamp:
*
* - If value is modified by client 1, then modified by client 2, it will take the value from client 2
* - If value is modified by client 1, then deleted by client 2, the value will be deleted after merge
* - If value is deleted by client 1, then updated by client 2, the value will be restored and set to the value from client 2 after merge
*/
userDataGet<T>(itemType: ModelType, itemId: string, key: string): Promise<T>;
/**
* Sets a note user data. See {@link JoplinData.userDataGet} for more details.
*/
userDataSet<T>(itemType: ModelType, itemId: string, key: string, value: T): Promise<void>;
/**
* Deletes a note user data. See {@link JoplinData.userDataGet} for more details.
*/
userDataDelete(itemType: ModelType, itemId: string, key: string): Promise<void>;
}

View File

@@ -0,0 +1,10 @@
/**
* @ignore
*
* Not sure if it's the best way to hook into the app
* so for now disable filters.
*/
export default class JoplinFilters {
on(name: string, callback: Function): Promise<void>;
off(name: string, callback: Function): Promise<void>;
}

View File

@@ -0,0 +1,61 @@
import { Rectangle } from './types';
export interface Implementation {
nativeImage: any;
}
export interface CreateFromBufferOptions {
width?: number;
height?: number;
scaleFactor?: number;
}
export interface ResizeOptions {
width?: number;
height?: number;
quality?: 'good' | 'better' | 'best';
}
export type Handle = string;
/**
* Provides imaging functions to resize or process images. You create an image
* using one of the `createFrom` functions, then use the other functions to
* process the image.
*
* Images are associated with a handle which is what will be available to the
* plugin. Once you are done with an image, free it using the `free()` function.
*
* [View the
* example](https://github.com/laurent22/joplin/blob/dev/packages/app-cli/tests/support/plugins/imaging/src/index.ts)
*
*/
export default class JoplinImaging {
private implementation_;
private images_;
constructor(implementation: Implementation);
private createImageHandle;
private imageByHandle;
private cacheImage;
createFromPath(filePath: string): Promise<Handle>;
createFromResource(resourceId: string): Promise<Handle>;
getSize(handle: Handle): Promise<any>;
resize(handle: Handle, options?: ResizeOptions): Promise<string>;
crop(handle: Handle, rectange: Rectangle): Promise<string>;
toPngFile(handle: Handle, filePath: string): Promise<void>;
/**
* Quality is between 0 and 100
*/
toJpgFile(handle: Handle, filePath: string, quality?: number): Promise<void>;
private tempFilePath;
/**
* Creates a new Joplin resource from the image data. The image will be
* first converted to a JPEG.
*/
toJpgResource(handle: Handle, resourceProps: any, quality?: number): Promise<import("../../database/types").ResourceEntity>;
/**
* Creates a new Joplin resource from the image data. The image will be
* first converted to a PNG.
*/
toPngResource(handle: Handle, resourceProps: any): Promise<import("../../database/types").ResourceEntity>;
/**
* Image data is not automatically deleted by Joplin so make sure you call
* this method on the handle once you are done.
*/
free(handle: Handle): Promise<void>;
}

View 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/help/api/references/rest_api
*/
export default class JoplinInterop {
registerExportModule(module: ExportModule): Promise<void>;
registerImportModule(module: ImportModule): Promise<void>;
}

View File

@@ -0,0 +1,43 @@
import Plugin from '../Plugin';
import { ContentScriptType, Script } from './types';
/**
* This class provides access to plugin-related features.
*/
export default class JoplinPlugins {
private plugin;
constructor(plugin: Plugin);
/**
* Registers a new plugin. This is the entry point when creating a plugin. You should pass a simple object with an `onStart` method to it.
* That `onStart` method will be executed as soon as the plugin is loaded.
*
* ```typescript
* joplin.plugins.register({
* onStart: async function() {
* // Run your plugin code here
* }
* });
* ```
*/
register(script: Script): Promise<void>;
/**
* @deprecated Use joplin.contentScripts.register()
*/
registerContentScript(type: ContentScriptType, id: string, scriptPath: string): Promise<void>;
/**
* Gets the plugin own data directory path. Use this to store any
* plugin-related data. Unlike [[installationDir]], any data stored here
* will be persisted.
*/
dataDir(): Promise<string>;
/**
* Gets the plugin installation directory. This can be used to access any
* asset that was packaged with the plugin. This directory should be
* considered read-only because any data you store here might be deleted or
* re-created at any time. To store new persistent data, use [[dataDir]].
*/
installationDir(): Promise<string>;
/**
* @deprecated Use joplin.require()
*/
require(_path: string): any;
}

View File

@@ -0,0 +1,63 @@
import Plugin from '../Plugin';
import { SettingItem, SettingSection } from './types';
export interface ChangeEvent {
/**
* Setting keys that have been changed
*/
keys: string[];
}
export type ChangeHandler = (event: ChangeEvent) => void;
export declare const namespacedKey: (pluginId: string, key: string) => string;
/**
* This API allows registering new settings and setting sections, as well as getting and setting settings. Once a setting has been registered it will appear in the config screen and be editable by the user.
*
* Settings are essentially key/value pairs.
*
* Note: Currently this API does **not** provide access to Joplin's built-in settings. This is by design as plugins that modify user settings could give unexpected results
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/settings)
*/
export default class JoplinSettings {
private plugin_;
constructor(plugin: Plugin);
/**
* Registers new settings.
* Note that registering a setting item is dynamic and will be gone next time Joplin starts.
* What it means is that you need to register the setting every time the plugin starts (for example in the onStart event).
* The setting value however will be preserved from one launch to the next so there is no risk that it will be lost even if for some
* reason the plugin fails to start at some point.
*/
registerSettings(settings: Record<string, SettingItem>): Promise<void>;
/**
* @deprecated Use joplin.settings.registerSettings()
*
* Registers a new setting.
*/
registerSetting(key: string, settingItem: SettingItem): Promise<void>;
/**
* Registers a new setting section. Like for registerSetting, it is dynamic and needs to be done every time the plugin starts.
*/
registerSection(name: string, section: SettingSection): Promise<void>;
/**
* Gets a setting value (only applies to setting you registered from your plugin)
*/
value(key: string): Promise<any>;
/**
* Sets a setting value (only applies to setting you registered from your plugin)
*/
setValue(key: string, value: any): Promise<void>;
/**
* Gets a global setting value, including app-specific settings and those set by other plugins.
*
* The list of available settings is not documented yet, but can be found by looking at the source code:
*
* https://github.com/laurent22/joplin/blob/dev/packages/lib/models/Setting.ts#L142
*/
globalValue(key: string): Promise<any>;
/**
* Called when one or multiple settings of your plugin have been changed.
* - For performance reasons, this event is triggered with a delay.
* - You will only get events for your own plugin settings.
*/
onChange(handler: ChangeHandler): Promise<void>;
}

View File

@@ -0,0 +1,31 @@
import Plugin from '../Plugin';
import JoplinViewsDialogs from './JoplinViewsDialogs';
import JoplinViewsMenuItems from './JoplinViewsMenuItems';
import JoplinViewsMenus from './JoplinViewsMenus';
import JoplinViewsToolbarButtons from './JoplinViewsToolbarButtons';
import JoplinViewsPanels from './JoplinViewsPanels';
import JoplinViewsNoteList from './JoplinViewsNoteList';
/**
* This namespace provides access to view-related services.
*
* All view services provide a `create()` method which you would use to create the view object, whether it's a dialog, a toolbar button or a menu item.
* In some cases, the `create()` method will return a [[ViewHandle]], which you would use to act on the view, for example to set certain properties or call some methods.
*/
export default class JoplinViews {
private store;
private plugin;
private panels_;
private menuItems_;
private menus_;
private toolbarButtons_;
private dialogs_;
private noteList_;
private implementation_;
constructor(implementation: any, plugin: Plugin, store: any);
get dialogs(): JoplinViewsDialogs;
get panels(): JoplinViewsPanels;
get menuItems(): JoplinViewsMenuItems;
get menus(): JoplinViewsMenus;
get toolbarButtons(): JoplinViewsToolbarButtons;
get noteList(): JoplinViewsNoteList;
}

View File

@@ -0,0 +1,74 @@
import Plugin from '../Plugin';
import { ButtonSpec, ViewHandle, DialogResult } from './types';
/**
* Allows creating and managing dialogs. A dialog is modal window that
* contains a webview and a row of buttons. You can update the
* webview using the `setHtml` method. Dialogs are hidden by default and
* you need to call `open()` to open them. Once the user clicks on a
* button, the `open` call will return an object indicating what button was
* clicked on.
*
* ## Retrieving form values
*
* If your HTML content included one or more forms, a `formData` object
* will also be included with the key/value for each form.
*
* ## Special button IDs
*
* The following buttons IDs have a special meaning:
*
* - `ok`, `yes`, `submit`, `confirm`: They are considered "submit" buttons
* - `cancel`, `no`, `reject`: They are considered "dismiss" buttons
*
* This information is used by the application to determine what action
* should be done when the user presses "Enter" or "Escape" within the
* dialog. If they press "Enter", the first "submit" button will be
* automatically clicked. If they press "Escape" the first "dismiss" button
* will be automatically clicked.
*
* [View the demo
* plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/dialog)
*/
export default class JoplinViewsDialogs {
private store;
private plugin;
private implementation_;
constructor(implementation: any, plugin: Plugin, store: any);
private controller;
/**
* Creates a new dialog
*/
create(id: string): Promise<ViewHandle>;
/**
* Displays a message box with OK/Cancel buttons. Returns the button index that was clicked - "0" for OK and "1" for "Cancel"
*/
showMessageBox(message: string): Promise<number>;
/**
* Displays a dialog to select a file or a directory. Same options and
* output as
* https://www.electronjs.org/docs/latest/api/dialog#dialogshowopendialogbrowserwindow-options
*/
showOpenDialog(options: any): Promise<any>;
/**
* Sets the dialog HTML content
*/
setHtml(handle: ViewHandle, html: string): Promise<string>;
/**
* Adds and loads a new JS or CSS files into the dialog.
*/
addScript(handle: ViewHandle, scriptPath: string): Promise<void>;
/**
* Sets the dialog buttons.
*/
setButtons(handle: ViewHandle, buttons: ButtonSpec[]): Promise<ButtonSpec[]>;
/**
* Opens the dialog
*/
open(handle: ViewHandle): Promise<DialogResult>;
/**
* Toggle on whether to fit the dialog size to the content or not.
* When set to false, the dialog is set to 90vw and 80vh
* @default true
*/
setFitToContent(handle: ViewHandle, status: boolean): Promise<boolean>;
}

View File

@@ -0,0 +1,16 @@
import { CreateMenuItemOptions, MenuItemLocation } from './types';
import Plugin from '../Plugin';
/**
* Allows creating and managing menu items.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command)
*/
export default class JoplinViewsMenuItems {
private store;
private plugin;
constructor(plugin: Plugin, store: any);
/**
* Creates a new menu item and associate it with the given command. You can specify under which menu the item should appear using the `location` parameter.
*/
create(id: string, commandName: string, location?: MenuItemLocation, options?: CreateMenuItemOptions): Promise<void>;
}

View File

@@ -0,0 +1,18 @@
import { MenuItem, MenuItemLocation } from './types';
import Plugin from '../Plugin';
/**
* Allows creating menus.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/menu)
*/
export default class JoplinViewsMenus {
private store;
private plugin;
constructor(plugin: Plugin, store: any);
private registerCommandAccelerators;
/**
* Creates a new menu from the provided menu items and place it at the given location. As of now, it is only possible to place the
* menu as a sub-menu of the application build-in menus.
*/
create(id: string, label: string, menuItems: MenuItem[], location?: MenuItemLocation): Promise<void>;
}

View File

@@ -0,0 +1,24 @@
import { Store } from 'redux';
import Plugin from '../Plugin';
import { ListRenderer } from './noteListType';
/**
* This API allows you to customise how each note in the note list is rendered.
* The renderer you implement follows a unidirectional data flow.
*
* The app provides the required dependencies whenever a note is updated - you
* process these dependencies, and return some props, which are then passed to
* your template and rendered. See [[[ListRenderer]]] for a detailed description
* of each property of the renderer.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/note_list_renderer)
*
* The default list renderer is implemented using the same API, so it worth checking it too:
*
* [Default list renderer](https://github.com/laurent22/joplin/tree/dev/packages/lib/services/noteList/defaultListRenderer.ts)
*/
export default class JoplinViewsNoteList {
private plugin_;
private store_;
constructor(plugin: Plugin, store: Store);
registerRenderer(renderer: ListRenderer): Promise<void>;
}

View File

@@ -0,0 +1,78 @@
import Plugin from '../Plugin';
import { ViewHandle } from './types';
/**
* Allows creating and managing view panels. View panels currently are
* displayed at the right of the sidebar and allows displaying any HTML
* content (within a webview) and update it in real-time. For example it
* could be used to display a table of content for the active note, or
* display various metadata or graph.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/toc)
*/
export default class JoplinViewsPanels {
private store;
private plugin;
constructor(plugin: Plugin, store: any);
private controller;
/**
* Creates a new panel
*/
create(id: string): Promise<ViewHandle>;
/**
* Sets the panel webview HTML
*/
setHtml(handle: ViewHandle, html: string): Promise<string>;
/**
* Adds and loads a new JS or CSS files into the panel.
*/
addScript(handle: ViewHandle, scriptPath: string): Promise<void>;
/**
* Called when a message is sent from the webview (using postMessage).
*
* To post a message from the webview to the plugin use:
*
* ```javascript
* const response = await webviewApi.postMessage(message);
* ```
*
* - `message` can be any JavaScript object, string or number
* - `response` is whatever was returned by the `onMessage` handler
*
* Using this mechanism, you can have two-way communication between the
* plugin and webview.
*
* See the [postMessage
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/post_messages) for more details.
*
*/
onMessage(handle: ViewHandle, callback: Function): Promise<void>;
/**
* Sends a message to the webview.
*
* The webview must have registered a message handler prior, otherwise the message is ignored. Use;
*
* ```javascript
* webviewApi.onMessage((message) => { ... });
* ```
*
* - `message` can be any JavaScript object, string or number
*
* The view API may have only one onMessage handler defined.
* This method is fire and forget so no response is returned.
*
* It is particularly useful when the webview needs to react to events emitted by the plugin or the joplin api.
*/
postMessage(handle: ViewHandle, message: any): void;
/**
* Shows the panel
*/
show(handle: ViewHandle, show?: boolean): Promise<void>;
/**
* Hides the panel
*/
hide(handle: ViewHandle): Promise<void>;
/**
* Tells whether the panel is visible or not
*/
visible(handle: ViewHandle): Promise<boolean>;
}

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