1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-24 20:19:10 +02:00

Compare commits

...

608 Commits

Author SHA1 Message Date
Laurent Cozic
4ad0ced568 Android 3.2.1 2024-11-10 14:33:30 +00:00
Laurent Cozic
cc87ece6fb Desktop release v3.2.1 2024-11-10 14:09:34 +00:00
Shashank Tyagi
4356a2010d Desktop: Fix drop cursor styling issue (#11336) (#11345)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-11-10 14:06:54 +00:00
Laurent Cozic
f091c32992 Plugins: Add support for editor plugins (#11296) 2024-11-10 14:04:46 +00:00
Laurent Cozic
49e86d116f Desktop, Mobile: Fixed vertical alignment of checkboxes 2024-11-10 12:04:28 +00:00
Laurent Cozic
e16f452bdf Desktop: By default disable pasting colors in RTE, and added option to enable it 2024-11-09 23:58:15 +00:00
Laurent Cozic
de83b42972 Tools: Trying to fix Renovate Yarn install 2024-11-09 22:06:08 +00:00
Laurent Cozic
2426cedb18 Tools: Trying to fix CLA signature with protected branch 2024-11-09 21:46:43 +00:00
renovate[bot]
6a7d0ee22c Update dependency @react-native-community/geolocation to v3.3.0 (#11342)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-09 21:13:08 +00:00
Laurent Cozic
0b4b768049 lock files 2024-11-09 13:55:48 +00:00
Laurent Cozic
33942d44c8 Revert "Desktop: Add OneNote Importer (#10642)"
This reverts commit b248700e28.

We need to find a solution to make building the Rust package optional
2024-11-09 13:42:37 +00:00
Laurent Cozic
551bcc68cf Merge branch 'release-3.1' into dev 2024-11-09 13:41:37 +00:00
Laurent Cozic
50b16c6054 iOS 13.1.7 2024-11-09 13:05:25 +00:00
Laurent Cozic
3ff720463b Android 3.1.8 2024-11-09 13:04:50 +00:00
Laurent Cozic
d58126484a Desktop release v3.1.24 2024-11-09 12:56:27 +00:00
Liffindra Angga Zaaldian
5056ac4e61 fix typos and proper translation (#11362) 2024-11-09 12:54:51 +00:00
Henry Heino
360ece6f88 Desktop: Fix title rendering in GotoAnything search results (#11356) 2024-11-09 12:54:29 +00:00
Henry Heino
a08ebb9ce5 Android: Fixes #11324: Fix sharing to Joplin causes back navigation to get stuck (#11355) 2024-11-09 12:54:09 +00:00
Henry Heino
0876086caa Desktop: Fixes #11335: Markdown editor: Auto-close backticks (#11351) 2024-11-09 12:53:25 +00:00
Laurent Cozic
a169f757a6 Update renovate.json5 2024-11-09 12:52:31 +00:00
Henry Heino
a616dc3cd2 Desktop: Fix errors found by automated accessibility testing (#11246)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-11-09 12:50:06 +00:00
pedr
b248700e28 Desktop: Add OneNote Importer (#10642) 2024-11-09 12:47:01 +00:00
Henry Heino
5aa29d38ef Mobile: Resolves #11202: Use a FontAwesome icon for the trash folder (#11357) 2024-11-09 12:46:47 +00:00
Henry Heino
4d5b1ce5fd Mobile: Accessibility: Improve setting control accessibility (#11358) 2024-11-09 12:46:16 +00:00
Henry Heino
1e21fc242b Chore: Website CI: Do not commit after making changes (#11360) 2024-11-09 12:46:03 +00:00
renovate[bot]
a99202412c Update dependency source-map-loader to v5 (#11349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-09 12:45:00 +00:00
renovate[bot]
279e93398f Update dependency madge to v7 (#11348)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-09 12:44:52 +00:00
Henry Heino
3894c05217 Chore: Fix website build (#11359) 2024-11-09 12:44:12 +00:00
Henry Heino
1fca7eddcb Mobile: Fixes #11325: Fix error on creating new notes if the user is a share recipient (#11326) 2024-11-08 15:34:39 +00:00
Henry Heino
4a88d6ff7a Desktop: Multiple window support (#11181)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-11-08 15:32:05 +00:00
renovate[bot]
cbef725cc8 Update dependency ldapts to v7.1.0 (#11344)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 15:31:42 +00:00
renovate[bot]
3711f72cb0 Update dependency highlight.js to v11.10.0 (#11343)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 15:31:34 +00:00
renovate[bot]
1db8e65321 Update dependency @react-native-community/datetimepicker to v8.2.0 (#11341)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 15:31:00 +00:00
Henry Heino
9fb104ec7c Mobile: Fixes #11276: Fix new note button is pushed offscreen on certain Android devices (#11323) 2024-11-08 13:01:29 +00:00
renovate[bot]
39924b7dd2 Update dependency react-native-localize to v3.2.1 (#11340) 2024-11-08 12:33:17 +00:00
renovate[bot]
1766f4a63d Update dependency node-mocks-http to v1.15.1 (#11339) 2024-11-08 12:05:27 +00:00
renovate[bot]
0b6082d679 Update dependency lint-staged to v15.2.8 (#11332) 2024-11-07 19:42:35 +00:00
renovate[bot]
62ccf1eb2f Update dependency expo to v51.0.26 (#11331) 2024-11-07 19:23:50 +00:00
renovate[bot]
496d6c8254 Update dependency @types/yargs to v17.0.33 (#11330) 2024-11-07 18:53:41 +00:00
renovate[bot]
f3bd6d473c Update dependency @types/serviceworker to v0.0.92 (#11329) 2024-11-07 18:46:04 +00:00
pedr
0aba14f581 Desktop,CLI: Fixes #10653: Change Resource filetype detecting strategy (#10907)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-11-07 13:46:08 +00:00
pedr
02a0d0d0cc Desktop, Mobile: Resolves #10664: Allow user to generate deletion logs (#11083) 2024-11-07 13:45:29 +00:00
Laurent Cozic
5a44f62fb6 Chore: Fixed CI logic 2024-11-06 17:58:12 +00:00
Laurent Cozic
10583bf426 Merge branch 'release-3.1' into dev 2024-11-05 17:57:23 +00:00
Laurent Cozic
b3ea127848 Desktop release v3.1.23 2024-11-05 17:54:37 +00:00
Henry Heino
cbe55055e9 Desktop: Fixes #11313: Don't completely left-align the editor with the toolbar (#11316) 2024-11-05 17:53:35 +00:00
Laurent Cozic
6f174952ab Chore: Removed pre jobs from CI 2024-11-05 17:29:50 +00:00
Henry Heino
2194eb4df5 Chore: Desktop: Fixes #9608: Fix comment style in Linux launcher file (#11309)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-11-05 09:06:10 +00:00
Henry Heino
9b9bb6eb49 Chore: Disable flaky test: Disable Rich Text Editor case of the editor.setText command test (#11311) 2024-11-05 09:04:44 +00:00
Laurent Cozic
da10297572 Desktop release v3.1.22 2024-11-04 20:42:34 +00:00
Laurent Cozic
9866c27156 Chore: Fixed macOS CI 2024-11-04 20:42:19 +00:00
Laurent Cozic
ce26e085ff Merge branch 'release-3.1' into dev 2024-11-04 20:33:15 +00:00
Laurent Cozic
6875fd271c Android 3.1.7 2024-11-04 20:28:06 +00:00
Laurent Cozic
a5c14c8d10 Desktop release v3.1.21 2024-11-04 20:21:49 +00:00
Henry Heino
580188c477 Tools: Update CI runner to MacOS 13 (#11308) 2024-11-04 19:17:32 +00:00
renovate[bot]
0e1f6f48ef Update dependency @react-native/metro-config to v0.74.87 (#11306) 2024-11-03 22:43:04 +00:00
Laurent Cozic
b10a993592 Chore: Retrying test that may get stuck 2024-11-03 20:25:15 +00:00
Laurent Cozic
50e1c26890 Tools: Disable skipped workflow logic to allow automerge to work 2024-11-03 16:57:19 +00:00
Laurent Cozic
fb09870d21 Tools: Trying to fix automerge action 2024-11-03 16:02:44 +00:00
Laurent Cozic
43fb20bd79 Revert "Update dependency @react-native/metro-config to v0.74.87 (#11305)"
This reverts commit 99b01c2822.
2024-11-03 15:55:18 +00:00
Laurent Cozic
4339ae72b6 Revert "Update dependency @types/node to v18.19.43 (#11303)"
This reverts commit 82d4c4d4cc.
2024-11-03 15:55:04 +00:00
renovate[bot]
99b01c2822 Update dependency @react-native/metro-config to v0.74.87 (#11305) 2024-11-03 14:04:53 +00:00
renovate[bot]
82d4c4d4cc Update dependency @types/node to v18.19.43 (#11303) 2024-11-03 13:38:16 +00:00
Laurent Cozic
6fff7284cf Tools: Trying to fix automerge action 2024-11-03 13:03:26 +00:00
Laurent Cozic
e0b420c288 Revert "Update dependency @types/node to v18.19.43 (#11301)"
This reverts commit 8fb85abe1a.

Reason: Breaks CI
2024-11-03 12:59:47 +00:00
Laurent Cozic
c9ee4900ef Doc: Fixed plugin API note list images 2024-11-02 21:53:51 +00:00
renovate[bot]
8fb85abe1a Update dependency @types/node to v18.19.43 (#11301) 2024-11-01 06:05:07 +00:00
Joplin Bot
7590c13db4 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-11-01 00:53:02 +00:00
tiberiusteng
2fc9bd476b Mobile: Fixes #9204: Handle callback url triggered app launch (#11280)
Co-authored-by: Tib Teng <661892+tiberiusteng@users.noreply.github.com>
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-10-31 08:19:13 +00:00
Henry Heino
ddd18551eb Mobile: Fixes #11197: Fix search result note hidden after powering on device (#11297) 2024-10-31 08:18:13 +00:00
Henry Heino
e32d6e93f3 Mobile: Center sidebar icons (#11299) 2024-10-31 08:17:18 +00:00
Henry Heino
7193dd1918 Chore: Fix CI: Update yarn.lock (#11298) 2024-10-31 08:16:55 +00:00
Laurent Cozic
c7bb4f0e4b Setup new release 3.2 2024-10-30 23:43:30 +00:00
Henry Heino
a62e35c123 Chore: Attempt to reduce plugin API automated test failures (#11288)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-10-30 22:16:50 +00:00
Henry Heino
100f8a23f4 Mobile: Camera screen: Support scanning QR codes (#11245) 2024-10-30 21:12:27 +00:00
Henry Heino
612d72d765 Desktop: Fixes #11274: Fix content dropped into the Markdown editor is missing a cursor preview or dropped at the wrong location (#11289) 2024-10-30 21:09:59 +00:00
Henry Heino
2974465882 Desktop: Resolves #11279: Remove left/right edge margin around editor content when disabled in settings (#11290) 2024-10-30 21:09:37 +00:00
Henry Heino
f7f4a50d35 Desktop: Custom CSS: Add cm-listItem class to lines with list items, don't add region start/end markers for items that are always single-line (#11291) 2024-10-30 21:09:23 +00:00
Henry Heino
441021bb7e Android: Fix build: Upgrade react-native-quick-crypto to v0.7.5 (#11294) 2024-10-30 20:47:59 +00:00
Joplin Bot
4c0ec8c5a0 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-10-30 18:21:24 +00:00
renovate[bot]
9f8552a038 Update dependency bulma to v1.0.2 (#11284) 2024-10-29 00:16:35 +00:00
renovate[bot]
05a588af48 Update dependency react-native-quick-crypto to v0.7.2 (#11285) 2024-10-29 00:16:27 +00:00
renovate[bot]
743ed2d9b8 Update dependency @react-native/babel-preset to v0.74.86 (#11282) 2024-10-28 22:37:19 +00:00
renovate[bot]
289d36f1f1 Update dependency @react-native/metro-config to v0.74.86 (#11283) 2024-10-28 22:23:20 +00:00
Henry Heino
cce6898d83 Chore: Fix CI (#11281) 2024-10-28 22:07:49 +00:00
Laurent Cozic
f4ee4a178e Chore: Added tests for renderMarkup command 2024-10-27 21:39:44 +00:00
Laurent Cozic
ff09937ca2 Plugins: Added a renderMarkup command to render MD or HTML markup to HTML 2024-10-27 21:19:38 +00:00
Laurent Cozic
a2d0908eb6 Chore: Removed unnused uglify-js 2024-10-27 21:15:29 +00:00
renovate[bot]
d060edba66 Update dependency react-native-localize to v3.2.0 (#11267)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-27 21:06:35 +00:00
renovate[bot]
d2a45be18f Update dependency bulma to v1 (#11272)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-27 21:03:07 +00:00
github-actions[bot]
84d0b1f080 @Vansh5632 has signed the CLA in laurent22/joplin#11273 2024-10-27 15:59:23 +00:00
renovate[bot]
3c6f7ceeaa Update dependency @types/serviceworker to v0.0.90 (#11271) 2024-10-27 08:30:18 +00:00
ovari
fba1ad2d95 hu (magyar - Hungarian) translation (#11265) 2024-10-26 22:38:44 +01:00
Laurent Cozic
b32dc39965 Update renovate.json5 2024-10-26 22:31:13 +01:00
github-actions[bot]
49338b91c8 @laurent22 has signed the CLA in laurent22/joplin#11265 2024-10-26 20:32:47 +00:00
renovate[bot]
26fa2e7900 Update dependency react-native-paper to v5.12.5 (#11266) 2024-10-26 20:19:36 +00:00
Self Not Found
aa6348c5c2 All: Add new encryption methods based on native crypto libraries (#10696)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
Co-authored-by: Henry Heino <personalizedrefrigerator@gmail.com>
2024-10-26 21:15:10 +01:00
Henry Heino
bed5297829 Desktop,Mobile,Web: Add support for overwrite mode in the Markdown editor (#11262) 2024-10-26 21:12:27 +01:00
Henry Heino
3732a57af3 Chore: Mobile: Use stronger types in side-menu and support FontAwesome icons (#11247) 2024-10-26 21:10:01 +01:00
Henry Heino
f1e5ab8255 Desktop: Re-enable media with local file URLs in the note viewer (#11244) 2024-10-26 21:08:51 +01:00
mrjo118
c2844470c5 Desktop: Fixes #10887: Prevent disabling of textbox inputs after entering an incorrect password (#11241) 2024-10-26 21:07:22 +01:00
Henry Heino
6cbdde578d Desktop: Accessibility: Add accessible label to the "remove from share" button (#11233) 2024-10-26 21:06:25 +01:00
Henry Heino
4057aae300 Desktop: Accessiblity: Make keyboard shortcuts settings screen keyboard-navigable (#11232) 2024-10-26 21:06:18 +01:00
Henry Heino
f07e4e9b5a Desktop: Accessibility: Add missing labels to the note attachments screen and master password dialog (#11231) 2024-10-26 21:06:09 +01:00
Gabriele Monaco
2d9c2d533d update italian translation (#11230) 2024-10-26 21:05:53 +01:00
Henry Heino
92c13c2991 Desktop,Mobile: Add setting to disable markup autocompletion (#11222) 2024-10-26 21:04:04 +01:00
Henry Heino
d7f4f5f2b8 Mobile,Desktop: Upgrade CodeMirror packages (#11221) 2024-10-26 21:03:18 +01:00
Henry Heino
59feec1fe2 Desktop,Mobile: Fix list renumbering in the Markdown editor resets the first list item number to 1 (#11220) 2024-10-26 21:03:13 +01:00
Henry Heino
e77fa19fea Desktop: Allow Markdown editor search dialog to be localised (#11219) 2024-10-26 21:02:54 +01:00
Henry Heino
4580c63ac7 Desktop: Accessibility: Declare app locale with the HTML lang attribute (#11218) 2024-10-26 21:02:47 +01:00
Henry Heino
576a73db5b Chore: Desktop: Fix SCSS compilation warning (#11217) 2024-10-26 21:02:40 +01:00
Henry Heino
4e7d74e49a Chore: Refactoring: Prefer empty array to KeychainServiceDriverDummy (#11216) 2024-10-26 21:02:34 +01:00
Henry Heino
c6d319e333 Desktop: Upgrade to Electron 32.2.0 (#11200) 2024-10-26 21:02:29 +01:00
Henry Heino
9f5282c8f5 Android: Allow switching the voice typing library to Whisper (#11158)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-10-26 21:00:56 +01:00
Henry Heino
3a316a1dbc Chore: Disable flaky end-to-end PDF link test (#11248) 2024-10-26 21:00:32 +01:00
Henry Heino
08f29b7866 Chore: Desktop: Wait for plugins to load before running certain plugin-related tests (#11224) 2024-10-26 20:58:54 +01:00
ScriptInfra
c364fd087f Update faq.md (#11263) 2024-10-26 20:58:13 +01:00
renovate[bot]
006fb215a1 Update dependency node-mocks-http to v1.15.0 (#11258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-25 13:55:48 +01:00
renovate[bot]
27742b9cc3 Update dependency @playwright/test to v1.45.3 (#11260) 2024-10-25 09:27:32 +00:00
renovate[bot]
4d679ce928 Update dependency pg to v8.12.0 (#11259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-25 09:37:31 +01:00
renovate[bot]
0774f03863 Update dependency @playwright/test to v1.45.0 (#11257)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-25 09:37:19 +01:00
renovate[bot]
db966f919e Update dependency url to v0.11.4 (#11256) 2024-10-25 00:35:12 +00:00
renovate[bot]
d46afbf067 Update dependency dayjs to v1.11.12 (#11254) 2024-10-25 00:16:25 +00:00
renovate[bot]
badc7dabe8 Update dependency jsdom to v24.1.1 (#11255) 2024-10-25 00:16:19 +00:00
renovate[bot]
8102e52c59 Update dependency @types/markdown-it to v13.0.9 (#11253) 2024-10-24 23:52:25 +00:00
Joplin Bot
173b4f3ab3 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-10-24 12:24:56 +00:00
Joplin Bot
549934b04e Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-10-22 12:25:10 +00:00
Laurent Cozic
683601c427 Tools: Ensures that pull requests that fail CI do not get automerged 2024-10-22 12:05:17 +01:00
renovate[bot]
334005c1ff Update dependency @types/node to v18.19.42 (#11242) 2024-10-22 11:03:38 +00:00
Laurent Cozic
81993628ab Desktop release v3.1.20 2024-10-22 11:51:50 +01:00
Laurent Cozic
2779a9cffc Server: Added more logging for sharing 2024-10-21 17:56:06 +01:00
Laurent Cozic
1d6c1e4664 Server: Add logging statement to evaluate the performance of the sharing service 2024-10-19 16:31:46 +01:00
github-actions[bot]
9edcd4eb8f @glemco has signed the CLA in laurent22/joplin#11230 2024-10-18 13:23:20 +00:00
Laurent Cozic
0b3f6a268e iOS 13.1.6 2024-10-17 23:17:57 +01:00
Laurent Cozic
a2069df3e0 Android 3.1.6 2024-10-17 23:14:16 +01:00
Laurent Cozic
1ad150c1bf Desktop release v3.1.19 2024-10-17 23:05:46 +01:00
Henry Heino
41b251d67a Linux: Move keychain support behind an off-by-default feature flag (#11227) 2024-10-17 22:58:03 +01:00
renovate[bot]
9175780382 Update dependency @types/node to v18.19.41 (#11228) 2024-10-17 21:52:28 +00:00
Henry Heino
2c40cec639 Chore: Desktop: Fix incorrect log tag (#11215) 2024-10-17 22:49:50 +01:00
Henry Heino
efb58c5f40 Desktop: Fix error screen shown on opening settings when an incompatible plugin is installed (#11223) 2024-10-17 22:49:29 +01:00
Henry Heino
6afa2d1385 Desktop: Accessibility: Make keyboard focus visible for dropdowns (#11177) 2024-10-15 18:00:31 +01:00
Henry Heino
38be0e81a9 Desktop: Accessibility: Add ARIA information to the sidebar's notebook and tag list (#11196) 2024-10-15 17:59:51 +01:00
renovate[bot]
609ee3e227 Update dependency @react-native-community/datetimepicker to v8.1.1 (#11210)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-15 17:56:51 +01:00
renovate[bot]
23a6bbe014 Update dependency @adobe/css-tools to v4.4.0 (#11209)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-15 17:02:52 +01:00
renovate[bot]
1b9e9655be Update dependency @types/node to v18.19.40 (#11213) 2024-10-15 15:49:05 +00:00
Henry Heino
9d8cd1d707 Desktop: Security: Open more target="_blank" links in a browser (#11212) 2024-10-15 16:38:33 +01:00
Henry Heino
591c458a4f Desktop: Security: Improve KaTeX error handling (#11207) 2024-10-15 16:37:15 +01:00
Laurent Cozic
6974c8ba11 Tools: Update script to test plugins 2024-10-14 18:25:48 +01:00
renovate[bot]
e1531b77c6 Update dependency sass to v1.77.8 (#11208) 2024-10-14 17:15:56 +00:00
renovate[bot]
23cd7d90d1 Update dependency compare-versions to v6.1.1 (#11204) 2024-10-14 17:05:58 +00:00
renovate[bot]
2ccbd9fdc2 Update dependency react-native-safe-area-context to v4.10.8 (#11205) 2024-10-14 17:05:56 +00:00
renovate[bot]
bfdc6ca7bf Update dependency react-native-webview to v13.10.5 (#11206) 2024-10-14 17:05:49 +00:00
Laurent Cozic
f9b1a32ae7 Tools: Update script to test plugins 2024-10-14 17:52:31 +01:00
Henry Heino
1a195e23dd Desktop: Security: Improve Markdown viewer link handling (#11201) 2024-10-14 17:51:28 +01:00
Joplin Bot
26ae3f853e Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-10-12 00:47:59 +00:00
Laurent Cozic
e84e9a58e1 iOS 13.1.5 2024-10-11 23:29:52 +01:00
Laurent Cozic
3b8da5023d Tools: Always run pod install 2024-10-11 23:28:45 +01:00
Laurent Cozic
548d41d0d4 lock files 2024-10-11 23:28:29 +01:00
Laurent Cozic
d6c921249f iOS 13.1.4 2024-10-11 23:21:27 +01:00
Laurent Cozic
e044c50b03 Android 3.1.5 2024-10-11 23:16:57 +01:00
Laurent Cozic
beec74d792 Desktop release v3.1.18 2024-10-11 23:05:38 +01:00
pedr
8b4e163b28 Server: Fixes #10532: Fix PostgreSQL version check failing on Windows Server because wrong regex (#11038) 2024-10-11 22:26:01 +01:00
Henry Heino
b61467097d Mobile: Fixes #11134: Fix automatic resource download mode (#11144) 2024-10-11 22:14:18 +01:00
Matthew Moore
447e4638d1 add typecript information regarding turndown-plugin-gfm (#11153)
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
2024-10-11 22:14:05 +01:00
ScriptInfra
b831525b20 Update faq.md (#11169)
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-10-11 22:12:05 +01:00
Henry Heino
e05be832d5 Desktop, Mobile: Downgrade CodeMirror packages to fix various Android regressions (#11170) 2024-10-11 22:08:17 +01:00
Henry Heino
64c9c3179f Chore: Update KaTeX asset files (#11172) 2024-10-11 22:08:07 +01:00
Henry Heino
0ea61f26eb Desktop: Accessibility: Fix context menu button doesn't open the note list context menu (regression) (#11175) 2024-10-11 22:07:56 +01:00
Henry Heino
349fa426ea Mobile: Fixes #11183: Fix new note/edit buttons only work if pressed quickly (#11185) 2024-10-11 22:04:29 +01:00
Henry Heino
e3d5f0c9cf Chore: Desktop: Use SCSS instead of styled-components for plugin dialogs and toolbar buttons (#11189) 2024-10-11 22:03:41 +01:00
Joplin Bot
e63d545ed8 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-10-11 18:20:26 +00:00
Laurent Cozic
ab3058612d Doc: Add sponsor 2024-10-11 19:00:43 +01:00
Laurent Cozic
715abcce32 Plugins: Add support for joplin.settings.values and deprecate joplin.settings.value 2024-10-11 18:56:04 +01:00
renovate[bot]
f165b3f870 Update dependency @types/serviceworker to v0.0.89 (#11191) 2024-10-11 03:01:01 +00:00
renovate[bot]
8895d745e7 Update dependency glob to v10.4.5 (#11192) 2024-10-11 03:01:00 +00:00
renovate[bot]
33a9b96a31 Update dependency pm2 to v5.4.2 (#11193) 2024-10-11 03:00:52 +00:00
github-actions[bot]
d1ac3d415e @moorage has signed the CLA in laurent22/joplin#11153 2024-10-05 22:34:48 +00:00
Henry Heino
432fac8fda Chore: Fix CI (#11173) 2024-10-05 12:22:44 -07:00
renovate[bot]
0f23882d47 Update dependency nodemon to v3.1.7 (#11162) 2024-10-01 02:49:36 +00:00
renovate[bot]
693c0f22c8 Update eslint (#11163) 2024-10-01 02:49:34 +00:00
renovate[bot]
e2db7a6b61 Update types (#11164) 2024-10-01 02:49:27 +00:00
renovate[bot]
2a74f60812 Update dependency katex to v0.16.11 (#11159) 2024-10-01 02:19:59 +00:00
renovate[bot]
2419291976 Update dependency nodemon to v3.1.4 (#11160) 2024-10-01 02:19:57 +00:00
renovate[bot]
733845eb95 Update eslint (#11161) 2024-10-01 02:19:50 +00:00
Joplin Bot
b3315aeb03 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-10-01 00:52:32 +00:00
renovate[bot]
d88c522d96 Update dependency @react-native/babel-preset to v0.74.85 (#11156) 2024-09-30 02:46:33 +00:00
renovate[bot]
c0cefc30f4 Update dependency @react-native/metro-config to v0.74.85 (#11157) 2024-09-30 02:17:39 +00:00
renovate[bot]
0dc3589661 Update dependency nodemon to v3.1.2 (#11140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-28 16:24:50 +01:00
Henry Heino
f64c3d5484 Desktop: Remove Math Mode from the list of plugins incompatible with the new editor (#11143) 2024-09-28 16:21:59 +01:00
Henry Heino
5fceb5a3c9 Chore: Reduce mobile note screen test flakiness (#11145) 2024-09-28 16:20:46 +01:00
renovate[bot]
916b3f6f69 Update dependency rate-limiter-flexible to v5.0.3 (#11148) 2024-09-28 11:15:33 +00:00
renovate[bot]
0c4e8eeafc Update dependency react-native-document-picker to v9.3.0 (#11141)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-28 11:30:30 +01:00
renovate[bot]
b27e0ff1f4 Update dependency rate-limiter-flexible to v5 (#11147)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-28 11:29:30 +01:00
Laurent Cozic
59ffb0f265 Update renovate.json5 2024-09-28 11:29:10 +01:00
renovate[bot]
20b4fd85c1 Update dependency react-native-safe-area-context to v4.10.7 (#11138) 2024-09-27 20:52:29 +00:00
renovate[bot]
fc2da05ba6 Update dependency stream to v0.0.3 (#11139) 2024-09-27 20:52:22 +00:00
Henry Heino
948ca605b0 Mobile,Desktop: Fixes #11135: Fix incorrect list switching behavior (#11137) 2024-09-27 21:28:56 +01:00
Henry Heino
eda2c69334 Desktop: Fixes #11129: Improve performance by allowing note list background timers to be cancelled (#11133) 2024-09-27 15:25:55 +01:00
Henry Heino
42ab9ecd95 Mobile: Fixes #11130: Fix regression: Search screen not hidden when cached for search result navigation (#11131) 2024-09-27 15:23:31 +01:00
Henry Heino
5935c9c147 Chore: Mobile: Improve note screen tests and fix CI warning (#11126) 2024-09-27 15:23:02 +01:00
Joplin Bot
90640e590e Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-09-26 12:25:12 +00:00
Laurent Cozic
75b8caf816 Desktop, Mobile: Plugins: Name webview root attribute so that it can be styled 2024-09-26 11:40:13 +01:00
Laurent Cozic
3ea403d004 Desktop release v3.1.17 2024-09-26 11:36:01 +01:00
Laurent Cozic
058a559de4 Desktop: Enable again auto-updates 2024-09-26 11:35:42 +01:00
Laurent Cozic
ac43c62ce8 Chore: Disable custom protocol debug logging 2024-09-26 11:35:42 +01:00
Henry Heino
c4a7749f2a Desktop: Fixes #11105: Plugin API: Save changes made with editor.setText (#11117) 2024-09-26 11:35:32 +01:00
Joplin Bot
e6c09da639 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-09-24 18:20:50 +00:00
Laurent Cozic
2d05b5f43e Android 3.1.4 2024-09-24 15:23:16 +01:00
Laurent Cozic
63d0855a59 Desktop release v3.1.16 2024-09-24 15:15:43 +01:00
Henry Heino
3d42485315 Mobile: Show loading indicator while loading search results (#11104) 2024-09-24 15:12:02 +01:00
renovate[bot]
f772cc500c Update dependency jsdom to v24.1.0 (#11114)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 20:16:50 +01:00
renovate[bot]
ad8bcacbca Update dependency glob to v10.4.2 (#11112) 2024-09-23 17:59:26 +00:00
renovate[bot]
fbab549a1c Update dependency pm2 to v5.4.1 (#11113) 2024-09-23 17:59:19 +00:00
pedr
817f3bc121 Cli: Fixes #10992: Disable deprecation warning when running Joplin from CLI (#11074) 2024-09-23 18:20:13 +01:00
pedr
e3576683b0 Desktop,Mobile,Cli: Fixes #10608: WebDAV synchronisation not working because of URL encoding differences (#11076) 2024-09-23 18:19:51 +01:00
renovate[bot]
85c2eb43dd Update dependency turndown to v7.2.0 (#11103)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-22 01:45:21 +01:00
renovate[bot]
0f2b2b1e7b Update dependency pm2 to v5.4.0 (#11102)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-22 01:45:05 +01:00
renovate[bot]
8fd2eeaea5 Update dependency glob to v10.4.1 (#11101)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-22 01:44:56 +01:00
renovate[bot]
b97a14c559 Update dependency nodemailer to v6.9.14 (#11098) 2024-09-21 17:43:23 +00:00
renovate[bot]
bbb97bcb02 Update dependency react-native-webview to v13.10.4 (#11099) 2024-09-21 17:43:21 +00:00
renovate[bot]
8a51ed892a Update dependency sass to v1.77.6 (#11100) 2024-09-21 17:43:14 +00:00
Henry Heino
0cac69c2fa Chore: Migrate back-button.js to TypeScript (#11087) 2024-09-21 18:28:41 +01:00
Henry Heino
feb946acfb Chore: Mobile: Search screen: Use stronger types, try to prevent multiple concurrent attempts to update the result list (#11075) 2024-09-21 18:28:33 +01:00
Henry Heino
220f867814 Mobile: Resolves #10763: Support permanent note deletion on mobile (#10786) 2024-09-21 13:05:27 +01:00
Henry Heino
050a896c8b Android,Web: Fix scroll issues and incorrect main content height (#11071) 2024-09-21 13:05:17 +01:00
Henry Heino
d13e7b32c3 Desktop,Mobile,Cli: Fixes #11017: Delete revisions on the sync target when deleted locally (#11035) 2024-09-21 13:04:54 +01:00
Alice
a56f104fe8 Desktop: Seamless-Updates: triggering updates (#11079) 2024-09-21 13:02:22 +01:00
Henry Heino
99696637b9 Chore: Desktop: Add extra check to try to prevent duplicate setting key warning (#11084) 2024-09-21 13:01:08 +01:00
Henry Heino
be5a6c189a Desktop: New Markdown editor: Fix horizontal rule button when cursor is not on a new line (#11085) 2024-09-21 13:00:43 +01:00
Henry Heino
a01f519131 Mobile: Resolves #11082: Make pressing "back" navigate to the previous note after following a link (#11086) 2024-09-21 13:00:31 +01:00
Dave Goldberg
a71ee1d0b8 Doc: Add Backblaze to S3 Providers (#11088)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-09-21 12:59:38 +01:00
Henry Heino
a40bb77feb Mobile: Use fade animation for edit link dialog (#11090) 2024-09-21 12:58:20 +01:00
Henry Heino
5c23765458 Mobile: Scroll dropdown to selected value when first opened (#11091) 2024-09-21 12:58:01 +01:00
Henry Heino
d023ce592c Desktop: Fix ctrl/cmd-n can create new notes while the trash folder is selected (#11092) 2024-09-21 12:57:48 +01:00
Henry Heino
8c4bf057d6 Chore: Mobile: Improve Notes screen type safety (#11093) 2024-09-21 12:57:38 +01:00
Henry Heino
b9dc226031 Chore: Mobile: Migrate NoteItem and Checkbox to TypeScript (#11094) 2024-09-21 12:57:26 +01:00
Henry Heino
a81c1ff663 Chore: Mobile: Convert side-menu-content-note.js to a TypeScript function component (#11095) 2024-09-21 12:57:08 +01:00
Jonatan
c909d85acc Update Swedish translation (#11096) 2024-09-21 12:56:55 +01:00
Henry Heino
0965c6d257 Desktop,Mobile: Fixes #11065: Improve performance when there are many selected items (#11067) 2024-09-21 12:53:16 +01:00
Laurent Cozic
5beb80bf61 Desktop, Mobile: Automatically detect and use operating system theme by default 2024-09-20 19:31:35 +01:00
renovate[bot]
1b2f5e5cd8 Update dependency @types/node to v18.19.39 (#11089) 2024-09-20 17:52:37 +00:00
github-actions[bot]
2db82ac732 @dhgoldberg has signed the CLA in laurent22/joplin#11088 2024-09-20 14:29:03 +00:00
renovate[bot]
3f1ec682b9 Update dependency @types/node to v18.19.38 (#11080) 2024-09-19 05:27:44 +00:00
renovate[bot]
59b3030e45 Update dependency @types/node to v18.19.37 (#11078) 2024-09-18 11:52:31 +00:00
Joplin Bot
54d223a721 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-09-17 12:24:41 +00:00
Laurent Cozic
e5771a36bb Desktop release v3.1.15 2024-09-17 09:37:02 +01:00
Laurent Cozic
31a5ee20df Tools: Trying to fix autoupdate CI script 2024-09-17 09:35:39 +01:00
Laurent Cozic
efd9ada977 Desktop release v3.1.14 2024-09-17 07:37:06 +01:00
Alice
b4450ae4ef Desktop: Seamless-Updates: used axios for download function (#11068) 2024-09-17 07:36:53 +01:00
github-actions[bot]
73076bd4b7 @mrjo118 has signed the CLA in laurent22/joplin#11069 2024-09-17 00:13:07 +00:00
Laurent Cozic
0ba0550baf Desktop release v3.1.13 2024-09-16 22:24:40 +01:00
Laurent Cozic
41b03f9356 macOS: Fixed shortcut for permanent note deletion 2024-09-16 22:22:27 +01:00
et al.
95f1992b8a Update Simplified Chinese translation (#11061) 2024-09-16 22:22:08 +01:00
Henry Heino
11c1c0638d Desktop: Resolves #11063: Improve the performance of GoToAnything (#11064) 2024-09-16 22:20:44 +01:00
Henry Heino
e0daf807a6 Mobile: Fixes #11028: Accessibility: Fix sidebar broken in right-to-left mode, improve screen reader accessibility (#11056) 2024-09-16 22:17:12 +01:00
Alice
2594c1edb1 Desktop: Seamless-Updates: used download function from tool-utils (#11066) 2024-09-16 22:13:24 +01:00
github-actions[bot]
e80bede7b7 @howfool has signed the CLA in laurent22/joplin#11061 2024-09-16 13:37:59 +00:00
renovate[bot]
1eb721c717 Update dependency @types/node to v18.19.36 (#11057) 2024-09-16 03:03:06 +00:00
renovate[bot]
38b6484f12 Update dependency @types/node to v18.19.35 (#11055) 2024-09-15 19:42:31 +00:00
Laurent Cozic
a0163ba793 Desktop release v3.1.12 2024-09-15 20:17:57 +01:00
Alice
e2e589e907 Desktop: Seamless-Updates: added debugging logs for createReleaseAssets (#11053) 2024-09-15 20:17:44 +01:00
renovate[bot]
93f96c03b1 Update dependency react-native-safe-area-context to v4.10.5 (#11051) 2024-09-15 14:52:44 +00:00
Laurent Cozic
77f09a4408 Desktop release v3.1.11 2024-09-15 15:32:08 +01:00
Alice
faf30306da Desktop: Seamless-Updates: updated asset name locally after update call to GitHub API (#11050) 2024-09-15 15:31:41 +01:00
Laurent Cozic
c1c02204fa Desktop release v3.1.10 2024-09-15 11:02:44 +01:00
Alice
017480eb45 Desktop: Seamless-Updates: used url instead of browser url and added api heade… (#11049) 2024-09-15 11:02:02 +01:00
Laurent Cozic
8931a68ec8 Desktop release v3.1.9 2024-09-14 22:24:02 +01:00
Henry Heino
3c6a419cad Desktop: Accessibility: Add "Move to" context menu action for notebooks (#11039) 2024-09-14 22:18:07 +01:00
renovate[bot]
dce4c715e3 Update dependency markdown-it-sup to v2 (#11048)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 22:16:57 +01:00
Alice
5763de3b26 Desktop: Seamless-Updates: generated and uploaded latest-mac-arm64.yml to GitHub Releases (#11042) 2024-09-14 22:16:42 +01:00
renovate[bot]
4fa61e443f Update dependency markdown-it-ins to v4 (#11045)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 18:39:39 +01:00
renovate[bot]
84e312563a Update dependency react-native-device-info to v10.14.0 (#11044)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 18:38:33 +01:00
renovate[bot]
707c21a2fe Update dependency sass to v1.77.5 (#11043) 2024-09-14 15:22:02 +00:00
renovate[bot]
d0057ae838 Update dependency lint-staged to v15.2.7 (#11041) 2024-09-14 14:52:40 +00:00
pedr
8d3ac630c5 Desktop: Fixes #10560: Fix table column and rows not being resizable on RTE (#11037) 2024-09-13 18:07:52 +01:00
pedr
b5f06b6958 Desktop: Fixes #10561: Table options not visible on dark theme (#11036) 2024-09-13 18:07:03 +01:00
Henry Heino
5a07b795d3 Desktop, Mobile: Upgrade CodeMirror packages (#11034) 2024-09-13 13:24:37 +01:00
Alice
bfab4426ca Seamless-Updates: Auto Updater Service is architecture dependent (#11015) 2024-09-13 11:03:14 +01:00
Henry Heino
bcb5218e1a Desktop: Fix editor/viewer loses focus when visible panels are changed with ctrl-l (#11029) 2024-09-12 17:54:10 +01:00
Henry Heino
c897cc1582 Desktop: Update plugin compatibility layer to allow more legacy plugins (e.g. Markdown Prettier) to run (#11033) 2024-09-12 17:51:38 +01:00
Henry Heino
ea61bfc498 Mobile: Fixes #10253: Move accessibility focus to the first note action menu item on open (#11031) 2024-09-12 09:04:23 +01:00
Henry Heino
ca5d35339f Desktop: Accessibility: Improve text read by screen readers when focusing the note viewer (#11030) 2024-09-12 09:00:35 +01:00
Laurent Cozic
5c00ea93c2 Doc: Move next release 3.1 dates by 10 days 2024-09-11 20:59:05 +01:00
Henry Heino
f005977ce0 Desktop: Encryption screen: Fix "invalid password" border shown for some correct passwords (#11027) 2024-09-11 19:02:31 +01:00
Henry Heino
79773dab95 Mobile,Desktop: Fix unable to change incorrect decryption password if the same as the master password (#11026) 2024-09-11 19:01:57 +01:00
Henry Heino
69168f1ec2 Desktop: Fixes #11020: Fix clicking on most non-media resource links opens them inline (#11022) 2024-09-11 16:49:35 +01:00
Henry Heino
147a66d64e Desktop: Accessibility: Fix multi-note selection menu not tab-focusable (#11018) 2024-09-10 19:29:17 +01:00
Joplin Bot
ec36847de0 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-09-09 00:48:14 +00:00
renovate[bot]
d7bef7e923 Update dependency jsdom to v24 (#11007)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 22:56:53 +01:00
Laurent Cozic
55faab25b5 Desktop release v3.1.8 2024-09-08 20:50:06 +01:00
Alice
4da8060e62 Desktop: Seamless-Updates - rename latest-mac.yml to latest-mac-arm64.yml (#10985) 2024-09-08 20:49:29 +01:00
Laurent Cozic
821cfc5bd8 Update renovate.json5 2024-09-08 16:27:44 +01:00
renovate[bot]
9956caea1b Update dependency react-native-share to v10.2.1 (#11003) 2024-09-08 12:09:18 +00:00
renovate[bot]
f95b663f28 Update dependency react-native-webview to v13.10.3 (#11004) 2024-09-08 12:09:17 +00:00
renovate[bot]
dd990e7cf6 Update dependency sass to v1.77.4 (#11005) 2024-09-08 12:09:09 +00:00
davidsmoot
23dec124dd Doc: Update nextcloud.md (#10987)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-09-08 12:49:39 +01:00
renovate[bot]
2b6cb908fa Update dependency react-native-webview to v13.10.0 (#11000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 03:57:35 +01:00
renovate[bot]
40475d60fb Update dependency react-native-share to v10.2.0 (#10999)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 03:57:19 +01:00
renovate[bot]
48e96a055f Update dependency sass to v1.77.1 (#11001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 02:50:44 +01:00
renovate[bot]
3dbc9a5723 Update dependency tesseract.js to v5.1.0 (#11002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 02:50:24 +01:00
renovate[bot]
9832af0d3a Update dependency react-native-localize to v3.1.0 (#10997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 21:22:17 +01:00
renovate[bot]
26caf2a4c6 Update dependency @playwright/test to v1.44.1 (#10998) 2024-09-07 19:23:22 +00:00
renovate[bot]
29d7804ffd Update dependency react-native-document-picker to v9.2.0 (#10996)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 20:16:35 +01:00
renovate[bot]
6fe0104483 Update dependency @playwright/test to v1.44.0 (#10995)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 20:15:19 +01:00
Henry Heino
04f5433839 Mobile: Drawing: Fix clicking "cancel" after starting a new drawing in editing mode creates an empty resource (#10986) 2024-09-07 15:11:08 +01:00
Henry Heino
0bfa28d795 Mobile,Desktop,CLI: Fixes #10856: Decrypt master keys only as needed (#10990) 2024-09-07 11:56:13 +01:00
Laurent Cozic
ac2258769a Desktop: Fixes #10865: Removed unneeded electron-log dependency 2024-09-06 18:06:04 +01:00
github-actions[bot]
7cd0ed1714 @davidsmoot has signed the CLA in laurent22/joplin#10987 2024-09-05 11:49:13 +00:00
Laurent Cozic
803d508c69 Desktop release v3.1.7 2024-09-04 12:14:55 +01:00
Henry Heino
3c13568107 Chore: Mobile tests: Fix CodeMirror-related warnings (#10978) 2024-09-04 12:14:23 +01:00
Henry Heino
e41394b57f Chore: Tests: Improve Playwright test reliability (#10981) 2024-09-04 12:14:12 +01:00
Henry Heino
0b13dbddd8 Chore: Mobile tests: Fix warning: "A worker process ... has been force exited" (#10980) 2024-09-04 12:14:05 +01:00
Henry Heino
2a2dd96c02 Chore: Mobile tests: Hide debug logging (#10977) 2024-09-04 12:13:48 +01:00
renovate[bot]
2f7b2fb948 Update dependency css-loader to v6.11.0 (#10976)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-04 12:13:42 +01:00
Alice
4e8316a6ee Desktop: Seamless-Updates - generated latest-mac-arm64.yml (#10982) 2024-09-04 12:11:17 +01:00
renovate[bot]
01412b4500 Update dependency @rollup/plugin-replace to v5.0.7 (#10983) 2024-09-04 02:35:06 +00:00
renovate[bot]
2df8137281 Update dependency js-draw to v1.20.3 (#10973) 2024-09-03 03:43:16 +00:00
renovate[bot]
f24e229a4e Update dependency pg to v8.11.6 (#10974) 2024-09-03 03:43:14 +00:00
renovate[bot]
fa6060d6d2 Update dependency react-native-safe-area-context to v4.10.4 (#10975) 2024-09-03 03:43:07 +00:00
renovate[bot]
2d6796db16 Update dependency @react-native/babel-preset to v0.74.84 (#10970) 2024-09-03 03:07:48 +00:00
renovate[bot]
82be4f566a Update dependency @js-draw/material-icons to v1.20.3 (#10969) 2024-09-03 03:00:56 +00:00
renovate[bot]
f353686166 Update dependency @react-native/metro-config to v0.74.84 (#10971) 2024-09-03 03:00:20 +00:00
renovate[bot]
a6dbe4b67a Update dependency @rollup/plugin-replace to v5.0.6 (#10972) 2024-09-03 03:00:13 +00:00
Joplin Bot
b597d5f9d1 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-09-02 18:20:26 +00:00
Laurent Cozic
f0496bd348 Android 3.1.3 2024-09-02 13:18:23 +01:00
Laurent Cozic
a746c02d4a Desktop release v3.1.6 2024-09-02 13:05:22 +01:00
Laurent Cozic
02def5900e lock file 2024-09-02 13:04:32 +01:00
Henry Heino
fd06c18cf0 Desktop: Windows portable: Fix keychain-backed storage incorrectly enabled (#10942) 2024-09-02 12:26:43 +01:00
Alice
6163364b26 Desktop: Seamless-Updates - added tests for autoUpdaterService (#10935)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-09-02 12:24:19 +01:00
renovate[bot]
7e9c7d7d23 Update dependency @types/node to v18.19.34 (#10966) 2024-09-02 02:37:00 +00:00
renovate[bot]
88d02b04dd Update dependency ldapts to v7.0.12 (#10951) 2024-09-01 20:33:07 +00:00
renovate[bot]
42e39b7789 Update dependency re-resizable to v6.9.17 (#10953) 2024-09-01 20:33:05 +00:00
renovate[bot]
9b3ce555cb Update dependency react-native-webview to v13.8.7 (#10956) 2024-09-01 20:33:04 +00:00
renovate[bot]
bae311b2a9 Update dependency sharp to v0.33.4 (#10958) 2024-09-01 20:32:56 +00:00
Laurent Cozic
f8a09e5540 Update renovate.json5 2024-09-01 21:14:35 +01:00
renovate[bot]
461ba1762a Update dependency sass to v1.76.0 (#10962)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:11:34 +01:00
renovate[bot]
82a4b8915b Update dependency async-mutex to v0.5.0 (#10961)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:11:21 +01:00
renovate[bot]
e8593e7ae5 Update dependency @react-native-clipboard/clipboard to v1.14.1 (#10960)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:11:13 +01:00
renovate[bot]
8f1c7bf61c Update dependency @playwright/test to v1.43.1 (#10959)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:11:04 +01:00
renovate[bot]
23c08f77e0 Update dependency react-native-safe-area-context to v4.10.3 (#10955)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:10:28 +01:00
renovate[bot]
e1fa7d0e83 Update dependency react-native-device-info to v10.13.2 (#10954)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:10:15 +01:00
renovate[bot]
fc3c59bad5 Update dependency lint-staged to v15.2.5 (#10952)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:10:01 +01:00
renovate[bot]
8588e36373 Update dependency koa to v2.15.3 (#10950)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:09:44 +01:00
renovate[bot]
1f43b199d5 Update dependency glob to v10.3.16 (#10949)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-01 21:09:37 +01:00
Joplin Bot
e2fd48eecd Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-09-01 00:53:18 +00:00
renovate[bot]
d0e6368867 Update dependency @types/react to v18.3.3 (#10964) 2024-08-31 18:04:01 +00:00
renovate[bot]
4f98aad24f Update dependency dayjs to v1.11.11 (#10948)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-31 17:59:17 +00:00
renovate[bot]
fae313785d Update dependency react-native-zip-archive to v6.1.2 (#10957) 2024-08-31 15:29:19 +00:00
renovate[bot]
db5bbeecd4 Update react monorepo (#10963) 2024-08-31 15:28:44 +00:00
Henry Heino
d2b7d64f4f Desktop: Accessibility: Improve note list keyboard and screen reader accessibility (#10940) 2024-08-31 16:05:01 +01:00
Henry Heino
4f2d0c8e5d Desktop: Add left/right arrow keys as expand/collapse shortcuts for notebooks (#10944) 2024-08-31 15:44:12 +01:00
Alice
3bca12fd4a Desktop: Seamless-Updates: added latest-mac-arm64.yml (#10941) 2024-08-31 15:42:07 +01:00
Henry Heino
4ccc46e4db Docs: Fix typo: Change "Thee" to "The" (#10945) 2024-08-31 15:40:28 +01:00
renovate[bot]
5062cd1616 Update dependency @bam.tech/react-native-image-resizer to v3.0.10 (#10938) 2024-08-28 20:52:24 +00:00
renovate[bot]
1710155a6f Update dependency @types/jsdom to v21.1.7 (#10939) 2024-08-28 20:52:17 +00:00
Joplin Bot
4cb693b4d6 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-28 00:45:16 +00:00
Joplin Bot
e607a7376f Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-27 18:20:33 +00:00
Laurent Cozic
d1403ba2cb Desktop release v3.1.4 2024-08-27 18:06:16 +01:00
Henry Heino
74be949d33 Desktop: Accessibility: Improve note title focus handling (#10932) 2024-08-27 18:05:48 +01:00
Alice
2afc2ca369 Desktop: Seamless-Updates: implemented flow for prereleases (#10892) 2024-08-27 18:04:18 +01:00
Laurent Cozic
b617a84696 All: Resolves #10407: Added feature flag to disable sync lock support (#10925) 2024-08-23 12:16:19 +01:00
Henry Heino
c691fedc12 Mac: Fixes #10921: Markdown editor: Fix custom arrow-key shortcuts fail to register (#10922) 2024-08-23 11:49:30 +01:00
Henry Heino
12a26023dd Chore: CI: Fix .eslintignore and .gitignore CI check passes when it should fail (#10923) 2024-08-23 11:49:17 +01:00
Laurent Cozic
700ffa2529 Desktop, Mobile, Cli: Make feature flags advanced settings by default 2024-08-23 11:39:40 +01:00
Laurent Cozic
5fdd088504 Desktop, Mobile: Fixed italic support in Fountain documents 2024-08-23 10:05:50 +01:00
Laurent Cozic
fe89b1cf21 Merge branch 'release-3.0' into dev 2024-08-23 09:52:04 +01:00
Henry Heino
3d1bbf3c4d Chore: Web: Fix build fails on Windows (#10919) 2024-08-22 21:53:52 +01:00
Henry Heino
580d2914e7 Mobile,Desktop: Fixes #10914: Fix BMP image rendering in the Markdown viewer (#10915) 2024-08-22 21:53:44 +01:00
Henry Heino
33599324d6 Desktop: Fixes #10737: Fix Fix editing notes in "Conflicts" causes them to temporarily vanish (#10913) 2024-08-22 21:53:39 +01:00
Henry Heino
02bdb7a79c Docs: Include dependency overview (#10911)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-08-22 21:53:27 +01:00
Henry Heino
a1c64eeefc Web: Fix renderer plugin assets fail to load on secondary profiles (#10903) 2024-08-22 21:52:42 +01:00
Henry Heino
78015028ec Desktop, Mobile: Fixes #10891: Markdown editor: Fix toggling bulleted lists when items start with asterisks (#10902) 2024-08-22 21:52:36 +01:00
Henry Heino
beff45e195 Desktop: Fix viewer and panel plugins that check for the presence of exports fail to load (#10900) 2024-08-22 21:52:29 +01:00
Henry Heino
6a0dd4e20d Desktop: Fixes #10895: Fix alt+up/alt+down fails to re-order multiple lines (#10899) 2024-08-22 21:52:22 +01:00
Henry Heino
ea420967c4 Chore: Remove recently-added .gitignored files (#10898) 2024-08-22 21:52:17 +01:00
Henry Heino
c19d0773b3 Mobile,Desktop,Cli: Fixes #10896: Fix "Enable auto-updates" enabled by default and visible on unsupported platforms (#10897) 2024-08-22 21:51:57 +01:00
Henry Heino
59a8c2115c Chore: Fix CI: Add Famegear to cspell dictionary (#10912) 2024-08-21 20:57:11 +01:00
Joplin Bot
88cae93fc4 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-21 18:20:16 +00:00
Laurent Cozic
4eb0fb542e Doc: Update sponsors 2024-08-21 18:26:58 +01:00
Henry Heino
60a1617b22 Chore: Fix compilation errors due to test resources with .ts extensions (#10909) 2024-08-21 18:24:33 +01:00
Henry Heino
e05d7197bd Docs: Improve explanation for using custom OCR language data (#10910) 2024-08-21 18:24:05 +01:00
Joplin Bot
9dc29d034b Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-21 12:23:24 +00:00
renovate[bot]
32fe122e60 Update dependency @fortawesome/react-fontawesome to v0.2.2 (#10905) 2024-08-21 08:45:31 +00:00
renovate[bot]
8fcb377162 Update dependency @rollup/plugin-commonjs to v25.0.8 (#10906) 2024-08-21 08:45:24 +00:00
Laurent Cozic
598677b207 Desktop release v3.0.15 2024-08-21 09:36:44 +01:00
renovate[bot]
b3437fa4cd Update dependency @js-draw/material-icons to v1.20.2 (#10894) 2024-08-19 20:52:32 +00:00
Joplin Bot
0d82584777 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-18 12:23:44 +00:00
Laurent Cozic
e627fb7fad Doc: Update sponsors 2024-08-18 10:41:09 +01:00
Joplin Bot
b60acf038b Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-17 18:18:50 +00:00
renovate[bot]
111820c0cf Update dependency @js-draw/material-icons to v1.20.1 (#10890) 2024-08-17 11:38:01 +00:00
Laurent Cozic
263a7ef076 Desktop release v3.1.3 2024-08-17 12:23:14 +01:00
Henry Heino
255d3e737d Chore: Windows: Fix building the desktop app clears the list of supported Rich Text Editor locales (#10885) 2024-08-17 12:22:52 +01:00
Henry Heino
9cb13af7b0 Chore: Windows: Fix mobile plugin assets change when rebuilding the mobile app (#10886) 2024-08-17 12:22:35 +01:00
Henry Heino
7bc81880e1 Windows: Fix handleCustomProtocols test (#10884) 2024-08-17 12:22:13 +01:00
Henry Heino
eb53c7e3b9 Windows: Fix PDF, video, and audio rendering (#10881) 2024-08-17 12:22:03 +01:00
Henry Heino
b94cf5a107 Desktop: Resolves #5762: Rich Text Editor: Add eight spaces when pressing tab (#10880) 2024-08-17 12:21:43 +01:00
Alice
72163018b4 Desktop: Seamless-Updates - added flow for automatic updates for releases (#10857)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-08-17 12:19:05 +01:00
github-actions[bot]
0cbf8d8ebc @maresmar has signed the CLA in laurent22/joplin#10882 2024-08-16 18:34:22 +00:00
Joplin Bot
bde14f9ddc Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-16 12:23:54 +00:00
Henry Heino
b220413a9b Desktop: Security: Fix HTML parsing bug (#10876) 2024-08-15 19:37:58 +01:00
Henry Heino
72472623cc Merge remote-tracking branch 'origin/release-3.0' into dev 2024-08-15 08:34:56 -07:00
Laurent Cozic
7e599c3a3e Desktop release v3.1.2 2024-08-15 16:09:57 +01:00
Henry Heino
74ba386ae3 Docs: Mobile plugins: Document using the web app to run mobile plugins (#10831) 2024-08-15 16:09:11 +01:00
Henry Heino
06f05d3823 Docs: Add example transformers.js-based plugin (#10840) 2024-08-15 16:08:57 +01:00
Henry Heino
6ada0a0103 Docs: Explain purpose of main Cloud Teams account (#10841)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-08-15 16:08:43 +01:00
Henry Heino
39bd7d3aef Mobile: Fixes #10867: Fix toolbar overflow menu is invisible (#10871) 2024-08-15 16:02:05 +01:00
Henry Heino
b5313067cd Desktop: Allow searching when only the note viewer is visible and sync search with editor (#10866) 2024-08-15 16:01:52 +01:00
Henry Heino
1edef99811 Desktop: Upgrade electron to v29.4.5 (#10847)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-08-15 16:00:46 +01:00
Alice
6518c17679 Desktop: Seamless-Updates: generate latest-mac.yml file (#10869) 2024-08-15 15:59:18 +01:00
Laurent Cozic
3ef07ac39a Clipper release v3.1.1 2024-08-15 10:51:18 +01:00
Laurent Cozic
bfcf3815a4 Chore: Fixing clipper dependencies 2024-08-15 10:50:14 +01:00
renovate[bot]
292479ac28 Update dependency @fortawesome/react-fontawesome to v0.2.1 (#10875) 2024-08-15 05:35:10 +00:00
Laurent Cozic
786e58ed54 Chore: Remove jcenter() dependency, now discontinued (#10868) 2024-08-13 14:40:45 +01:00
Naoki Kawamukai
b88630855f All: Translation: Update ja_JP.po (#10864) 2024-08-12 16:40:07 -04:00
cedecode
b956a21dae All: Translation: Update de_DE.po (#10863) 2024-08-12 16:39:11 -04:00
Henry Heino
c4ebb64fb2 Chore: Mobile,Testing: Fix keychain warning (#10861) 2024-08-12 15:34:36 +01:00
renovate[bot]
fb181cf935 Update dependency @react-native-community/datetimepicker to v8.0.1 (#10862) 2024-08-12 02:56:05 +00:00
Joplin Bot
f6fdc9fe66 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-10 18:18:17 +00:00
Laurent Cozic
23f521de74 iOS 13.1.3 2024-08-10 14:08:45 +01:00
Joplin Bot
88ed7c934f Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-10 12:21:37 +00:00
renovate[bot]
4c7a1f0f88 Update dependency @react-native-community/netinfo to v11.3.2 (#10855) 2024-08-10 12:05:01 +00:00
Laurent Cozic
98b7354373 iOS 13.1.2 2024-08-10 12:51:29 +01:00
Laurent Cozic
8d8cca06eb Android 3.1.2 2024-08-10 12:50:34 +01:00
Henry Heino
45b61e1f49 iOS: Fix crash on opening the sidebar (#10852) 2024-08-09 20:49:10 +01:00
Henry Heino
f58d29a6a6 Mobile: Fixes #10848: Fix WebDAV sync on mobile (#10849) 2024-08-09 20:49:01 +01:00
Joplin Bot
4caca4934e Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-09 12:23:13 +00:00
Laurent Cozic
a8613d1444 lock file 2024-08-09 12:16:58 +01:00
Laurent Cozic
c6377eafbf iOS 13.1.1 2024-08-09 12:15:35 +01:00
Laurent Cozic
aa23d5cdff Android 3.1.1 2024-08-09 12:14:25 +01:00
Laurent Cozic
a97c04c21c Desktop release v3.1.1 2024-08-09 11:48:06 +01:00
Laurent Cozic
9f66d7cfcd Chore: Setup new release 3.1 2024-08-09 11:47:43 +01:00
Laurent Cozic
a52b206dfb Chore: Temporarily disable new auto-update code 2024-08-09 11:45:08 +01:00
Henry Heino
806377e6ee Desktop: Resolves #10835: Allow specifying custom language data URLs (#10846) 2024-08-09 11:29:39 +01:00
Henry Heino
6ce55a5737 Chore: Update ignore files (#10845) 2024-08-08 20:03:02 +01:00
Henry Heino
cd40861ec8 Chore: Generator: Update types (#10844) 2024-08-08 20:02:53 +01:00
Henry Heino
a1aa4f78c9 Desktop: Resolves #10746: Fix "View OCR text" not present in context menu when right-clicking an image (#10842) 2024-08-08 20:02:08 +01:00
Henry Heino
0caecedb8f Desktop: Fixes #10828: Fix error when canceling bulk PDF export (#10839) 2024-08-08 20:00:19 +01:00
Henry Heino
af7e172438 Desktop: Fix crash on opening certain plugin dialogs (#10838) 2024-08-08 20:00:13 +01:00
Henry Heino
1f45252fc6 Docs: Update the Markdown editor plugin tutorial to reflect recent Joplin changes (#10830) 2024-08-08 19:57:56 +01:00
Henry Heino
d2ae02d066 Mobile: Include commit information in version information screen (#10829) 2024-08-08 19:57:32 +01:00
丛林意志
6d98f8102d Chore: i18n: Fixed localization issue and added spaces around words in Chinese-English text (#10821) 2024-08-08 19:56:34 +01:00
Henry Heino
08eab7a73a Desktop: Use Electron safeStorage for keychain support (#10535) 2024-08-08 19:53:43 +01:00
Joplin Bot
8d8c91ef50 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-08 12:23:28 +00:00
Alice
88b3c7f526 Desktop: Seamless-Updates - creation of update notification (#10791) 2024-08-08 10:49:21 +01:00
github-actions[bot]
24731edf92 @rxliuli has signed the CLA in laurent22/joplin#10843 2024-08-08 08:12:21 +00:00
Joplin Bot
85557b6882 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-07 18:19:36 +00:00
Joplin Bot
8dfc873ceb Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-07 12:23:29 +00:00
Laurent Cozic
8961aebc3a Doc: Fixed release cycle 2024-08-06 19:25:48 +01:00
renovate[bot]
500c31565d Update dependency @types/node to v18.19.33 (#10837) 2024-08-06 16:16:30 +00:00
Henry Heino
223a685529 Docs: Fix typo: Change "Table of Content" to "Table of Contents" (#10832) 2024-08-06 17:00:23 +01:00
Andy Piper
135d46f31b Doc: Correct typo and add detail to config_screen.md (#10823) 2024-08-05 21:34:09 +01:00
Henry Heino
9f997c2fb6 Desktop: Accessibility: Fix screen reader doesn't read Goto Anything search results or help button label (#10816) 2024-08-05 19:37:23 +01:00
pedr
a6cf0a3a81 Desktop: Fixes #10740: Improve the reliability of fetching resources (#10826) 2024-08-05 19:36:54 +01:00
renovate[bot]
1c2c071952 Update dependency @types/node to v18.19.32 (#10827) 2024-08-05 15:03:38 +00:00
github-actions[bot]
08348c88eb @shivam1234100 has signed the CLA in laurent22/joplin#10825 2024-08-05 14:38:34 +00:00
github-actions[bot]
70bfb9f18d @conglinyizhi has signed the CLA in laurent22/joplin#10821 2024-08-04 05:17:18 +00:00
Henry Heino
292d2fbc15 Desktop: Accessibility: Restore keyboard focus when closing a dialog (#10817) 2024-08-03 16:43:16 +01:00
Henry Heino
88cf1d6232 Desktop: Fix prompt tag dialog input can be wider than its container (#10818) 2024-08-03 16:43:00 +01:00
Henry Heino
9cf298ef44 Desktop: Accessibility: Improve keyboard navigation in the Markdown and note toolbar (#10819) 2024-08-03 16:42:46 +01:00
Henry Heino
19af6a8722 Desktop,Mobile: Fixes #10785: Fix math is invisible in certain mermaid diagrams (#10820) 2024-08-03 16:42:16 +01:00
pedr
5c8be448ab Desktop: Fixes #10668: Tags and Delete note not being available on Search and on All Notes list (#10729) 2024-08-02 17:44:30 +01:00
Henry Heino
f69dffcf23 Mobile: Support building for web (#10650) 2024-08-02 14:51:49 +01:00
Henry Heino
88271bf1a7 Desktop: Fixes #10815: Fix Enter key submits dialogs even if a button has focus (#10814) 2024-08-02 14:51:25 +01:00
Henry Heino
14cc053094 Desktop: Accessibility: Improve settings screen keyboard navigation and screen reader accessibility (#10812) 2024-08-02 14:49:15 +01:00
Henry Heino
65ef700fdc Mobile, Desktop: Improve RTL support in the Markdown editor (#10810) 2024-08-02 14:47:56 +01:00
Henry Heino
9dbd481f28 Desktop: Fix images fail to render in the preview pane for HTML notes (#10806) 2024-08-02 14:47:43 +01:00
Henry Heino
e5c8b4bb66 Desktop: Resolves #9450: Make the beta markdown editor the default (#10796) 2024-08-02 14:47:26 +01:00
renovate[bot]
ff6d700499 Update dependency @types/nodemailer to v6.4.15 (#10808) 2024-08-01 05:52:33 +00:00
Joplin Bot
fc1699ac91 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-08-01 00:47:00 +00:00
Henry Heino
596bcd8d8b Desktop: Accessibility: Improve focus handling for plugin and prompt dialogs (#10801) 2024-07-31 14:10:58 +01:00
Pavel Koneski
ecc4f3e22a Deskop: Linux: Add option to select installation directory (#10800) 2024-07-31 13:57:04 +01:00
renovate[bot]
c0dc30d0c4 Update dependency @types/markdown-it to v13.0.8 (#10804) 2024-07-31 09:04:19 +00:00
github-actions[bot]
f02af3af3b @BCSharp has signed the CLA in laurent22/joplin#10800 2024-07-30 19:09:01 +00:00
Joplin Bot
8179d3e723 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-30 18:18:57 +00:00
Henry Heino
60e347a782 Android: Fix crash on opening settings on old versions of Android (#10793) 2024-07-29 22:18:16 +01:00
Joplin Bot
06264847cc Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-29 18:19:24 +00:00
Laurent Cozic
3137d5be33 Merge branch 'release-3.0' into dev 2024-07-29 13:47:43 +01:00
Joplin Bot
d4c35b8c0b Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-28 18:18:14 +00:00
Laurent Cozic
39ad1e23a8 iOS 13.0.7 2024-07-28 15:08:29 +01:00
Laurent Cozic
d6dd23e921 Android 3.0.9 2024-07-28 15:06:25 +01:00
Henry Heino
b108bf799d Desktop: Accessibility: Add missing labels and role information to several controls (#10788) 2024-07-28 14:53:32 +01:00
Henry Heino
6d92e982dc Chore: iOS: Fix build by downgrading @react-native-clipboard/clipboard (#10787) 2024-07-28 14:53:17 +01:00
Henry Heino
40bd2dfe21 Desktop: Rich Text Editor: Preserve cursor location when updating editor content (#10781) 2024-07-28 14:49:51 +01:00
Joplin Bot
819de1cfa4 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-28 12:21:12 +00:00
Alice
a6d6e70b3d Chore: Desktop: Seamless-Updates - creation of auto updater service (#10772) 2024-07-28 12:09:30 +01:00
Laurent Cozic
05cf51ec65 Desktop release v3.0.14 2024-07-26 12:44:35 +01:00
Henry Heino
0935b6f697 Desktop: Fixes #10672: External editing: Fix notes often not updated when saved from Vim (#10780) 2024-07-26 12:39:21 +01:00
Henry Heino
dd5240d018 Desktop: Improve focus handling for notebook edit, share, and sync dialogs (#10779) 2024-07-26 12:39:01 +01:00
Henry Heino
3fbb3b6b82 Desktop: Fixes #10768: Make :w trigger sync in the beta editor's Vim mode (#10778) 2024-07-26 12:38:07 +01:00
Henry Heino
77b74daa0e Android: Fix pasting PNG and JPEG images from the clipboard (#10777) 2024-07-26 12:37:55 +01:00
Henry Heino
8c0769fdb3 Chore: Mobile: Add note screen tests (#10766) 2024-07-26 12:35:50 +01:00
Henry Heino
d2028588e8 Desktop: Resolves #10424: Move the note viewer to a separate process (#10678) 2024-07-26 12:22:49 +01:00
Laurent Cozic
4b99c2062c Update dictionary 2024-07-26 08:23:57 +01:00
Joplin Bot
ce0218700e Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-26 00:43:08 +00:00
Laurent Cozic
d63f498f4c Doc: Add sponsor 2024-07-25 22:41:26 +01:00
Laurent Cozic
56d2aced8a Server v3.0.1 2024-07-25 18:18:48 +01:00
Henry Heino
db2a194b69 Merge remote-tracking branch 'origin/release-3.0' into dev 2024-07-25 08:10:48 -07:00
github-actions[bot]
f7a970f466 @Aarya01Patil has signed the CLA in laurent22/joplin#10783 2024-07-25 11:57:59 +00:00
Henry Heino
f7fa7a195f Server: Allow web client sync (#10775) 2024-07-24 23:45:11 +01:00
Laurent Cozic
e6ec27a501 Server: Prevent item size calculation task from failing when a user has been deleted 2024-07-24 19:16:40 +01:00
Henry Heino
331f7ebe5c Mobile: Plugins: Fix incorrect Node exports emulation (#10776) 2024-07-23 20:10:59 +01:00
joe
afcd2d2a39 update zh_TW.po file (#10773) 2024-07-23 12:56:08 +01:00
github-actions[bot]
8129f4a89f @fishpcblog has signed the CLA in laurent22/joplin#10773 2024-07-23 11:08:23 +00:00
github-actions[bot]
72c1bb3724 @BHAV0207 has signed the CLA in laurent22/joplin#10769 2024-07-20 10:59:43 +00:00
cedecode
8fdccd287e Update de_DE.po (#10767) 2024-07-19 21:44:06 +01:00
Joplin Bot
b69a7403bc Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-19 18:19:04 +00:00
Laurent Cozic
bdc9fa9dc3 Doc: Added sponsor 2024-07-19 15:54:41 +01:00
Laurent Cozic
9c07e57e28 lock file 2024-07-18 15:06:47 +01:00
Henry Heino
821daeca94 Chore: Mobile: Add NoteBodyViewer tests (#10747) 2024-07-18 09:44:13 +01:00
ERYpTION
480bf238f6 Update da_DK.po (#10758) 2024-07-18 09:44:00 +01:00
Henry Heino
8ff13e5fc4 Android: Fixes #10681: Fix Dropbox sync for certain device languages (#10759) 2024-07-18 09:43:49 +01:00
Henry Heino
8e1970d08e Desktop: Update bundled Backup plugin to v1.4.2 (#10760)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-07-18 09:43:20 +01:00
Henry Heino
86d92dd302 Chore: Fix indentation in generate-plugin-doc/package.json (#10762)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2024-07-18 09:43:07 +01:00
Henry Heino
71b466507f Mobile: Upgrade react-native-webview to 13.8.6 to fix CI (#10761) 2024-07-17 22:49:10 +01:00
renovate[bot]
11ce5f6c52 Update dependency nodemailer to v6.9.13 (#10699) 2024-07-17 20:38:53 +00:00
renovate[bot]
630b4061f0 Update dependency pg to v8.11.5 (#10700) 2024-07-17 20:38:51 +00:00
renovate[bot]
912c943114 Update dependency react-native-webview to v13.8.4 (#10702) 2024-07-17 20:38:49 +00:00
renovate[bot]
8e377e0306 Update dependency sharp to v0.33.3 (#10704) 2024-07-17 20:38:13 +00:00
renovate[bot]
1535e020a3 Update dependency style-to-js to v1.1.12 (#10705) 2024-07-17 20:38:11 +00:00
renovate[bot]
23d5d3426d Update dependency tar to v6.2.1 (#10706) 2024-07-17 20:38:04 +00:00
Laurent Cozic
6ab7a0836e Tools: Automerge pull requests with the "automerge" label 2024-07-17 20:51:54 +01:00
Laurent Cozic
278691211d Tools: Automerge pull requests with the "automerge" label 2024-07-17 20:06:26 +01:00
Laurent Cozic
356d4688a0 Tools: Automerge pull requests with the "automerge" label 2024-07-17 19:52:52 +01:00
renovate[bot]
6b1d31387b Update dependency @react-native-community/geolocation to v3.2.1 (#10757)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 18:56:46 +00:00
pedr
70bfb26c9a Mobile: Fixes: #10677: Following a link to a previously open note wouldn't work (#10750) 2024-07-16 19:38:54 +01:00
Henry Heino
71f70f4d2c Mobile: Resolves #9017: Support pasting images (#10751) 2024-07-16 19:28:05 +01:00
Henry Heino
64e4ebb1f3 Mobile: Fix manual resource download mode (#10748) 2024-07-16 19:27:08 +01:00
Liffindra Angga Zaaldian
2d984ce9a8 Update Indonesian translation (#10741) 2024-07-16 19:25:54 +01:00
Henry Heino
eaf160e0b1 Docs: Update user-facing plugin documentation to reflect that plugins are now supported on mobile (#10738) 2024-07-16 19:25:38 +01:00
Henry Heino
624bfd9175 Desktop: Fixes #10733: Fix not-yet-created images lost while editing with the Rich Text Editor (#10734) 2024-07-16 19:25:23 +01:00
Henry Heino
9ad1249f11 Chore: Mobile: Migrate shim-init-react to TypeScript (#10731) 2024-07-16 19:23:03 +01:00
sysescool
668849603d Desktop: Fixes #10716: fix joplin install fails because ldconfig not found libfuse2 but it is indeed installed. (#10717) 2024-07-16 19:20:51 +01:00
renovate[bot]
24f4c8e6ab Update dependency terminal-kit to v3.1.1 (#10713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 19:03:33 +01:00
renovate[bot]
46f5784edc Update dependency react-native-get-random-values to v1.11.0 (#10712)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 19:01:49 +01:00
renovate[bot]
fae2443481 Update dependency react-native-device-info to v10.13.1 (#10711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 19:01:40 +01:00
renovate[bot]
37d65e000a Update dependency jsdom to v23.2.0 (#10709)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 19:01:17 +01:00
renovate[bot]
6dd90eb03f Update dependency @react-native-community/geolocation to v3.2.0 (#10708)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 19:01:07 +01:00
CUI Hao
3d8f713eb7 Chore: Add a sleep in the note duplication test (#10719)
Fixes a test failure on very fast computers.
2024-07-15 07:33:59 -07:00
renovate[bot]
c35efe15d2 Update dependency @react-native-community/slider to v4.5.2 (#10744)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-15 02:46:52 +00:00
Henry Heino
1596b46b86 Chore: Fixes #10721: Fix test failure in CI (#10735) 2024-07-11 12:59:56 -07:00
Henry Heino
4de0236194 Chore: Docs: Fix missing closing tag (#10730)
The video element is not a void element. As such, if it's missing a closing tag, it's considered to be unclosed.
See https://developer.mozilla.org/en-US/docs/Glossary/Void_element#self-closing_tags.
2024-07-11 10:16:33 -07:00
Jeremy Kao
2ab9702e32 Docs: Update the UI path for sync status on the mobile app (#10718)
The instructions for how to view synchronisation status on mobile were out of date.
2024-07-11 07:44:09 -07:00
github-actions[bot]
24954bd0f0 @shubhiscoding has signed the CLA in laurent22/joplin#10728 2024-07-09 11:06:20 +00:00
renovate[bot]
2d4322be56 Update dependency @types/node to v18.19.31 (#10727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-09 10:37:55 +00:00
renovate[bot]
abb069bf50 Update dependency @react-native-community/slider to v4.5.1 (#10726)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-09 10:35:50 +00:00
renovate[bot]
a81d9fe17a Update dependency koa to v2.15.2 (#10698)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-09 08:11:32 +00:00
renovate[bot]
6d44158050 Update dependency glob to v10.3.12 (#10697)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-09 08:10:19 +00:00
Dmitriy Q
a63cf3a90d All: Translation: Update ru_RU.po (#10720) 2024-07-09 04:08:49 -04:00
github-actions[bot]
ddb4f8c45b @cuihaoleo has signed the CLA in laurent22/joplin#10719 2024-07-08 04:28:43 +00:00
github-actions[bot]
d7adab59ef @imsardine has signed the CLA in laurent22/joplin#10718 2024-07-08 03:49:24 +00:00
github-actions[bot]
e41374496e @sysescool has signed the CLA in laurent22/joplin#10717 2024-07-08 03:19:52 +00:00
Arda Kılıçdağı
62d514463c Turkish Translations updated (#10692) 2024-07-06 18:26:25 +02:00
jduar
332078b4ea Update Portuguese pt_PT.po translation. (#10691) 2024-07-06 18:26:13 +02:00
github-actions[bot]
c60e11646d @jduar has signed the CLA in laurent22/joplin#10691 2024-07-06 14:06:06 +00:00
Joplin Bot
c607fe9c75 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-06 12:20:41 +00:00
Laurent Cozic
1a4ba2c74a Merge branch 'release-3.0' into dev 2024-07-06 13:41:53 +02:00
Laurent Cozic
e49bca8315 iOS 13.0.6 2024-07-06 13:23:17 +02:00
Laurent Cozic
636fbdf7d0 Android 3.0.8 2024-07-06 13:21:55 +02:00
Laurent Cozic
ee97434bb0 Tools: Skip more minor changes for changelog generation 2024-07-06 12:19:17 +02:00
Laurent Cozic
599cf5b86f Desktop release v3.0.13 2024-07-06 12:12:46 +02:00
Henry Heino
2fd6a3a2fa Desktop: Fixes #10685: Fix shift-delete asks to permanently delete the current note, rather than cut text, when the editor is selected. (#10687) 2024-07-06 12:05:35 +02:00
Henry Heino
a3e04103de Desktop: Fixes #10679: Fix incorrect text rendering on MacOS by changing the default font to Avenir Next (#10686) 2024-07-05 19:58:09 +02:00
renovate[bot]
731260926d Update dependency @types/node to v18.19.30 (#10684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-05 13:49:54 +02:00
ben-igel
a43635610a Update de_DE.po to make the german translation of the sort lines command better understandable (#10682) 2024-07-05 13:18:58 +02:00
github-actions[bot]
e307459652 @ben-igel has signed the CLA in laurent22/joplin#10682 2024-07-04 17:51:49 +00:00
Henry Heino
c197a83de8 Desktop: Fix error in plugin content scripts generated with Webpack (#10680) 2024-07-04 14:58:26 +02:00
Henry Heino
320d0df60d Desktop, Mobile: Fixes #10674: Fix sidebar performance regression with many nested notebooks (#10676) 2024-07-04 14:56:57 +02:00
Joplin Bot
7e4533d811 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-03 12:22:19 +00:00
cedecode
f32fe63205 All: Update de_DE.po (small improvements) (#10673) 2024-07-03 13:53:32 +02:00
Laurent Cozic
be117bca86 Tools: Run packageJsonLint hook only when JSON files are being committed 2024-07-03 10:54:13 +02:00
Laurent Cozic
2b7bd902f3 Merge branch 'release-3.0' into dev 2024-07-03 10:47:27 +02:00
Laurent Cozic
3e0fb48e44 Api: Do not return deleted notes in folders/:id/notes call 2024-07-03 10:41:31 +02:00
Laurent Cozic
6d7fd19167 Chore: Add word to dic 2024-07-03 00:52:08 +02:00
Laurent Cozic
c3520d9eb1 CLI v3.0.1 2024-07-02 21:00:43 +02:00
Laurent Cozic
5fd3cecc96 Lock file 2024-07-02 21:00:43 +02:00
Laurent Cozic
0d8666c946 Releasing sub-packages 2024-07-02 21:00:42 +02:00
Joplin Bot
12db667128 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-02 18:18:51 +00:00
Laurent Cozic
6215de6080 Doc: Added new sponsor 2024-07-02 19:16:15 +02:00
renovate[bot]
7d2f384475 Update dependency @types/node to v18.19.29 (#10671)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-02 19:13:33 +02:00
Laurent Cozic
6ea1ac09a4 Doc: Fixed news filename 2024-07-02 15:17:20 +02:00
Laurent Cozic
f2841a9a94 Tools: Add script to validate Markdown filenames on commit 2024-07-02 15:16:16 +02:00
Joplin Bot
46ade2e0f8 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-01 18:19:29 +00:00
Henry Heino
d89be23069 Chore: Migrate SQL queries in preparation for web support (#10670) 2024-07-01 19:56:40 +02:00
Laurent Cozic
337d50437b Doc: Add release notes 3.0 2024-07-01 18:16:08 +02:00
Laurent Cozic
2479a8471e Merge branch 'release-3.0' into dev 2024-07-01 18:02:27 +02:00
rnbastos
6c091910cd Update pt_BR.po (#10667) 2024-07-01 17:32:43 +02:00
pedr
a074532497 Desktop, Mobile: Fixes #10645: Show notification in case Joplin Cloud credential is not valid anymore (#10649) 2024-07-01 17:21:17 +02:00
Joplin Bot
5d2df358ac Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-07-01 00:47:08 +00:00
Laurent Cozic
dfdc2fda27 Fixed tests 2024-06-29 18:38:18 +02:00
Laurent Cozic
a1f9c9c3d8 All: Set min version for synchronising to 3.0.0 2024-06-29 18:38:18 +02:00
Joplin Bot
838da6f161 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-06-29 12:22:44 +00:00
Laurent Cozic
a86ee1d34e Merge branch 'release-3.0' into dev 2024-06-29 12:25:11 +02:00
Laurent Cozic
5f34a1bc92 Doc: Add Multi-factor authentication guide 2024-06-28 19:43:59 +02:00
renovate[bot]
f781face3a Update dependency @types/node to v18.19.28 (#10663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-28 13:03:05 +02:00
Laurent Cozic
78ecd28d73 Merge branch 'release-3.0' into dev 2024-06-27 11:54:19 +02:00
github-actions[bot]
85e57a3953 @cedecode has signed the CLA in laurent22/joplin#10658 2024-06-25 22:11:34 +00:00
qx100
95968f6690 All: Update zh_CN.po (#10651) 2024-06-25 15:05:06 +02:00
Henry Heino
f0b73ee916 Docs: Document creating and managing to-do notes (#10563) 2024-06-25 15:01:54 +02:00
Henry Heino
a44412ae78 Chore: Increase strength of Settings types (#10605) 2024-06-25 15:01:39 +02:00
Henry Heino
c7116b135f Chore: Refactor mobile plugin logic into locations more consistent with other parts of the app (#10636) 2024-06-25 14:59:59 +02:00
Siddhant Paritosh Rao
801d36c41f Mobile: Fixes #10596: remove search bar from plugins screen (#10648) 2024-06-25 14:59:41 +02:00
Henry Heino
1d46adf801 Mobile: Fix dayjs-related startup error (#10652) 2024-06-24 17:15:57 +02:00
Laurent Cozic
94edaea210 Doc: Removed outdated hot reload information 2024-06-23 09:36:56 +01:00
Henry Heino
5db88995c0 Chore: Fix CI (#10646) 2024-06-21 09:37:25 +01:00
Laurent Cozic
8eda8d3c84 Fixed test 2024-06-20 18:25:51 +01:00
Laurent Cozic
1437dd5f27 Desktop: Use relative time in note list for today and yesterday 2024-06-20 14:01:13 +01:00
Laurent Cozic
9eb4944614 Server: Remove USERS_WITH_REPLICATION env variable 2024-06-19 23:34:00 +01:00
Joplin Bot
b4ef5abb88 Doc: Auto-update documentation
Auto-updated using release-website.sh
2024-06-19 18:18:05 +00:00
955 changed files with 113916 additions and 14850 deletions

View File

@@ -51,8 +51,10 @@ packages/app-desktop/node_modules
packages/app-desktop/packageInfo.js
packages/app-desktop/services/electron-context-menu.js
packages/app-desktop/vendor/lib/
packages/app-mobile/packageInfo.js
packages/app-mobile/android
packages/app-mobile/**/*.bundle.js
packages/app-mobile/web/public/pluginAssets/**/*
packages/app-mobile/ios
packages/app-mobile/lib/rnInjectedJs/
packages/app-mobile/locales
@@ -148,11 +150,16 @@ 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/exportDeletionLog.test.js
packages/app-desktop/commands/exportDeletionLog.js
packages/app-desktop/commands/exportFolders.js
packages/app-desktop/commands/exportNotes.js
packages/app-desktop/commands/focusElement.js
packages/app-desktop/commands/index.js
packages/app-desktop/commands/openNoteInNewWindow.js
packages/app-desktop/commands/openProfileDirectory.js
packages/app-desktop/commands/renderMarkup.test.js
packages/app-desktop/commands/renderMarkup.js
packages/app-desktop/commands/replaceMisspelling.js
packages/app-desktop/commands/restoreNoteRevision.js
packages/app-desktop/commands/startExternalEditing.js
@@ -167,9 +174,13 @@ packages/app-desktop/gui/Button/Button.js
packages/app-desktop/gui/ClipperConfigScreen.js
packages/app-desktop/gui/ConfigScreen/ButtonBar.js
packages/app-desktop/gui/ConfigScreen/ConfigScreen.js
packages/app-desktop/gui/ConfigScreen/FontSearch.js
packages/app-desktop/gui/ConfigScreen/Sidebar.js
packages/app-desktop/gui/ConfigScreen/controls/FontSearch.js
packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.js
packages/app-desktop/gui/ConfigScreen/controls/SettingComponent.js
packages/app-desktop/gui/ConfigScreen/controls/SettingDescription.js
packages/app-desktop/gui/ConfigScreen/controls/SettingHeader.js
packages/app-desktop/gui/ConfigScreen/controls/SettingLabel.js
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
@@ -199,62 +210,14 @@ packages/app-desktop/gui/KeymapConfig/styles/index.js
packages/app-desktop/gui/KeymapConfig/utils/getLabel.js
packages/app-desktop/gui/KeymapConfig/utils/useCommandStatus.js
packages/app-desktop/gui/KeymapConfig/utils/useKeymap.js
packages/app-desktop/gui/MainScreen/MainScreen.js
packages/app-desktop/gui/MainScreen/commands/addProfile.js
packages/app-desktop/gui/MainScreen/commands/commandPalette.js
packages/app-desktop/gui/MainScreen/commands/deleteFolder.js
packages/app-desktop/gui/MainScreen/commands/deleteNote.js
packages/app-desktop/gui/MainScreen/commands/duplicateNote.js
packages/app-desktop/gui/MainScreen/commands/editAlarm.js
packages/app-desktop/gui/MainScreen/commands/exportPdf.js
packages/app-desktop/gui/MainScreen/commands/gotoAnything.js
packages/app-desktop/gui/MainScreen/commands/hideModalMessage.js
packages/app-desktop/gui/MainScreen/commands/index.js
packages/app-desktop/gui/MainScreen/commands/leaveSharedFolder.js
packages/app-desktop/gui/MainScreen/commands/moveToFolder.js
packages/app-desktop/gui/MainScreen/commands/newFolder.js
packages/app-desktop/gui/MainScreen/commands/newNote.js
packages/app-desktop/gui/MainScreen/commands/newSubFolder.js
packages/app-desktop/gui/MainScreen/commands/newTodo.js
packages/app-desktop/gui/MainScreen/commands/openFolder.js
packages/app-desktop/gui/MainScreen/commands/openFolderDialog.js
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
packages/app-desktop/gui/MainScreen/commands/showModalMessage.js
packages/app-desktop/gui/MainScreen/commands/showNoteContentProperties.js
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
packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.js
packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js
packages/app-desktop/gui/MainScreen/commands/toggleNoteType.js
packages/app-desktop/gui/MainScreen/commands/toggleNotesSortOrderField.js
packages/app-desktop/gui/MainScreen/commands/toggleNotesSortOrderReverse.js
packages/app-desktop/gui/MainScreen/commands/togglePerFolderSortOrder.js
packages/app-desktop/gui/MainScreen/commands/toggleSideBar.js
packages/app-desktop/gui/MainScreen/commands/toggleVisiblePanes.js
packages/app-desktop/gui/MainScreen.js
packages/app-desktop/gui/MasterPasswordDialog/Dialog.js
packages/app-desktop/gui/MenuBar.js
packages/app-desktop/gui/MultiNoteActions.js
packages/app-desktop/gui/Navigator.js
packages/app-desktop/gui/NewWindowOrIFrame.js
packages/app-desktop/gui/NoteContentPropertiesDialog.js
packages/app-desktop/gui/NoteEditor/EditorWindow.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
@@ -280,7 +243,9 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useScrollUtils.
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/localisation.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useRefocusOnVisiblePaneChange.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
@@ -291,11 +256,15 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/shouldPasteResources.
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/shouldPasteResources.js
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/useKeyboardRefocusHandler.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useLinkTooltips.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useTabIndenter.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/WarningBanner/BannerContent.js
packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
packages/app-desktop/gui/NoteEditor/commands/index.js
@@ -309,6 +278,7 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.test.js
packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.js
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
packages/app-desktop/gui/NoteEditor/utils/getWindowCommandPriority.js
packages/app-desktop/gui/NoteEditor/utils/index.js
packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
@@ -322,6 +292,8 @@ packages/app-desktop/gui/NoteEditor/utils/useFormNote.js
packages/app-desktop/gui/NoteEditor/utils/useMarkupToHtml.js
packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.js
packages/app-desktop/gui/NoteEditor/utils/useNoteSearchBar.js
packages/app-desktop/gui/NoteEditor/utils/usePluginEditorView.test.js
packages/app-desktop/gui/NoteEditor/utils/usePluginEditorView.js
packages/app-desktop/gui/NoteEditor/utils/usePluginServiceRegistration.js
packages/app-desktop/gui/NoteEditor/utils/useScheduleSaveCallbacks.js
packages/app-desktop/gui/NoteEditor/utils/useScrollWhenReadyOptions.js
@@ -332,8 +304,10 @@ packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js
packages/app-desktop/gui/NoteList/commands/index.js
packages/app-desktop/gui/NoteList/utils/canManuallySortNotes.js
packages/app-desktop/gui/NoteList/utils/types.js
packages/app-desktop/gui/NoteList/utils/useActiveDescendantId.js
packages/app-desktop/gui/NoteList/utils/useDragAndDrop.js
packages/app-desktop/gui/NoteList/utils/useFocusNote.js
packages/app-desktop/gui/NoteList/utils/useFocusVisible.js
packages/app-desktop/gui/NoteList/utils/useItemCss.js
packages/app-desktop/gui/NoteList/utils/useMoveNote.js
packages/app-desktop/gui/NoteList/utils/useOnKeyDown.js
@@ -354,6 +328,7 @@ 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/getNoteElementIdFromJoplinId.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
@@ -362,6 +337,7 @@ packages/app-desktop/gui/NoteListItem/utils/useItemElement.js
packages/app-desktop/gui/NoteListItem/utils/useItemEventHandlers.js
packages/app-desktop/gui/NoteListItem/utils/useOnContextMenu.js
packages/app-desktop/gui/NoteListItem/utils/useRenderedNote.js
packages/app-desktop/gui/NoteListItem/utils/useRootElement.test.js
packages/app-desktop/gui/NoteListItem/utils/useRootElement.js
packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js
packages/app-desktop/gui/NotePropertiesDialog.js
@@ -372,7 +348,9 @@ 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/LabelledPasswordInput.js
packages/app-desktop/gui/PasswordInput/PasswordInput.js
packages/app-desktop/gui/PasswordInput/types.js
packages/app-desktop/gui/PdfViewer.js
packages/app-desktop/gui/PromptDialog.js
packages/app-desktop/gui/ResizableLayout/MoveButtons.js
@@ -406,16 +384,19 @@ packages/app-desktop/gui/Sidebar/commands/focusElementSideBar.js
packages/app-desktop/gui/Sidebar/commands/index.js
packages/app-desktop/gui/Sidebar/hooks/useFocusHandler.js
packages/app-desktop/gui/Sidebar/hooks/useOnRenderItem.js
packages/app-desktop/gui/Sidebar/hooks/useOnRenderListWrapper.js
packages/app-desktop/gui/Sidebar/hooks/useOnSidebarKeyDownHandler.js
packages/app-desktop/gui/Sidebar/hooks/useSelectedSidebarIndex.js
packages/app-desktop/gui/Sidebar/hooks/useSidebarCommandHandler.js
packages/app-desktop/gui/Sidebar/hooks/useSidebarListData.js
packages/app-desktop/gui/Sidebar/hooks/utils/toggleHeader.js
packages/app-desktop/gui/Sidebar/listItemComponents/AllNotesItem.js
packages/app-desktop/gui/Sidebar/listItemComponents/EmptyExpandLink.js
packages/app-desktop/gui/Sidebar/listItemComponents/ExpandIcon.js
packages/app-desktop/gui/Sidebar/listItemComponents/ExpandLink.js
packages/app-desktop/gui/Sidebar/listItemComponents/FolderItem.js
packages/app-desktop/gui/Sidebar/listItemComponents/HeaderItem.js
packages/app-desktop/gui/Sidebar/listItemComponents/ListItemWrapper.js
packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.js
packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js
packages/app-desktop/gui/Sidebar/styles/index.js
@@ -429,10 +410,71 @@ packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
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/UpdateNotification/UpdateNotification.js
packages/app-desktop/gui/WindowCommandsAndDialogs/AppDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/ModalMessageOverlay.js
packages/app-desktop/gui/WindowCommandsAndDialogs/PluginDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/WindowCommandsAndDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/addProfile.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/commandPalette.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/deleteFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/duplicateNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/editAlarm.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/gotoAnything.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/hideModalMessage.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/index.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/leaveSharedFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newSubFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newTodo.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openFolderDialog.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openItem.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openPdfViewer.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openTag.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/print.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/renameFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/renameTag.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/resetLayout.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/revealResourceFile.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/search.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/setTags.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showEditorPlugin.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showModalMessage.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteContentProperties.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteProperties.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showPrompt.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareFolderDialog.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareNoteDialog.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.test.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditorPlugin.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditors.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleLayoutMoveMode.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleMenuBar.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNoteList.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNoteType.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNotesSortOrderField.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNotesSortOrderReverse.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/togglePerFolderSortOrder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleSideBar.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleVisiblePanes.js
packages/app-desktop/gui/WindowCommandsAndDialogs/types.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/appDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/usePrintToCallback.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/useSyncDialogState.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/useWindowCommands.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/useWindowControl.js
packages/app-desktop/gui/dialogs.js
packages/app-desktop/gui/hooks/useDocument.js
packages/app-desktop/gui/hooks/useEffectDebugger.js
packages/app-desktop/gui/hooks/useElementHeight.js
packages/app-desktop/gui/hooks/useImperativeHandlerDebugger.js
@@ -447,28 +489,41 @@ packages/app-desktop/gui/style/StyledLink.js
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/announceForAccessibility.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/goToAnything.spec.js
packages/app-desktop/integration-tests/main.spec.js
packages/app-desktop/integration-tests/markdownEditor.spec.js
packages/app-desktop/integration-tests/models/GoToAnything.js
packages/app-desktop/integration-tests/models/MainScreen.js
packages/app-desktop/integration-tests/models/NoteEditorScreen.js
packages/app-desktop/integration-tests/models/NoteList.js
packages/app-desktop/integration-tests/models/SettingsScreen.js
packages/app-desktop/integration-tests/models/Sidebar.js
packages/app-desktop/integration-tests/noteList.spec.js
packages/app-desktop/integration-tests/pluginApi.spec.js
packages/app-desktop/integration-tests/richTextEditor.spec.js
packages/app-desktop/integration-tests/settings.spec.js
packages/app-desktop/integration-tests/sidebar.spec.js
packages/app-desktop/integration-tests/simpleBackup.spec.js
packages/app-desktop/integration-tests/util/activateMainMenuItem.js
packages/app-desktop/integration-tests/util/createStartupArgs.js
packages/app-desktop/integration-tests/util/extendedExpect.js
packages/app-desktop/integration-tests/util/firstNonDevToolsWindow.js
packages/app-desktop/integration-tests/util/getImageSourceSize.js
packages/app-desktop/integration-tests/util/setDarkMode.js
packages/app-desktop/integration-tests/util/setFilePickerResponse.js
packages/app-desktop/integration-tests/util/setMessageBoxResponse.js
packages/app-desktop/integration-tests/util/test.js
packages/app-desktop/integration-tests/util/waitForNextOpenPath.js
packages/app-desktop/integration-tests/wcag.spec.js
packages/app-desktop/playwright.config.js
packages/app-desktop/plugins/GotoAnything.js
packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.js
packages/app-desktop/services/autoUpdater/AutoUpdaterService.js
packages/app-desktop/services/bridge.js
packages/app-desktop/services/commands/stateToWhenClauseContext.js
packages/app-desktop/services/commands/types.js
@@ -493,18 +548,24 @@ packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/tools/copy7Zip.js
packages/app-desktop/tools/generateLatestArm64Yml.js
packages/app-desktop/tools/githubReleasesUtils.js
packages/app-desktop/tools/modifyReleaseAssets.js
packages/app-desktop/tools/notarizeMacApp.js
packages/app-desktop/tools/renameReleaseAssets.js
packages/app-desktop/utils/7zip/getPathToExecutable7Zip.js
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/customProtocols/constants.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.test.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.js
packages/app-desktop/utils/customProtocols/registerCustomProtocols.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-desktop/utils/window/types.js
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/commands/index.js
packages/app-mobile/commands/newNote.test.js
@@ -513,19 +574,34 @@ 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/commands/util/showResource.js
packages/app-mobile/components/BackButtonDialogBox.js
packages/app-mobile/components/BetaChip.js
packages/app-mobile/components/CameraView.js
packages/app-mobile/components/CameraView/ActionButtons.js
packages/app-mobile/components/CameraView/Camera/index.jest.js
packages/app-mobile/components/CameraView/Camera/index.js
packages/app-mobile/components/CameraView/Camera/types.js
packages/app-mobile/components/CameraView/CameraView.test.js
packages/app-mobile/components/CameraView/CameraView.js
packages/app-mobile/components/CameraView/ScannedBarcodes.js
packages/app-mobile/components/CameraView/types.js
packages/app-mobile/components/CameraView/utils/fitRectIntoBounds.js
packages/app-mobile/components/CameraView/utils/useBarcodeScanner.js
packages/app-mobile/components/Checkbox.js
packages/app-mobile/components/DialogManager.js
packages/app-mobile/components/DismissibleDialog.js
packages/app-mobile/components/Dropdown.test.js
packages/app-mobile/components/Dropdown.js
packages/app-mobile/components/ExtendedWebView.js
packages/app-mobile/components/ExtendedWebView/index.jest.js
packages/app-mobile/components/ExtendedWebView/index.js
packages/app-mobile/components/ExtendedWebView/index.web.js
packages/app-mobile/components/ExtendedWebView/types.js
packages/app-mobile/components/FolderPicker.js
packages/app-mobile/components/Icon.js
packages/app-mobile/components/IconButton.js
packages/app-mobile/components/Modal.js
packages/app-mobile/components/ModalDialog.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.test.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
@@ -575,27 +651,54 @@ 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/NoteItem.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/Menu.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/WebBetaButton.js
packages/app-mobile/components/ScreenHeader/index.js
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/SideMenuContentNote.js
packages/app-mobile/components/TextInput.js
packages/app-mobile/components/accessibility/AccessibleModalMenu.js
packages/app-mobile/components/accessibility/AccessibleView.js
packages/app-mobile/components/app-nav.js
packages/app-mobile/components/base-screen.js
packages/app-mobile/components/biometrics/BiometricPopup.js
packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/buttons/FloatingActionButton.js
packages/app-mobile/components/buttons/TextButton.js
packages/app-mobile/components/buttons/index.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/plugins/PluginRunner.js
packages/app-mobile/components/plugins/PluginRunnerWebView.js
packages/app-mobile/components/plugins/backgroundPage/initializeDialogWebView.js
packages/app-mobile/components/plugins/backgroundPage/initializePluginBackgroundIframe.js
packages/app-mobile/components/plugins/backgroundPage/pluginRunnerBackgroundPage.js
packages/app-mobile/components/plugins/backgroundPage/startStopPlugin.js
packages/app-mobile/components/plugins/backgroundPage/utils/getFormData.test.js
packages/app-mobile/components/plugins/backgroundPage/utils/getFormData.js
packages/app-mobile/components/plugins/backgroundPage/utils/reportUnhandledErrors.js
packages/app-mobile/components/plugins/backgroundPage/utils/wrapConsoleLog.js
packages/app-mobile/components/plugins/dialogs/PluginDialogManager.js
packages/app-mobile/components/plugins/dialogs/PluginDialogWebView.js
packages/app-mobile/components/plugins/dialogs/PluginPanelViewer.js
packages/app-mobile/components/plugins/dialogs/PluginUserWebView.js
packages/app-mobile/components/plugins/dialogs/hooks/useDialogMessenger.js
packages/app-mobile/components/plugins/dialogs/hooks/useDialogSize.js
packages/app-mobile/components/plugins/dialogs/hooks/useViewInfos.js
packages/app-mobile/components/plugins/dialogs/hooks/useWebViewSetup.js
packages/app-mobile/components/plugins/types.js
packages/app-mobile/components/plugins/utils/createOnLogHandler.js
packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen/FileSystemPathSelector.js
packages/app-mobile/components/screens/ConfigScreen/JoplinCloudConfig.js
@@ -646,58 +749,45 @@ packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState
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.test.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/SearchScreen/SearchResults.js
packages/app-mobile/components/screens/SearchScreen/index.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/testing/TestProviderStack.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.test.js
packages/app-mobile/plugins/loadPlugins.js
packages/app-mobile/plugins/testing/MockPluginRunner.js
packages/app-mobile/index.web.js
packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
packages/app-mobile/services/AlarmServiceDriver.web.js
packages/app-mobile/services/BackButtonService.js
packages/app-mobile/services/e2ee/RSA.react-native.js
packages/app-mobile/services/e2ee/crypto.js
packages/app-mobile/services/plugins/PlatformImplementation.js
packages/app-mobile/services/profiles/index.js
packages/app-mobile/services/voiceTyping/VoiceTyping.js
packages/app-mobile/services/voiceTyping/utils/splitWhisperText.test.js
packages/app-mobile/services/voiceTyping/utils/splitWhisperText.js
packages/app-mobile/services/voiceTyping/vosk.android.js
packages/app-mobile/services/voiceTyping/vosk.ios.js
packages/app-mobile/services/voiceTyping/vosk.js
packages/app-mobile/services/voiceTyping/whisper.js
packages/app-mobile/setupQuickActions.js
packages/app-mobile/tools/buildInjectedJs/BundledFile.js
packages/app-mobile/tools/buildInjectedJs/constants.js
packages/app-mobile/tools/buildInjectedJs/copyJs.js
packages/app-mobile/tools/buildInjectedJs/gulpTasks.js
packages/app-mobile/tools/copyAssets.js
packages/app-mobile/utils/ShareExtension.js
packages/app-mobile/utils/ShareUtils.test.js
packages/app-mobile/utils/ShareUtils.js
@@ -706,9 +796,13 @@ 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/database-driver-react-native.js
packages/app-mobile/utils/database-driver-react-native.web.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/fs-driver-rn.web.js
packages/app-mobile/utils/fs-driver/fs-driver-rn.web.worker.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
@@ -717,17 +811,31 @@ packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
packages/app-mobile/utils/getPackageInfo.js
packages/app-mobile/utils/getVersionInfoText.js
packages/app-mobile/utils/hooks/useReduceMotionEnabled.js
packages/app-mobile/utils/image/fileToImage.web.js
packages/app-mobile/utils/image/getImageDimensions.js
packages/app-mobile/utils/image/resizeImage.js
packages/app-mobile/utils/initializeCommandService.js
packages/app-mobile/utils/injectedJs.js
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
packages/app-mobile/utils/lockToSingleInstance.js
packages/app-mobile/utils/makeShowMessageBox.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/shareFile.js
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/showMessageBox.js
packages/app-mobile/utils/shim-init-react/index.js
packages/app-mobile/utils/shim-init-react/index.web.js
packages/app-mobile/utils/shim-init-react/injectedJs.js
packages/app-mobile/utils/shim-init-react/shimInitShared.js
packages/app-mobile/utils/testing/createMockReduxStore.js
packages/app-mobile/utils/testing/getWebViewDomById.js
packages/app-mobile/utils/testing/getWebViewWindowById.js
packages/app-mobile/utils/types.js
packages/app-mobile/web/serviceWorker.js
packages/default-plugins/build.js
packages/default-plugins/buildDefaultPlugins.js
packages/default-plugins/commands/buildAll.js
@@ -753,8 +861,6 @@ 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
@@ -784,6 +890,7 @@ 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/utils/biDirectionalTextExtension.js
packages/editor/CodeMirror/utils/formatting/RegionSpec.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.test.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.js
@@ -797,8 +904,14 @@ packages/editor/CodeMirror/utils/formatting/toggleRegionFormatGlobally.test.js
packages/editor/CodeMirror/utils/formatting/toggleRegionFormatGlobally.js
packages/editor/CodeMirror/utils/formatting/toggleSelectedLinesStartWith.js
packages/editor/CodeMirror/utils/formatting/types.js
packages/editor/CodeMirror/utils/getSearchState.js
packages/editor/CodeMirror/utils/growSelectionToNode.js
packages/editor/CodeMirror/utils/handlePasteEvent.js
packages/editor/CodeMirror/utils/isCursorAtBeginning.js
packages/editor/CodeMirror/utils/isInSyntaxNode.js
packages/editor/CodeMirror/utils/overwriteModeExtension.test.js
packages/editor/CodeMirror/utils/overwriteModeExtension.js
packages/editor/CodeMirror/utils/searchExtension.js
packages/editor/CodeMirror/utils/setupVim.js
packages/editor/SelectionFormatting.js
packages/editor/events.js
@@ -828,6 +941,7 @@ packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.test.js
packages/lib/AsyncActionQueue.js
packages/lib/BaseApplication.js
packages/lib/BaseModel.test.js
packages/lib/BaseModel.js
packages/lib/BaseSyncTarget.js
packages/lib/ClipperServer.js
@@ -857,11 +971,14 @@ packages/lib/array.js
packages/lib/callbackUrlUtils.test.js
packages/lib/callbackUrlUtils.js
packages/lib/clipperUtils.js
packages/lib/commands/deleteNote.js
packages/lib/commands/historyBackward.js
packages/lib/commands/historyForward.js
packages/lib/commands/index.js
packages/lib/commands/openMasterPasswordDialog.js
packages/lib/commands/permanentlyDeleteNote.js
packages/lib/commands/synchronize.js
packages/lib/components/EncryptionConfigScreen/utils.test.js
packages/lib/components/EncryptionConfigScreen/utils.js
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
packages/lib/components/shared/config/config-shared.js
@@ -887,6 +1004,7 @@ packages/lib/eventManager.js
packages/lib/file-api-driver-joplinServer.js
packages/lib/file-api-driver-local.js
packages/lib/file-api-driver-memory.js
packages/lib/file-api-driver-webdav.test.js
packages/lib/file-api-driver.test.js
packages/lib/file-api.test.js
packages/lib/file-api.js
@@ -898,7 +1016,12 @@ packages/lib/geolocation-node.js
packages/lib/hooks/useAsyncEffect.js
packages/lib/hooks/useElementSize.js
packages/lib/hooks/useEventListener.js
packages/lib/hooks/useNowEffect.test.js
packages/lib/hooks/useNowEffect.js
packages/lib/hooks/usePlugin.js
packages/lib/hooks/usePrevious.js
packages/lib/hooks/useQueuedAsyncEffect.test.js
packages/lib/hooks/useQueuedAsyncEffect.js
packages/lib/htmlUtils.test.js
packages/lib/htmlUtils.js
packages/lib/htmlUtils2.test.js
@@ -944,8 +1067,10 @@ 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/builtInMetadata.js
packages/lib/models/settings/settingValidations.test.js
packages/lib/models/settings/settingValidations.js
packages/lib/models/settings/types.js
packages/lib/models/utils/getCollator.js
packages/lib/models/utils/getConflictFolderId.js
packages/lib/models/utils/isItemId.js
@@ -1004,6 +1129,7 @@ packages/lib/services/commands/commandsToMarkdownTable.js
packages/lib/services/commands/focusEditorIfEditorCommand.js
packages/lib/services/commands/isEditorCommand.js
packages/lib/services/commands/propsHaveChanged.js
packages/lib/services/commands/stateToWhenClauseContext.test.js
packages/lib/services/commands/stateToWhenClauseContext.js
packages/lib/services/contextkey/contextkey.js
packages/lib/services/database/addMigrationFile.js
@@ -1021,6 +1147,10 @@ packages/lib/services/debug/populateDatabase.js
packages/lib/services/e2ee/EncryptionService.test.js
packages/lib/services/e2ee/EncryptionService.js
packages/lib/services/e2ee/RSA.node.js
packages/lib/services/e2ee/crypto.test.js
packages/lib/services/e2ee/crypto.js
packages/lib/services/e2ee/cryptoShared.js
packages/lib/services/e2ee/cryptoTestUtils.js
packages/lib/services/e2ee/ppk.test.js
packages/lib/services/e2ee/ppk.js
packages/lib/services/e2ee/ppkTestUtils.js
@@ -1055,9 +1185,10 @@ 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.test.js
packages/lib/services/keychain/KeychainService.js
packages/lib/services/keychain/KeychainServiceDriver.dummy.js
packages/lib/services/keychain/KeychainServiceDriver.mobile.js
packages/lib/services/keychain/KeychainServiceDriver.electron.js
packages/lib/services/keychain/KeychainServiceDriver.node.js
packages/lib/services/keychain/KeychainServiceDriverBase.js
packages/lib/services/noteList/defaultLeftToRightListRenderer.js
@@ -1099,6 +1230,7 @@ packages/lib/services/plugins/api/JoplinPlugins.js
packages/lib/services/plugins/api/JoplinSettings.js
packages/lib/services/plugins/api/JoplinViews.js
packages/lib/services/plugins/api/JoplinViewsDialogs.js
packages/lib/services/plugins/api/JoplinViewsEditor.js
packages/lib/services/plugins/api/JoplinViewsMenuItems.js
packages/lib/services/plugins/api/JoplinViewsMenus.js
packages/lib/services/plugins/api/JoplinViewsNoteList.js
@@ -1110,9 +1242,14 @@ packages/lib/services/plugins/api/noteListType.js
packages/lib/services/plugins/api/types.js
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.js
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js
packages/lib/services/plugins/loadPlugins.test.js
packages/lib/services/plugins/loadPlugins.js
packages/lib/services/plugins/reducer.js
packages/lib/services/plugins/testing/MockPlatformImplementation.js
packages/lib/services/plugins/testing/MockPluginRunner.js
packages/lib/services/plugins/utils/createViewHandle.js
packages/lib/services/plugins/utils/executeSandboxCall.js
packages/lib/services/plugins/utils/getActivePluginEditorView.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.test.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
@@ -1227,6 +1364,7 @@ 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.test.js
packages/lib/shim-init-node.js
packages/lib/shim.js
packages/lib/string-utils.test.js
@@ -1251,14 +1389,19 @@ packages/lib/types.js
packages/lib/urlUtils.js
packages/lib/utils/ActionLogger.test.js
packages/lib/utils/ActionLogger.js
packages/lib/utils/attachedResources.js
packages/lib/utils/credentialFiles.js
packages/lib/utils/dom/makeSandboxedIframe.js
packages/lib/utils/focusHandler.js
packages/lib/utils/frontMatter.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/WorkerMessenger.js
packages/lib/utils/ipc/WorkerToWindowMessenger.js
packages/lib/utils/ipc/types.js
packages/lib/utils/ipc/utils/isTransferableObject.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.test.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.test.js
@@ -1266,9 +1409,12 @@ packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud/index.js
packages/lib/utils/joplinCloud/types.js
packages/lib/utils/markupLanguageUtils.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js
packages/lib/utils/resolvePathWithinDir.test.js
packages/lib/utils/resolvePathWithinDir.js
packages/lib/utils/userFetcher.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/utils/webDAVUtils.js
@@ -1364,7 +1510,23 @@ packages/tools/generate-database-types.js
packages/tools/generate-images.js
packages/tools/git-changelog.test.js
packages/tools/git-changelog.js
packages/tools/licenseChecker.js
packages/tools/licenses/getLicenses.js
packages/tools/licenses/licenseChecker.js
packages/tools/licenses/licenseOverrides/fontAwesomeOverride/index.js
packages/tools/licenses/licenseOverrides/fontIsoOverride/index.js
packages/tools/licenses/licenseOverrides/index.js
packages/tools/licenses/licenseOverrides/materialCommunityIconsOverride/index.js
packages/tools/licenses/licenseOverrides/materialIconsOverride/index.js
packages/tools/licenses/licenseOverrides/types.js
packages/tools/licenses/licenseStatementBuilder.js
packages/tools/licenses/licenseText/agplv3.js
packages/tools/licenses/licenseText/apache2.js
packages/tools/licenses/licenseText/mit.js
packages/tools/licenses/utils/equalIgnoringSpacing.js
packages/tools/licenses/utils/matchApache2.test.js
packages/tools/licenses/utils/matchApache2.js
packages/tools/licenses/utils/matchMit.test.js
packages/tools/licenses/utils/matchMit.js
packages/tools/packageJsonLint.js
packages/tools/postPreReleasesToForum.js
packages/tools/release-android.js
@@ -1383,9 +1545,11 @@ packages/tools/update-readme-download.test.js
packages/tools/update-readme-download.js
packages/tools/update-readme-sponsors.js
packages/tools/updateMarkdownDoc.js
packages/tools/utils/discourse.test.js
packages/tools/utils/discourse.js
packages/tools/utils/loadSponsors.js
packages/tools/utils/translation.js
packages/tools/validateFilenames.js
packages/tools/website/build.js
packages/tools/website/buildTranslations.js
packages/tools/website/processDocs.test.js

View File

@@ -15,6 +15,19 @@ module.exports = {
'globals': {
'Atomics': 'readonly',
'SharedArrayBuffer': 'readonly',
'BufferEncoding': 'readonly',
'AsyncIterable': 'readonly',
'FileSystemFileHandle': 'readonly',
'FileSystemDirectoryHandle': 'readonly',
'ReadableStreamDefaultReader': 'readonly',
'FileSystemCreateWritableOptions': 'readonly',
'FileSystemHandle': 'readonly',
'IDBTransactionMode': 'readonly',
// ServiceWorker
'ExtendableEvent': 'readonly',
'WindowClient': 'readonly',
'FetchEvent': 'readonly',
// Jest variables
'test': 'readonly',
@@ -274,6 +287,14 @@ module.exports = {
'match': true,
},
},
{
selector: 'enumMember',
format: null,
'filter': {
'regex': '^(sha1|sha256|sha384|sha512|AES_128_GCM|AES_192_GCM|AES_256_GCM)$',
'match': true,
},
},
// -----------------------------------
// INTERFACE

View File

@@ -180,6 +180,10 @@ fi
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Checking for files that should have been ignored..."
# .gitignore and .eslintignore can be modified during yarn install. Reset them
# so that checkIgnoredFiles works.
git restore .gitignore .eslintignore
node packages/tools/checkIgnoredFiles.js
testResult=$?
if [ $testResult -ne 0 ]; then

25
.github/workflows/automerge.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: automerge
on:
schedule:
- cron: '*/10 * * * *'
jobs:
# This job will make the action fail if any of the checks hasn't passed
# https://github.com/marketplace/actions/allcheckspassed
# allchecks:
# runs-on: ubuntu-latest
# steps:
# - uses: wechuli/allcheckspassed@v1
automerge:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- id: automerge
name: automerge
uses: "pascalgn/automerge-action@v0.16.3"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
MERGE_METHOD: "squash"
LOG: "DEBUG"

View File

@@ -5,20 +5,8 @@ name: react-native-android-build-apk
on: [push, pull_request]
jobs:
pre_job:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
concurrent_skipping: 'same_content_newer'
AssembleRelease:
needs: pre_job
if: github.repository == 'laurent22/joplin' && needs.pre_job.outputs.should_skip != 'true'
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- name: Install Linux dependencies

View File

@@ -1,21 +1,9 @@
name: Build macOS M1
on: [push, pull_request]
jobs:
pre_job:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
concurrent_skipping: 'same_content_newer'
Main:
needs: pre_job
# We always process desktop release tags, because they also publish the release
if: github.repository == 'laurent22/joplin' && (needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/v'))
if: github.repository == 'laurent22/joplin'
runs-on: macos-latest
steps:
@@ -44,6 +32,14 @@ jobs:
with:
python-version: '3.11'
- name: Set Publish Flag
run: |
if [[ $GIT_TAG_NAME = v* ]]; then
echo "PUBLISH_ENABLED=true" >> $GITHUB_ENV
else
echo "PUBLISH_ENABLED=false" >> $GITHUB_ENV
fi
- name: Build macOS M1 app
env:
APPLE_ASC_PROVIDER: ${{ secrets.APPLE_ASC_PROVIDER }}
@@ -56,20 +52,23 @@ jobs:
GH_REPO: ${{ github.repository }}
IS_CONTINUOUS_INTEGRATION: 1
BUILD_SEQUENCIAL: 1
PUBLISH_ENABLED: ${{ env.PUBLISH_ENABLED }}
run: |
export npm_config_arch=arm64
export npm_config_target_arch=arm64
yarn install
cd packages/app-desktop
npm pkg set 'build.mac.artifactName'='${productName}-${version}-${arch}.${ext}'
npm pkg set 'build.mac.target.target'='dmg'
npm pkg set 'build.mac.target.arch[0]'='arm64'
npm pkg set 'build.mac.target[0].target'='dmg'
npm pkg set 'build.mac.target[0].arch[0]'='arm64'
npm pkg set 'build.mac.target[1].target'='zip'
npm pkg set 'build.mac.target[1].arch[0]'='arm64'
if [[ $GIT_TAG_NAME = v* ]]; then
if [[ "$PUBLISH_ENABLED" == "true" ]]; then
echo "Building and publishing desktop application..."
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64
yarn renameReleaseAssets --repo="$GH_REPO" --tag="$GIT_TAG_NAME" --token="$GITHUB_TOKEN"
yarn modifyReleaseAssets --repo="$GH_REPO" --tag="$GIT_TAG_NAME" --token="$GITHUB_TOKEN"
else
echo "Building but *not* publishing desktop application..."
@@ -81,4 +80,4 @@ jobs:
npm pkg set 'build.mac.identity'=null --json
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn dist --mac --arm64 --publish=never
fi
fi

View File

@@ -22,7 +22,7 @@ jobs:
path-to-signatures: 'readme/cla_signatures.json'
path-to-document: 'https://github.com/laurent22/joplin/blob/dev/readme/cla.md' # e.g. a CLA or a DCO document
# branch should not be protected
branch: 'dev'
branch: 'cla_signatures'
allowlist: joplinbot,renovate[bot]
# the followings are the optional inputs - If the optional inputs are not given, then default values will be taken

View File

@@ -1,29 +1,15 @@
name: Joplin Continuous Integration
on: [push, pull_request]
jobs:
pre_job:
if: github.repository == 'laurent22/joplin'
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
# https://github.com/actions/runner-images/issues/6709
runs-on: ubuntu-20.04
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
concurrent_skipping: 'same_content_newer'
Main:
needs: pre_job
# We always process server or desktop release tags, because they also publish the release
if: github.repository == 'laurent22/joplin' && (needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/v'))
if: github.repository == 'laurent22/joplin'
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
# https://github.com/actions/runner-images/issues/6709
os: [macos-12, ubuntu-20.04, windows-2019]
os: [macos-13, ubuntu-20.04, windows-2019]
steps:
# Trying to fix random networking issues on Windows
@@ -157,8 +143,7 @@ jobs:
yarn install && cd packages/app-desktop && yarn dist --publish=never
ServerDockerImage:
needs: pre_job
if: github.repository == 'laurent22/joplin' && needs.pre_job.outputs.should_skip != 'true'
if: github.repository == 'laurent22/joplin'
runs-on: ${{ matrix.os }}
strategy:
matrix:

344
.gitignore vendored
View File

@@ -127,11 +127,16 @@ 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/exportDeletionLog.test.js
packages/app-desktop/commands/exportDeletionLog.js
packages/app-desktop/commands/exportFolders.js
packages/app-desktop/commands/exportNotes.js
packages/app-desktop/commands/focusElement.js
packages/app-desktop/commands/index.js
packages/app-desktop/commands/openNoteInNewWindow.js
packages/app-desktop/commands/openProfileDirectory.js
packages/app-desktop/commands/renderMarkup.test.js
packages/app-desktop/commands/renderMarkup.js
packages/app-desktop/commands/replaceMisspelling.js
packages/app-desktop/commands/restoreNoteRevision.js
packages/app-desktop/commands/startExternalEditing.js
@@ -146,9 +151,13 @@ packages/app-desktop/gui/Button/Button.js
packages/app-desktop/gui/ClipperConfigScreen.js
packages/app-desktop/gui/ConfigScreen/ButtonBar.js
packages/app-desktop/gui/ConfigScreen/ConfigScreen.js
packages/app-desktop/gui/ConfigScreen/FontSearch.js
packages/app-desktop/gui/ConfigScreen/Sidebar.js
packages/app-desktop/gui/ConfigScreen/controls/FontSearch.js
packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.js
packages/app-desktop/gui/ConfigScreen/controls/SettingComponent.js
packages/app-desktop/gui/ConfigScreen/controls/SettingDescription.js
packages/app-desktop/gui/ConfigScreen/controls/SettingHeader.js
packages/app-desktop/gui/ConfigScreen/controls/SettingLabel.js
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
@@ -178,62 +187,14 @@ packages/app-desktop/gui/KeymapConfig/styles/index.js
packages/app-desktop/gui/KeymapConfig/utils/getLabel.js
packages/app-desktop/gui/KeymapConfig/utils/useCommandStatus.js
packages/app-desktop/gui/KeymapConfig/utils/useKeymap.js
packages/app-desktop/gui/MainScreen/MainScreen.js
packages/app-desktop/gui/MainScreen/commands/addProfile.js
packages/app-desktop/gui/MainScreen/commands/commandPalette.js
packages/app-desktop/gui/MainScreen/commands/deleteFolder.js
packages/app-desktop/gui/MainScreen/commands/deleteNote.js
packages/app-desktop/gui/MainScreen/commands/duplicateNote.js
packages/app-desktop/gui/MainScreen/commands/editAlarm.js
packages/app-desktop/gui/MainScreen/commands/exportPdf.js
packages/app-desktop/gui/MainScreen/commands/gotoAnything.js
packages/app-desktop/gui/MainScreen/commands/hideModalMessage.js
packages/app-desktop/gui/MainScreen/commands/index.js
packages/app-desktop/gui/MainScreen/commands/leaveSharedFolder.js
packages/app-desktop/gui/MainScreen/commands/moveToFolder.js
packages/app-desktop/gui/MainScreen/commands/newFolder.js
packages/app-desktop/gui/MainScreen/commands/newNote.js
packages/app-desktop/gui/MainScreen/commands/newSubFolder.js
packages/app-desktop/gui/MainScreen/commands/newTodo.js
packages/app-desktop/gui/MainScreen/commands/openFolder.js
packages/app-desktop/gui/MainScreen/commands/openFolderDialog.js
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
packages/app-desktop/gui/MainScreen/commands/showModalMessage.js
packages/app-desktop/gui/MainScreen/commands/showNoteContentProperties.js
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
packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.js
packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js
packages/app-desktop/gui/MainScreen/commands/toggleNoteType.js
packages/app-desktop/gui/MainScreen/commands/toggleNotesSortOrderField.js
packages/app-desktop/gui/MainScreen/commands/toggleNotesSortOrderReverse.js
packages/app-desktop/gui/MainScreen/commands/togglePerFolderSortOrder.js
packages/app-desktop/gui/MainScreen/commands/toggleSideBar.js
packages/app-desktop/gui/MainScreen/commands/toggleVisiblePanes.js
packages/app-desktop/gui/MainScreen.js
packages/app-desktop/gui/MasterPasswordDialog/Dialog.js
packages/app-desktop/gui/MenuBar.js
packages/app-desktop/gui/MultiNoteActions.js
packages/app-desktop/gui/Navigator.js
packages/app-desktop/gui/NewWindowOrIFrame.js
packages/app-desktop/gui/NoteContentPropertiesDialog.js
packages/app-desktop/gui/NoteEditor/EditorWindow.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
@@ -259,7 +220,9 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useScrollUtils.
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/localisation.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useRefocusOnVisiblePaneChange.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
@@ -270,11 +233,15 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/shouldPasteResources.
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/shouldPasteResources.js
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/useKeyboardRefocusHandler.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useLinkTooltips.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useTabIndenter.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/WarningBanner/BannerContent.js
packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
packages/app-desktop/gui/NoteEditor/commands/index.js
@@ -288,6 +255,7 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.test.js
packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.js
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
packages/app-desktop/gui/NoteEditor/utils/getWindowCommandPriority.js
packages/app-desktop/gui/NoteEditor/utils/index.js
packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
@@ -301,6 +269,8 @@ packages/app-desktop/gui/NoteEditor/utils/useFormNote.js
packages/app-desktop/gui/NoteEditor/utils/useMarkupToHtml.js
packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.js
packages/app-desktop/gui/NoteEditor/utils/useNoteSearchBar.js
packages/app-desktop/gui/NoteEditor/utils/usePluginEditorView.test.js
packages/app-desktop/gui/NoteEditor/utils/usePluginEditorView.js
packages/app-desktop/gui/NoteEditor/utils/usePluginServiceRegistration.js
packages/app-desktop/gui/NoteEditor/utils/useScheduleSaveCallbacks.js
packages/app-desktop/gui/NoteEditor/utils/useScrollWhenReadyOptions.js
@@ -311,8 +281,10 @@ packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js
packages/app-desktop/gui/NoteList/commands/index.js
packages/app-desktop/gui/NoteList/utils/canManuallySortNotes.js
packages/app-desktop/gui/NoteList/utils/types.js
packages/app-desktop/gui/NoteList/utils/useActiveDescendantId.js
packages/app-desktop/gui/NoteList/utils/useDragAndDrop.js
packages/app-desktop/gui/NoteList/utils/useFocusNote.js
packages/app-desktop/gui/NoteList/utils/useFocusVisible.js
packages/app-desktop/gui/NoteList/utils/useItemCss.js
packages/app-desktop/gui/NoteList/utils/useMoveNote.js
packages/app-desktop/gui/NoteList/utils/useOnKeyDown.js
@@ -333,6 +305,7 @@ 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/getNoteElementIdFromJoplinId.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
@@ -341,6 +314,7 @@ packages/app-desktop/gui/NoteListItem/utils/useItemElement.js
packages/app-desktop/gui/NoteListItem/utils/useItemEventHandlers.js
packages/app-desktop/gui/NoteListItem/utils/useOnContextMenu.js
packages/app-desktop/gui/NoteListItem/utils/useRenderedNote.js
packages/app-desktop/gui/NoteListItem/utils/useRootElement.test.js
packages/app-desktop/gui/NoteListItem/utils/useRootElement.js
packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js
packages/app-desktop/gui/NotePropertiesDialog.js
@@ -351,7 +325,9 @@ 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/LabelledPasswordInput.js
packages/app-desktop/gui/PasswordInput/PasswordInput.js
packages/app-desktop/gui/PasswordInput/types.js
packages/app-desktop/gui/PdfViewer.js
packages/app-desktop/gui/PromptDialog.js
packages/app-desktop/gui/ResizableLayout/MoveButtons.js
@@ -385,16 +361,19 @@ packages/app-desktop/gui/Sidebar/commands/focusElementSideBar.js
packages/app-desktop/gui/Sidebar/commands/index.js
packages/app-desktop/gui/Sidebar/hooks/useFocusHandler.js
packages/app-desktop/gui/Sidebar/hooks/useOnRenderItem.js
packages/app-desktop/gui/Sidebar/hooks/useOnRenderListWrapper.js
packages/app-desktop/gui/Sidebar/hooks/useOnSidebarKeyDownHandler.js
packages/app-desktop/gui/Sidebar/hooks/useSelectedSidebarIndex.js
packages/app-desktop/gui/Sidebar/hooks/useSidebarCommandHandler.js
packages/app-desktop/gui/Sidebar/hooks/useSidebarListData.js
packages/app-desktop/gui/Sidebar/hooks/utils/toggleHeader.js
packages/app-desktop/gui/Sidebar/listItemComponents/AllNotesItem.js
packages/app-desktop/gui/Sidebar/listItemComponents/EmptyExpandLink.js
packages/app-desktop/gui/Sidebar/listItemComponents/ExpandIcon.js
packages/app-desktop/gui/Sidebar/listItemComponents/ExpandLink.js
packages/app-desktop/gui/Sidebar/listItemComponents/FolderItem.js
packages/app-desktop/gui/Sidebar/listItemComponents/HeaderItem.js
packages/app-desktop/gui/Sidebar/listItemComponents/ListItemWrapper.js
packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.js
packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js
packages/app-desktop/gui/Sidebar/styles/index.js
@@ -408,10 +387,71 @@ packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
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/UpdateNotification/UpdateNotification.js
packages/app-desktop/gui/WindowCommandsAndDialogs/AppDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/ModalMessageOverlay.js
packages/app-desktop/gui/WindowCommandsAndDialogs/PluginDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/WindowCommandsAndDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/addProfile.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/commandPalette.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/deleteFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/duplicateNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/editAlarm.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/gotoAnything.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/hideModalMessage.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/index.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/leaveSharedFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newSubFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newTodo.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openFolderDialog.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openItem.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openPdfViewer.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/openTag.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/print.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/renameFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/renameTag.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/resetLayout.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreFolder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreNote.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/revealResourceFile.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/search.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/setTags.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showEditorPlugin.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showModalMessage.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteContentProperties.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteProperties.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showPrompt.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareFolderDialog.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareNoteDialog.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.test.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditorPlugin.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditors.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleLayoutMoveMode.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleMenuBar.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNoteList.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNoteType.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNotesSortOrderField.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleNotesSortOrderReverse.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/togglePerFolderSortOrder.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleSideBar.js
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleVisiblePanes.js
packages/app-desktop/gui/WindowCommandsAndDialogs/types.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/appDialogs.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/usePrintToCallback.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/useSyncDialogState.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/useWindowCommands.js
packages/app-desktop/gui/WindowCommandsAndDialogs/utils/useWindowControl.js
packages/app-desktop/gui/dialogs.js
packages/app-desktop/gui/hooks/useDocument.js
packages/app-desktop/gui/hooks/useEffectDebugger.js
packages/app-desktop/gui/hooks/useElementHeight.js
packages/app-desktop/gui/hooks/useImperativeHandlerDebugger.js
@@ -426,28 +466,41 @@ packages/app-desktop/gui/style/StyledLink.js
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/announceForAccessibility.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/goToAnything.spec.js
packages/app-desktop/integration-tests/main.spec.js
packages/app-desktop/integration-tests/markdownEditor.spec.js
packages/app-desktop/integration-tests/models/GoToAnything.js
packages/app-desktop/integration-tests/models/MainScreen.js
packages/app-desktop/integration-tests/models/NoteEditorScreen.js
packages/app-desktop/integration-tests/models/NoteList.js
packages/app-desktop/integration-tests/models/SettingsScreen.js
packages/app-desktop/integration-tests/models/Sidebar.js
packages/app-desktop/integration-tests/noteList.spec.js
packages/app-desktop/integration-tests/pluginApi.spec.js
packages/app-desktop/integration-tests/richTextEditor.spec.js
packages/app-desktop/integration-tests/settings.spec.js
packages/app-desktop/integration-tests/sidebar.spec.js
packages/app-desktop/integration-tests/simpleBackup.spec.js
packages/app-desktop/integration-tests/util/activateMainMenuItem.js
packages/app-desktop/integration-tests/util/createStartupArgs.js
packages/app-desktop/integration-tests/util/extendedExpect.js
packages/app-desktop/integration-tests/util/firstNonDevToolsWindow.js
packages/app-desktop/integration-tests/util/getImageSourceSize.js
packages/app-desktop/integration-tests/util/setDarkMode.js
packages/app-desktop/integration-tests/util/setFilePickerResponse.js
packages/app-desktop/integration-tests/util/setMessageBoxResponse.js
packages/app-desktop/integration-tests/util/test.js
packages/app-desktop/integration-tests/util/waitForNextOpenPath.js
packages/app-desktop/integration-tests/wcag.spec.js
packages/app-desktop/playwright.config.js
packages/app-desktop/plugins/GotoAnything.js
packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.js
packages/app-desktop/services/autoUpdater/AutoUpdaterService.js
packages/app-desktop/services/bridge.js
packages/app-desktop/services/commands/stateToWhenClauseContext.js
packages/app-desktop/services/commands/types.js
@@ -472,18 +525,24 @@ packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/tools/copy7Zip.js
packages/app-desktop/tools/generateLatestArm64Yml.js
packages/app-desktop/tools/githubReleasesUtils.js
packages/app-desktop/tools/modifyReleaseAssets.js
packages/app-desktop/tools/notarizeMacApp.js
packages/app-desktop/tools/renameReleaseAssets.js
packages/app-desktop/utils/7zip/getPathToExecutable7Zip.js
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/customProtocols/constants.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.test.js
packages/app-desktop/utils/customProtocols/handleCustomProtocols.js
packages/app-desktop/utils/customProtocols/registerCustomProtocols.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-desktop/utils/window/types.js
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/commands/index.js
packages/app-mobile/commands/newNote.test.js
@@ -492,19 +551,34 @@ 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/commands/util/showResource.js
packages/app-mobile/components/BackButtonDialogBox.js
packages/app-mobile/components/BetaChip.js
packages/app-mobile/components/CameraView.js
packages/app-mobile/components/CameraView/ActionButtons.js
packages/app-mobile/components/CameraView/Camera/index.jest.js
packages/app-mobile/components/CameraView/Camera/index.js
packages/app-mobile/components/CameraView/Camera/types.js
packages/app-mobile/components/CameraView/CameraView.test.js
packages/app-mobile/components/CameraView/CameraView.js
packages/app-mobile/components/CameraView/ScannedBarcodes.js
packages/app-mobile/components/CameraView/types.js
packages/app-mobile/components/CameraView/utils/fitRectIntoBounds.js
packages/app-mobile/components/CameraView/utils/useBarcodeScanner.js
packages/app-mobile/components/Checkbox.js
packages/app-mobile/components/DialogManager.js
packages/app-mobile/components/DismissibleDialog.js
packages/app-mobile/components/Dropdown.test.js
packages/app-mobile/components/Dropdown.js
packages/app-mobile/components/ExtendedWebView.js
packages/app-mobile/components/ExtendedWebView/index.jest.js
packages/app-mobile/components/ExtendedWebView/index.js
packages/app-mobile/components/ExtendedWebView/index.web.js
packages/app-mobile/components/ExtendedWebView/types.js
packages/app-mobile/components/FolderPicker.js
packages/app-mobile/components/Icon.js
packages/app-mobile/components/IconButton.js
packages/app-mobile/components/Modal.js
packages/app-mobile/components/ModalDialog.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.test.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
@@ -554,27 +628,54 @@ 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/NoteItem.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/Menu.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/WebBetaButton.js
packages/app-mobile/components/ScreenHeader/index.js
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/SideMenuContentNote.js
packages/app-mobile/components/TextInput.js
packages/app-mobile/components/accessibility/AccessibleModalMenu.js
packages/app-mobile/components/accessibility/AccessibleView.js
packages/app-mobile/components/app-nav.js
packages/app-mobile/components/base-screen.js
packages/app-mobile/components/biometrics/BiometricPopup.js
packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/buttons/FloatingActionButton.js
packages/app-mobile/components/buttons/TextButton.js
packages/app-mobile/components/buttons/index.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/plugins/PluginRunner.js
packages/app-mobile/components/plugins/PluginRunnerWebView.js
packages/app-mobile/components/plugins/backgroundPage/initializeDialogWebView.js
packages/app-mobile/components/plugins/backgroundPage/initializePluginBackgroundIframe.js
packages/app-mobile/components/plugins/backgroundPage/pluginRunnerBackgroundPage.js
packages/app-mobile/components/plugins/backgroundPage/startStopPlugin.js
packages/app-mobile/components/plugins/backgroundPage/utils/getFormData.test.js
packages/app-mobile/components/plugins/backgroundPage/utils/getFormData.js
packages/app-mobile/components/plugins/backgroundPage/utils/reportUnhandledErrors.js
packages/app-mobile/components/plugins/backgroundPage/utils/wrapConsoleLog.js
packages/app-mobile/components/plugins/dialogs/PluginDialogManager.js
packages/app-mobile/components/plugins/dialogs/PluginDialogWebView.js
packages/app-mobile/components/plugins/dialogs/PluginPanelViewer.js
packages/app-mobile/components/plugins/dialogs/PluginUserWebView.js
packages/app-mobile/components/plugins/dialogs/hooks/useDialogMessenger.js
packages/app-mobile/components/plugins/dialogs/hooks/useDialogSize.js
packages/app-mobile/components/plugins/dialogs/hooks/useViewInfos.js
packages/app-mobile/components/plugins/dialogs/hooks/useWebViewSetup.js
packages/app-mobile/components/plugins/types.js
packages/app-mobile/components/plugins/utils/createOnLogHandler.js
packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen/FileSystemPathSelector.js
packages/app-mobile/components/screens/ConfigScreen/JoplinCloudConfig.js
@@ -625,58 +726,45 @@ packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState
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.test.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/SearchScreen/SearchResults.js
packages/app-mobile/components/screens/SearchScreen/index.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/testing/TestProviderStack.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.test.js
packages/app-mobile/plugins/loadPlugins.js
packages/app-mobile/plugins/testing/MockPluginRunner.js
packages/app-mobile/index.web.js
packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
packages/app-mobile/services/AlarmServiceDriver.web.js
packages/app-mobile/services/BackButtonService.js
packages/app-mobile/services/e2ee/RSA.react-native.js
packages/app-mobile/services/e2ee/crypto.js
packages/app-mobile/services/plugins/PlatformImplementation.js
packages/app-mobile/services/profiles/index.js
packages/app-mobile/services/voiceTyping/VoiceTyping.js
packages/app-mobile/services/voiceTyping/utils/splitWhisperText.test.js
packages/app-mobile/services/voiceTyping/utils/splitWhisperText.js
packages/app-mobile/services/voiceTyping/vosk.android.js
packages/app-mobile/services/voiceTyping/vosk.ios.js
packages/app-mobile/services/voiceTyping/vosk.js
packages/app-mobile/services/voiceTyping/whisper.js
packages/app-mobile/setupQuickActions.js
packages/app-mobile/tools/buildInjectedJs/BundledFile.js
packages/app-mobile/tools/buildInjectedJs/constants.js
packages/app-mobile/tools/buildInjectedJs/copyJs.js
packages/app-mobile/tools/buildInjectedJs/gulpTasks.js
packages/app-mobile/tools/copyAssets.js
packages/app-mobile/utils/ShareExtension.js
packages/app-mobile/utils/ShareUtils.test.js
packages/app-mobile/utils/ShareUtils.js
@@ -685,9 +773,13 @@ 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/database-driver-react-native.js
packages/app-mobile/utils/database-driver-react-native.web.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/fs-driver-rn.web.js
packages/app-mobile/utils/fs-driver/fs-driver-rn.web.worker.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
@@ -696,17 +788,31 @@ packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
packages/app-mobile/utils/getPackageInfo.js
packages/app-mobile/utils/getVersionInfoText.js
packages/app-mobile/utils/hooks/useReduceMotionEnabled.js
packages/app-mobile/utils/image/fileToImage.web.js
packages/app-mobile/utils/image/getImageDimensions.js
packages/app-mobile/utils/image/resizeImage.js
packages/app-mobile/utils/initializeCommandService.js
packages/app-mobile/utils/injectedJs.js
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
packages/app-mobile/utils/lockToSingleInstance.js
packages/app-mobile/utils/makeShowMessageBox.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/shareFile.js
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/showMessageBox.js
packages/app-mobile/utils/shim-init-react/index.js
packages/app-mobile/utils/shim-init-react/index.web.js
packages/app-mobile/utils/shim-init-react/injectedJs.js
packages/app-mobile/utils/shim-init-react/shimInitShared.js
packages/app-mobile/utils/testing/createMockReduxStore.js
packages/app-mobile/utils/testing/getWebViewDomById.js
packages/app-mobile/utils/testing/getWebViewWindowById.js
packages/app-mobile/utils/types.js
packages/app-mobile/web/serviceWorker.js
packages/default-plugins/build.js
packages/default-plugins/buildDefaultPlugins.js
packages/default-plugins/commands/buildAll.js
@@ -732,8 +838,6 @@ 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
@@ -763,6 +867,7 @@ 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/utils/biDirectionalTextExtension.js
packages/editor/CodeMirror/utils/formatting/RegionSpec.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.test.js
packages/editor/CodeMirror/utils/formatting/findInlineMatch.js
@@ -776,8 +881,14 @@ packages/editor/CodeMirror/utils/formatting/toggleRegionFormatGlobally.test.js
packages/editor/CodeMirror/utils/formatting/toggleRegionFormatGlobally.js
packages/editor/CodeMirror/utils/formatting/toggleSelectedLinesStartWith.js
packages/editor/CodeMirror/utils/formatting/types.js
packages/editor/CodeMirror/utils/getSearchState.js
packages/editor/CodeMirror/utils/growSelectionToNode.js
packages/editor/CodeMirror/utils/handlePasteEvent.js
packages/editor/CodeMirror/utils/isCursorAtBeginning.js
packages/editor/CodeMirror/utils/isInSyntaxNode.js
packages/editor/CodeMirror/utils/overwriteModeExtension.test.js
packages/editor/CodeMirror/utils/overwriteModeExtension.js
packages/editor/CodeMirror/utils/searchExtension.js
packages/editor/CodeMirror/utils/setupVim.js
packages/editor/SelectionFormatting.js
packages/editor/events.js
@@ -807,6 +918,7 @@ packages/lib/ArrayUtils.js
packages/lib/AsyncActionQueue.test.js
packages/lib/AsyncActionQueue.js
packages/lib/BaseApplication.js
packages/lib/BaseModel.test.js
packages/lib/BaseModel.js
packages/lib/BaseSyncTarget.js
packages/lib/ClipperServer.js
@@ -836,11 +948,14 @@ packages/lib/array.js
packages/lib/callbackUrlUtils.test.js
packages/lib/callbackUrlUtils.js
packages/lib/clipperUtils.js
packages/lib/commands/deleteNote.js
packages/lib/commands/historyBackward.js
packages/lib/commands/historyForward.js
packages/lib/commands/index.js
packages/lib/commands/openMasterPasswordDialog.js
packages/lib/commands/permanentlyDeleteNote.js
packages/lib/commands/synchronize.js
packages/lib/components/EncryptionConfigScreen/utils.test.js
packages/lib/components/EncryptionConfigScreen/utils.js
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
packages/lib/components/shared/config/config-shared.js
@@ -866,6 +981,7 @@ packages/lib/eventManager.js
packages/lib/file-api-driver-joplinServer.js
packages/lib/file-api-driver-local.js
packages/lib/file-api-driver-memory.js
packages/lib/file-api-driver-webdav.test.js
packages/lib/file-api-driver.test.js
packages/lib/file-api.test.js
packages/lib/file-api.js
@@ -877,7 +993,12 @@ packages/lib/geolocation-node.js
packages/lib/hooks/useAsyncEffect.js
packages/lib/hooks/useElementSize.js
packages/lib/hooks/useEventListener.js
packages/lib/hooks/useNowEffect.test.js
packages/lib/hooks/useNowEffect.js
packages/lib/hooks/usePlugin.js
packages/lib/hooks/usePrevious.js
packages/lib/hooks/useQueuedAsyncEffect.test.js
packages/lib/hooks/useQueuedAsyncEffect.js
packages/lib/htmlUtils.test.js
packages/lib/htmlUtils.js
packages/lib/htmlUtils2.test.js
@@ -923,8 +1044,10 @@ 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/builtInMetadata.js
packages/lib/models/settings/settingValidations.test.js
packages/lib/models/settings/settingValidations.js
packages/lib/models/settings/types.js
packages/lib/models/utils/getCollator.js
packages/lib/models/utils/getConflictFolderId.js
packages/lib/models/utils/isItemId.js
@@ -983,6 +1106,7 @@ packages/lib/services/commands/commandsToMarkdownTable.js
packages/lib/services/commands/focusEditorIfEditorCommand.js
packages/lib/services/commands/isEditorCommand.js
packages/lib/services/commands/propsHaveChanged.js
packages/lib/services/commands/stateToWhenClauseContext.test.js
packages/lib/services/commands/stateToWhenClauseContext.js
packages/lib/services/contextkey/contextkey.js
packages/lib/services/database/addMigrationFile.js
@@ -1000,6 +1124,10 @@ packages/lib/services/debug/populateDatabase.js
packages/lib/services/e2ee/EncryptionService.test.js
packages/lib/services/e2ee/EncryptionService.js
packages/lib/services/e2ee/RSA.node.js
packages/lib/services/e2ee/crypto.test.js
packages/lib/services/e2ee/crypto.js
packages/lib/services/e2ee/cryptoShared.js
packages/lib/services/e2ee/cryptoTestUtils.js
packages/lib/services/e2ee/ppk.test.js
packages/lib/services/e2ee/ppk.js
packages/lib/services/e2ee/ppkTestUtils.js
@@ -1034,9 +1162,10 @@ 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.test.js
packages/lib/services/keychain/KeychainService.js
packages/lib/services/keychain/KeychainServiceDriver.dummy.js
packages/lib/services/keychain/KeychainServiceDriver.mobile.js
packages/lib/services/keychain/KeychainServiceDriver.electron.js
packages/lib/services/keychain/KeychainServiceDriver.node.js
packages/lib/services/keychain/KeychainServiceDriverBase.js
packages/lib/services/noteList/defaultLeftToRightListRenderer.js
@@ -1078,6 +1207,7 @@ packages/lib/services/plugins/api/JoplinPlugins.js
packages/lib/services/plugins/api/JoplinSettings.js
packages/lib/services/plugins/api/JoplinViews.js
packages/lib/services/plugins/api/JoplinViewsDialogs.js
packages/lib/services/plugins/api/JoplinViewsEditor.js
packages/lib/services/plugins/api/JoplinViewsMenuItems.js
packages/lib/services/plugins/api/JoplinViewsMenus.js
packages/lib/services/plugins/api/JoplinViewsNoteList.js
@@ -1089,9 +1219,14 @@ packages/lib/services/plugins/api/noteListType.js
packages/lib/services/plugins/api/types.js
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.js
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js
packages/lib/services/plugins/loadPlugins.test.js
packages/lib/services/plugins/loadPlugins.js
packages/lib/services/plugins/reducer.js
packages/lib/services/plugins/testing/MockPlatformImplementation.js
packages/lib/services/plugins/testing/MockPluginRunner.js
packages/lib/services/plugins/utils/createViewHandle.js
packages/lib/services/plugins/utils/executeSandboxCall.js
packages/lib/services/plugins/utils/getActivePluginEditorView.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.test.js
packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
@@ -1206,6 +1341,7 @@ 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.test.js
packages/lib/shim-init-node.js
packages/lib/shim.js
packages/lib/string-utils.test.js
@@ -1230,14 +1366,19 @@ packages/lib/types.js
packages/lib/urlUtils.js
packages/lib/utils/ActionLogger.test.js
packages/lib/utils/ActionLogger.js
packages/lib/utils/attachedResources.js
packages/lib/utils/credentialFiles.js
packages/lib/utils/dom/makeSandboxedIframe.js
packages/lib/utils/focusHandler.js
packages/lib/utils/frontMatter.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/WorkerMessenger.js
packages/lib/utils/ipc/WorkerToWindowMessenger.js
packages/lib/utils/ipc/types.js
packages/lib/utils/ipc/utils/isTransferableObject.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.test.js
packages/lib/utils/ipc/utils/mergeCallbacksAndSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.test.js
@@ -1245,9 +1386,12 @@ packages/lib/utils/ipc/utils/separateCallbacksFromSerializable.js
packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
packages/lib/utils/joplinCloud/index.js
packages/lib/utils/joplinCloud/types.js
packages/lib/utils/markupLanguageUtils.js
packages/lib/utils/processStartFlags.js
packages/lib/utils/replaceUnsupportedCharacters.test.js
packages/lib/utils/replaceUnsupportedCharacters.js
packages/lib/utils/resolvePathWithinDir.test.js
packages/lib/utils/resolvePathWithinDir.js
packages/lib/utils/userFetcher.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/utils/webDAVUtils.js
@@ -1343,7 +1487,23 @@ packages/tools/generate-database-types.js
packages/tools/generate-images.js
packages/tools/git-changelog.test.js
packages/tools/git-changelog.js
packages/tools/licenseChecker.js
packages/tools/licenses/getLicenses.js
packages/tools/licenses/licenseChecker.js
packages/tools/licenses/licenseOverrides/fontAwesomeOverride/index.js
packages/tools/licenses/licenseOverrides/fontIsoOverride/index.js
packages/tools/licenses/licenseOverrides/index.js
packages/tools/licenses/licenseOverrides/materialCommunityIconsOverride/index.js
packages/tools/licenses/licenseOverrides/materialIconsOverride/index.js
packages/tools/licenses/licenseOverrides/types.js
packages/tools/licenses/licenseStatementBuilder.js
packages/tools/licenses/licenseText/agplv3.js
packages/tools/licenses/licenseText/apache2.js
packages/tools/licenses/licenseText/mit.js
packages/tools/licenses/utils/equalIgnoringSpacing.js
packages/tools/licenses/utils/matchApache2.test.js
packages/tools/licenses/utils/matchApache2.js
packages/tools/licenses/utils/matchMit.test.js
packages/tools/licenses/utils/matchMit.js
packages/tools/packageJsonLint.js
packages/tools/postPreReleasesToForum.js
packages/tools/release-android.js
@@ -1362,9 +1522,11 @@ packages/tools/update-readme-download.test.js
packages/tools/update-readme-download.js
packages/tools/update-readme-sponsors.js
packages/tools/updateMarkdownDoc.js
packages/tools/utils/discourse.test.js
packages/tools/utils/discourse.js
packages/tools/utils/loadSponsors.js
packages/tools/utils/translation.js
packages/tools/validateFilenames.js
packages/tools/website/build.js
packages/tools/website/buildTranslations.js
packages/tools/website/processDocs.test.js

View File

@@ -0,0 +1,118 @@
# Fixes sync issues caused by locale-sensitive lowercasing
# of HTTP headers.
# See https://github.com/laurent22/joplin/issues/10681
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java
index 8ac9e7a855162cefbf99024eb013c8a3b11de1ec..1c639cf9d84821b6ffc132960e2d1c044bedbd48 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java
@@ -2,6 +2,7 @@ package com.RNFetchBlob;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
+import java.util.Locale;
class RNFetchBlobConfig {
@@ -33,7 +34,7 @@ class RNFetchBlobConfig {
}
if(options.hasKey("binaryContentTypes"))
this.binaryContentTypes = options.getArray("binaryContentTypes");
- if(this.path != null && path.toLowerCase().contains("?append=true")) {
+ if(this.path != null && path.toLowerCase(Locale.ROOT).contains("?append=true")) {
this.overwrite = false;
}
if(options.hasKey("overwrite"))
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
index a4d70153f41e6c14eec65412b5b59822f1c6750b..d98c439f7b0aeb79afc82ab9f653e9c021086426 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.util.Locale;
class RNFetchBlobFS {
@@ -210,7 +211,7 @@ class RNFetchBlobFS {
return;
}
- switch (encoding.toLowerCase()) {
+ switch (encoding.toLowerCase(Locale.ROOT)) {
case "base64" :
promise.resolve(Base64.encodeToString(bytes, Base64.NO_WRAP));
break;
@@ -1050,7 +1051,7 @@ class RNFetchBlobFS {
if(encoding.equalsIgnoreCase("ascii")) {
return data.getBytes(Charset.forName("US-ASCII"));
}
- else if(encoding.toLowerCase().contains("base64")) {
+ else if(encoding.toLowerCase(Locale.ROOT).contains("base64")) {
return Base64.decode(data, Base64.NO_WRAP);
}
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
index a8abd71833879201e3438b2fa51d712a311c4551..b70cc13c004229f69157de5f82ae5ec3abf4358e 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
@@ -49,6 +49,7 @@ import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
@@ -300,14 +301,14 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
responseFormat = ResponseFormat.UTF8;
}
else {
- builder.header(key.toLowerCase(), value);
- mheaders.put(key.toLowerCase(), value);
+ builder.header(key.toLowerCase(Locale.ROOT), value);
+ mheaders.put(key.toLowerCase(Locale.ROOT), value);
}
}
}
if(method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put") || method.equalsIgnoreCase("patch")) {
- String cType = getHeaderIgnoreCases(mheaders, "Content-Type").toLowerCase();
+ String cType = getHeaderIgnoreCases(mheaders, "Content-Type").toLowerCase(Locale.ROOT);
if(rawRequestBodyArray != null) {
requestType = RequestType.Form;
@@ -323,7 +324,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|| rawRequestBody.startsWith(RNFetchBlobConst.CONTENT_PREFIX)) {
requestType = RequestType.SingleFile;
}
- else if (cType.toLowerCase().contains(";base64") || cType.toLowerCase().startsWith("application/octet")) {
+ else if (cType.toLowerCase(Locale.ROOT).contains(";base64") || cType.toLowerCase(Locale.ROOT).startsWith("application/octet")) {
cType = cType.replace(";base64","").replace(";BASE64","");
if(mheaders.containsKey("content-type"))
mheaders.put("content-type", cType);
@@ -686,7 +687,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
boolean isCustomBinary = false;
if(options.binaryContentTypes != null) {
for(int i = 0; i< options.binaryContentTypes.size();i++) {
- if(ctype.toLowerCase().contains(options.binaryContentTypes.getString(i).toLowerCase())) {
+ if(ctype.toLowerCase(Locale.ROOT).contains(options.binaryContentTypes.getString(i).toLowerCase(Locale.ROOT))) {
isCustomBinary = true;
break;
}
@@ -698,13 +699,13 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
private String getHeaderIgnoreCases(Headers headers, String field) {
String val = headers.get(field);
if(val != null) return val;
- return headers.get(field.toLowerCase()) == null ? "" : headers.get(field.toLowerCase());
+ return headers.get(field.toLowerCase(Locale.ROOT)) == null ? "" : headers.get(field.toLowerCase(Locale.ROOT));
}
private String getHeaderIgnoreCases(HashMap<String,String> headers, String field) {
String val = headers.get(field);
if(val != null) return val;
- String lowerCasedValue = headers.get(field.toLowerCase());
+ String lowerCasedValue = headers.get(field.toLowerCase(Locale.ROOT));
return lowerCasedValue == null ? "" : lowerCasedValue;
}

File diff suppressed because one or more lines are too long

875
.yarn/releases/yarn-3.8.3.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-3.6.4.cjs
yarnPath: .yarn/releases/yarn-3.8.3.cjs
logFilters:

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -1,4 +1,47 @@
<?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>
<?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>Mon, 01 Jul 2024 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 01 Jul 2024 00:00:00 GMT</pubDate><item><title><![CDATA[What's new in Joplin 3.0]]></title><description><![CDATA[<h2>Desktop application<a name="desktop-application" href="#desktop-application" class="heading-anchor">🔗</a></h2>
<h3>Trash folder<a name="trash-folder" href="#trash-folder" class="heading-anchor">🔗</a></h3>
<p>Joplin now support a trash folder - any deleted notes or notebooks will be moved to that folder. You can also choose to have these notes permanently deleted after a number of days.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20240701-trash.png" alt=""></p>
<p>Support for the trash folder has a somewhat long history in Joplin since it's an obvious and important feature to add, yet it can be particularly tricky once you start realising how many parts of the app it's going to impact.</p>
<p>Many attempts have been made over time: my first attempt was based on the note history feature. Indeed since this feature already saves versions of notes, it seems to make sense to use it for the trash feature, and indeed the note history feature <a href="https://joplinapp.org/news/20190523-221026">was designed for this originally</a>. However that approach turned to be needlessly complicated and after modifying hundreds of files just for this, the idea was dropped.</p>
<p>The next one was based on using a <a href="https://github.com/laurent22/joplin/issues/483">special &quot;trash&quot; tag</a> - deleted notes would have this tag attached to them and would appear in a special &quot;trash&quot; folder. This approach also had <a href="https://github.com/laurent22/joplin/issues/483">many issues</a> probably the main one being that notebooks can't be tagged, which means we would have to add support for tagged notebooks and that in itself would also be a massive change.</p>
<p><a href="https://discourse.joplinapp.org/t/trashcan/3998/16">Various</a>, <a href="https://discourse.joplinapp.org/t/poll-trash-bin-plugin/19951">ideas,</a> were also attempted using plugins, by creating a special &quot;trash folder&quot;, but in the end no such plugin was ever created, probably due to limitations of the plugin API.</p>
<p>In the end, turned out that this <a href="https://github.com/laurent22/joplin/issues/483#issuecomment-585655742">old idea</a> of adding a &quot;deleted&quot; property to each note and notebook was the easiest approach. With this it was simpler to get to a working solution relatively quickly, and then it was a matter of ensuring that deleted notes don't appear where they shouldn't, such as search results, etc.</p>
<h3>Joplin Cloud multi-factor authentication<a name="joplin-cloud-multi-factor-authentication" href="#joplin-cloud-multi-factor-authentication" class="heading-anchor">🔗</a></h3>
<p>Multi-factor authentication (MFA), also known as two-factor authentication (2FA) is a security process that requires you to provide two or more verification factors to gain access to a system or account. It typically includes something you know (password), something you have (security token), and something you are (biometric verification).</p>
<p>To better secure your account, Joplin Cloud and all Joplin applications now support MFA. To enable it, go to your Joplin Cloud profile, click on &quot;Enable multi-factor authentication&quot; and follow the instructions. Please note that all your applications will then be disconnected, so you will need to login again (your data of course will remain on the app so you won't have to download it again).</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20240701-mfa.png" alt=""></p>
<h3>Note list with multiple columns<a name="note-list-with-multiple-columns" href="#note-list-with-multiple-columns" class="heading-anchor">🔗</a></h3>
<p>In this release we add support for multiple columns in the note list. You can display various properties of the notes, as well as sort the notes by these properties. As usual this feature can be controlled and customised by plugins so for example it should be possible to display custom columns, and display custom information including thumbnails.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20240701-note-list-multi.png" alt=""></p>
<h3>Plugin API enhancement<a name="plugin-api-enhancement" href="#plugin-api-enhancement" class="heading-anchor">🔗</a></h3>
<p>The plugin API has received several updates to facilitate easy customisation of the app As mentioned above, it is now possible to customise the new note list. Besides this, we've added support for loading PDFs and creating images from them, which can for example be used to create thumbnails.</p>
<p>Many other small enhancements have been made to the plugin API to help you tailor the app to your needs!</p>
<h3>View OCR data<a name="view-ocr-data" href="#view-ocr-data" class="heading-anchor">🔗</a></h3>
<p>Now when you right-click on an image or PDF you have an option to view the OCR (Optical character recognition) data associated with it. That will allow you for example to easily copy and paste the text.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20240701-ocr-data.png" alt=""></p>
<h2>Plugin support on mobile<a name="plugin-support-on-mobile" href="#plugin-support-on-mobile" class="heading-anchor">🔗</a></h2>
<p>As always, most of the above changes also apply to mobile (iOS and Android), for example the trash folder and MFA support.</p>
<p>Additionally the mobile application now adds support for plugins. To enable the feature, go to the settings then to the &quot;Plugins&quot; section. The feature is currently in Beta, in particular it means that some plugins do not work or only partially work. Normally the app should not offer you to install a non-working plugin but that may still happen. In general if you notice any issue with this beta feature please let me us know as we're keen to improve it.</p>
<p>Support for cross-platform plugins in Joplin is great news as it means a lot of new features become available on mobile. As of now, we have checked the following plugins and can confirm that they work on mobile:</p>
<ul>
<li><a href="https://joplinapp.org/plugins/plugin/com.whatever.quick-links/">Quick Links</a></li>
<li><a href="https://joplinapp.org/plugins/plugin/com.whatever.inline-tags/">Inline Tags</a></li>
<li><a href="https://joplinapp.org/plugins/plugin/io.github.personalizedrefrigerator.codemirror6-settings/">CodeMirror 6 settings</a></li>
<li><a href="https://joplinapp.org/plugins/plugin/com.hieuthi.joplin.function-plot/">Function plot</a></li>
<li><a href="https://joplinapp.org/plugins/plugin/joplin.plugin.space-indenter/">Space indenter</a></li>
<li><a href="https://joplinapp.org/plugins/plugin/joplin.plugin.alondmnt.tag-navigator/">Inline Tag Navigator</a></li>
</ul>
<p>Those are just some examples - many more are working!</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20240701-mobile-plugins.png" alt=""></p>
<h1>Full changelogs<a name="full-changelogs" href="#full-changelogs" class="heading-anchor">🔗</a></h1>
<p>This is just an overview of the main features. The full changelogs are 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/20240701-release-3-0</link><guid isPermaLink="false">20240701-release-3-0</guid><pubDate>Mon, 01 Jul 2024 00:00:00 GMT</pubDate><twitter-text>What&apos;s new in Joplin 3.0</twitter-text></item><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>
@@ -394,7 +437,4 @@ sys 0m38.013s</p>
</tr>
</tbody>
</table>
]]></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></channel></rss>
]]></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></channel></rss>

View File

@@ -28,6 +28,7 @@ SILENT=false
ALLOW_ROOT=false
SHOW_CHANGELOG=false
INCLUDE_PRE_RELEASE=false
INSTALL_DIR="${HOME}/.joplin" # default installation directory
print() {
if [[ "${SILENT}" == false ]]; then
@@ -57,6 +58,7 @@ showHelp() {
print "\t" "--force" "\t" "Always download the latest version"
print "\t" "--silent" "\t" "Don't print any output"
print "\t" "--prerelease" "\t" "Check for new Versions including Pre-Releases"
print "\t" "--install-dir" "\t" "Set installation directory; default: \"${INSTALL_DIR}\""
if [[ ! -z $1 ]]; then
print "\n" "${COLOR_RED}ERROR: " "$*" "${COLOR_RESET}" "\n"
@@ -84,6 +86,7 @@ while getopts "${optspec}" OPT; do
force ) FORCE=true ;;
changelog ) SHOW_CHANGELOG=true ;;
prerelease ) INCLUDE_PRE_RELEASE=true ;;
install-dir ) INSTALL_DIR="$OPTARG" ;;
[^\?]* ) showHelp "Illegal option --${OPT}"; exit 2 ;;
\? ) showHelp "Illegal option -${OPTARG}"; exit 2 ;;
esac
@@ -120,9 +123,10 @@ fi
print "Checking dependencies..."
## Check if libfuse2 is present.
if [[ $(command -v ldconfig) ]]; then
LIBFUSE=$(ldconfig -p | grep "libfuse.so.2" || echo '')
else
LIBFUSE=$(find /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib -name "libfuse.so.2" 2>/dev/null | grep "libfuse.so.2" || echo '')
LIBFUSE=$(ldconfig -p | grep "libfuse.so.2" || echo '')
fi
if [[ $LIBFUSE == "" ]]; then
LIBFUSE=$(find /lib /usr/lib /lib64 /usr/lib64 /usr/local/lib -name "libfuse.so.2" 2>/dev/null | grep "libfuse.so.2" || echo '')
fi
if [[ $LIBFUSE == "" ]]; then
print "${COLOR_RED}Error: Can't get libfuse2 on system, please install libfuse2${COLOR_RESET}"
@@ -142,17 +146,17 @@ else
fi
# Check if it's in the latest version
if [[ -e ~/.joplin/VERSION ]] && [[ $(< ~/.joplin/VERSION) == "${RELEASE_VERSION}" ]]; then
if [[ -e "${INSTALL_DIR}/VERSION" ]] && [[ $(< "${INSTALL_DIR}/VERSION") == "${RELEASE_VERSION}" ]]; then
print "${COLOR_GREEN}You already have the latest version${COLOR_RESET} ${RELEASE_VERSION} ${COLOR_GREEN}installed.${COLOR_RESET}"
([[ "$FORCE" == true ]] && print "Forcing installation...") || exit 0
else
[[ -e ~/.joplin/VERSION ]] && CURRENT_VERSION=$(< ~/.joplin/VERSION)
[[ -e "${INSTALL_DIR}/VERSION" ]] && CURRENT_VERSION=$(< "${INSTALL_DIR}/VERSION")
print "The latest version is ${RELEASE_VERSION}, but you have ${CURRENT_VERSION:-no version} installed."
fi
# Check if it's an update or a new install
DOWNLOAD_TYPE="New"
if [[ -f ~/.joplin/Joplin.AppImage ]]; then
if [[ -f "${INSTALL_DIR}/Joplin.AppImage" ]]; then
DOWNLOAD_TYPE="Update"
fi
@@ -165,16 +169,16 @@ wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
#-----------------------------------------------------
print 'Installing Joplin...'
# Delete previous version (in future versions joplin.desktop shouldn't exist)
rm -f ~/.joplin/*.AppImage ~/.local/share/applications/joplin.desktop ~/.joplin/VERSION
rm -f "${INSTALL_DIR}"/*.AppImage ~/.local/share/applications/joplin.desktop "${INSTALL_DIR}/VERSION"
# Creates the folder where the binary will be stored
mkdir -p ~/.joplin/
mkdir -p "${INSTALL_DIR}/"
# Download the latest version
mv "${TEMP_DIR}/Joplin.AppImage" ~/.joplin/Joplin.AppImage
mv "${TEMP_DIR}/Joplin.AppImage" "${INSTALL_DIR}/Joplin.AppImage"
# Gives execution privileges
chmod +x ~/.joplin/Joplin.AppImage
chmod +x "${INSTALL_DIR}/Joplin.AppImage"
print "${COLOR_GREEN}OK${COLOR_RESET}"
@@ -253,13 +257,14 @@ if [[ $DESKTOP =~ .*gnome.*|.*kde.*|.*xfce.*|.*mate.*|.*lxqt.*|.*unity.*|.*x-cin
Encoding=UTF-8
Name=Joplin
Comment=Joplin for Desktop
Exec=env APPIMAGELAUNCHER_DISABLE=TRUE ${HOME}/.joplin/Joplin.AppImage ${SANDBOXPARAM} %u
Exec=env APPIMAGELAUNCHER_DISABLE=TRUE "${INSTALL_DIR}/Joplin.AppImage" ${SANDBOXPARAM} %u
Icon=joplin
StartupWMClass=Joplin
Type=Application
Categories=Office;
MimeType=x-scheme-handler/joplin;
X-GNOME-SingleWindow=true // should be removed eventually as it was upstream to be an XDG specification
# should be removed eventually as it was upstream to be an XDG specification
X-GNOME-SingleWindow=true
SingleMainWindow=true
EOF
@@ -278,7 +283,7 @@ fi
print "${COLOR_GREEN}Joplin version${COLOR_RESET} ${RELEASE_VERSION} ${COLOR_GREEN}installed.${COLOR_RESET}"
# Record version
echo "$RELEASE_VERSION" > ~/.joplin/VERSION
echo "$RELEASE_VERSION" > "${INSTALL_DIR}/VERSION"
#-----------------------------------------------------
if [[ "$SHOW_CHANGELOG" == true ]]; then

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://bestkru.com"><img title="BestKru" width="256" src="https://joplinapp.org/images/sponsors/BestKru.png"/></a> <a href="https://www.socialfollowers.uk/buy-tiktok-followers/"><img title="Social Followers" width="256" src="https://joplinapp.org/images/sponsors/SocialFollowers.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://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> <a href="https://www.socialfollowers.uk/buy-tiktok-followers/"><img title="Social Followers" width="256" src="https://joplinapp.org/images/sponsors/SocialFollowers.png"/></a> <a href="https://stormlikes.com/"><img title="Stormlikes" width="256" src="https://joplinapp.org/images/sponsors/Stormlikes.png"/></a> <a href="https://route4me.com"><img title="Route4Me" width="256" src="https://joplinapp.org/images/sponsors/Route4Me.png"/></a> <a href="https://buyyoutubviews.com"><img title="BYTV" width="256" src="https://joplinapp.org/images/sponsors/BYTV.png"/></a> <a href="https://www.famegear.com"><img title="Famegear" width="256" src="https://joplinapp.org/images/sponsors/Famegear.png"/></a> <a href="https://casinoreviews.net"><img title="Casino Reviews" width="256" src="https://joplinapp.org/images/sponsors/CasinoReviews.png"/></a>
<!-- SPONSORS-ORG -->
* * *

View File

@@ -61,6 +61,7 @@
"/packages/turndown/config",
"/readme/_i18n",
"/readme/about/changelog/desktop.md",
"/readme/licenses.md",
"/readme/i18n",
"cspell.json",
"node_modules"

View File

@@ -15,7 +15,6 @@
# SLAVE_POSTGRES_USER=joplin
# SLAVE_POSTGRES_PORT=5433
# SLAVE_POSTGRES_HOST=localhost
# USERS_WITH_REPLICATION=ID1,ID2,...
version: '2'

View File

@@ -0,0 +1,13 @@
A <strong>Joplin</strong> egy ingyenes, nyílt forráskódú jegyzetkészítő és teendők készítésére szolgáló alkalmazás, amely számos jegyzetfüzetbe rendezett jegyzet kezelésére képes. A jegyzetek kereshetők, másolhatók, címkézhetők és módosíthatók akár közvetlenül az alkalmazásokból, akár saját szövegszerkesztőből.
A jegyzetek <a href="https://joplinapp.org/help/apps/markdown">Markdown formátumban</a> vannak.
Az Evernote-ból exportált jegyzetek <a href="https://joplinapp.org/help/apps/import_export">importálhatók</a> a Joplinba, beleértve a formázott tartalmat (amelyet Markdown-ba konvertálunk), az erőforrásokat (képeket, mellékletek stb.) és teljes metaadatok (földrajzi hely, frissített idő, létrehozási idő stb.). Sima Markdown fájlok is importálhatók.
A Joplin „offline elszobb”, ami azt jelenti, hogy mindig minden adata a telefonján vagy a számítógépén van. Ez biztosítja, hogy jegyzetei mindig elérhetőek legyenek, akár van internetkapcsolata, akár nem.</p>
A jegyzetek biztonságosan <a href="https://joplinapp.org/help/apps/sync">összehangolhatók</a> a <a href="https://joplinapp.org/help/apps/sync/e2ee">végpontok közötti titkosítás</a> segítségével különféle felhőszolgáltatásokkal, köztük a Nextcloud, a Dropbox, a OneDrive és a <a href="https://joplinapp.org/plans/">Joplin Cloud</a> segítségével.
A teljes szöveges keresés minden platformon elérhető, hogy gyorsan megtalálja a szükséges információkat. Az alkalmazás beépülő modulok és témák segítségével testreszabható, és könnyedén létrehozhatja sajátját is.
Az alkalmazás elérhető Android, iOS, Linux, macOS és Windows rendszeren. Egy <a href="https://joplinapp.org/help/apps/clipper">Web Clipper</a>, amely weboldalakat és képernyőképeket menthet a böngészőből, szintén elérhető a <a href="https://addons.mozilla.org/firefox/addon/joplin-web-clipper/">Firefox</a> és <a href="https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek">Chrome</a>.

View File

@@ -0,0 +1 @@
Jegyzetkészítő és teendők alkalmazás Linux, macOS, Windows és mobileszközök közötti összehangolással

View File

@@ -21,7 +21,8 @@ module.exports = {
// 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',
'*.{js,jsx,ts,tsx,task3}': 'yarn linter-precommit',
'*.{json,task4}': 'yarn packageJsonLint',
'*.{md,mdx,task5}': 'yarn spellcheck',
'*.{md,mdx,task6}': 'yarn validateFilenames',
};

View File

@@ -9,7 +9,8 @@
"url": "git+https://github.com/laurent22/joplin.git"
},
"engines": {
"node": ">=18"
"node": ">=18",
"yarn": "3.8.3"
},
"scripts": {
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
@@ -59,6 +60,7 @@
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
"updateNews": "node ./packages/tools/website/updateNews",
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
"validateFilenames": "node ./packages/tools/validateFilenames.js",
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
"watchWebsite": "nodemon --delay 1 --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --watch packages/doc-builder/build --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
},
@@ -71,44 +73,45 @@
"@crowdin/cli": "3",
"@joplin/utils": "~2.12",
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
"@typescript-eslint/eslint-plugin": "6.8.0",
"@typescript-eslint/parser": "6.8.0",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"cspell": "5.21.2",
"eslint": "8.52.0",
"eslint": "8.57.0",
"eslint-interactive": "10.8.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-jest": "27.4.3",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "7.33.2",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jest": "27.9.0",
"eslint-plugin-promise": "6.2.0",
"eslint-plugin-react": "7.34.3",
"execa": "5.1.1",
"fs-extra": "11.2.0",
"glob": "10.3.10",
"glob": "10.4.5",
"gulp": "4.0.2",
"husky": "3.1.0",
"lerna": "3.22.1",
"lint-staged": "15.2.2",
"madge": "6.1.0",
"lint-staged": "15.2.8",
"madge": "7.0.0",
"npm-package-json-lint": "7.1.0",
"typescript": "5.2.2"
"typescript": "5.4.5"
},
"dependencies": {
"@types/fs-extra": "11.0.4",
"eslint-plugin-github": "4.10.1",
"eslint-plugin-github": "4.10.2",
"http-server": "14.1.1",
"node-gyp": "9.4.1",
"nodemon": "3.0.3"
"nodemon": "3.1.7"
},
"packageManager": "yarn@3.6.4",
"packageManager": "yarn@3.8.3",
"resolutions": {
"react-native-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch",
"react-native-vosk@0.1.12": "patch:react-native-vosk@npm%3A0.1.12#./.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch",
"eslint": "patch:eslint@8.52.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
"eslint": "patch:eslint@8.57.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
"app-builder-lib@24.4.0": "patch:app-builder-lib@npm%3A24.4.0#./.yarn/patches/app-builder-lib-npm-24.4.0-05322ff057.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": "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",
"react-native@0.74.1": "patch:react-native@npm%3A0.74.1#./.yarn/patches/react-native-npm-0.74.1-754c02ae9e.patch"
"react-native@0.74.1": "patch:react-native@npm%3A0.74.1#./.yarn/patches/react-native-npm-0.74.1-754c02ae9e.patch",
"rn-fetch-blob@0.12.0": "patch:rn-fetch-blob@npm%3A0.12.0#./.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.patch"
}
}

View File

@@ -8,8 +8,7 @@ import shim from '@joplin/lib/shim';
import * as pathUtils from '@joplin/lib/path-utils';
import { getEncryptionEnabled, localSyncInfo } from '@joplin/lib/services/synchronizer/syncInfoUtils';
import { generateMasterKeyAndEnableEncryption, loadMasterKeysFromSettings, masterPasswordIsValid, setupAndDisableEncryption } from '@joplin/lib/services/e2ee/utils';
const imageType = require('image-type');
const readChunk = require('read-chunk');
import { fromFile as fileTypeFromFile } from 'file-type';
class Command extends BaseCommand {
public usage() {
@@ -136,8 +135,7 @@ class Command extends BaseCommand {
const outputDir = options.output ? options.output : require('os').tmpdir();
let outFile = `${outputDir}/${pathUtils.filename(args.path)}.${Date.now()}.bin`;
await EncryptionService.instance().decryptFile(args.path, outFile);
const buffer = await readChunk(outFile, 0, 64);
const detectedType = imageType(buffer);
const detectedType = await fileTypeFromFile(outFile);
if (detectedType) {
const newOutFile = `${outFile}.${detectedType.ext}`;

View File

@@ -1,4 +1,4 @@
import Setting, { SettingStorage } from '@joplin/lib/models/Setting';
import Setting, { AppType, SettingStorage } from '@joplin/lib/models/Setting';
import { SettingItemType } from '@joplin/lib/services/plugins/api/types';
import shim from '@joplin/lib/shim';
@@ -61,7 +61,7 @@ class Command extends BaseCommand {
const description: string[] = [];
if (md.label && md.label()) description.push(md.label());
if (md.description && md.description('desktop')) description.push(md.description('desktop'));
if (md.description && md.description(AppType.Desktop)) description.push(md.description(AppType.Desktop));
if (description.length) props.description = description.join('. ');
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env node
#!/usr/bin/env -S NODE_OPTIONS=--no-deprecation node
// Use njstrace to find out what Node.js might be spending time on
// var njstrace = require('njstrace').inject();

View File

@@ -35,49 +35,48 @@
],
"owner": "Laurent Cozic"
},
"version": "3.0.1",
"version": "3.2.0",
"bin": "./main.js",
"engines": {
"node": ">=10.0.0"
},
"dependencies": {
"@joplin/lib": "~3.0",
"@joplin/renderer": "~3.0",
"@joplin/utils": "~3.0",
"@joplin/lib": "~3.2",
"@joplin/renderer": "~3.2",
"@joplin/utils": "~3.2",
"aws-sdk": "2.1340.0",
"chalk": "4.1.2",
"compare-version": "0.1.2",
"file-type": "16.5.4",
"fs-extra": "11.2.0",
"html-entities": "1.4.0",
"image-type": "3.1.0",
"keytar": "7.9.0",
"md5": "2.3.0",
"node-rsa": "1.1.1",
"open": "8.4.2",
"proper-lockfile": "4.1.2",
"read-chunk": "2.1.0",
"server-destroy": "1.0.1",
"sharp": "0.33.2",
"sharp": "0.33.4",
"sprintf-js": "1.1.3",
"sqlite3": "5.1.6",
"string-padding": "1.0.2",
"strip-ansi": "6.0.1",
"tcp-port-used": "1.0.2",
"terminal-kit": "3.0.2",
"terminal-kit": "3.1.1",
"tkwidgets": "0.5.27",
"url-parse": "1.5.10",
"word-wrap": "1.2.5",
"yargs-parser": "21.1.1"
},
"devDependencies": {
"@joplin/tools": "~3.0",
"@joplin/tools": "~3.2",
"@types/fs-extra": "11.0.4",
"@types/jest": "29.5.8",
"@types/node": "18.19.26",
"@types/jest": "29.5.12",
"@types/node": "18.19.42",
"@types/proper-lockfile": "^4.1.2",
"gulp": "4.0.2",
"jest": "29.7.0",
"temp": "0.9.4",
"typescript": "5.2.2"
"typescript": "5.4.5"
}
}

View File

@@ -1,14 +1,17 @@
import MdToHtml from '@joplin/renderer/MdToHtml';
import MdToHtml, { LinkRenderingType } from '@joplin/renderer/MdToHtml';
const { filename } = require('@joplin/lib/path-utils');
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import shim from '@joplin/lib/shim';
import { RenderOptions } from '@joplin/renderer/types';
import { isResourceUrl, resourceUrlToId } from '@joplin/lib/models/utils/resourceUtils';
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: {
isResourceUrl: () => false,
isResourceUrl: isResourceUrl,
urlToId: resourceUrlToId,
},
fsDriver: shim.fsDriver(),
...options,
@@ -39,7 +42,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 = {
const mdToHtmlOptions: RenderOptions = {
bodyOnly: true,
};
@@ -51,6 +54,8 @@ describe('MdToHtml', () => {
};
} else if (mdFilename.startsWith('sourcemap_')) {
mdToHtmlOptions.mapsToLine = true;
} else if (mdFilename.startsWith('resource_')) {
mdToHtmlOptions.resources = {};
}
const markdown = await shim.fsDriver().readFile(mdFilePath);
@@ -213,6 +218,9 @@ describe('MdToHtml', () => {
const mdToHtmlLinkifyOn = newTestMdToHtml({
pluginOptions: {
linkify: { enabled: true },
link_open: {
linkRenderingType: LinkRenderingType.HrefHandler,
},
},
});
@@ -222,29 +230,52 @@ describe('MdToHtml', () => {
},
});
const renderOptions = {
bodyOnly: true,
plainResourceRendering: true,
linkRenderingType: LinkRenderingType.HrefHandler,
};
for (const testCase of testCases) {
const [input, expectedLinkifyOff, expectedLinkifyOn] = testCase;
{
const actual = await mdToHtmlLinkifyOn.render(input, null, {
bodyOnly: true,
plainResourceRendering: true,
});
const actual = await mdToHtmlLinkifyOn.render(input, null, renderOptions);
expect(actual.html).toBe(expectedLinkifyOn);
}
{
const actual = await mdToHtmlLinkifyOff.render(input, null, {
bodyOnly: true,
plainResourceRendering: true,
});
const actual = await mdToHtmlLinkifyOff.render(input, null, renderOptions);
expect(actual.html).toBe(expectedLinkifyOff);
}
}
}));
it.each([
'[test](http://example.com/)',
'[test](mailto:test@example.com)',
])('should add onclick handlers to links when linkRenderingType is JavaScriptHandler (%j)', async (markdown) => {
const mdToHtml = newTestMdToHtml();
const renderWithoutOnClickOptions = {
bodyOnly: true,
linkRenderingType: LinkRenderingType.HrefHandler,
};
expect(
(await mdToHtml.render(markdown, undefined, renderWithoutOnClickOptions)).html,
).not.toContain('onclick');
const renderWithOnClickOptions = {
bodyOnly: true,
linkRenderingType: LinkRenderingType.JavaScriptHandler,
};
expect(
(await mdToHtml.render(markdown, undefined, renderWithOnClickOptions)).html,
).toMatch(/<a data-from-md .*onclick=['"].*['"].*>/);
});
it('should return attributes of line numbers', (async () => {
const mdToHtml = newTestMdToHtml();
@@ -321,4 +352,12 @@ describe('MdToHtml', () => {
expect(html).toContain('Inline</span>');
expect(html).toContain('Block</span>');
});
it('should sanitize KaTeX errors', async () => {
const markdown = '$\\a<svg>$';
const renderResult = await newTestMdToHtml().render(markdown, null, { bodyOnly: true });
// Should not contain the HTML in unsanitized form
expect(renderResult.html).not.toContain('<svg>');
});
});

View File

@@ -0,0 +1,48 @@
<p>Markdown images:</p>
<ul>
<li>
With ALT and title:
<div
class="not-loaded-resource not-loaded-image-resource resource-status-test"
data-original-alt="test"
data-original-title="testing"
data-resource-id="0415d61cc33e47afa6dde45948c3177f"
>
<img src="data:image/svg+xml;utf8,some-icon-here"/>
</div>
</li>
<li>
With neither ALT nor title:
<div
class="not-loaded-resource not-loaded-image-resource resource-status-error"
data-original-alt=""
data-original-title=""
data-resource-id="0a25d61cc33e57afa6dde45948c3177f"
>
<img src="data:image/svg+xml;utf8,some-icon-here"/>
</div>
</li>
</ul>
<p>HTML images:</p>
<ul>
<li>
<div
class="not-loaded-resource not-loaded-image-resource resource-status-error"
data-original-before=" width=&quot;230&quot;"
data-original-after=" style=&quot;border: 32px inset red;&quot;/"
data-resource-id="0415d61cc33e47afa6dde45948c3177f"
>
<img src="data:image/svg+xml;utf8,some-icon-here"/>
</div>
</li>
<li>
<div
class="not-loaded-resource not-loaded-image-resource resource-status-error"
data-original-after="/"
data-resource-id="0415d61cc33e47afa6dde45948c3177f"
>
<img src="data:image/svg+xml;utf8,some-icon-here"/>
</div>
</li>
</ul>

View File

@@ -0,0 +1,9 @@
Markdown images:
- With ALT and title:![test](:/0415d61cc33e47afa6dde45948c3177f "testing")
- With neither ALT nor title:![](:/0a25d61cc33e57afa6dde45948c3177f)
HTML images:
- <img width="230" src=":/0415d61cc33e47afa6dde45948c3177f" style="border: 32px inset red;"/>
- <img src=":/0415d61cc33e47afa6dde45948c3177f" />

View File

@@ -0,0 +1,15 @@
<div class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22345" data-original-alt data-original-title="test" contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;&Tab;&lt;svg width=&quot;1700&quot; height=&quot;1536&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&Tab;&Tab; &lt;path d=&quot;M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z&quot;/&gt;
&Tab;&Tab;&lt;/svg&gt;
&Tab;"/></div>
<div class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22346" data-original-alt="test" data-original-title contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;&Tab;&lt;svg width=&quot;1700&quot; height=&quot;1536&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&Tab;&Tab; &lt;path d=&quot;M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z&quot;/&gt;
&Tab;&Tab;&lt;/svg&gt;
&Tab;"/></div>
<div class="not-loaded-resource not-loaded-image-resource resource-status-notDownloaded" data-resource-id="a1test2a1test2a1test2a1test22347" data-original-before=" " data-original-after=" class=&quot;jop-noMdConv&quot;/" contenteditable="false"><img src="data:image/svg+xml;utf8,
&Tab;&Tab;&lt;svg width=&quot;1700&quot; height=&quot;1536&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&Tab;&Tab; &lt;path d=&quot;M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z&quot;/&gt;
&Tab;&Tab;&lt;/svg&gt;
&Tab;"/></div>

View File

@@ -0,0 +1,3 @@
![](:/a1test2a1test2a1test2a1test22345 "test")
![test](:/a1test2a1test2a1test2a1test22346)
<img src=":/a1test2a1test2a1test2a1test22347"/>

View File

@@ -0,0 +1,2 @@
<div class="jop-noMdConv">
&lt;.a

View File

@@ -0,0 +1,2 @@
<div>
<.a<iframe src="http://example.com/" >

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
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,10 @@
# Worker example
This plugin demonstrates how to create a `Worker` and, within it, use `transformers.js` for text classification.
At present, this plugin only works on desktop. However, it should also be possible to load the `Worker` from a plugin panel or dialog on mobile (but not web).
**Notes**:
- `plugin.config.json` was updated to target **web**. This allows the plugin to load `transformers.js` from the worker without depending on `node-loader`.
- This simplifies the build process and should make it easier to add mobile and web support to this plugin.
- WASM files and other assets are copied by `tools/copyAssets.js`.

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>;
}

View File

@@ -0,0 +1,16 @@
import { ToolbarButtonLocation } from './types';
import Plugin from '../Plugin';
/**
* Allows creating and managing toolbar buttons.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/register_command)
*/
export default class JoplinViewsToolbarButtons {
private store;
private plugin;
constructor(plugin: Plugin, store: any);
/**
* Creates a new toolbar button and associate it with the given command.
*/
create(id: string, commandName: string, location: ToolbarButtonLocation): Promise<void>;
}

View File

@@ -0,0 +1,24 @@
import Plugin from '../Plugin';
export interface Implementation {
injectCustomStyles(elementId: string, cssFilePath: string): Promise<void>;
}
export default class JoplinWindow {
private plugin_;
private store_;
private implementation_;
constructor(implementation: Implementation, plugin: Plugin, store: any);
/**
* Loads a chrome CSS file. It will apply to the window UI elements, except
* for the note viewer. It is the same as the "Custom stylesheet for
* Joplin-wide app styles" setting. See the [Load CSS Demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/load_css)
* for an example.
*/
loadChromeCssFile(filePath: string): Promise<void>;
/**
* Loads a note CSS file. It will apply to the note viewer, as well as any
* exported or printed note. It is the same as the "Custom stylesheet for
* rendered Markdown" setting. See the [Load CSS Demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/load_css)
* for an example.
*/
loadNoteCssFile(filePath: string): Promise<void>;
}

View File

@@ -0,0 +1,87 @@
import { FolderEntity } from '../../database/types';
import { Disposable, MenuItem } from './types';
export interface EditContextMenuFilterObject {
items: MenuItem[];
}
type FilterHandler<T> = (object: T) => Promise<void>;
declare enum ItemChangeEventType {
Create = 1,
Update = 2,
Delete = 3
}
interface ItemChangeEvent {
id: string;
event: ItemChangeEventType;
}
interface SyncStartEvent {
withErrors: boolean;
}
interface ResourceChangeEvent {
id: string;
}
type ItemChangeHandler = (event: ItemChangeEvent) => void;
type SyncStartHandler = (event: SyncStartEvent) => void;
type ResourceChangeHandler = (event: ResourceChangeEvent) => void;
/**
* The workspace service provides access to all the parts of Joplin that
* are being worked on - i.e. the currently selected notes or notebooks as
* well as various related events, such as when a new note is selected, or
* when the note content changes.
*
* [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins)
*/
export default class JoplinWorkspace {
private store;
constructor(store: any);
/**
* Called when a new note or notes are selected.
*/
onNoteSelectionChange(callback: Function): Promise<Disposable>;
/**
* Called when the content of a note changes.
* @deprecated Use `onNoteChange()` instead, which is reliably triggered whenever the note content, or any note property changes.
*/
onNoteContentChange(callback: Function): Promise<void>;
/**
* Called when the content of the current note changes.
*/
onNoteChange(handler: ItemChangeHandler): Promise<Disposable>;
/**
* Called when a resource is changed. Currently this handled will not be
* called when a resource is added or deleted.
*/
onResourceChange(handler: ResourceChangeHandler): Promise<void>;
/**
* Called when an alarm associated with a to-do is triggered.
*/
onNoteAlarmTrigger(handler: Function): Promise<Disposable>;
/**
* Called when the synchronisation process is starting.
*/
onSyncStart(handler: SyncStartHandler): Promise<Disposable>;
/**
* Called when the synchronisation process has finished.
*/
onSyncComplete(callback: Function): Promise<Disposable>;
/**
* Called just before the editor context menu is about to open. Allows
* adding items to it.
*/
filterEditorContextMenu(handler: FilterHandler<EditContextMenuFilterObject>): void;
/**
* Gets the currently selected note
*/
selectedNote(): Promise<any>;
/**
* Gets the currently selected folder. In some cases, for example during
* search or when viewing a tag, no folder is actually selected in the user
* interface. In that case, that function would return the last selected
* folder.
*/
selectedFolder(): Promise<FolderEntity>;
/**
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
*/
selectedNoteIds(): Promise<string[]>;
}
export {};

View File

@@ -0,0 +1,5 @@
import type Joplin from './Joplin';
declare const joplin: Joplin;
export default joplin;

View File

@@ -0,0 +1,156 @@
import { Size } from './types';
type ListRendererDatabaseDependency = 'folder.created_time' | 'folder.encryption_applied' | 'folder.encryption_cipher_text' | 'folder.icon' | 'folder.id' | 'folder.is_shared' | 'folder.master_key_id' | 'folder.parent_id' | 'folder.share_id' | 'folder.title' | 'folder.updated_time' | 'folder.user_created_time' | 'folder.user_data' | 'folder.user_updated_time' | 'folder.type_' | 'note.altitude' | 'note.application_data' | 'note.author' | 'note.body' | 'note.conflict_original_id' | 'note.created_time' | 'note.encryption_applied' | 'note.encryption_cipher_text' | 'note.id' | 'note.is_conflict' | 'note.is_shared' | 'note.is_todo' | 'note.latitude' | 'note.longitude' | 'note.markup_language' | 'note.master_key_id' | 'note.order' | 'note.parent_id' | 'note.share_id' | 'note.source' | 'note.source_application' | 'note.source_url' | 'note.title' | 'note.todo_completed' | 'note.todo_due' | 'note.updated_time' | 'note.user_created_time' | 'note.user_data' | 'note.user_updated_time' | 'note.type_';
export declare enum ItemFlow {
TopToBottom = "topToBottom",
LeftToRight = "leftToRight"
}
export type RenderNoteView = Record<string, any>;
export interface OnChangeEvent {
elementId: string;
value: any;
noteId: string;
}
export type OnRenderNoteHandler = (props: any) => Promise<RenderNoteView>;
export type OnChangeHandler = (event: OnChangeEvent) => Promise<void>;
/**
* Most of these are the built-in note properties, such as `note.title`,
* `note.todo_completed`, etc.
*
* Additionally, the `item.*` properties are specific to the rendered item. The
* most important being `item.selected`, which you can use to display the
* selected note in a different way.
*
* Finally some special properties are provided to make it easier to render
* notes. In particular, if possible prefer `note.titleHtml` to `note.title`
* since some important processing has already been done on the string, such as
* handling the search highlighter and escaping. Since it's HTML and already
* escaped you would insert it using `{{{titleHtml}}}` (triple-mustache syntax,
* which disables escaping).
*
* `notes.tag` gives you the list of tags associated with the note.
*
* `note.isWatched` tells you if the note is currently opened in an external
* editor. In which case you would generally display some indicator.
*/
export type ListRendererDepependency = ListRendererDatabaseDependency | 'item.size.width' | 'item.size.height' | 'item.selected' | 'note.titleHtml' | 'note.isWatched' | 'note.tags';
export interface ListRenderer {
/**
* It must be unique to your plugin.
*/
id: string;
/**
* Can be top to bottom or left to right. Left to right gives you more
* option to set the size of the items since you set both its width and
* height.
*/
flow: ItemFlow;
/**
* The size of each item must be specified in advance for performance
* reasons, and cannot be changed afterwards. If the item flow is top to
* bottom, you only need to specificy the item height (the width will be
* ignored).
*/
itemSize: Size;
/**
* The CSS is relative to the list item container. What will appear in the
* page is essentially `.note-list-item { YOUR_CSS; }`. It means you can use
* child combinator with guarantee it will only apply to your own items. In
* this example, the styling will apply to `.note-list-item > .content`:
*
* ```css
* > .content {
* padding: 10px;
* }
* ```
*
* In order to get syntax highlighting working here, it's recommended
* installing an editor extension such as [es6-string-html VSCode
* extension](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html)
*/
itemCss?: string;
/**
* List the dependencies that your plugin needs to render the note list
* items. Only these will be passed to your `onRenderNote` handler. Ensure
* that you do not add more than what you need since there is a performance
* penalty for each property.
*/
dependencies: ListRendererDepependency[];
/**
* This is the HTML template that will be used to render the note list item.
* This is a [Mustache template](https://github.com/janl/mustache.js) and it
* will receive the variable you return from `onRenderNote` as tags. For
* example, if you return a property named `formattedDate` from
* `onRenderNote`, you can insert it in the template using `Created date:
* {{formattedDate}}`.
*
* In order to get syntax highlighting working here, it's recommended
* installing an editor extension such as [es6-string-html VSCode
* extension](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html)
*/
itemTemplate: string;
/**
* This user-facing text is used for example in the View menu, so that your
* renderer can be selected.
*/
label: () => Promise<string>;
/**
* This is where most of the real-time processing will happen. When a note
* is rendered for the first time and every time it changes, this handler
* receives the properties specified in the `dependencies` property. You can
* then process them, load any additional data you need, and once done you
* need to return the properties that are needed in the `itemTemplate` HTML.
* Again, to use the formatted date example, you could have such a renderer:
*
* ```typescript
* dependencies: [
* 'note.title',
* 'note.created_time',
* ],
*
* itemTemplate: // html
* `
* <div>
* Title: {{note.title}}<br/>
* Date: {{formattedDate}}
* </div>
* `,
*
* onRenderNote: async (props: any) => {
* const formattedDate = dayjs(props.note.created_time).format();
* return {
* // Also return the props, so that note.title is available from the
* // template
* ...props,
* formattedDate,
* }
* },
* ```
*/
onRenderNote: OnRenderNoteHandler;
/**
* This handler allows adding some interacivity to the note renderer -
* whenever an input element within the item is changed (for example, when a
* checkbox is clicked, or a text input is changed), this `onChange` handler
* is going to be called.
*
* You can inspect `event.elementId` to know which element had some changes,
* and `event.value` to know the new value. `event.noteId` also tells you
* what note is affected, so that you can potentially apply changes to it.
*
* You specify the element ID, by setting a `data-id` attribute on the
* input.
*
* For example, if you have such a template:
*
* ```html
* <div>
* <input type="text" value="{{note.title}}" data-id="noteTitleInput"/>
* </div>
* ```
*
* The event handler will receive an event with `elementId` set to
* `noteTitleInput`.
*/
onChange?: OnChangeHandler;
}
export {};

View File

@@ -0,0 +1,181 @@
/* eslint-disable multiline-comment-style */
import { Size } from './types';
// AUTO-GENERATED by generate-database-type
type ListRendererDatabaseDependency = 'folder.created_time' | 'folder.encryption_applied' | 'folder.encryption_cipher_text' | 'folder.icon' | 'folder.id' | 'folder.is_shared' | 'folder.master_key_id' | 'folder.parent_id' | 'folder.share_id' | 'folder.title' | 'folder.updated_time' | 'folder.user_created_time' | 'folder.user_data' | 'folder.user_updated_time' | 'folder.type_' | 'note.altitude' | 'note.application_data' | 'note.author' | 'note.body' | 'note.conflict_original_id' | 'note.created_time' | 'note.encryption_applied' | 'note.encryption_cipher_text' | 'note.id' | 'note.is_conflict' | 'note.is_shared' | 'note.is_todo' | 'note.latitude' | 'note.longitude' | 'note.markup_language' | 'note.master_key_id' | 'note.order' | 'note.parent_id' | 'note.share_id' | 'note.source' | 'note.source_application' | 'note.source_url' | 'note.title' | 'note.todo_completed' | 'note.todo_due' | 'note.updated_time' | 'note.user_created_time' | 'note.user_data' | 'note.user_updated_time' | 'note.type_';
// AUTO-GENERATED by generate-database-type
export enum ItemFlow {
TopToBottom = 'topToBottom',
LeftToRight = 'leftToRight',
}
export type RenderNoteView = Record<string, any>;
export interface OnChangeEvent {
elementId: string;
value: any;
noteId: string;
}
export type OnRenderNoteHandler = (props: any)=> Promise<RenderNoteView>;
export type OnChangeHandler = (event: OnChangeEvent)=> Promise<void>;
/**
* Most of these are the built-in note properties, such as `note.title`,
* `note.todo_completed`, etc.
*
* Additionally, the `item.*` properties are specific to the rendered item. The
* most important being `item.selected`, which you can use to display the
* selected note in a different way.
*
* Finally some special properties are provided to make it easier to render
* notes. In particular, if possible prefer `note.titleHtml` to `note.title`
* since some important processing has already been done on the string, such as
* handling the search highlighter and escaping. Since it's HTML and already
* escaped you would insert it using `{{{titleHtml}}}` (triple-mustache syntax,
* which disables escaping).
*
* `notes.tag` gives you the list of tags associated with the note.
*
* `note.isWatched` tells you if the note is currently opened in an external
* editor. In which case you would generally display some indicator.
*/
export type ListRendererDepependency =
ListRendererDatabaseDependency |
'item.size.width' |
'item.size.height' |
'item.selected' |
'note.titleHtml' |
'note.isWatched' |
'note.tags';
export interface ListRenderer {
/**
* It must be unique to your plugin.
*/
id: string;
/**
* Can be top to bottom or left to right. Left to right gives you more
* option to set the size of the items since you set both its width and
* height.
*/
flow: ItemFlow;
/**
* The size of each item must be specified in advance for performance
* reasons, and cannot be changed afterwards. If the item flow is top to
* bottom, you only need to specificy the item height (the width will be
* ignored).
*/
itemSize: Size;
/**
* The CSS is relative to the list item container. What will appear in the
* page is essentially `.note-list-item { YOUR_CSS; }`. It means you can use
* child combinator with guarantee it will only apply to your own items. In
* this example, the styling will apply to `.note-list-item > .content`:
*
* ```css
* > .content {
* padding: 10px;
* }
* ```
*
* In order to get syntax highlighting working here, it's recommended
* installing an editor extension such as [es6-string-html VSCode
* extension](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html)
*/
itemCss?: string;
/**
* List the dependencies that your plugin needs to render the note list
* items. Only these will be passed to your `onRenderNote` handler. Ensure
* that you do not add more than what you need since there is a performance
* penalty for each property.
*/
dependencies: ListRendererDepependency[];
/**
* This is the HTML template that will be used to render the note list item.
* This is a [Mustache template](https://github.com/janl/mustache.js) and it
* will receive the variable you return from `onRenderNote` as tags. For
* example, if you return a property named `formattedDate` from
* `onRenderNote`, you can insert it in the template using `Created date:
* {{formattedDate}}`.
*
* In order to get syntax highlighting working here, it's recommended
* installing an editor extension such as [es6-string-html VSCode
* extension](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html)
*/
itemTemplate: string;
/**
* This user-facing text is used for example in the View menu, so that your
* renderer can be selected.
*/
label: ()=> Promise<string>;
/**
* This is where most of the real-time processing will happen. When a note
* is rendered for the first time and every time it changes, this handler
* receives the properties specified in the `dependencies` property. You can
* then process them, load any additional data you need, and once done you
* need to return the properties that are needed in the `itemTemplate` HTML.
* Again, to use the formatted date example, you could have such a renderer:
*
* ```typescript
* dependencies: [
* 'note.title',
* 'note.created_time',
* ],
*
* itemTemplate: // html
* `
* <div>
* Title: {{note.title}}<br/>
* Date: {{formattedDate}}
* </div>
* `,
*
* onRenderNote: async (props: any) => {
* const formattedDate = dayjs(props.note.created_time).format();
* return {
* // Also return the props, so that note.title is available from the
* // template
* ...props,
* formattedDate,
* }
* },
* ```
*/
onRenderNote: OnRenderNoteHandler;
/**
* This handler allows adding some interacivity to the note renderer -
* whenever an input element within the item is changed (for example, when a
* checkbox is clicked, or a text input is changed), this `onChange` handler
* is going to be called.
*
* You can inspect `event.elementId` to know which element had some changes,
* and `event.value` to know the new value. `event.noteId` also tells you
* what note is affected, so that you can potentially apply changes to it.
*
* You specify the element ID, by setting a `data-id` attribute on the
* input.
*
* For example, if you have such a template:
*
* ```html
* <div>
* <input type="text" value="{{note.title}}" data-id="noteTitleInput"/>
* </div>
* ```
*
* The event handler will receive an event with `elementId` set to
* `noteTitleInput`.
*/
onChange?: OnChangeHandler;
}

View File

@@ -0,0 +1,748 @@
/* eslint-disable multiline-comment-style */
// =================================================================
// Command API types
// =================================================================
export interface Command {
/**
* Name of command - must be globally unique
*/
name: string;
/**
* Label to be displayed on menu items or keyboard shortcut editor for example.
* If it is missing, it's assumed it's a private command, to be called programmatically only.
* In that case the command will not appear in the shortcut editor or command panel, and logically
* should not be used as a menu item.
*/
label?: string;
/**
* Icon to be used on toolbar buttons for example
*/
iconName?: string;
/**
* Code to be ran when the command is executed. It may return a result.
*/
execute(...args: any[]): Promise<any | void>;
/**
* Defines whether the command should be enabled or disabled, which in turns
* affects the enabled state of any associated button or menu item.
*
* The condition should be expressed as a "when-clause" (as in Visual Studio
* Code). It's a simple boolean expression that evaluates to `true` or
* `false`. It supports the following operators:
*
* Operator | Symbol | Example
* -- | -- | --
* Equality | == | "editorType == markdown"
* Inequality | != | "currentScreen != config"
* Or | \|\| | "noteIsTodo \|\| noteTodoCompleted"
* And | && | "oneNoteSelected && !inConflictFolder"
*
* Joplin, unlike VSCode, also supports parentheses, which allows creating
* more complex expressions such as `cond1 || (cond2 && cond3)`. Only one
* level of parentheses is possible (nested ones aren't supported).
*
* Currently the supported context variables aren't documented, but you can
* find the list below:
*
* - [Global When Clauses](https://github.com/laurent22/joplin/blob/dev/packages/lib/services/commands/stateToWhenClauseContext.ts)
* - [Desktop app When Clauses](https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/services/commands/stateToWhenClauseContext.ts)
*
* Note: Commands are enabled by default unless you use this property.
*/
enabledCondition?: string;
}
// =================================================================
// Interop API types
// =================================================================
export enum FileSystemItem {
File = 'file',
Directory = 'directory',
}
export enum ImportModuleOutputFormat {
Markdown = 'md',
Html = 'html',
}
/**
* Used to implement a module to export data from Joplin. [View the demo plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/json_export) for an example.
*
* In general, all the event handlers you'll need to implement take a `context` object as a first argument. This object will contain the export or import path as well as various optional properties, such as which notes or notebooks need to be exported.
*
* To get a better sense of what it will contain it can be useful to print it using `console.info(context)`.
*/
export interface ExportModule {
/**
* The format to be exported, eg "enex", "jex", "json", etc.
*/
format: string;
/**
* The description that will appear in the UI, for example in the menu item.
*/
description: string;
/**
* Whether the module will export a single file or multiple files in a directory. It affects the open dialog that will be presented to the user when using your exporter.
*/
target: FileSystemItem;
/**
* Only applies to single file exporters or importers
* It tells whether the format can package multiple notes into one file.
* For example JEX or ENEX can, but HTML cannot.
*/
isNoteArchive: boolean;
/**
* The extensions of the files exported by your module. For example, it is `["htm", "html"]` for the HTML module, and just `["jex"]` for the JEX module.
*/
fileExtensions?: string[];
/**
* Called when the export process starts.
*/
onInit(context: ExportContext): Promise<void>;
/**
* Called when an item needs to be processed. An "item" can be any Joplin object, such as a note, a folder, a notebook, etc.
*/
onProcessItem(context: ExportContext, itemType: number, item: any): Promise<void>;
/**
* Called when a resource file needs to be exported.
*/
onProcessResource(context: ExportContext, resource: any, filePath: string): Promise<void>;
/**
* Called when the export process is done.
*/
onClose(context: ExportContext): Promise<void>;
}
export interface ImportModule {
/**
* The format to be exported, eg "enex", "jex", "json", etc.
*/
format: string;
/**
* The description that will appear in the UI, for example in the menu item.
*/
description: string;
/**
* Only applies to single file exporters or importers
* It tells whether the format can package multiple notes into one file.
* For example JEX or ENEX can, but HTML cannot.
*/
isNoteArchive: boolean;
/**
* The type of sources that are supported by the module. Tells whether the module can import files or directories or both.
*/
sources: FileSystemItem[];
/**
* Tells the file extensions of the exported files.
*/
fileExtensions?: string[];
/**
* Tells the type of notes that will be generated, either HTML or Markdown (default).
*/
outputFormat?: ImportModuleOutputFormat;
/**
* Called when the import process starts. There is only one event handler within which you should import the complete data.
*/
onExec(context: ImportContext): Promise<void>;
}
export interface ExportOptions {
format?: string;
path?: string;
sourceFolderIds?: string[];
sourceNoteIds?: string[];
// modulePath?: string;
target?: FileSystemItem;
}
export interface ExportContext {
destPath: string;
options: ExportOptions;
/**
* You can attach your own custom data using this propery - it will then be passed to each event handler, allowing you to keep state from one event to the next.
*/
userData?: any;
}
export interface ImportContext {
sourcePath: string;
options: any;
warnings: string[];
}
// =================================================================
// Misc types
// =================================================================
export interface Script {
onStart?(event: any): Promise<void>;
}
export interface Disposable {
// dispose():void;
}
export enum ModelType {
Note = 1,
Folder = 2,
Setting = 3,
Resource = 4,
Tag = 5,
NoteTag = 6,
Search = 7,
Alarm = 8,
MasterKey = 9,
ItemChange = 10,
NoteResource = 11,
ResourceLocalState = 12,
Revision = 13,
Migration = 14,
SmartFilter = 15,
Command = 16,
}
export interface VersionInfo {
version: string;
profileVersion: number;
syncVersion: number;
}
// =================================================================
// Menu types
// =================================================================
export interface CreateMenuItemOptions {
accelerator: string;
}
export enum MenuItemLocation {
File = 'file',
Edit = 'edit',
View = 'view',
Note = 'note',
Tools = 'tools',
Help = 'help',
/**
* @deprecated Do not use - same as NoteListContextMenu
*/
Context = 'context',
// If adding an item here, don't forget to update isContextMenuItemLocation()
/**
* When a command is called from the note list context menu, the
* command will receive the following arguments:
*
* - `noteIds:string[]`: IDs of the notes that were right-clicked on.
*/
NoteListContextMenu = 'noteListContextMenu',
EditorContextMenu = 'editorContextMenu',
/**
* When a command is called from a folder context menu, the
* command will receive the following arguments:
*
* - `folderId:string`: ID of the folder that was right-clicked on
*/
FolderContextMenu = 'folderContextMenu',
/**
* When a command is called from a tag context menu, the
* command will receive the following arguments:
*
* - `tagId:string`: ID of the tag that was right-clicked on
*/
TagContextMenu = 'tagContextMenu',
}
export function isContextMenuItemLocation(location: MenuItemLocation): boolean {
return [
MenuItemLocation.Context,
MenuItemLocation.NoteListContextMenu,
MenuItemLocation.EditorContextMenu,
MenuItemLocation.FolderContextMenu,
MenuItemLocation.TagContextMenu,
].includes(location);
}
export interface MenuItem {
/**
* Command that should be associated with the menu item. All menu item should
* have a command associated with them unless they are a sub-menu.
*/
commandName?: string;
/**
* Arguments that should be passed to the command. They will be as rest
* parameters.
*/
commandArgs?: any[];
/**
* Set to "separator" to create a divider line
*/
type?: ('normal' | 'separator' | 'submenu' | 'checkbox' | 'radio');
/**
* Accelerator associated with the menu item
*/
accelerator?: string;
/**
* Menu items that should appear below this menu item. Allows creating a menu tree.
*/
submenu?: MenuItem[];
/**
* Menu item label. If not specified, the command label will be used instead.
*/
label?: string;
}
// =================================================================
// View API types
// =================================================================
export interface ButtonSpec {
id: ButtonId;
title?: string;
onClick?(): void;
}
export type ButtonId = string;
export enum ToolbarButtonLocation {
/**
* This toolbar in the top right corner of the application. It applies to the note as a whole, including its metadata.
*/
NoteToolbar = 'noteToolbar',
/**
* This toolbar is right above the text editor. It applies to the note body only.
*/
EditorToolbar = 'editorToolbar',
}
export type ViewHandle = string;
export interface EditorCommand {
name: string;
value?: any;
}
export interface DialogResult {
id: ButtonId;
formData?: any;
}
export interface Size {
width?: number;
height?: number;
}
export interface Rectangle {
x?: number;
y?: number;
width?: number;
height?: number;
}
// =================================================================
// Settings types
// =================================================================
export enum SettingItemType {
Int = 1,
String = 2,
Bool = 3,
Array = 4,
Object = 5,
Button = 6,
}
export enum SettingItemSubType {
FilePathAndArgs = 'file_path_and_args',
FilePath = 'file_path', // Not supported on mobile!
DirectoryPath = 'directory_path', // Not supported on mobile!
}
export enum AppType {
Desktop = 'desktop',
Mobile = 'mobile',
Cli = 'cli',
}
export enum SettingStorage {
Database = 1,
File = 2,
}
// Redefine a simplified interface to mask internal details
// and to remove function calls as they would have to be async.
export interface SettingItem {
value: any;
type: SettingItemType;
/**
* Currently only used to display a file or directory selector. Always set
* `type` to `SettingItemType.String` when using this property.
*/
subType?: SettingItemSubType;
label: string;
description?: string;
/**
* A public setting will appear in the Configuration screen and will be
* modifiable by the user. A private setting however will not appear there,
* and can only be changed programmatically. You may use this to store some
* values that you do not want to directly expose.
*/
public: boolean;
/**
* You would usually set this to a section you would have created
* specifically for the plugin.
*/
section?: string;
/**
* To create a setting with multiple options, set this property to `true`.
* That setting will render as a dropdown list in the configuration screen.
*/
isEnum?: boolean;
/**
* This property is required when `isEnum` is `true`. In which case, it
* should contain a map of value => label.
*/
options?: Record<any, any>;
/**
* Reserved property. Not used at the moment.
*/
appTypes?: AppType[];
/**
* Set this to `true` to store secure data, such as passwords. Any such
* setting will be stored in the system keychain if one is available.
*/
secure?: boolean;
/**
* An advanced setting will be moved under the "Advanced" button in the
* config screen.
*/
advanced?: boolean;
/**
* Set the min, max and step values if you want to restrict an int setting
* to a particular range.
*/
minimum?: number;
maximum?: number;
step?: number;
/**
* Either store the setting in the database or in settings.json. Defaults to database.
*/
storage?: SettingStorage;
}
export interface SettingSection {
label: string;
iconName?: string;
description?: string;
name?: string;
}
// =================================================================
// Data API types
// =================================================================
/**
* An array of at least one element and at most three elements.
*
* - **[0]**: Resource name (eg. "notes", "folders", "tags", etc.)
* - **[1]**: (Optional) Resource ID.
* - **[2]**: (Optional) Resource link.
*/
export type Path = string[];
// =================================================================
// Content Script types
// =================================================================
export type PostMessageHandler = (message: any)=> Promise<any>;
/**
* When a content script is initialised, it receives a `context` object.
*/
export interface ContentScriptContext {
/**
* The plugin ID that registered this content script
*/
pluginId: string;
/**
* The content script ID, which may be necessary to post messages
*/
contentScriptId: string;
/**
* Can be used by CodeMirror content scripts to post a message to the plugin
*/
postMessage: PostMessageHandler;
}
export interface ContentScriptModuleLoadedEvent {
userData?: any;
}
export interface ContentScriptModule {
onLoaded?: (event: ContentScriptModuleLoadedEvent)=> void;
plugin: ()=> any;
assets?: ()=> void;
}
export interface MarkdownItContentScriptModule extends Omit<ContentScriptModule, 'plugin'> {
plugin: (markdownIt: any, options: any)=> any;
}
type EditorCommandCallback = (...args: any[])=> any;
export interface CodeMirrorControl {
/** Points to a CodeMirror 6 EditorView instance. */
editor: any;
cm6: any;
/** `extension` should be a [CodeMirror 6 extension](https://codemirror.net/docs/ref/#state.Extension). */
addExtension(extension: any|any[]): void;
supportsCommand(name: string): boolean;
execCommand(name: string, ...args: any[]): any;
registerCommand(name: string, callback: EditorCommandCallback): void;
joplinExtensions: {
/**
* Returns a [CodeMirror 6 extension](https://codemirror.net/docs/ref/#state.Extension) that
* registers the given [CompletionSource](https://codemirror.net/docs/ref/#autocomplete.CompletionSource).
*
* Use this extension rather than the built-in CodeMirror [`autocompletion`](https://codemirror.net/docs/ref/#autocomplete.autocompletion)
* if you don't want to use [langaugeData-based autocompletion](https://codemirror.net/docs/ref/#autocomplete.autocompletion^config.override).
*
* Using `autocompletion({ override: [ ... ]})` causes errors when done by multiple plugins.
*/
completionSource(completionSource: any): any;
/**
* Creates an extension that enables or disables [`languageData`-based autocompletion](https://codemirror.net/docs/ref/#autocomplete.autocompletion^config.override).
*/
enableLanguageDataAutocomplete: { of: (enabled: boolean)=> any };
};
}
export interface MarkdownEditorContentScriptModule extends Omit<ContentScriptModule, 'plugin'> {
plugin: (editorControl: CodeMirrorControl)=> void;
}
export enum ContentScriptType {
/**
* Registers a new Markdown-It plugin, which should follow the template
* below.
*
* ```javascript
* module.exports = {
* default: function(context) {
* return {
* plugin: function(markdownIt, pluginOptions) {
* // ...
* },
* assets: {
* // ...
* },
* }
* }
* }
* ```
*
* See [the
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/content_script)
* for a simple Markdown-it plugin example.
*
* ## Exported members
*
* - The `context` argument is currently unused but could be used later on
* to provide access to your own plugin so that the content script and
* plugin can communicate.
*
* - The **required** `plugin` key is the actual Markdown-It plugin - check
* the [official doc](https://github.com/markdown-it/markdown-it) for more
* information.
*
* - Using the **optional** `assets` key you may specify assets such as JS
* or CSS that should be loaded in the rendered HTML document. Check for
* example the Joplin [Mermaid
* plugin](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml/rules/mermaid.ts)
* to see how the data should be structured.
*
* ## Getting the settings from the renderer
*
* You can access your plugin settings from the renderer by calling
* `pluginOptions.settingValue("your-setting-key')`.
*
* ## Posting messages from the content script to your plugin
*
* The application provides the following function to allow executing
* commands from the rendered HTML code:
*
* ```javascript
* const response = await webviewApi.postMessage(contentScriptId, message);
* ```
*
* - `contentScriptId` is the ID you've defined when you registered the
* content script. You can retrieve it from the
* {@link ContentScriptContext | context}.
* - `message` can be any basic JavaScript type (number, string, plain
* object), but it cannot be a function or class instance.
*
* When you post a message, the plugin can send back a `response` thus
* allowing two-way communication:
*
* ```javascript
* await joplin.contentScripts.onMessage(contentScriptId, (message) => {
* // Process message
* return response; // Can be any object, string or number
* });
* ```
*
* See {@link JoplinContentScripts.onMessage} for more details, as well as
* the [postMessage
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/post_messages).
*
* ## Registering an existing Markdown-it plugin
*
* To include a regular Markdown-It plugin, that doesn't make use of any
* Joplin-specific features, you would simply create a file such as this:
*
* ```javascript
* module.exports = {
* default: function(context) {
* return {
* plugin: require('markdown-it-toc-done-right');
* }
* }
* }
* ```
*/
MarkdownItPlugin = 'markdownItPlugin',
/**
* Registers a new CodeMirror plugin, which should follow the template
* below.
*
* ```javascript
* module.exports = {
* default: function(context) {
* return {
* plugin: function(CodeMirror) {
* // ...
* },
* codeMirrorResources: [],
* codeMirrorOptions: {
* // ...
* },
* assets: {
* // ...
* },
* }
* }
* }
* ```
*
* - The `context` argument is currently unused but could be used later on
* to provide access to your own plugin so that the content script and
* plugin can communicate.
*
* - The `plugin` key is your CodeMirror plugin. This is where you can
* register new commands with CodeMirror or interact with the CodeMirror
* instance as needed.
*
* - The `codeMirrorResources` key is an array of CodeMirror resources that
* will be loaded and attached to the CodeMirror module. These are made up
* of addons, keymaps, and modes. For example, for a plugin that want's to
* enable clojure highlighting in code blocks. `codeMirrorResources` would
* be set to `['mode/clojure/clojure']`.
*
* - The `codeMirrorOptions` key contains all the
* [CodeMirror](https://codemirror.net/doc/manual.html#config) options
* that will be set or changed by this plugin. New options can alse be
* declared via
* [`CodeMirror.defineOption`](https://codemirror.net/doc/manual.html#defineOption),
* and then have their value set here. For example, a plugin that enables
* line numbers would set `codeMirrorOptions` to `{'lineNumbers': true}`.
*
* - Using the **optional** `assets` key you may specify **only** CSS assets
* that should be loaded in the rendered HTML document. Check for example
* the Joplin [Mermaid
* plugin](https://github.com/laurent22/joplin/blob/dev/packages/renderer/MdToHtml/rules/mermaid.ts)
* to see how the data should be structured.
*
* One of the `plugin`, `codeMirrorResources`, or `codeMirrorOptions` keys
* must be provided for the plugin to be valid. Having multiple or all
* provided is also okay.
*
* See also the [demo
* plugin](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/codemirror_content_script)
* for an example of all these keys being used in one plugin.
*
* ## Posting messages from the content script to your plugin
*
* In order to post messages to the plugin, you can use the postMessage
* function passed to the {@link ContentScriptContext | context}.
*
* ```javascript
* const response = await context.postMessage('messageFromCodeMirrorContentScript');
* ```
*
* When you post a message, the plugin can send back a `response` thus
* allowing two-way communication:
*
* ```javascript
* await joplin.contentScripts.onMessage(contentScriptId, (message) => {
* // Process message
* return response; // Can be any object, string or number
* });
* ```
*
* See {@link JoplinContentScripts.onMessage} for more details, as well as
* the [postMessage
* demo](https://github.com/laurent22/joplin/tree/dev/packages/app-cli/tests/support/plugins/post_messages).
*
*/
CodeMirrorPlugin = 'codeMirrorPlugin',
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
{
"name": "joplin-plugin-worker-example",
"version": "1.0.0",
"scripts": {
"dist": "webpack --env joplin-plugin-config=buildMain && webpack --env joplin-plugin-config=buildExtraScripts && npm run copyAssets && webpack --env joplin-plugin-config=createArchive",
"copyAssets": "node tools/copyAssets.js",
"prepare": "npm run dist",
"updateVersion": "webpack --env joplin-plugin-config=updateVersion",
"update": "npm install -g generator-joplin && yo joplin --node-package-manager npm --update --force"
},
"license": "MIT",
"keywords": [
"joplin-plugin"
],
"files": [
"publish"
],
"devDependencies": {
"@types/node": "^18.7.13",
"chalk": "^4.1.0",
"copy-webpack-plugin": "^11.0.0",
"fs-extra": "^10.1.0",
"glob": "^8.0.3",
"tar": "^6.1.11",
"ts-loader": "^9.3.1",
"typescript": "^4.8.2",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"overrides": {
"@xenova/transformers": {
"sharp": "0.33.4"
}
},
"dependencies": {
"@xenova/transformers": "^2.17.2"
}
}

View File

@@ -0,0 +1,6 @@
{
"extraScripts": [ "worker.ts" ],
"webpackOverrides": {
"target": "web"
}
}

View File

@@ -0,0 +1,39 @@
import joplin from 'api';
import { ToolbarButtonLocation } from 'api/types';
joplin.plugins.register({
onStart: async function() {
const worker = new Worker(`${await joplin.plugins.installationDir()}/worker.js`);
worker.onmessage = event => {
if ('response' in event.data) {
alert(
JSON.stringify(event.data.response)
);
}
};
joplin.commands.register({
name: 'classifySelection',
label: 'Run sentiment analysis on selected text',
iconName: 'fas fa-robot',
execute: async () => {
const selectedText = await joplin.commands.execute('selectedText');
if (!selectedText) {
alert('No text selected!');
return;
}
worker.postMessage({
type: 'classify',
text: selectedText,
});
},
});
await joplin.views.toolbarButtons.create(
'classifySelectionButton',
'classifySelection',
ToolbarButtonLocation.EditorToolbar,
);
},
});

View File

@@ -0,0 +1,15 @@
{
"manifest_version": 1,
"id": "com.example.worker",
"app_min_version": "3.0",
"version": "1.0.0",
"name": "Web Worker",
"description": "Shows how to load a web worker from a plugin.",
"author": "",
"homepage_url": "",
"repository_url": "",
"keywords": [],
"categories": [],
"screenshots": [],
"icons": {}
}

View File

@@ -0,0 +1,30 @@
// @ts-ignore -- no types available for transformers.js
import { pipeline, env } from '@xenova/transformers';
// Use code similar to the following to use local models
// See https://github.com/xenova/transformers.js?tab=readme-ov-file#settings
// env.localModelPath = './models/';
// env.allowRemoteModels = false;
// Don't fetch ONNX WASM from the internet (see tools/copyModels.js).
env.backends.onnx.wasm.wasmPaths = './onnx-dist/';
let pipe: (text: string)=>Promise<unknown>;
const classify = async (text: string) => {
pipe ??= await pipeline('sentiment-analysis');
const classification = await pipe(text);
console.debug('classified', text, 'as', classification);
return classification;
};
self.addEventListener('message', async (event) => {
console.debug('got message', event.data);
if (event.data.type === 'classify') {
postMessage({
response: await classify(event.data.text),
});
}
});

View File

@@ -0,0 +1,12 @@
const fs = require('fs-extra');
const path = require('path');
// Copy WASM files
// See https://github.com/xenova/transformers.js/issues/367#issuecomment-1777743129
const onnxDistFiles = path.dirname(require.resolve('onnxruntime-web'));
const baseDir = path.dirname(__dirname);
fs.copy(onnxDistFiles, path.join(baseDir, 'dist', 'onnx-dist'));
// Predownload model files -- TODO.
// See https://huggingface.co/docs/transformers.js/custom_usage#use-custom-models

View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"outDir": "./dist/",
"module": "commonjs",
"target": "es2015",
"jsx": "react",
"allowJs": true,
"baseUrl": "."
}
}

View File

@@ -0,0 +1,403 @@
// -----------------------------------------------------------------------------
// This file is used to build the plugin file (.jpl) and plugin info (.json). It
// is recommended not to edit this file as it would be overwritten when updating
// the plugin framework. If you do make some changes, consider using an external
// JS file and requiring it here to minimize the changes. That way when you
// update, you can easily restore the functionality you've added.
// -----------------------------------------------------------------------------
/* eslint-disable no-console */
const path = require('path');
const crypto = require('crypto');
const fs = require('fs-extra');
const chalk = require('chalk');
const CopyPlugin = require('copy-webpack-plugin');
const tar = require('tar');
const glob = require('glob');
const execSync = require('child_process').execSync;
// AUTO-GENERATED by updateCategories
const allPossibleCategories = [{ 'name': 'appearance' }, { 'name': 'developer tools' }, { 'name': 'productivity' }, { 'name': 'themes' }, { 'name': 'integrations' }, { 'name': 'viewer' }, { 'name': 'search' }, { 'name': 'tags' }, { 'name': 'editor' }, { 'name': 'files' }, { 'name': 'personal knowledge management' }];
// AUTO-GENERATED by updateCategories
const rootDir = path.resolve(__dirname);
const userConfigFilename = './plugin.config.json';
const userConfigPath = path.resolve(rootDir, userConfigFilename);
const distDir = path.resolve(rootDir, 'dist');
const srcDir = path.resolve(rootDir, 'src');
const publishDir = path.resolve(rootDir, 'publish');
const userConfig = { extraScripts: [], ...(fs.pathExistsSync(userConfigPath) ? require(userConfigFilename) : {}) };
const manifestPath = `${srcDir}/manifest.json`;
const packageJsonPath = `${rootDir}/package.json`;
const allPossibleScreenshotsType = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
const manifest = readManifest(manifestPath);
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
const { builtinModules } = require('node:module');
// Webpack5 doesn't polyfill by default and displays a warning when attempting to require() built-in
// node modules. Set these to false to prevent Webpack from warning about not polyfilling these modules.
// We don't need to polyfill because the plugins run in Electron's Node environment.
const moduleFallback = {};
for (const moduleName of builtinModules) {
moduleFallback[moduleName] = false;
}
const getPackageJson = () => {
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
};
function validatePackageJson() {
const content = getPackageJson();
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
}
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
}
if (content.scripts && content.scripts.postinstall) {
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
}
}
function fileSha256(filePath) {
const content = fs.readFileSync(filePath);
return crypto.createHash('sha256').update(content).digest('hex');
}
function currentGitInfo() {
try {
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
if (branch === 'HEAD') branch = 'master';
return `${branch}:${commit}`;
} catch (error) {
const messages = error.message ? error.message.split('\n') : [''];
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
return '';
}
}
function validateCategories(categories) {
if (!categories) return null;
if ((categories.length !== new Set(categories).size)) throw new Error('Repeated categories are not allowed');
// eslint-disable-next-line github/array-foreach -- Old code before rule was applied
categories.forEach(category => {
if (!allPossibleCategories.map(category => { return category.name; }).includes(category)) throw new Error(`${category} is not a valid category. Please make sure that the category name is lowercase. Valid categories are: \n${allPossibleCategories.map(category => { return category.name; })}\n`);
});
}
function validateScreenshots(screenshots) {
if (!screenshots) return null;
for (const screenshot of screenshots) {
if (!screenshot.src) throw new Error('You must specify a src for each screenshot');
// Avoid attempting to download and verify URL screenshots.
if (screenshot.src.startsWith('https://') || screenshot.src.startsWith('http://')) {
continue;
}
const screenshotType = screenshot.src.split('.').pop();
if (!allPossibleScreenshotsType.includes(screenshotType)) throw new Error(`${screenshotType} is not a valid screenshot type. Valid types are: \n${allPossibleScreenshotsType}\n`);
const screenshotPath = path.resolve(rootDir, screenshot.src);
// Max file size is 1MB
const fileMaxSize = 1024;
const fileSize = fs.statSync(screenshotPath).size / 1024;
if (fileSize > fileMaxSize) throw new Error(`Max screenshot file size is ${fileMaxSize}KB. ${screenshotPath} is ${fileSize}KB`);
}
}
function readManifest(manifestPath) {
const content = fs.readFileSync(manifestPath, 'utf8');
const output = JSON.parse(content);
if (!output.id) throw new Error(`Manifest plugin ID is not set in ${manifestPath}`);
validateCategories(output.categories);
validateScreenshots(output.screenshots);
return output;
}
function createPluginArchive(sourceDir, destPath) {
const distFiles = glob.sync(`${sourceDir}/**/*`, { nodir: true, windowsPathsNoEscape: true })
.map(f => f.substr(sourceDir.length + 1));
if (!distFiles.length) throw new Error('Plugin archive was not created because the "dist" directory is empty');
fs.removeSync(destPath);
tar.create(
{
strict: true,
portable: true,
file: destPath,
cwd: sourceDir,
sync: true,
},
distFiles,
);
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
}
const writeManifest = (manifestPath, content) => {
fs.writeFileSync(manifestPath, JSON.stringify(content, null, '\t'), 'utf8');
};
function createPluginInfo(manifestPath, destPath, jplFilePath) {
const contentText = fs.readFileSync(manifestPath, 'utf8');
const content = JSON.parse(contentText);
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
content._publish_commit = currentGitInfo();
writeManifest(destPath, content);
}
function onBuildCompleted() {
try {
fs.removeSync(path.resolve(publishDir, 'index.js'));
createPluginArchive(distDir, pluginArchiveFilePath);
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
validatePackageJson();
} catch (error) {
console.error(chalk.red(error.message));
}
}
const baseConfig = {
mode: 'production',
target: 'node',
stats: 'errors-only',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
...userConfig.webpackOverrides,
};
const pluginConfig = { ...baseConfig, entry: './src/index.ts',
resolve: {
alias: {
api: path.resolve(__dirname, 'api'),
},
fallback: moduleFallback,
// JSON files can also be required from scripts so we include this.
// https://github.com/joplin/plugin-bibtex/pull/2
extensions: ['.js', '.tsx', '.ts', '.json'],
},
output: {
filename: 'index.js',
path: distDir,
},
plugins: [
new CopyPlugin({
patterns: [
{
from: '**/*',
context: path.resolve(__dirname, 'src'),
to: path.resolve(__dirname, 'dist'),
globOptions: {
ignore: [
// All TypeScript files are compiled to JS and
// already copied into /dist so we don't copy them.
'**/*.ts',
'**/*.tsx',
],
},
},
],
}),
] };
// These libraries can be included with require(...) or
// joplin.require(...) from content scripts.
const externalContentScriptLibraries = [
'@codemirror/view',
'@codemirror/state',
'@codemirror/search',
'@codemirror/language',
'@codemirror/autocomplete',
'@codemirror/commands',
'@codemirror/highlight',
'@codemirror/lint',
'@codemirror/lang-html',
'@codemirror/lang-markdown',
'@codemirror/language-data',
'@lezer/common',
'@lezer/markdown',
'@lezer/highlight',
];
const extraScriptExternals = {};
for (const library of externalContentScriptLibraries) {
extraScriptExternals[library] = { commonjs: library };
}
const extraScriptConfig = {
...baseConfig,
resolve: {
alias: {
api: path.resolve(__dirname, 'api'),
},
fallback: moduleFallback,
extensions: ['.js', '.tsx', '.ts', '.json'],
},
// We support requiring @codemirror/... libraries through require('@codemirror/...')
externalsType: 'commonjs',
externals: extraScriptExternals,
};
const createArchiveConfig = {
stats: 'errors-only',
entry: './dist/index.js',
resolve: {
fallback: moduleFallback,
},
output: {
filename: 'index.js',
path: publishDir,
},
plugins: [{
apply(compiler) {
compiler.hooks.done.tap('archiveOnBuildListener', onBuildCompleted);
},
}],
};
function resolveExtraScriptPath(name) {
const relativePath = `./src/${name}`;
const fullPath = path.resolve(`${rootDir}/${relativePath}`);
if (!fs.pathExistsSync(fullPath)) throw new Error(`Could not find extra script: "${name}" at "${fullPath}"`);
const s = name.split('.');
s.pop();
const nameNoExt = s.join('.');
return {
entry: relativePath,
output: {
filename: `${nameNoExt}.js`,
path: distDir,
library: 'default',
libraryTarget: 'commonjs',
libraryExport: 'default',
},
};
}
function buildExtraScriptConfigs(userConfig) {
if (!userConfig.extraScripts.length) return [];
const output = [];
for (const scriptName of userConfig.extraScripts) {
const scriptPaths = resolveExtraScriptPath(scriptName);
output.push({ ...extraScriptConfig, entry: scriptPaths.entry,
output: scriptPaths.output });
}
return output;
}
const increaseVersion = version => {
try {
const s = version.split('.');
const d = Number(s[s.length - 1]) + 1;
s[s.length - 1] = `${d}`;
return s.join('.');
} catch (error) {
error.message = `Could not parse version number: ${version}: ${error.message}`;
throw error;
}
};
const updateVersion = () => {
const packageJson = getPackageJson();
packageJson.version = increaseVersion(packageJson.version);
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8');
const manifest = readManifest(manifestPath);
manifest.version = increaseVersion(manifest.version);
writeManifest(manifestPath, manifest);
if (packageJson.version !== manifest.version) {
console.warn(chalk.yellow(`Version numbers have been updated but they do not match: package.json (${packageJson.version}), manifest.json (${manifest.version}). Set them to the required values to get them in sync.`));
}
};
function main(environ) {
const configName = environ['joplin-plugin-config'];
if (!configName) throw new Error('A config file must be specified via the --joplin-plugin-config flag');
// Webpack configurations run in parallel, while we need them to run in
// sequence, and to do that it seems the only way is to run webpack multiple
// times, with different config each time.
const configs = {
// Builds the main src/index.ts and copy the extra content from /src to
// /dist including scripts, CSS and any other asset.
buildMain: [pluginConfig],
// Builds the extra scripts as defined in plugin.config.json. When doing
// so, some JavaScript files that were copied in the previous might be
// overwritten here by the compiled version. This is by design. The
// result is that JS files that don't need compilation, are simply
// copied to /dist, while those that do need it are correctly compiled.
buildExtraScripts: buildExtraScriptConfigs(userConfig),
// Ths config is for creating the .jpl, which is done via the plugin, so
// it doesn't actually need an entry and output, however webpack won't
// run without this. So we give it an entry that we know is going to
// exist and output in the publish dir. Then the plugin will delete this
// temporary file before packaging the plugin.
createArchive: [createArchiveConfig],
};
// If we are running the first config step, we clean up and create the build
// directories.
if (configName === 'buildMain') {
fs.removeSync(distDir);
fs.removeSync(publishDir);
fs.mkdirpSync(publishDir);
}
if (configName === 'updateVersion') {
updateVersion();
return [];
}
return configs[configName];
}
module.exports = (env) => {
let exportedConfigs = [];
try {
exportedConfigs = main(env);
} catch (error) {
console.error(error.message);
process.exit(1);
}
if (!exportedConfigs.length) {
// Nothing to do - for example where there are no external scripts to
// compile.
process.exit(0);
}
return exportedConfigs;
};

View File

@@ -0,0 +1,198 @@
%PDF-1.3
%����
1 0 obj
<<
/Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R
>>
endobj
2 0 obj
<<
/Type /Outlines
/Count 0
>>
endobj
3 0 obj
<<
/Type /Pages
/Count 2
/Kids [ 4 0 R 6 0 R ]
>>
endobj
4 0 obj
<<
/Type /Page
/Parent 3 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 8 0 R
>>
/MediaBox [0 0 612.0000 792.0000]
/Contents 5 0 R
>>
endobj
5 0 obj
<< /Length 1074 >>
stream
2 J
BT
0 0 0 rg
/F1 0027 Tf
57.3750 722.2800 Td
( A Simple PDF File ) Tj
ET
BT
/F1 0010 Tf
69.2500 688.6080 Td
( This is a small demonstration .pdf file - ) Tj
ET
BT
/F1 0010 Tf
69.2500 664.7040 Td
( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 652.7520 Td
( text. And more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 628.8480 Td
( And more text. And more text. And more text. And more text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 616.8960 Td
( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj
ET
BT
/F1 0010 Tf
69.2500 604.9440 Td
( more text. And more text. And more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 592.9920 Td
( And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 569.0880 Td
( And more text. And more text. And more text. And more text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 557.1360 Td
( text. And more text. And more text. Even more. Continued on page 2 ...) Tj
ET
endstream
endobj
6 0 obj
<<
/Type /Page
/Parent 3 0 R
/Resources <<
/Font <<
/F1 9 0 R
>>
/ProcSet 8 0 R
>>
/MediaBox [0 0 612.0000 792.0000]
/Contents 7 0 R
>>
endobj
7 0 obj
<< /Length 676 >>
stream
2 J
BT
0 0 0 rg
/F1 0027 Tf
57.3750 722.2800 Td
( Simple PDF File 2 ) Tj
ET
BT
/F1 0010 Tf
69.2500 688.6080 Td
( ...continued from page 1. Yet more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 676.6560 Td
( And more text. And more text. And more text. And more text. And more ) Tj
ET
BT
/F1 0010 Tf
69.2500 664.7040 Td
( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj
ET
BT
/F1 0010 Tf
69.2500 652.7520 Td
( paint dry. And more text. And more text. And more text. And more text. ) Tj
ET
BT
/F1 0010 Tf
69.2500 640.8000 Td
( Boring. More, a little more text. The end, and just as well. ) Tj
ET
endstream
endobj
8 0 obj
[/PDF /Text]
endobj
9 0 obj
<<
/Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
10 0 obj
<<
/Creator (Rave \(http://www.nevrona.com/rave\))
/Producer (Nevrona Designs)
/CreationDate (D:20060301072826)
>>
endobj
xref
0 11
0000000000 65535 f
0000000019 00000 n
0000000093 00000 n
0000000147 00000 n
0000000222 00000 n
0000000390 00000 n
0000001522 00000 n
0000001690 00000 n
0000002423 00000 n
0000002456 00000 n
0000002574 00000 n
trailer
<<
/Size 11
/Root 1 0 R
/Info 10 0 R
>>
startxref
2714
%%EOF

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Joplin Web Clipper [DEV]",
"version": "3.0.0",
"version": "3.2.0",
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
"homepage_url": "https://joplinapp.org",
"content_security_policy": {
@@ -54,8 +54,9 @@
}
},
"background": {
"scripts": ["service_worker.mjs"],
"scripts": [
"service_worker.mjs"
],
"service_worker": "service_worker.mjs",
"type": "module"
},

View File

@@ -18,6 +18,7 @@
"@babel/preset-react": "7.23.3",
"babel-loader": "9.1.3",
"css-loader": "6.8.1",
"fs-extra": "11.2.0",
"html-webpack-plugin": "5.6.0",
"react-redux": "9.0.4",
"redux": "5.0.1",
@@ -2980,6 +2981,20 @@
"flat": "cli.js"
}
},
"node_modules/fs-extra": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=14.14"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -3279,6 +3294,18 @@
"node": ">=6"
}
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -4217,6 +4244,15 @@
"node": ">=4"
}
},
"node_modules/universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true,
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
@@ -6579,6 +6615,17 @@
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
"dev": true
},
"fs-extra": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -6780,6 +6827,16 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^2.0.0"
}
},
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -7456,6 +7513,12 @@
"integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
"dev": true
},
"universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true
},
"update-browserslist-db": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",

View File

@@ -18,6 +18,7 @@
"@babel/preset-react": "7.23.3",
"babel-loader": "9.1.3",
"css-loader": "6.8.1",
"fs-extra": "11.2.0",
"html-webpack-plugin": "5.6.0",
"react-redux": "9.0.4",
"redux": "5.0.1",

View File

@@ -24,3 +24,4 @@ build/defaultPlugins/
build/7zip/7za
build/7zip/7za.exe
sentry.properties
downloads/

View File

@@ -1,9 +1,11 @@
import Logger from '@joplin/utils/Logger';
import Logger, { LoggerWrapper } from '@joplin/utils/Logger';
import { PluginMessage } from './services/plugins/PluginRunner';
import shim from '@joplin/lib/shim';
import AutoUpdaterService, { defaultUpdateInterval, initialUpdateStartup } from './services/autoUpdater/AutoUpdaterService';
import type ShimType from '@joplin/lib/shim';
const shim: typeof ShimType = require('@joplin/lib/shim').default;
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';
import { BrowserWindow, Tray, screen } from 'electron';
import { BrowserWindow, Tray, WebContents, screen } from 'electron';
import bridge from './bridge';
const url = require('url');
const path = require('path');
@@ -13,7 +15,10 @@ const fs = require('fs-extra');
import { dialog, ipcMain } from 'electron';
import { _ } from '@joplin/lib/locale';
import restartInSafeModeFromMain from './utils/restartInSafeModeFromMain';
import handleCustomProtocols, { CustomProtocolHandler } from './utils/customProtocols/handleCustomProtocols';
import { clearTimeout, setTimeout } from 'timers';
import { resolve } from 'path';
import { defaultWindowId } from '@joplin/lib/reducer';
interface RendererProcessQuitReply {
canClose: boolean;
@@ -24,22 +29,34 @@ interface PluginWindows {
[key: string]: any;
}
export default class ElectronAppWrapper {
type SecondaryWindowId = string;
interface SecondaryWindowData {
electronId: number;
}
export default class ElectronAppWrapper {
private logger_: Logger = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private electronApp_: any;
private env_: string;
private isDebugMode_: boolean;
private profilePath_: string;
private win_: BrowserWindow = null;
private mainWindowHidden_ = true;
private pluginWindows_: PluginWindows = {};
private secondaryWindows_: Map<SecondaryWindowId, SecondaryWindowData> = new Map();
private willQuitApp_ = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private tray_: any = null;
private buildDir_: string = null;
private rendererProcessQuitReply_: RendererProcessQuitReply = null;
private pluginWindows_: PluginWindows = {};
private initialCallbackUrl_: string = null;
private updaterService_: AutoUpdaterService = null;
private customProtocolHandler_: CustomProtocolHandler = null;
private updatePollInterval_: ReturnType<typeof setTimeout>|null = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public constructor(electronApp: any, env: string, profilePath: string|null, isDebugMode: boolean, initialCallbackUrl: string) {
@@ -62,10 +79,26 @@ export default class ElectronAppWrapper {
return this.logger_;
}
public window() {
public mainWindow() {
return this.win_;
}
public activeWindow() {
return BrowserWindow.getFocusedWindow() ?? this.win_;
}
public windowById(joplinId: string) {
if (joplinId === defaultWindowId) {
return this.mainWindow();
}
const windowData = this.secondaryWindows_.get(joplinId);
if (windowData !== undefined) {
return BrowserWindow.fromId(windowData.electronId);
}
return null;
}
public env() {
return this.env_;
}
@@ -204,6 +237,15 @@ export default class ElectronAppWrapper {
}
});
this.mainWindowHidden_ = !windowOptions.show;
this.win_.on('hide', () => {
this.mainWindowHidden_ = true;
});
this.win_.on('show', () => {
this.mainWindowHidden_ = false;
});
void this.win_.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
@@ -226,14 +268,40 @@ export default class ElectronAppWrapper {
}, 3000);
}
// will-frame-navigate is fired by clicking on a link within the BrowserWindow.
this.win_.webContents.on('will-frame-navigate', event => {
// If the link changes the URL of the browser window,
if (event.isMainFrame) {
event.preventDefault();
void bridge().openExternal(event.url);
}
});
const addWindowEventHandlers = (webContents: WebContents) => {
// will-frame-navigate is fired by clicking on a link within the BrowserWindow.
webContents.on('will-frame-navigate', event => {
// If the link changes the URL of the browser window,
if (event.isMainFrame) {
event.preventDefault();
void bridge().openExternal(event.url);
}
});
// Override calls to window.open and links with target="_blank": Open most in a browser instead
// of Electron:
webContents.setWindowOpenHandler((event) => {
if (event.url === 'about:blank') {
// Script-controlled pages: Used for opening notes in new windows
return {
action: 'allow',
overrideBrowserWindowOptions: {
webPreferences: {
preload: resolve(__dirname, './utils/window/secondaryWindowPreload.js'),
},
},
};
} else if (event.url.match(/^https?:\/\//)) {
void bridge().openExternal(event.url);
}
return { action: 'deny' };
});
webContents.on('did-create-window', (event) => {
addWindowEventHandlers(event.webContents);
});
};
addWindowEventHandlers(this.win_.webContents);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
this.win_.on('close', (event: any) => {
@@ -254,7 +322,8 @@ export default class ElectronAppWrapper {
this.hide();
}
} else {
if (this.trayShown() && !this.willQuitApp_) {
const hasBackgroundWindows = this.secondaryWindows_.size > 0;
if ((hasBackgroundWindows || this.trayShown()) && !this.willQuitApp_) {
event.preventDefault();
this.win_.hide();
} else {
@@ -284,6 +353,23 @@ export default class ElectronAppWrapper {
}
});
ipcMain.on('secondary-window-added', (event, windowId: string) => {
const window = BrowserWindow.fromWebContents(event.sender);
const electronWindowId = window?.id;
this.secondaryWindows_.set(windowId, { electronId: electronWindowId });
window.once('close', () => {
this.secondaryWindows_.delete(windowId);
const allSecondaryWindowsClosed = this.secondaryWindows_.size === 0;
const mainWindowVisuallyClosed = this.mainWindowHidden_;
if (allSecondaryWindowsClosed && mainWindowVisuallyClosed && !this.trayShown()) {
// Gracefully quit the app if the user has closed all windows
this.win_.close();
}
});
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
ipcMain.on('asynchronous-message', (_event: any, message: string, args: any) => {
if (message === 'appCloseReply') {
@@ -322,6 +408,14 @@ export default class ElectronAppWrapper {
}
});
ipcMain.on('apply-update-now', () => {
this.updaterService_.updateApp();
});
ipcMain.on('check-for-updates', () => {
void this.updaterService_.checkForUpdates(true);
});
// Let us register listeners on the window, so we can update the state
// automatically (the listeners will be removed when the window is closed)
// and restore the maximized or full screen state
@@ -354,6 +448,7 @@ export default class ElectronAppWrapper {
}
public quit() {
this.stopPeriodicUpdateCheck();
this.electronApp_.quit();
}
@@ -406,11 +501,11 @@ export default class ElectronAppWrapper {
this.tray_.setContextMenu(contextMenu);
this.tray_.on('click', () => {
if (!this.window()) {
if (!this.mainWindow()) {
console.warn('The window object was not available during the click event from tray icon');
return;
}
this.window().show();
this.mainWindow().show();
});
} catch (error) {
console.error('Cannot create tray', error);
@@ -437,7 +532,7 @@ export default class ElectronAppWrapper {
// Someone tried to open a second instance - focus our window instead
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
this.electronApp_.on('second-instance', (_e: any, argv: string[]) => {
const win = this.window();
const win = this.mainWindow();
if (!win) return;
if (win.isMinimized()) win.restore();
win.show();
@@ -454,6 +549,40 @@ export default class ElectronAppWrapper {
return false;
}
public initializeCustomProtocolHandler(logger: LoggerWrapper) {
this.customProtocolHandler_ ??= handleCustomProtocols(logger);
}
// Electron's autoUpdater has to be init from the main process
public initializeAutoUpdaterService(logger: LoggerWrapper, devMode: boolean, includePreReleases: boolean) {
if (shim.isWindows() || shim.isMac()) {
if (!this.updaterService_) {
this.updaterService_ = new AutoUpdaterService(this.win_, logger, devMode, includePreReleases);
this.startPeriodicUpdateCheck();
}
}
}
private startPeriodicUpdateCheck = (updateInterval: number = defaultUpdateInterval): void => {
this.stopPeriodicUpdateCheck();
this.updatePollInterval_ = setInterval(() => {
void this.updaterService_.checkForUpdates(false);
}, updateInterval);
setTimeout(this.updaterService_.checkForUpdates, initialUpdateStartup);
};
private stopPeriodicUpdateCheck = (): void => {
if (this.updatePollInterval_) {
clearInterval(this.updatePollInterval_);
this.updatePollInterval_ = null;
this.updaterService_ = null;
}
};
public getCustomProtocolHandler() {
return this.customProtocolHandler_;
}
public async start() {
// Since we are doing other async things before creating the window, we might miss
// the "ready" event. So we use the function below to make sure that the app is ready.

View File

@@ -2,13 +2,14 @@ const fs = require('fs');
const path = require('path');
const os = require('os');
const sha512 = require('js-sha512');
const distDirName = 'dist';
const distPath = path.join(__dirname, distDirName);
const generateChecksumFile = () => {
if (os.platform() !== 'linux') {
return []; // SHA-512 is only for AppImage
return; // SHA-512 is only for AppImage
}
const distDirName = 'dist';
const distPath = path.join(__dirname, distDirName);
let appImageName = '';
const files = fs.readdirSync(distPath);
for (const key in files) {
@@ -27,7 +28,13 @@ const generateChecksumFile = () => {
const sha512FileName = `${appImageName}.sha512`;
const sha512FilePath = path.join(distPath, sha512FileName);
fs.writeFileSync(sha512FilePath, checksum);
return [sha512FilePath];
return sha512FilePath;
};
exports.default = generateChecksumFile;
const mainHook = () => {
const sha512FilePath = generateChecksumFile();
const outputFiles = [sha512FilePath].filter(item => item);
return outputFiles;
};
exports.default = mainHook;

View File

@@ -1,4 +1,4 @@
import { AppState } from './app.reducer';
import { AppState, createAppDefaultWindowState } from './app.reducer';
import appReducer, { createAppDefaultState } from './app.reducer';
describe('app.reducer', () => {
@@ -47,4 +47,28 @@ describe('app.reducer', () => {
]);
});
it('showing a dialog in one window should hide dialogs with the same ID in background windows', () => {
const state: AppState = {
...createAppDefaultState({}, {}),
backgroundWindows: {
testWindow: {
...createAppDefaultWindowState(),
windowId: 'testWindow',
visibleDialogs: {
testDialog: true,
},
},
},
};
const newState = appReducer(state, {
type: 'VISIBLE_DIALOGS_ADD',
name: 'testDialog',
});
expect(newState.backgroundWindows.testWindow.visibleDialogs).toEqual({});
expect(newState.visibleDialogs).toEqual({ testDialog: true });
});
});

View File

@@ -1,6 +1,6 @@
import produce from 'immer';
import Setting from '@joplin/lib/models/Setting';
import { defaultState, State } from '@joplin/lib/reducer';
import { defaultState, defaultWindowState, State, WindowState } from '@joplin/lib/reducer';
import iterateItems from './gui/ResizableLayout/utils/iterateItems';
import { LayoutItem } from './gui/ResizableLayout/utils/types';
import validateLayout from './gui/ResizableLayout/utils/validateLayout';
@@ -30,56 +30,89 @@ export interface EditorScrollPercents {
[noteId: string]: number;
}
export interface AppState extends State {
export interface VisibleDialogs {
[dialogKey: string]: boolean;
}
export interface AppWindowState extends WindowState {
noteVisiblePanes: string[];
editorCodeView: boolean;
visibleDialogs: VisibleDialogs;
dialogs: AppStateDialog[];
devToolsVisible: boolean;
}
interface BackgroundWindowStates {
[windowId: string]: AppWindowState;
}
export interface AppState extends State, AppWindowState {
backgroundWindows: BackgroundWindowStates;
route: AppStateRoute;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
navHistory: any[];
noteVisiblePanes: string[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
windowContentSize: any;
watchedNoteFiles: string[];
lastEditorScrollPercents: EditorScrollPercents;
devToolsVisible: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
visibleDialogs: any; // empty object if no dialog is visible. Otherwise contains the list of visible dialogs.
focusedField: string;
layoutMoveMode: boolean;
startupPluginsLoaded: boolean;
modalOverlayMessage: string|null;
// Extra reducer keys go here
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
watchedResources: any;
mainLayout: LayoutItem;
dialogs: AppStateDialog[];
isResettingLayout: boolean;
}
export const createAppDefaultWindowState = (): AppWindowState => {
return {
...defaultWindowState,
visibleDialogs: {},
dialogs: [],
noteVisiblePanes: ['editor', 'viewer'],
editorCodeView: true,
devToolsVisible: false,
};
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
export function createAppDefaultState(windowContentSize: any, resourceEditWatcherDefaultState: any): AppState {
return {
...defaultState,
...createAppDefaultWindowState(),
route: {
type: 'NAV_GO',
routeName: 'Main',
props: {},
},
navHistory: [],
noteVisiblePanes: ['editor', 'viewer'],
windowContentSize, // bridge().windowContentSize(),
watchedNoteFiles: [],
lastEditorScrollPercents: {},
devToolsVisible: false,
visibleDialogs: {}, // empty object if no dialog is visible. Otherwise contains the list of visible dialogs.
focusedField: null,
layoutMoveMode: false,
mainLayout: null,
startupPluginsLoaded: false,
dialogs: [],
isResettingLayout: false,
modalOverlayMessage: null,
...resourceEditWatcherDefaultState,
};
}
const hideBackgroundDialogsWithId = produce((state: AppState, id: string) => {
for (const windowId of Object.keys(state.backgroundWindows)) {
const win = state.backgroundWindows[windowId];
if (id in win.visibleDialogs) {
delete win.visibleDialogs[id];
}
}
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
export default function(state: AppState, action: any) {
let newState = state;
@@ -171,9 +204,17 @@ export default function(state: AppState, action: any) {
break;
case 'NOTE_VISIBLE_PANES_SET':
newState = {
...state,
noteVisiblePanes: action.panes,
};
break;
newState = { ...state };
newState.noteVisiblePanes = action.panes;
case 'EDITOR_CODE_VIEW_CHANGE':
newState = {
...state,
editorCodeView: action.value,
};
break;
case 'MAIN_LAYOUT_SET':
@@ -217,6 +258,14 @@ export default function(state: AppState, action: any) {
break;
case 'SHOW_MODAL_MESSAGE':
newState = { ...newState, modalOverlayMessage: action.message };
break;
case 'HIDE_MODAL_MESSAGE':
newState = { ...newState, modalOverlayMessage: null };
break;
case 'NOTE_FILE_WATCHER_ADD':
if (newState.watchedNoteFiles.indexOf(action.id) < 0) {
@@ -272,12 +321,14 @@ export default function(state: AppState, action: any) {
newState = { ...state };
newState.visibleDialogs = { ...newState.visibleDialogs };
newState.visibleDialogs[action.name] = true;
newState = hideBackgroundDialogsWithId(newState, action.name);
break;
case 'VISIBLE_DIALOGS_REMOVE':
newState = { ...state };
newState.visibleDialogs = { ...newState.visibleDialogs };
delete newState.visibleDialogs[action.name];
newState = hideBackgroundDialogsWithId(newState, action.name);
break;
case 'FOCUS_SET':

View File

@@ -5,7 +5,8 @@ import PluginService, { PluginSettings } from '@joplin/lib/services/plugins/Plug
import resourceEditWatcherReducer, { defaultState as resourceEditWatcherDefaultState } from '@joplin/lib/services/ResourceEditWatcher/reducer';
import PluginRunner from './services/plugins/PluginRunner';
import PlatformImplementation from './services/plugins/PlatformImplementation';
import shim from '@joplin/lib/shim';
import type ShimType from '@joplin/lib/shim';
const shim: typeof ShimType = require('@joplin/lib/shim').default;
import AlarmService from '@joplin/lib/services/AlarmService';
import AlarmServiceDriverNode from '@joplin/lib/services/AlarmServiceDriverNode';
import Logger, { TargetType } from '@joplin/utils/Logger';
@@ -33,8 +34,8 @@ const Menu = bridge().Menu;
const PluginManager = require('@joplin/lib/services/PluginManager');
import RevisionService from '@joplin/lib/services/RevisionService';
import MigrationService from '@joplin/lib/services/MigrationService';
import { loadCustomCss, injectCustomStyles } from '@joplin/lib/CssUtils';
import mainScreenCommands from './gui/MainScreen/commands/index';
import { loadCustomCss } from '@joplin/lib/CssUtils';
import mainScreenCommands from './gui/WindowCommandsAndDialogs/commands/index';
import noteEditorCommands from './gui/NoteEditor/commands/index';
import noteListCommands from './gui/NoteList/commands/index';
import noteListControlsCommands from './gui/NoteListControls/commands/index';
@@ -71,6 +72,7 @@ import OcrService from '@joplin/lib/services/ocr/OcrService';
import OcrDriverTesseract from '@joplin/lib/services/ocr/drivers/OcrDriverTesseract';
import SearchEngine from '@joplin/lib/services/search/SearchEngine';
import { PackageInfo } from '@joplin/lib/versionInfo';
import { CustomProtocolHandler } from './utils/customProtocols/handleCustomProtocols';
import { refreshFolders } from '@joplin/lib/folders-screen-utils';
const pluginClasses = [
@@ -88,6 +90,7 @@ class Application extends BaseApplication {
private checkAllPluginStartedIID_: any = null;
private initPluginServiceDone_ = false;
private ocrService_: OcrService;
private protocolHandler_: CustomProtocolHandler;
public constructor() {
super();
@@ -115,13 +118,29 @@ class Application extends BaseApplication {
}
}
private updateLanguage() {
setLocale(Setting.value('locale'));
// The bridge runs within the main process, with its own instance of locale.js
// so it needs to be set too here.
bridge().setLocale(Setting.value('locale'));
const htmlContainer = document.querySelector('html');
// HTML expects the lang attribute to be in BCP47 format, with a dash rather than
// an underscore:
const htmlLang = Setting.value('locale').replace(/_/g, '-');
htmlContainer.setAttribute('lang', htmlLang);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
protected async generalMiddleware(store: any, next: any, action: any) {
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'locale' || action.type === 'SETTING_UPDATE_ALL') {
setLocale(Setting.value('locale'));
// The bridge runs within the main process, with its own instance of locale.js
// so it needs to be set too here.
bridge().setLocale(Setting.value('locale'));
this.updateLanguage();
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'renderer.fileUrls' || action.type === 'SETTING_UPDATE_ALL') {
bridge().electronApp().getCustomProtocolHandler().setMediaAccessEnabled(
Setting.value('renderer.fileUrls'),
);
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'showTrayIcon' || action.type === 'SETTING_UPDATE_ALL') {
@@ -129,11 +148,7 @@ class Application extends BaseApplication {
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'ocr.enabled' || action.type === 'SETTING_UPDATE_ALL') {
this.setupOcrService();
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'style.editor.fontFamily' || action.type === 'SETTING_UPDATE_ALL') {
this.updateEditorFont();
void this.setupOcrService();
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'windowContentZoomFactor' || action.type === 'SETTING_UPDATE_ALL') {
@@ -167,6 +182,12 @@ class Application extends BaseApplication {
this.handleThemeAutoDetect();
}
if (action.type === 'PLUGIN_ADD') {
const plugin = PluginService.instance().pluginById(action.plugin.id);
this.protocolHandler_.allowReadAccessToDirectory(plugin.baseDir);
this.protocolHandler_.allowReadAccessToDirectory(plugin.dataDir);
}
return result;
}
@@ -193,7 +214,7 @@ class Application extends BaseApplication {
app.destroyTray();
} else {
const contextMenu = Menu.buildFromTemplate([
{ label: _('Open %s', app.electronApp().name), click: () => { app.window().show(); } },
{ label: _('Open %s', app.electronApp().name), click: () => { app.mainWindow().show(); } },
{ type: 'separator' },
{ label: _('Quit'), click: () => { void app.quit(); } },
]);
@@ -201,23 +222,6 @@ class Application extends BaseApplication {
}
}
public updateEditorFont() {
const fontFamilies = [];
if (Setting.value('style.editor.fontFamily')) fontFamilies.push(`"${Setting.value('style.editor.fontFamily')}"`);
fontFamilies.push('Avenir, Arial, sans-serif');
// The '*' and '!important' parts are necessary to make sure Russian text is displayed properly
// https://github.com/laurent22/joplin/issues/155
//
// Note: Be careful about the specificity here. Incorrect specificity can break monospaced fonts in tables.
const css = `.CodeMirror5 *, .cm-editor .cm-content { font-family: ${fontFamilies.join(', ')} !important; }`;
const styleTag = document.createElement('style');
styleTag.type = 'text/css';
styleTag.appendChild(document.createTextNode(css));
document.head.appendChild(styleTag);
}
public setupContextMenu() {
// bridge().setupContextMenu((misspelledWord: string, dictionarySuggestions: string[]) => {
// let output = SpellCheckerService.instance().contextMenuItems(misspelledWord, dictionarySuggestions);
@@ -353,16 +357,29 @@ class Application extends BaseApplication {
Setting.setValue('wasClosedSuccessfully', false);
}
private setupOcrService() {
private async setupOcrService() {
if (Setting.value('ocr.clearLanguageDataCache')) {
Setting.setValue('ocr.clearLanguageDataCache', false);
try {
await OcrDriverTesseract.clearLanguageDataCache();
} catch (error) {
this.logger().warn('OCR: Failed to clear language data cache.', error);
}
}
if (Setting.value('ocr.enabled')) {
if (!this.ocrService_) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const Tesseract = (window as any).Tesseract;
const driver = new OcrDriverTesseract(
{ createWorker: Tesseract.createWorker },
`${bridge().buildDir()}/tesseract.js/worker.min.js`,
`${bridge().buildDir()}/tesseract.js-core`,
{
workerPath: `${bridge().buildDir()}/tesseract.js/worker.min.js`,
corePath: `${bridge().buildDir()}/tesseract.js-core`,
languageDataPath: Setting.value('ocr.languageDataPath') || null,
},
);
this.ocrService_ = new OcrService(driver);
@@ -382,6 +399,33 @@ class Application extends BaseApplication {
eventManager.on(EventName.ResourceChange, handleResourceChange);
}
private setupAutoUpdaterService() {
if (Setting.value('featureFlag.autoUpdaterServiceEnabled')) {
bridge().electronApp().initializeAutoUpdaterService(
Logger.create('AutoUpdaterService'),
Setting.value('env') === 'dev',
Setting.value('autoUpdate.includePreReleases'),
);
}
}
private async setupCustomCss() {
const chromeCssPath = Setting.customCssFilePath(Setting.customCssFilenames.JOPLIN_APP);
if (await shim.fsDriver().exists(chromeCssPath)) {
this.store().dispatch({
// Main window custom CSS
type: 'CUSTOM_CHROME_CSS_ADD',
filePath: chromeCssPath,
});
}
this.store().dispatch({
// Markdown preview pane
type: 'CUSTOM_VIEWER_CSS_APPEND',
css: await loadCustomCss(Setting.customCssFilePath(Setting.customCssFilenames.RENDERED_MARKDOWN)),
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async start(argv: string[], startOptions: StartOptions = null): Promise<any> {
// If running inside a package, the command line, instead of being "node.exe <path> <flags>" is "joplin.exe <flags>" so
@@ -396,7 +440,7 @@ class Application extends BaseApplication {
if (Setting.value('sync.upgradeState') === Setting.SYNC_UPGRADE_STATE_MUST_DO) {
reg.logger().info('app.start: doing upgradeSyncTarget action');
bridge().window().show();
bridge().mainWindow().show();
return { action: 'upgradeSyncTarget' };
}
@@ -414,8 +458,7 @@ class Application extends BaseApplication {
syncDebugLog.info(`Profile dir: ${dir}`);
}
// Loads app-wide styles. (Markdown preview-specific styles loaded in app.js)
await injectCustomStyles('appStyles', Setting.customCssFilePath(Setting.customCssFilenames.JOPLIN_APP));
this.setupAutoUpdaterService();
AlarmService.setDriver(new AlarmServiceDriverNode({ appName: packageInfo.build.appId }));
AlarmService.setLogger(reg.logger());
@@ -427,6 +470,20 @@ class Application extends BaseApplication {
bridge().openDevTools();
}
bridge().electronApp().initializeCustomProtocolHandler(
Logger.create('handleCustomProtocols'),
);
this.protocolHandler_ = bridge().electronApp().getCustomProtocolHandler();
this.protocolHandler_.allowReadAccessToDirectory(__dirname); // App bundle directory
this.protocolHandler_.allowReadAccessToDirectory(Setting.value('cacheDir'));
this.protocolHandler_.allowReadAccessToDirectory(Setting.value('resourceDir'));
// this.protocolHandler_.allowReadAccessTo(Setting.value('tempDir'));
// For now, this doesn't seem necessary:
// this.protocolHandler_.allowReadAccessTo(Setting.value('profileDir'));
// If it is needed, note that they decrease the security of the protcol
// handler, and, as such, it may make sense to also limit permissions of
// allowed pages with a Content Security Policy.
PluginManager.instance().dispatch_ = this.dispatch.bind(this);
PluginManager.instance().setLogger(reg.logger());
PluginManager.instance().register(pluginClasses);
@@ -477,6 +534,8 @@ class Application extends BaseApplication {
items: tags,
});
await this.setupCustomCss();
// const masterKeys = await MasterKey.all();
// this.dispatch({
@@ -519,13 +578,6 @@ class Application extends BaseApplication {
ids: Setting.value('collapsedFolderIds'),
});
// Loads custom Markdown preview styles
const cssString = await loadCustomCss(Setting.customCssFilePath(Setting.customCssFilenames.RENDERED_MARKDOWN));
this.store().dispatch({
type: 'CUSTOM_CSS_APPEND',
css: cssString,
});
this.store().dispatch({
type: 'NOTE_DEVTOOLS_SET',
value: Setting.value('flagOpenDevTools'),
@@ -534,17 +586,19 @@ class Application extends BaseApplication {
// Note: Auto-update is a misnomer in the code.
// The code below only checks, if a new version is available.
// We only allow Windows and macOS users to automatically check for updates
if (shim.isWindows() || shim.isMac()) {
const runAutoUpdateCheck = () => {
if (Setting.value('autoUpdateEnabled')) {
void checkForUpdates(true, bridge().window(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') });
}
};
if (!Setting.value('featureFlag.autoUpdaterServiceEnabled')) {
if (shim.isWindows() || shim.isMac()) {
const runAutoUpdateCheck = () => {
if (Setting.value('autoUpdateEnabled')) {
void checkForUpdates(true, bridge().mainWindow(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') });
}
};
// Initial check on startup
shim.setTimeout(() => { runAutoUpdateCheck(); }, 5000);
// Then every x hours
shim.setInterval(() => { runAutoUpdateCheck(); }, 12 * 60 * 60 * 1000);
// Initial check on startup
shim.setTimeout(() => { runAutoUpdateCheck(); }, 5000);
// Then every x hours
shim.setInterval(() => { runAutoUpdateCheck(); }, 12 * 60 * 60 * 1000);
}
}
initializeUserFetcher();
@@ -557,9 +611,9 @@ class Application extends BaseApplication {
}, 1000 * 60 * 60);
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
bridge().window().hide();
bridge().mainWindow().hide();
} else {
bridge().window().show();
bridge().mainWindow().show();
}
void ShareService.instance().maintenance();
@@ -632,6 +686,15 @@ class Application extends BaseApplication {
Setting.setValue('linking.extraAllowedExtensions', newExtensions);
});
window.addEventListener('focus', () => {
const currentWindowId = this.store().getState().windowId;
this.dispatch({
type: 'WINDOW_FOCUS',
windowId: 'default',
lastWindowId: currentWindowId,
});
});
await this.initPluginService();
this.setupContextMenu();

View File

@@ -1,7 +1,7 @@
import ElectronAppWrapper from './ElectronAppWrapper';
import shim from '@joplin/lib/shim';
import { _, setLocale } from '@joplin/lib/locale';
import { BrowserWindow, nativeTheme, nativeImage, shell, dialog, MessageBoxSyncOptions } from 'electron';
import { BrowserWindow, nativeTheme, nativeImage, shell, dialog, MessageBoxSyncOptions, safeStorage } from 'electron';
import { dirname, toSystemSlashes } from '@joplin/lib/path-utils';
import { fileUriToPath } from '@joplin/utils/url';
import { urlDecode } from '@joplin/lib/string-utils';
@@ -14,6 +14,7 @@ import { extname, normalize } from 'path';
import isSafeToOpen from './utils/isSafeToOpen';
import { closeSync, openSync, readSync, statSync } from 'fs';
import { KB } from '@joplin/utils/bytes';
import { defaultWindowId } from '@joplin/lib/reducer';
interface LastSelectedPath {
file: string;
@@ -234,7 +235,7 @@ export class Bridge {
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
public setupContextMenu(_spellCheckerMenuItemsHandler: Function) {
require('electron-context-menu')({
allWindows: [this.window()],
allWindows: [this.mainWindow()],
electronApp: this.electronApp(),
@@ -259,8 +260,29 @@ export class Bridge {
});
}
public window() {
return this.electronWrapper_.window();
public mainWindow() {
return this.electronWrapper_.mainWindow();
}
public activeWindow() {
return this.electronWrapper_.activeWindow();
}
public windowById(id: string) {
return this.electronWrapper_.windowById(id);
}
// Switches to the window with the given ID, but only if that window was not the
// last focused window
public switchToWindow(windowId: string) {
const targetWindow = this.windowById(windowId);
if (this.activeWindow() !== this.windowById(windowId)) {
targetWindow.show();
}
}
public switchToMainWindow() {
this.switchToWindow(defaultWindowId);
}
public showItemInFolder(fullPath: string) {
@@ -272,36 +294,31 @@ export class Bridge {
return new BrowserWindow(options);
}
// Note: This provides the size of the main window. Prefer CSS where possible.
public windowContentSize() {
if (!this.window()) return { width: 0, height: 0 };
const s = this.window().getContentSize();
return { width: s[0], height: s[1] };
}
public windowSize() {
if (!this.window()) return { width: 0, height: 0 };
const s = this.window().getSize();
if (!this.mainWindow()) return { width: 0, height: 0 };
const s = this.mainWindow().getContentSize();
return { width: s[0], height: s[1] };
}
public windowSetSize(width: number, height: number) {
if (!this.window()) return;
return this.window().setSize(width, height);
if (!this.mainWindow()) return;
return this.mainWindow().setSize(width, height);
}
public openDevTools() {
return this.window().webContents.openDevTools();
return this.activeWindow().webContents.openDevTools();
}
public closeDevTools() {
return this.window().webContents.closeDevTools();
return this.activeWindow().webContents.closeDevTools();
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public async showSaveDialog(options: any) {
if (!options) options = {};
if (!('defaultPath' in options) && this.lastSelectedPaths_.file) options.defaultPath = this.lastSelectedPaths_.file;
const { filePath } = await dialog.showSaveDialog(this.window(), options);
const { filePath } = await dialog.showSaveDialog(this.activeWindow(), options);
if (filePath) {
this.lastSelectedPaths_.file = filePath;
}
@@ -316,7 +333,7 @@ export class Bridge {
if (!('defaultPath' in options) && (this.lastSelectedPaths_ as any)[fileType]) options.defaultPath = (this.lastSelectedPaths_ as any)[fileType];
if (!('createDirectory' in options)) options.createDirectory = true;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const { filePaths } = await dialog.showOpenDialog(this.window(), options as any);
const { filePaths } = await dialog.showOpenDialog(this.activeWindow(), options as any);
if (filePaths && filePaths.length) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
(this.lastSelectedPaths_ as any)[fileType] = dirname(filePaths[0]);
@@ -327,7 +344,7 @@ export class Bridge {
// Don't use this directly - call one of the showXxxxxxxMessageBox() instead
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private showMessageBox_(window: any, options: MessageDialogOptions): number {
if (!window) window = this.window();
if (!window) window = this.activeWindow();
return dialog.showMessageBoxSync(window, { message: '', ...options });
}
@@ -337,7 +354,7 @@ export class Bridge {
...options,
};
return this.showMessageBox_(this.window(), {
return this.showMessageBox_(this.activeWindow(), {
type: 'error',
message: message,
buttons: options.buttons,
@@ -350,7 +367,7 @@ export class Bridge {
...options,
};
const result = this.showMessageBox_(this.window(), { type: 'question',
const result = this.showMessageBox_(this.activeWindow(), { type: 'question',
message: message,
cancelId: 1,
buttons: options.buttons, ...options });
@@ -360,7 +377,7 @@ export class Bridge {
/* returns the index of the clicked button */
public showMessageBox(message: string, options: MessageDialogOptions = {}) {
const result = this.showMessageBox_(this.window(), { type: 'question',
const result = this.showMessageBox_(this.activeWindow(), { type: 'question',
message: message,
buttons: [_('OK'), _('Cancel')], ...options });
@@ -369,7 +386,7 @@ export class Bridge {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public showInfoMessageBox(message: string, options: any = {}) {
const result = this.showMessageBox_(this.window(), { type: 'info',
const result = this.showMessageBox_(this.activeWindow(), { type: 'info',
message: message,
buttons: [_('OK')], ...options });
return result === 0;
@@ -413,7 +430,7 @@ export class Bridge {
const allowOpenId = 2;
const learnMoreId = 1;
const fileExtensionDescription = JSON.stringify(fileExtension);
const result = await dialog.showMessageBox(this.window(), {
const result = await dialog.showMessageBox(this.activeWindow(), {
title: _('Unknown file type'),
message:
_('Joplin doesn\'t recognise the %s extension. Opening this file could be dangerous. What would you like to do?', fileExtensionDescription),
@@ -452,8 +469,7 @@ export class Bridge {
return nativeTheme.shouldUseDarkColors;
}
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
public addEventListener(name: string, fn: Function) {
public addEventListener(name: string, fn: ()=> void) {
if (name === 'nativeThemeUpdated') {
nativeTheme.on('updated', fn);
} else {
@@ -485,6 +501,21 @@ export class Bridge {
return nativeImage.createFromPath(path);
}
public safeStorage = {
isEncryptionAvailable() {
return safeStorage.isEncryptionAvailable();
},
encryptString(data: string) {
return safeStorage.encryptString(data).toString('base64');
},
decryptString(base64Data: string) {
return safeStorage.decryptString(Buffer.from(base64Data, 'base64'));
},
getSelectedStorageBackend() {
return safeStorage.getSelectedStorageBackend();
},
};
}
let bridge_: Bridge = null;

View File

@@ -0,0 +1,102 @@
import shim from '@joplin/lib/shim';
import * as exportDeletionLog from './exportDeletionLog';
import Setting from '@joplin/lib/models/Setting';
import { AppState, createAppDefaultState } from '../app.reducer';
jest.mock('../services/bridge', () => ({
__esModule: true,
default: () => ({
openItem: jest.fn,
}),
}));
const logContentWithDeleteAction = `
2024-09-17 18:34:28: Running migration: 20
2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 1
2024-09-17 18:34:28: Running migration: 27
2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 2
2024-09-17 18:34:28: Running migration: 33
2024-09-17 18:34:28: SearchEngine: Updating FTS table...
2024-09-17 18:34:28: Updating items_normalized from {"updated_time":0,"id":""}
2024-09-17 18:34:28: SearchEngine: Updated FTS table in 1ms. Inserted: 0. Deleted: 0
2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 3
2024-09-17 18:34:29: Running migration: 35
2024-09-17 18:34:29: SearchEngine: Updating FTS table...
2024-09-17 18:34:29: Updating items_normalized from {"updated_time":0,"id":""}
2024-09-17 18:34:29: SearchEngine: Updated FTS table in 1ms. Inserted: 0. Deleted: 0
2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4
2024-09-17 18:34:29: Running migration: 42
2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5
2024-09-17 18:34:29: App: "syncInfoCache" was changed - setting up encryption related code
`;
const createFakeLogFile = async (filename: string, content: string) => {
await shim.fsDriver().writeFile(`${Setting.value('profileDir')}/${filename}`, content, 'utf8');
};
describe('exportDeletionLog', () => {
let state: AppState = undefined;
beforeAll(() => {
state = createAppDefaultState({}, {});
jest.useFakeTimers();
jest.setSystemTime(new Date('2024-09-18T12:00:00Z').getTime());
});
it('should get all deletion lines from the log file', async () => {
await createFakeLogFile('log.txt', logContentWithDeleteAction);
await exportDeletionLog.runtime().execute({ state, dispatch: () => {} });
const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8');
expect(result).toBe(
`2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 1
2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 2
2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 3
2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4
2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5
`);
});
it('should return a empty file if there is not deletion lines', async () => {
await createFakeLogFile('log.txt', '');
await exportDeletionLog.runtime().execute({ state, dispatch: () => {} });
const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8');
expect(result).toBe('');
});
it('should ignore logs from log files that are not recent', async () => {
const before = new Date('2024-09-16').getTime();
const after = new Date('2024-09-17').getTime();
await createFakeLogFile(`log-${before}.txt`, logContentWithDeleteAction);
await createFakeLogFile(`log-${after}.txt`, '');
await createFakeLogFile('log.txt', '');
await exportDeletionLog.runtime().execute({ state, dispatch: () => {} });
const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8');
expect(result).toBe('');
});
it('should contain the content from the recent log files', async () => {
const rotateLog = new Date('2024-09-17').getTime();
await createFakeLogFile(`log-${rotateLog}.txt`, '2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4');
await createFakeLogFile('log.txt', '2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5');
await exportDeletionLog.runtime().execute({ state, dispatch: () => {} });
const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8');
expect(result).toBe(
`2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4
2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5
`);
});
it('should contain the date in the filename', async () => {
await shim.fsDriver().remove(`${Setting.value('profileDir')}/deletion_log_20230111.txt`);
jest.setSystemTime(new Date('2023-01-11T12:00:00Z').getTime());
await createFakeLogFile('log.txt', '');
await exportDeletionLog.runtime().execute({ state, dispatch: () => {} });
const exists = await shim.fsDriver().exists(`${Setting.value('profileDir')}/deletion_log_20230111.txt`);
expect(exists).toBe(true);
});
});

View File

@@ -0,0 +1,52 @@
import { CommandRuntime, CommandDeclaration } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
import shim from '@joplin/lib/shim';
import Setting from '@joplin/lib/models/Setting';
import bridge from '../services/bridge';
import { formatMsToLocal } from '@joplin/utils/time';
export const declaration: CommandDeclaration = {
name: 'exportDeletionLog',
label: () => _('Export deletion log'),
};
const getDeletionLines = async (filePath: string) => {
const logFile: string = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/${filePath}`);
const deletionLines = logFile
.split('\n')
.filter(line => line.includes('DeleteAction'));
if (!deletionLines.length) return '';
return `${deletionLines.join('\n')}\n`;
};
export const runtime = (): CommandRuntime => {
return {
execute: async () => {
const files = await shim.fsDriver().readDirStats(Setting.value('profileDir'));
// Get all log.txt and log-{timestamp}.txt files but ignore deletion_log.txt
const logFiles = files.filter(f => f.path.match(/^log(-\d+)?\.txt$/gi));
const lastOneAndCurrent = logFiles.sort().slice(logFiles.length - 2);
let allDeletionLines = '';
for (const file of lastOneAndCurrent) {
const deletionLines = await getDeletionLines(file.path);
allDeletionLines += deletionLines;
}
const fileName = `deletion_log_${formatMsToLocal(Date.now(), 'YYYYMMDD')}.txt`;
const deletionLogPath = `${Setting.value('profileDir')}/${fileName}`;
await shim.fsDriver().writeFile(deletionLogPath, allDeletionLines, 'utf8');
await bridge().openItem(deletionLogPath);
},
};
};

View File

@@ -4,14 +4,18 @@ export const declaration: CommandDeclaration = {
name: 'focusElement',
};
export interface FocusElementOptions {
moveCursorToStart: boolean;
}
export const runtime = (): CommandRuntime => {
return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
execute: async (_context: any, target: string) => {
if (target === 'noteBody') return CommandService.instance().execute('focusElementNoteBody');
execute: async (_context: any, target: string, options?: FocusElementOptions) => {
if (target === 'noteBody') return CommandService.instance().execute('focusElementNoteBody', options);
if (target === 'noteList') return CommandService.instance().execute('focusElementNoteList');
if (target === 'sideBar') return CommandService.instance().execute('focusElementSideBar');
if (target === 'noteTitle') return CommandService.instance().execute('focusElementNoteTitle');
if (target === 'noteTitle') return CommandService.instance().execute('focusElementNoteTitle', options);
throw new Error(`Invalid focus target: ${target}`);
},
};

View File

@@ -2,10 +2,13 @@
import * as copyDevCommand from './copyDevCommand';
import * as editProfileConfig from './editProfileConfig';
import * as emptyTrash from './emptyTrash';
import * as exportDeletionLog from './exportDeletionLog';
import * as exportFolders from './exportFolders';
import * as exportNotes from './exportNotes';
import * as focusElement from './focusElement';
import * as openNoteInNewWindow from './openNoteInNewWindow';
import * as openProfileDirectory from './openProfileDirectory';
import * as renderMarkup from './renderMarkup';
import * as replaceMisspelling from './replaceMisspelling';
import * as restoreNoteRevision from './restoreNoteRevision';
import * as startExternalEditing from './startExternalEditing';
@@ -21,10 +24,13 @@ const index: any[] = [
copyDevCommand,
editProfileConfig,
emptyTrash,
exportDeletionLog,
exportFolders,
exportNotes,
focusElement,
openNoteInNewWindow,
openProfileDirectory,
renderMarkup,
replaceMisspelling,
restoreNoteRevision,
startExternalEditing,

View File

@@ -0,0 +1,36 @@
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
import { stateUtils } from '@joplin/lib/reducer';
import Note from '@joplin/lib/models/Note';
import { createAppDefaultWindowState } from '../app.reducer';
import Setting from '@joplin/lib/models/Setting';
export const declaration: CommandDeclaration = {
name: 'openNoteInNewWindow',
label: () => _('Edit in new window'),
iconName: 'icon-share',
};
let idCounter = 0;
export const runtime = (): CommandRuntime => {
return {
execute: async (context: CommandContext, noteId: string = null) => {
noteId = noteId || stateUtils.selectedNoteId(context.state);
const note = await Note.load(noteId, { fields: ['parent_id'] });
context.dispatch({
type: 'WINDOW_OPEN',
noteId,
folderId: note.parent_id,
windowId: `window-${noteId}-${idCounter++}`,
defaultAppWindowState: {
...createAppDefaultWindowState(),
noteVisiblePanes: Setting.value('noteVisiblePanes'),
editorCodeView: Setting.value('editor.codeView'),
},
});
},
enabledCondition: 'oneNoteSelected',
};
};

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