From f0c1042a71fa83cef2583f2ac381963b9a8a0665 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 18 Aug 2023 12:46:34 +0100 Subject: [PATCH 01/13] Desktop: Fetch release info from Joplin server --- packages/app-desktop/checkForUpdates.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/app-desktop/checkForUpdates.ts b/packages/app-desktop/checkForUpdates.ts index b58276df0..46c290236 100644 --- a/packages/app-desktop/checkForUpdates.ts +++ b/packages/app-desktop/checkForUpdates.ts @@ -23,8 +23,8 @@ function onCheckEnded() { isCheckingForUpdate_ = false; } -async function fetchLatestRelease() { - const response = await shim.fetch('https://api.github.com/repos/laurent22/joplin/releases'); +async function fetchLatestReleases() { + const response = await shim.fetch('https://objects.joplinusercontent.com/r/releases'); if (!response.ok) { const responseText = await response.text(); @@ -76,7 +76,7 @@ export default async function checkForUpdates(inBackground: boolean, parentWindo logger.info(`Checking with options ${JSON.stringify(options)}`); try { - const releases = await fetchLatestRelease(); + const releases = await fetchLatestReleases(); const release = extractVersionInfo(releases, process.platform, process.arch, shim.isPortable(), options); logger.info(`Current version: ${packageInfo.version}`); From 3778f190fbf062537031bc9157467cec7efc2f71 Mon Sep 17 00:00:00 2001 From: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com> Date: Sat, 19 Aug 2023 01:17:25 -0700 Subject: [PATCH 02/13] Desktop: Resolves #8493: Link to FAQ when encryption password may have been reset by an update (#8667) Co-authored-by: Laurent Cozic --- .eslintignore | 1 + .gitignore | 1 + .../gui/ConfigScreen/ConfigScreen.tsx | 26 ++++---------- .../controls/MissingPasswordHelpLink.tsx | 35 +++++++++++++++++++ .../EncryptionConfigScreen.tsx | 12 ++++++- 5 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.tsx diff --git a/.eslintignore b/.eslintignore index 0d0a1776b..920e97020 100644 --- a/.eslintignore +++ b/.eslintignore @@ -133,6 +133,7 @@ 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/Sidebar.js +packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.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 diff --git a/.gitignore b/.gitignore index 08b45a60b..c087fde1c 100644 --- a/.gitignore +++ b/.gitignore @@ -119,6 +119,7 @@ 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/Sidebar.js +packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.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 diff --git a/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx b/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx index 53ba0cc91..767478867 100644 --- a/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx +++ b/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx @@ -21,8 +21,7 @@ import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/d import JoplinCloudConfigScreen from '../JoplinCloudConfigScreen'; import ToggleAdvancedSettingsButton from './controls/ToggleAdvancedSettingsButton'; import shouldShowMissingPasswordWarning from '@joplin/lib/components/shared/config/shouldShowMissingPasswordWarning'; -import shim from '@joplin/lib/shim'; -import StyledLink from '../style/StyledLink'; +import MacOSMissingPasswordHelpLink from './controls/MissingPasswordHelpLink'; const { KeymapConfigScreen } = require('../KeymapConfig/KeymapConfigScreen'); const settingKeyToControl: any = { @@ -190,25 +189,14 @@ class ConfigScreenComponent extends React.Component { // saved yet). const matchesSavedTarget = settings['sync.target'] === this.props.settings['sync.target']; if (matchesSavedTarget && shouldShowMissingPasswordWarning(settings['sync.target'], settings)) { - const openMissingPasswordFAQ = () => - bridge().openExternal('https://joplinapp.org/faq#why-did-my-sync-and-encryption-passwords-disappear-after-updating-joplin'); - - const macInfoLink = ( - - {_('Help')} - - ); - - // The FAQ section related to missing passwords is specific to MacOS/ARM -- only show it - // in that case. - const showMacInfoLink = shim.isMac() && process.arch === 'arm64'; - settingComps.push(

- {_('Warning: Missing password.')}{' '}{showMacInfoLink ? macInfoLink : null} + {_('%s: Missing password.', _('Warning'))} + {' '} +

); } diff --git a/packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.tsx b/packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.tsx new file mode 100644 index 000000000..8c496aa3f --- /dev/null +++ b/packages/app-desktop/gui/ConfigScreen/controls/MissingPasswordHelpLink.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; + +import shim from '@joplin/lib/shim'; +import bridge from '../../../services/bridge'; +import StyledLink from '../../style/StyledLink'; + +interface Props { + theme: any; + text: string; +} + +const openMissingPasswordFAQ = () => + bridge().openExternal('https://joplinapp.org/faq#why-did-my-sync-and-encryption-passwords-disappear-after-updating-joplin'); + +// A link to a specific part of the FAQ related to passwords being cleared when upgrading +// to a MacOS/ARM release. +const MacOSMissingPasswordHelpLink: React.FunctionComponent = props => { + const macInfoLink = ( + + {props.text} + + ); + + // The FAQ section related to missing passwords is specific to MacOS/ARM -- only show it + // in that case. + const newArchitectureReleasedRecently = Date.now() <= Date.UTC(2023, 11); // 11 = December + const showMacInfoLink = shim.isMac() && process.arch === 'arm64' && newArchitectureReleasedRecently; + + return showMacInfoLink ? macInfoLink : null; +}; + +export default MacOSMissingPasswordHelpLink; diff --git a/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx b/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx index 3add1187e..93331d2a8 100644 --- a/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx +++ b/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx @@ -17,6 +17,7 @@ import Setting from '@joplin/lib/models/Setting'; import CommandService from '@joplin/lib/services/CommandService'; import { PublicPrivateKeyPair } from '@joplin/lib/services/e2ee/ppk'; import ToggleAdvancedSettingsButton from '../ConfigScreen/controls/ToggleAdvancedSettingsButton'; +import MacOSMissingPasswordHelpLink from '../ConfigScreen/controls/MissingPasswordHelpLink'; interface Props { themeId: any; @@ -252,7 +253,16 @@ const EncryptionConfigScreen = (props: Props) => { const buttonTitle = CommandService.instance().label('openMasterPasswordDialog'); const needPasswordMessage = !needMasterPassword ? null : ( -

{_('Your password is needed to decrypt some of your data.')}
{_('Please click on "%s" to proceed, or set the passwords in the "%s" list below.', buttonTitle, _('Encryption keys'))}

+

+ {_('Your password is needed to decrypt some of your data.')} +
+ {_('Please click on "%s" to proceed, or set the passwords in the "%s" list below.', buttonTitle, _('Encryption keys'))} +
+ +

); return ( From 973680ea279f0ebbf8170459016c76c01c5d6ede Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 19 Aug 2023 21:03:46 +0100 Subject: [PATCH 03/13] Desktop release v2.12.12 --- packages/app-desktop/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-desktop/package.json b/packages/app-desktop/package.json index 240756565..8e268ed37 100644 --- a/packages/app-desktop/package.json +++ b/packages/app-desktop/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/app-desktop", - "version": "2.12.11", + "version": "2.12.12", "description": "Joplin for Desktop", "main": "main.js", "private": true, From 5da37801976fd2a886f2d8b7bf106315509c1a50 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 13:48:49 +0100 Subject: [PATCH 04/13] Chore: Make package private --- packages/generate-plugin-doc/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/generate-plugin-doc/package.json b/packages/generate-plugin-doc/package.json index 89f96ba8a..56817d95e 100644 --- a/packages/generate-plugin-doc/package.json +++ b/packages/generate-plugin-doc/package.json @@ -1,6 +1,7 @@ { "name": "generate-plugin-doc", "packageManager": "yarn@3.6.0", + "private": true, "scripts": { "buildPluginDoc_": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme '../../Assets/PluginDocTheme/' --readme '../../Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out ../../../joplin-website/docs/api/references/plugin_api ../lib/services/plugins/api/" }, From 21929157b5184b261264c43cc851e7d17faed2c6 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 13:51:28 +0100 Subject: [PATCH 05/13] Releasing sub-packages --- packages/fork-htmlparser2/package.json | 2 +- packages/fork-sax/package.json | 2 +- packages/fork-uslug/package.json | 2 +- packages/htmlpack/package.json | 4 ++-- packages/lib/package.json | 18 +++++++++--------- packages/plugin-repo-cli/package.json | 8 ++++---- packages/react-native-saf-x/package.json | 2 +- packages/renderer/package.json | 6 +++--- packages/tools/package.json | 10 +++++----- packages/turndown-plugin-gfm/package.json | 2 +- packages/turndown/package.json | 2 +- packages/utils/package.json | 2 +- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/fork-htmlparser2/package.json b/packages/fork-htmlparser2/package.json index bc421a1cf..56e6e3b53 100644 --- a/packages/fork-htmlparser2/package.json +++ b/packages/fork-htmlparser2/package.json @@ -1,7 +1,7 @@ { "name": "@joplin/fork-htmlparser2", "description": "Fast & forgiving HTML/XML/RSS parser", - "version": "4.1.45", + "version": "4.1.46", "author": "Felix Boehm ", "publishConfig": { "access": "public" diff --git a/packages/fork-sax/package.json b/packages/fork-sax/package.json index dc6668e6f..70bf49fec 100644 --- a/packages/fork-sax/package.json +++ b/packages/fork-sax/package.json @@ -2,7 +2,7 @@ "name": "@joplin/fork-sax", "description": "An evented streaming XML parser in JavaScript", "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "version": "1.2.49", + "version": "1.2.50", "main": "lib/sax.js", "publishConfig": { "access": "public" diff --git a/packages/fork-uslug/package.json b/packages/fork-uslug/package.json index 8a0302af2..e39fc8f37 100644 --- a/packages/fork-uslug/package.json +++ b/packages/fork-uslug/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/fork-uslug", - "version": "1.0.10", + "version": "1.0.11", "description": "A permissive slug generator that works with unicode.", "author": "Jeremy Selier ", "publishConfig": { diff --git a/packages/htmlpack/package.json b/packages/htmlpack/package.json index 84db6dc6a..79fbd9d17 100644 --- a/packages/htmlpack/package.json +++ b/packages/htmlpack/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/htmlpack", - "version": "2.12.0", + "version": "2.12.1", "description": "Pack an HTML file and all its linked resources into a single HTML file", "main": "dist/index.js", "types": "src/index.ts", @@ -14,7 +14,7 @@ "author": "Laurent Cozic", "license": "MIT", "dependencies": { - "@joplin/fork-htmlparser2": "^4.1.45", + "@joplin/fork-htmlparser2": "^4.1.46", "css": "3.0.0", "datauri": "4.1.0", "fs-extra": "11.1.1", diff --git a/packages/lib/package.json b/packages/lib/package.json index 1677bbb3f..a2d6dc5c1 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/lib", - "version": "2.12.0", + "version": "2.12.1", "description": "Joplin Core library", "author": "Laurent Cozic", "homepage": "", @@ -31,14 +31,14 @@ "dependencies": { "@aws-sdk/client-s3": "3.296.0", "@aws-sdk/s3-request-presigner": "3.296.0", - "@joplin/fork-htmlparser2": "^4.1.44", - "@joplin/fork-sax": "^1.2.48", - "@joplin/fork-uslug": "^1.0.9", - "@joplin/htmlpack": "~2.12", - "@joplin/renderer": "~2.12", - "@joplin/turndown": "^4.0.66", - "@joplin/turndown-plugin-gfm": "^1.0.48", - "@joplin/utils": "~2.12", + "@joplin/fork-htmlparser2": "^4.1.46", + "@joplin/fork-sax": "^1.2.50", + "@joplin/fork-uslug": "^1.0.11", + "@joplin/htmlpack": "^2.12.1", + "@joplin/renderer": "^2.12.1", + "@joplin/turndown": "^4.0.68", + "@joplin/turndown-plugin-gfm": "^1.0.50", + "@joplin/utils": "^2.12.1", "@types/nanoid": "3.0.0", "async-mutex": "0.4.0", "base-64": "1.0.0", diff --git a/packages/plugin-repo-cli/package.json b/packages/plugin-repo-cli/package.json index e5d96b44f..0083a24a1 100644 --- a/packages/plugin-repo-cli/package.json +++ b/packages/plugin-repo-cli/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/plugin-repo-cli", - "version": "2.12.0", + "version": "2.12.1", "description": "", "main": "index.js", "bin": "./dist/index.js", @@ -18,9 +18,9 @@ "author": "", "license": "AGPL-3.0-or-later", "dependencies": { - "@joplin/lib": "~2.12", - "@joplin/tools": "~2.12", - "@joplin/utils": "~2.12", + "@joplin/lib": "^2.12.1", + "@joplin/tools": "^2.12.1", + "@joplin/utils": "^2.12.1", "fs-extra": "11.1.1", "gh-release-assets": "2.0.1", "node-fetch": "2.6.7", diff --git a/packages/react-native-saf-x/package.json b/packages/react-native-saf-x/package.json index 912880052..e1f849866 100644 --- a/packages/react-native-saf-x/package.json +++ b/packages/react-native-saf-x/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/react-native-saf-x", - "version": "2.12.0", + "version": "2.12.1", "description": "a module to help work with scoped storages on android easily", "main": "src/index", "react-native": "src/index", diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 5e1c34ac3..b339997a6 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/renderer", - "version": "2.12.0", + "version": "2.12.1", "description": "The Joplin note renderer, used the mobile and desktop application", "repository": "https://github.com/laurent22/joplin/tree/dev/packages/renderer", "main": "index.js", @@ -26,8 +26,8 @@ "typescript": "5.1.3" }, "dependencies": { - "@joplin/fork-htmlparser2": "^4.1.44", - "@joplin/fork-uslug": "^1.0.9", + "@joplin/fork-htmlparser2": "^4.1.46", + "@joplin/fork-uslug": "^1.0.11", "font-awesome-filetypes": "2.1.0", "fs-extra": "11.1.1", "highlight.js": "11.8.0", diff --git a/packages/tools/package.json b/packages/tools/package.json index 89d6cd8b1..d3be78d12 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/tools", - "version": "2.12.0", + "version": "2.12.1", "description": "Various tools for Joplin", "main": "index.js", "author": "Laurent Cozic", @@ -20,9 +20,9 @@ }, "license": "AGPL-3.0-or-later", "dependencies": { - "@joplin/lib": "~2.12", - "@joplin/renderer": "~2.12", - "@joplin/utils": "~2.12", + "@joplin/lib": "^2.12.1", + "@joplin/renderer": "^2.12.1", + "@joplin/utils": "^2.12.1", "compare-versions": "3.6.0", "dayjs": "1.11.9", "execa": "4.1.0", @@ -42,7 +42,7 @@ "yargs": "17.7.2" }, "devDependencies": { - "@joplin/fork-htmlparser2": "^4.1.44", + "@joplin/fork-htmlparser2": "^4.1.46", "@rmp135/sql-ts": "1.18.0", "@types/fs-extra": "11.0.1", "@types/jest": "29.5.3", diff --git a/packages/turndown-plugin-gfm/package.json b/packages/turndown-plugin-gfm/package.json index 478ca4743..45b2524e9 100644 --- a/packages/turndown-plugin-gfm/package.json +++ b/packages/turndown-plugin-gfm/package.json @@ -4,7 +4,7 @@ "publishConfig": { "access": "public" }, - "version": "1.0.49", + "version": "1.0.50", "author": "Dom Christie", "main": "lib/turndown-plugin-gfm.cjs.js", "devDependencies": { diff --git a/packages/turndown/package.json b/packages/turndown/package.json index cccc6458d..bd8e687d9 100644 --- a/packages/turndown/package.json +++ b/packages/turndown/package.json @@ -1,7 +1,7 @@ { "name": "@joplin/turndown", "description": "A library that converts HTML to Markdown", - "version": "4.0.67", + "version": "4.0.68", "author": "Dom Christie", "main": "lib/turndown.cjs.js", "publishConfig": { diff --git a/packages/utils/package.json b/packages/utils/package.json index c33531319..2da3e280d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/utils", - "version": "2.12.0", + "version": "2.12.1", "description": "Utilities for Joplin", "repository": "https://github.com/laurent22/joplin/tree/dev/packages/utils", "exports": { From e126a2d8bf1533d9ac0577dc7f29ea97b2b30167 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 13:52:14 +0100 Subject: [PATCH 06/13] Lock file --- yarn.lock | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/yarn.lock b/yarn.lock index a58fa657b..cca9da345 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4615,7 +4615,7 @@ __metadata: languageName: unknown linkType: soft -"@joplin/fork-htmlparser2@^4.1.44, @joplin/fork-htmlparser2@^4.1.45, @joplin/fork-htmlparser2@workspace:packages/fork-htmlparser2": +"@joplin/fork-htmlparser2@^4.1.46, @joplin/fork-htmlparser2@workspace:packages/fork-htmlparser2": version: 0.0.0-use.local resolution: "@joplin/fork-htmlparser2@workspace:packages/fork-htmlparser2" dependencies: @@ -4636,7 +4636,7 @@ __metadata: languageName: unknown linkType: soft -"@joplin/fork-sax@^1.2.48, @joplin/fork-sax@workspace:packages/fork-sax": +"@joplin/fork-sax@^1.2.50, @joplin/fork-sax@workspace:packages/fork-sax": version: 0.0.0-use.local resolution: "@joplin/fork-sax@workspace:packages/fork-sax" dependencies: @@ -4645,7 +4645,7 @@ __metadata: languageName: unknown linkType: soft -"@joplin/fork-uslug@^1.0.9, @joplin/fork-uslug@workspace:packages/fork-uslug": +"@joplin/fork-uslug@^1.0.11, @joplin/fork-uslug@workspace:packages/fork-uslug": version: 0.0.0-use.local resolution: "@joplin/fork-uslug@workspace:packages/fork-uslug" dependencies: @@ -4655,11 +4655,11 @@ __metadata: languageName: unknown linkType: soft -"@joplin/htmlpack@workspace:packages/htmlpack, @joplin/htmlpack@~2.12": +"@joplin/htmlpack@^2.12.1, @joplin/htmlpack@workspace:packages/htmlpack": version: 0.0.0-use.local resolution: "@joplin/htmlpack@workspace:packages/htmlpack" dependencies: - "@joplin/fork-htmlparser2": ^4.1.45 + "@joplin/fork-htmlparser2": ^4.1.46 "@types/fs-extra": 11.0.1 css: 3.0.0 datauri: 4.1.0 @@ -4668,20 +4668,20 @@ __metadata: languageName: unknown linkType: soft -"@joplin/lib@workspace:packages/lib, @joplin/lib@~2.12": +"@joplin/lib@^2.12.1, @joplin/lib@workspace:packages/lib, @joplin/lib@~2.12": version: 0.0.0-use.local resolution: "@joplin/lib@workspace:packages/lib" dependencies: "@aws-sdk/client-s3": 3.296.0 "@aws-sdk/s3-request-presigner": 3.296.0 - "@joplin/fork-htmlparser2": ^4.1.44 - "@joplin/fork-sax": ^1.2.48 - "@joplin/fork-uslug": ^1.0.9 - "@joplin/htmlpack": ~2.12 - "@joplin/renderer": ~2.12 - "@joplin/turndown": ^4.0.66 - "@joplin/turndown-plugin-gfm": ^1.0.48 - "@joplin/utils": ~2.12 + "@joplin/fork-htmlparser2": ^4.1.46 + "@joplin/fork-sax": ^1.2.50 + "@joplin/fork-uslug": ^1.0.11 + "@joplin/htmlpack": ^2.12.1 + "@joplin/renderer": ^2.12.1 + "@joplin/turndown": ^4.0.68 + "@joplin/turndown-plugin-gfm": ^1.0.50 + "@joplin/utils": ^2.12.1 "@types/fs-extra": 11.0.1 "@types/jest": 29.5.3 "@types/js-yaml": 4.0.5 @@ -4785,9 +4785,9 @@ __metadata: version: 0.0.0-use.local resolution: "@joplin/plugin-repo-cli@workspace:packages/plugin-repo-cli" dependencies: - "@joplin/lib": ~2.12 - "@joplin/tools": ~2.12 - "@joplin/utils": ~2.12 + "@joplin/lib": ^2.12.1 + "@joplin/tools": ^2.12.1 + "@joplin/utils": ^2.12.1 "@types/fs-extra": 11.0.1 "@types/jest": 29.5.3 "@types/node": 18.16.18 @@ -4836,12 +4836,12 @@ __metadata: languageName: unknown linkType: soft -"@joplin/renderer@workspace:packages/renderer, @joplin/renderer@~2.12": +"@joplin/renderer@^2.12.1, @joplin/renderer@workspace:packages/renderer, @joplin/renderer@~2.12": version: 0.0.0-use.local resolution: "@joplin/renderer@workspace:packages/renderer" dependencies: - "@joplin/fork-htmlparser2": ^4.1.44 - "@joplin/fork-uslug": ^1.0.9 + "@joplin/fork-htmlparser2": ^4.1.46 + "@joplin/fork-uslug": ^1.0.11 "@types/jest": 29.5.3 "@types/node": 18.16.18 font-awesome-filetypes: 2.1.0 @@ -4934,14 +4934,14 @@ __metadata: languageName: unknown linkType: soft -"@joplin/tools@workspace:packages/tools, @joplin/tools@~2.12": +"@joplin/tools@^2.12.1, @joplin/tools@workspace:packages/tools, @joplin/tools@~2.12": version: 0.0.0-use.local resolution: "@joplin/tools@workspace:packages/tools" dependencies: - "@joplin/fork-htmlparser2": ^4.1.44 - "@joplin/lib": ~2.12 - "@joplin/renderer": ~2.12 - "@joplin/utils": ~2.12 + "@joplin/fork-htmlparser2": ^4.1.46 + "@joplin/lib": ^2.12.1 + "@joplin/renderer": ^2.12.1 + "@joplin/utils": ^2.12.1 "@rmp135/sql-ts": 1.18.0 "@types/fs-extra": 11.0.1 "@types/jest": 29.5.3 @@ -4977,7 +4977,7 @@ __metadata: languageName: unknown linkType: soft -"@joplin/turndown-plugin-gfm@^1.0.48, @joplin/turndown-plugin-gfm@workspace:packages/turndown-plugin-gfm": +"@joplin/turndown-plugin-gfm@^1.0.50, @joplin/turndown-plugin-gfm@workspace:packages/turndown-plugin-gfm": version: 0.0.0-use.local resolution: "@joplin/turndown-plugin-gfm@workspace:packages/turndown-plugin-gfm" dependencies: @@ -4989,7 +4989,7 @@ __metadata: languageName: unknown linkType: soft -"@joplin/turndown@^4.0.66, @joplin/turndown@workspace:packages/turndown": +"@joplin/turndown@^4.0.68, @joplin/turndown@workspace:packages/turndown": version: 0.0.0-use.local resolution: "@joplin/turndown@workspace:packages/turndown" dependencies: @@ -5006,7 +5006,7 @@ __metadata: languageName: unknown linkType: soft -"@joplin/utils@workspace:packages/utils, @joplin/utils@~2.12": +"@joplin/utils@^2.12.1, @joplin/utils@workspace:packages/utils, @joplin/utils@~2.12": version: 0.0.0-use.local resolution: "@joplin/utils@workspace:packages/utils" dependencies: From 3577b245f678240fb51f365693e0a8e5192a0878 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 13:53:55 +0100 Subject: [PATCH 07/13] CLI v2.12.1 --- packages/app-cli/package.json | 2 +- readme/changelog_cli.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/app-cli/package.json b/packages/app-cli/package.json index 95d01b9ba..0708e4e51 100644 --- a/packages/app-cli/package.json +++ b/packages/app-cli/package.json @@ -35,7 +35,7 @@ ], "owner": "Laurent Cozic" }, - "version": "2.12.0", + "version": "2.12.1", "bin": "./main.js", "engines": { "node": ">=10.0.0" diff --git a/readme/changelog_cli.md b/readme/changelog_cli.md index 8fc82d0c0..11beae5d4 100644 --- a/readme/changelog_cli.md +++ b/readme/changelog_cli.md @@ -1,5 +1,14 @@ # Joplin terminal app changelog +## [cli-v2.12.1](https://github.com/laurent22/joplin/releases/tag/cli-v2.12.1) - 2023-08-23T12:53:19Z + +- New: Add support for share permissions (#8491) +- Improved: Allow importing Evernote task lists (#8440 by Rob Moffat) +- Improved: Rotating log files (#8376) (#5521 by [@hubert](https://github.com/hubert)) +- Improved: Updated packages @rmp135/sql-ts (v1.18.0), buildTools, clean-html (v2), dayjs (v1.11.9), domhandler (v5), gettext-parser (v7.0.1), glob (v10.3.3), highlight.js (v11.8.0), jsdom (v22.1.0), sass (v1.63.6), sharp (v0.32.3), standard (v17.1.0), word-wrap (v1.2.4) +- Improved: WebDAV: Show a more descriptive error message when the password is empty (#8477) (#8466 by Henry Heino) +- Security: Prevent XSS when passing specially encoded string to a link (57b4198) + ## [cli-v2.11.1](https://github.com/laurent22/joplin/releases/tag/cli-v2.11.1) - 2023-06-27T09:28:01Z - Improved: Updated packages aws, buildTools, domutils (v3.1.0), fs-extra (v11.1.1), jsdom (v21.1.2), markdown-it-multimd-table (v4.2.2), nanoid (v3.3.6), node-persist (v3.1.3), open (v8.4.2), reselect (v4.1.8), sass (v1.62.1), sharp (v0.32.1), sqlite3 (v5.1.6), tar (v6.1.15), turndown (v7.1.2), yargs (v17.7.2) From 73eedd3ec386a8dce88fd6eec8237cc6584a5168 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 18:16:06 +0100 Subject: [PATCH 08/13] Desktop: Fixes #8706: Pasting a resource in Rich Text editor breaks the resource link --- .../gui/MainScreen/commands/openItem.ts | 3 +- .../NoteEditor/utils/resourceHandling.test.ts | 5 + .../gui/NoteEditor/utils/resourceHandling.ts | 6 +- packages/lib/services/rest/routes/notes.ts | 2 +- packages/lib/urlUtils.js | 97 ------------------- packages/lib/urlUtils.test.js | 26 ----- packages/renderer/htmlUtils.ts | 35 +++++-- packages/renderer/package.json | 1 + packages/utils/package.json | 1 + yarn.lock | 1 + 10 files changed, 41 insertions(+), 136 deletions(-) diff --git a/packages/app-desktop/gui/MainScreen/commands/openItem.ts b/packages/app-desktop/gui/MainScreen/commands/openItem.ts index d4fd7f2b8..1ac94a2be 100644 --- a/packages/app-desktop/gui/MainScreen/commands/openItem.ts +++ b/packages/app-desktop/gui/MainScreen/commands/openItem.ts @@ -3,7 +3,8 @@ import shim from '@joplin/lib/shim'; import { _ } from '@joplin/lib/locale'; import bridge from '../../../services/bridge'; import { openItemById } from '../../NoteEditor/utils/contextMenu'; -const { parseResourceUrl, urlProtocol, fileUriToPath } = require('@joplin/lib/urlUtils'); +const { parseResourceUrl, urlProtocol } = require('@joplin/lib/urlUtils'); +import { fileUriToPath } from '@joplin/utils/url'; const { urlDecode } = require('@joplin/lib/string-utils'); export const declaration: CommandDeclaration = { diff --git a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts index e993bcade..7df618d26 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts @@ -1,10 +1,15 @@ +import Setting from '@joplin/lib/models/Setting'; import { processPastedHtml } from './resourceHandling'; describe('resourceHandling', () => { it('should sanitize pasted HTML', async () => { + Setting.setConstant('resourceDir', '/home/.config/joplin/resources'); + const testCases = [ ['Test: ', 'Test: '], ['test', 'test'], + ['test', 'test'], + ['evil.pdf', 'evil.pdf'], ['evil()', ''], ['', ''], [ diff --git a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts index 2b46f231c..11c8e90d0 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts @@ -8,7 +8,7 @@ import ResourceFetcher from '@joplin/lib/services/ResourceFetcher'; import htmlUtils from '@joplin/lib/htmlUtils'; import rendererHtmlUtils from '@joplin/renderer/htmlUtils'; import Logger from '@joplin/utils/Logger'; -const { fileUriToPath } = require('@joplin/lib/urlUtils'); +import { fileUriToPath } from '@joplin/utils/url'; const joplinRendererUtils = require('@joplin/renderer').utils; const { clipboard } = require('electron'); const mimeUtils = require('@joplin/lib/mime-utils.js').mime; @@ -179,6 +179,8 @@ export async function processPastedHtml(html: string) { return rendererHtmlUtils.sanitizeHtml( htmlUtils.replaceImageUrls(html, (src: string) => { return mappedResources[src]; - }) + }), { + allowedFilePrefixes: [Setting.value('resourceDir')], + } ); } diff --git a/packages/lib/services/rest/routes/notes.ts b/packages/lib/services/rest/routes/notes.ts index 828265ca1..8b90b0670 100644 --- a/packages/lib/services/rest/routes/notes.ts +++ b/packages/lib/services/rest/routes/notes.ts @@ -24,9 +24,9 @@ import * as ArrayUtils from '../../../ArrayUtils'; import Logger from '@joplin/utils/Logger'; const { mimeTypeFromHeaders } = require('../../../net-utils'); const { fileExtension, safeFileExtension, safeFilename, filename } = require('../../../path-utils'); -const { fileUriToPath } = require('../../../urlUtils'); const { MarkupToHtml } = require('@joplin/renderer'); const { ErrorNotFound } = require('../utils/errors'); +import { fileUriToPath } from '@joplin/utils/url'; const logger = Logger.create('routes/notes'); diff --git a/packages/lib/urlUtils.js b/packages/lib/urlUtils.js index f7bf754bf..d509716ae 100644 --- a/packages/lib/urlUtils.js +++ b/packages/lib/urlUtils.js @@ -105,101 +105,4 @@ urlUtils.objectToQueryString = function(query) { return queryString; }; -// This is a modified version of the file-uri-to-path package: -// -// - It removes the dependency to the "path" package, which wouldn't work with -// React Native. -// -// - It always returns paths with forward slashes "/". This is normally handled -// properly everywhere. -// -// - Adds the "platform" parameter to optionall return paths with "\" for win32 -function fileUriToPath_(uri, platform) { - const sep = '/'; - - if ( - typeof uri !== 'string' || - uri.length <= 7 || - uri.substring(0, 7) !== 'file://' - ) { - throw new TypeError( - 'must pass in a file:// URI to convert to a file path' - ); - } - - const rest = decodeURI(uri.substring(7)); - const firstSlash = rest.indexOf('/'); - let host = rest.substring(0, firstSlash); - let path = rest.substring(firstSlash + 1); - - // 2. Scheme Definition - // As a special case, can be the string "localhost" or the empty - // string; this is interpreted as "the machine from which the URL is - // being interpreted". - if (host === 'localhost') { - host = ''; - } - - if (host) { - host = sep + sep + host; - } - - // 3.2 Drives, drive letters, mount points, file system root - // Drive letters are mapped into the top of a file URI in various ways, - // depending on the implementation; some applications substitute - // vertical bar ("|") for the colon after the drive letter, yielding - // "file:///c|/tmp/test.txt". In some cases, the colon is left - // unchanged, as in "file:///c:/tmp/test.txt". In other cases, the - // colon is simply omitted, as in "file:///c/tmp/test.txt". - path = path.replace(/^(.+)\|/, '$1:'); - - // for Windows, we need to invert the path separators from what a URI uses - // if (sep === '\\') { - // path = path.replace(/\//g, '\\'); - // } - - if (/^.+:/.test(path)) { - // has Windows drive at beginning of path - } else { - // unix path… - path = sep + path; - } - - if (platform === 'win32') { - return (host + path).replace(/\//g, '\\'); - } else { - return host + path; - } -} - -urlUtils.fileUriToPath = (path, platform = 'linux') => { - const output = fileUriToPath_(path, platform); - - // The file-uri-to-path module converts Windows path such as - // - // file://c:/autoexec.bat => \\c:\autoexec.bat - // - // Probably because a file:// that starts with only two slashes is not - // quite valid. If we use three slashes, it works: - // - // file:///c:/autoexec.bat => c:\autoexec.bat - // - // However there are various places in the app where we can find - // paths with only two slashes because paths are often constructed - // as `file://${resourcePath}` - which works in all OSes except - // Windows. - // - // So here we introduce a special case - if we detect that we have - // an invalid Windows path that starts with \\x:, we just remove - // the first two backslashes. - // - // https://github.com/laurent22/joplin/issues/5693 - - if (output.match(/^\/\/[a-zA-Z]:/)) { - return output.substr(2); - } - - return output; -}; - module.exports = urlUtils; diff --git a/packages/lib/urlUtils.test.js b/packages/lib/urlUtils.test.js index f6704c90b..c23936830 100644 --- a/packages/lib/urlUtils.test.js +++ b/packages/lib/urlUtils.test.js @@ -71,30 +71,4 @@ describe('urlUtils', () => { } })); - it('should convert a file URI to a file path', (async () => { - // Tests imported from https://github.com/TooTallNate/file-uri-to-path/tree/master/test - const testCases = { - 'file://host/path': '//host/path', - 'file://localhost/etc/fstab': '/etc/fstab', - 'file:///etc/fstab': '/etc/fstab', - 'file:///c:/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', - 'file://localhost/c|/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', - 'file:///c|/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', - 'file://localhost/c:/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', - 'file://hostname/path/to/the%20file.txt': '//hostname/path/to/the file.txt', - 'file:///c:/path/to/the%20file.txt': 'c:/path/to/the file.txt', - 'file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc': 'C:/Documents and Settings/davris/FileSchemeURIs.doc', - 'file:///C:/caf%C3%A9/%C3%A5r/d%C3%BCnn/%E7%89%9B%E9%93%83/Ph%E1%BB%9F/%F0%9F%98%B5.exe': 'C:/café/år/dünn/牛铃/Phở/😵.exe', - }; - - for (const [input, expected] of Object.entries(testCases)) { - const actual = urlUtils.fileUriToPath(input); - expect(actual).toBe(expected); - } - - expect(urlUtils.fileUriToPath('file://c:/not/quite/right')).toBe('c:/not/quite/right'); - expect(urlUtils.fileUriToPath('file:///d:/better')).toBe('d:/better'); - expect(urlUtils.fileUriToPath('file:///c:/AUTOEXEC.BAT', 'win32')).toBe('c:\\AUTOEXEC.BAT'); - })); - }); diff --git a/packages/renderer/htmlUtils.ts b/packages/renderer/htmlUtils.ts index 54e819d46..1cfceea04 100644 --- a/packages/renderer/htmlUtils.ts +++ b/packages/renderer/htmlUtils.ts @@ -1,5 +1,5 @@ -const Entities = require('html-entities').AllHtmlEntities; -const htmlentities = new Entities().encode; +import { htmlentities } from '@joplin/utils/html'; +import { fileUriToPath } from '@joplin/utils/url'; const htmlparser2 = require('@joplin/fork-htmlparser2'); // [\s\S] instead of . for multiline matching @@ -31,7 +31,8 @@ const selfClosingElements = [ ]; interface SanitizeHtmlOptions { - addNoMdConvClass: boolean; + addNoMdConvClass?: boolean; + allowedFilePrefixes?: string[]; } class HtmlUtils { @@ -157,20 +158,36 @@ class HtmlUtils { .replace(/ Date: Wed, 23 Aug 2023 18:16:51 +0100 Subject: [PATCH 09/13] Desktop release v2.12.13 --- packages/app-desktop/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-desktop/package.json b/packages/app-desktop/package.json index 8e268ed37..a6e4ff25a 100644 --- a/packages/app-desktop/package.json +++ b/packages/app-desktop/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/app-desktop", - "version": "2.12.12", + "version": "2.12.13", "description": "Joplin for Desktop", "main": "main.js", "private": true, From 77df474b4621ae10252be4e16985b3d0e32adb2f Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 18:28:00 +0100 Subject: [PATCH 10/13] Tools: Enable eslint rule comma-dangle: always-multiline for functions --- .eslintrc.js | 4 +-- packages/app-cli/app/LinkSelector.ts | 2 +- packages/app-cli/app/app-gui.js | 2 +- packages/app-cli/app/command-sync.ts | 2 +- packages/app-cli/app/fuzzing.js | 2 +- packages/app-cli/tests/MdToHtml.ts | 2 +- .../tests/services/plugins/PluginService.ts | 2 +- .../services/plugins/defaultPluginsUtils.ts | 2 +- packages/app-cli/tests/testUtils.ts | 2 +- packages/app-clipper/popup/config/env.js | 6 ++-- packages/app-clipper/popup/config/modules.js | 6 ++-- packages/app-clipper/popup/config/paths.js | 2 +- packages/app-clipper/popup/config/pnpTs.js | 8 ++--- packages/app-clipper/popup/scripts/start.js | 16 ++++----- packages/app-desktop/app.ts | 2 +- .../app-desktop/gui/ClipperConfigScreen.tsx | 12 +++---- .../gui/ConfigScreen/ConfigScreen.tsx | 6 ++-- .../plugins/useOnInstallHandler.test.ts | 4 +-- packages/app-desktop/gui/DialogButtonRow.tsx | 6 ++-- .../EncryptionConfigScreen.tsx | 4 +-- packages/app-desktop/gui/ErrorBoundary.tsx | 10 +++--- packages/app-desktop/gui/ExtensionBadge.tsx | 2 +- packages/app-desktop/gui/ImportScreen.tsx | 2 +- .../gui/KeymapConfig/KeymapConfigScreen.tsx | 2 +- .../KeymapConfig/utils/useCommandStatus.ts | 2 +- .../app-desktop/gui/MainScreen/MainScreen.tsx | 20 +++++------ packages/app-desktop/gui/MenuBar.tsx | 8 ++--- packages/app-desktop/gui/MultiNoteActions.tsx | 2 +- .../NoteBody/CodeMirror/CodeMirror.tsx | 6 ++-- .../NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx | 4 +-- .../gui/NoteEditor/utils/resourceHandling.ts | 2 +- .../app-desktop/gui/NotePropertiesDialog.tsx | 2 +- .../app-desktop/gui/NoteRevisionViewer.tsx | 6 ++-- packages/app-desktop/gui/PromptDialog.tsx | 8 ++--- packages/app-desktop/gui/ResourceScreen.tsx | 2 +- packages/app-desktop/gui/Root.tsx | 2 +- packages/app-desktop/gui/Sidebar/Sidebar.tsx | 30 ++++++++-------- .../gui/StatusScreen/StatusScreen.tsx | 4 +-- packages/app-desktop/gui/note-viewer/lib.js | 2 +- .../app-desktop/gui/style/ConfigMenuBar.js | 2 +- .../app-desktop/gui/utils/NoteListUtils.ts | 34 +++++++++---------- packages/app-desktop/gulpfile.js | 2 +- .../services/plugins/UserWebview.tsx | 10 +++--- .../app-mobile/components/FolderPicker.tsx | 2 +- .../NoteBodyViewer/NoteBodyViewer.tsx | 6 ++-- .../NoteBodyViewer/hooks/useSource.ts | 2 +- .../NoteEditor/CodeMirror/CodeMirror.ts | 2 +- .../CodeMirror/decoratorExtension.ts | 2 +- ...rkdownCommands.bulletedVsChecklist.test.ts | 12 +++---- .../CodeMirror/markdownCommands.test.ts | 24 ++++++------- .../markdownCommands.toggleList.test.ts | 28 +++++++-------- .../NoteEditor/CodeMirror/markdownCommands.ts | 16 ++++----- .../CodeMirror/markdownMathParser.ts | 4 +-- .../CodeMirror/markdownReformatter.test.ts | 4 +-- .../CodeMirror/markdownReformatter.ts | 20 +++++------ .../CodeMirror/syntaxHighlightingLanguages.ts | 2 +- .../CodeMirror/testUtil/createEditor.ts | 2 +- .../CodeMirror/testUtil/forceFullParse.ts | 2 +- .../NoteEditor/MarkdownToolbar/Toolbar.tsx | 4 +-- .../MarkdownToolbar/ToolbarOverflowRows.tsx | 6 ++-- .../components/NoteEditor/NoteEditor.tsx | 6 ++-- .../components/NoteEditor/SearchPanel.tsx | 8 ++--- .../ProfileSwitcher/ProfileSwitcher.tsx | 6 ++-- .../app-mobile/components/ScreenHeader.tsx | 10 +++--- .../components/biometrics/BiometricPopup.tsx | 2 +- .../screens/ConfigScreen/ConfigScreen.tsx | 22 ++++++------ .../NoteExportButton.test.tsx | 2 +- .../app-mobile/components/screens/Note.tsx | 4 +-- .../components/screens/encryption-config.tsx | 2 +- .../components/side-menu-content.tsx | 10 +++--- packages/app-mobile/gulpfile.ts | 2 +- packages/app-mobile/metro.config.js | 2 +- packages/app-mobile/root.tsx | 2 +- packages/app-mobile/tools/buildInjectedJs.ts | 4 +-- packages/app-mobile/utils/autodetectTheme.ts | 2 +- .../utils/database-driver-react-native.js | 6 ++-- .../app-mobile/utils/geolocation-react.js | 2 +- .../generator-joplin/generators/app/index.js | 8 ++--- .../app/templates/webpack.config.js | 2 +- packages/lib/EventDispatcher.ts | 2 +- packages/lib/JoplinDatabase.ts | 4 +-- packages/lib/Synchronizer.ts | 4 +-- .../components/shared/config/config-shared.js | 2 +- packages/lib/file-api-driver-dropbox.js | 4 +-- packages/lib/hooks/useEventListener.ts | 2 +- packages/lib/markJsUtils.js | 2 +- packages/lib/models/BaseItem.ts | 10 +++--- packages/lib/models/NoteResource.ts | 4 +-- packages/lib/models/Setting.ts | 4 +-- packages/lib/models/Tag.ts | 2 +- packages/lib/reducer.ts | 4 +-- packages/lib/services/KeymapService.ts | 2 +- packages/lib/services/ResourceService.ts | 2 +- packages/lib/services/RevisionService.ts | 2 +- packages/lib/services/commands/MenuUtils.ts | 4 +-- packages/lib/services/interop/Module.test.ts | 2 +- packages/lib/services/interop/Module.ts | 4 +-- .../services/plugins/api/JoplinSettings.ts | 2 +- .../lib/services/searchengine/SearchEngine.ts | 6 ++-- .../lib/services/searchengine/queryBuilder.ts | 2 +- packages/lib/services/share/ShareService.ts | 4 +-- .../synchronizer/gui/useSyncTargetUpgrade.ts | 2 +- packages/lib/versionInfo.test.ts | 6 ++-- packages/pdf-viewer/VerticalPages.tsx | 2 +- .../plugins/ToggleSidebars/webpack.config.js | 2 +- .../react-native-alarm-notification/index.js | 2 +- packages/react-native-saf-x/src/index.ts | 12 +++---- .../src/middleware/notificationHandler.ts | 2 +- packages/server/src/models/ItemModel.ts | 4 +-- packages/server/src/models/ShareModel.ts | 6 ++-- .../src/models/SubscriptionModel.test.ts | 4 +-- packages/server/src/models/UserModel.ts | 4 +-- .../items/storage/loadStorageDriver.test.ts | 2 +- packages/server/src/models/utils/user.test.ts | 2 +- packages/server/src/routes/admin/tasks.ts | 2 +- packages/server/src/routes/api/items.test.ts | 14 ++++---- .../src/routes/api/shares.folder.test.ts | 6 ++-- packages/server/src/routes/index/stripe.ts | 6 ++-- .../server/src/services/MustacheService.ts | 2 +- .../src/services/UserDeletionService.ts | 4 +-- packages/server/src/tools/debugTools.ts | 4 +-- packages/server/src/utils/auth.test.ts | 2 +- packages/tools/build-translation.js | 2 +- .../tools/gulp/tasks/buildCommandIndex.js | 2 +- packages/tools/update-readme-contributors.js | 2 +- packages/tools/update-readme-sponsors.ts | 4 +-- 126 files changed, 335 insertions(+), 335 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index dd7c141a4..0eedf8e36 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -119,7 +119,7 @@ module.exports = { 'objects': 'always-multiline', 'imports': 'always-multiline', 'exports': 'always-multiline', - 'functions': 'never', + 'functions': 'always-multiline', }], 'comma-spacing': ['error', { 'before': false, 'after': true }], 'no-trailing-spaces': 'error', @@ -209,7 +209,7 @@ module.exports = { 'enums': 'always-multiline', 'generics': 'always-multiline', 'tuples': 'always-multiline', - 'functions': 'never', + 'functions': 'always-multiline', }], '@typescript-eslint/object-curly-spacing': ['error', 'always'], '@typescript-eslint/semi': ['error', 'always'], diff --git a/packages/app-cli/app/LinkSelector.ts b/packages/app-cli/app/LinkSelector.ts index 0f028ac39..65a217f19 100644 --- a/packages/app-cli/app/LinkSelector.ts +++ b/packages/app-cli/app/LinkSelector.ts @@ -50,7 +50,7 @@ class LinkSelector { link: matches[n][0], noteX: matches[n].index, noteY: i, - } + }, ); }); } diff --git a/packages/app-cli/app/app-gui.js b/packages/app-cli/app/app-gui.js index c3a84d335..f8d81fc46 100644 --- a/packages/app-cli/app/app-gui.js +++ b/packages/app-cli/app/app-gui.js @@ -482,7 +482,7 @@ class AppGui { if (this.linkSelector_.link) { this.term_.moveTo( this.linkSelector_.noteX + cursorOffsetX, - this.linkSelector_.noteY + cursorOffsetY + this.linkSelector_.noteY + cursorOffsetY, ); shim.setTimeout(() => this.term_.term().inverse(this.linkSelector_.link), 50); } diff --git a/packages/app-cli/app/command-sync.ts b/packages/app-cli/app/command-sync.ts index 0e1379046..4e8ecec64 100644 --- a/packages/app-cli/app/command-sync.ts +++ b/packages/app-cli/app/command-sync.ts @@ -173,7 +173,7 @@ class Command extends BaseCommand { reg.db(), sync.lockHandler(), appTypeToLockType(Setting.value('appType')), - Setting.value('clientId') + Setting.value('clientId'), ); migrationHandler.setLogger(cliUtils.stdoutLogger(this.stdout.bind(this))); diff --git a/packages/app-cli/app/fuzzing.js b/packages/app-cli/app/fuzzing.js index a76dfea64..871a26c2c 100644 --- a/packages/app-cli/app/fuzzing.js +++ b/packages/app-cli/app/fuzzing.js @@ -39,7 +39,7 @@ async function createClients() { // eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied execCommand(client, 'config sync.target 2').then(() => { return execCommand(client, `config sync.2.path ${syncDir}`); - }) + }), ); output.push(client); } diff --git a/packages/app-cli/tests/MdToHtml.ts b/packages/app-cli/tests/MdToHtml.ts index 8da7784ee..05efface0 100644 --- a/packages/app-cli/tests/MdToHtml.ts +++ b/packages/app-cli/tests/MdToHtml.ts @@ -248,7 +248,7 @@ describe('MdToHtml', () => { const result = await mdToHtml.render(input, null, { bodyOnly: true, mapsToLine: true }); expect(result.html.trim()).toBe('

Head

\n' + '

Fruits

\n' + - '
    \n
  • Apple
  • \n
' + '
    \n
  • Apple
  • \n
', ); } })); diff --git a/packages/app-cli/tests/services/plugins/PluginService.ts b/packages/app-cli/tests/services/plugins/PluginService.ts index e27dfca76..722a7288a 100644 --- a/packages/app-cli/tests/services/plugins/PluginService.ts +++ b/packages/app-cli/tests/services/plugins/PluginService.ts @@ -24,7 +24,7 @@ function newPluginService(appVersion = '1.4') { { dispatch: () => {}, getState: () => {}, - } + }, ); return service; } diff --git a/packages/app-cli/tests/services/plugins/defaultPluginsUtils.ts b/packages/app-cli/tests/services/plugins/defaultPluginsUtils.ts index e4f3a43a1..58b51c1c7 100644 --- a/packages/app-cli/tests/services/plugins/defaultPluginsUtils.ts +++ b/packages/app-cli/tests/services/plugins/defaultPluginsUtils.ts @@ -19,7 +19,7 @@ function newPluginService(appVersion = '1.4') { { dispatch: () => {}, getState: () => {}, - } + }, ); return service; } diff --git a/packages/app-cli/tests/testUtils.ts b/packages/app-cli/tests/testUtils.ts index f7ffab05e..95807849f 100644 --- a/packages/app-cli/tests/testUtils.ts +++ b/packages/app-cli/tests/testUtils.ts @@ -19,7 +19,7 @@ export function newPluginService(appVersion = '1.4', options: PluginServiceOptio { dispatch: () => {}, getState: options.getState ? options.getState : () => {}, - } + }, ); return service; } diff --git a/packages/app-clipper/popup/config/env.js b/packages/app-clipper/popup/config/env.js index 562ac99e7..4a4c1aaaf 100644 --- a/packages/app-clipper/popup/config/env.js +++ b/packages/app-clipper/popup/config/env.js @@ -10,7 +10,7 @@ delete require.cache[require.resolve('./paths')]; const NODE_ENV = process.env.NODE_ENV; if (!NODE_ENV) { throw new Error( - 'The NODE_ENV environment variable is required but was not specified.' + 'The NODE_ENV environment variable is required but was not specified.', ); } @@ -36,7 +36,7 @@ dotenvFiles.forEach(dotenvFile => { require('dotenv-expand')( require('dotenv').config({ path: dotenvFile, - }) + }), ); } }); @@ -78,7 +78,7 @@ function getClientEnvironment(publicUrl) { // This should only be used as an escape hatch. Normally you would put // images into the `src` and `import` them in code to get their paths. PUBLIC_URL: publicUrl, - } + }, ); // Stringify all values so we can feed into Webpack DefinePlugin const stringified = { diff --git a/packages/app-clipper/popup/config/modules.js b/packages/app-clipper/popup/config/modules.js index 22c52f219..f08d048c8 100644 --- a/packages/app-clipper/popup/config/modules.js +++ b/packages/app-clipper/popup/config/modules.js @@ -55,8 +55,8 @@ function getAdditionalModulePaths(options = {}) { throw new Error( chalk.red.bold( 'Your project\'s `baseUrl` can only be set to `src` or `node_modules`.' + - ' Create React App does not support other values at this time.' - ) + ' Create React App does not support other values at this time.', + ), ); } @@ -109,7 +109,7 @@ function getModules() { if (hasTsConfig && hasJsConfig) { throw new Error( - 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.' + 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.', ); } diff --git a/packages/app-clipper/popup/config/paths.js b/packages/app-clipper/popup/config/paths.js index 808d27110..ae4e3b59c 100644 --- a/packages/app-clipper/popup/config/paths.js +++ b/packages/app-clipper/popup/config/paths.js @@ -55,7 +55,7 @@ const moduleFileExtensions = [ // Resolve file paths in the same order as webpack const resolveModule = (resolveFn, filePath) => { const extension = moduleFileExtensions.find(extension => - fs.existsSync(resolveFn(`${filePath}.${extension}`)) + fs.existsSync(resolveFn(`${filePath}.${extension}`)), ); if (extension) { diff --git a/packages/app-clipper/popup/config/pnpTs.js b/packages/app-clipper/popup/config/pnpTs.js index 095794572..45e97b79d 100644 --- a/packages/app-clipper/popup/config/pnpTs.js +++ b/packages/app-clipper/popup/config/pnpTs.js @@ -7,14 +7,14 @@ exports.resolveModuleName = ( moduleName, containingFile, compilerOptions, - resolutionHost + resolutionHost, ) => { return resolveModuleName( moduleName, containingFile, compilerOptions, resolutionHost, - typescript.resolveModuleName + typescript.resolveModuleName, ); }; @@ -23,13 +23,13 @@ exports.resolveTypeReferenceDirective = ( moduleName, containingFile, compilerOptions, - resolutionHost + resolutionHost, ) => { return resolveModuleName( moduleName, containingFile, compilerOptions, resolutionHost, - typescript.resolveTypeReferenceDirective + typescript.resolveTypeReferenceDirective, ); }; diff --git a/packages/app-clipper/popup/scripts/start.js b/packages/app-clipper/popup/scripts/start.js index f994c9244..73dde4f56 100644 --- a/packages/app-clipper/popup/scripts/start.js +++ b/packages/app-clipper/popup/scripts/start.js @@ -46,15 +46,15 @@ if (process.env.HOST) { console.log( chalk.cyan( `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(process.env.HOST) - )}` - ) + chalk.bold(process.env.HOST), + )}`, + ), ); console.log( - 'If this was unintentional, check that you haven\'t mistakenly set it in your shell.' + 'If this was unintentional, check that you haven\'t mistakenly set it in your shell.', ); console.log( - `Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}` + `Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}`, ); console.log(); } @@ -102,7 +102,7 @@ checkBrowsers(paths.appPath, isInteractive) // Serve webpack assets generated by the compiler over a web server. const serverConfig = createDevServerConfig( proxyConfig, - urls.lanUrlForConfig + urls.lanUrlForConfig, ); const devServer = new WebpackDevServer(compiler, serverConfig); // Launch WebpackDevServer. @@ -120,8 +120,8 @@ checkBrowsers(paths.appPath, isInteractive) if (process.env.NODE_PATH) { console.log( chalk.yellow( - 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.' - ) + 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.', + ), ); console.log(); } diff --git a/packages/app-desktop/app.ts b/packages/app-desktop/app.ts index 0fc995061..3c4b6b125 100644 --- a/packages/app-desktop/app.ts +++ b/packages/app-desktop/app.ts @@ -74,7 +74,7 @@ const pluginClasses = [ const appDefaultState = createAppDefaultState( bridge().windowContentSize(), - resourceEditWatcherDefaultState + resourceEditWatcherDefaultState, ); class Application extends BaseApplication { diff --git a/packages/app-desktop/gui/ClipperConfigScreen.tsx b/packages/app-desktop/gui/ClipperConfigScreen.tsx index 36f9c1b7b..efefe8235 100644 --- a/packages/app-desktop/gui/ClipperConfigScreen.tsx +++ b/packages/app-desktop/gui/ClipperConfigScreen.tsx @@ -71,36 +71,36 @@ class ClipperConfigScreenComponent extends React.Component { webClipperStatusComps.push(

{_('The web clipper service is enabled and set to auto-start.')} -

+

, ); if (this.props.clipperServer.startState === 'started') { webClipperStatusComps.push(

{_('Status: Started on port %d', this.props.clipperServer.port)} -

+

, ); } else { webClipperStatusComps.push(

{_('Status: %s', this.props.clipperServer.startState)} -

+

, ); } webClipperStatusComps.push( + , ); } else { webClipperStatusComps.push(

{_('The web clipper service is not enabled.')} -

+

, ); webClipperStatusComps.push( + , ); } diff --git a/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx b/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx index 767478867..4c9d5155e 100644 --- a/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx +++ b/packages/app-desktop/gui/ConfigScreen/ConfigScreen.tsx @@ -197,7 +197,7 @@ class ConfigScreenComponent extends React.Component { theme={theme} text={_('Help')} /> -

+

, ); } @@ -219,7 +219,7 @@ class ConfigScreenComponent extends React.Component { onClick={this.checkSyncConfig_} /> {statusComp} - + , ); } } @@ -381,7 +381,7 @@ class ConfigScreenComponent extends React.Component { items.push( + , ); } diff --git a/packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.test.ts b/packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.test.ts index 9a60da4f4..4629d3cc8 100644 --- a/packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.test.ts +++ b/packages/app-desktop/gui/ConfigScreen/controls/plugins/useOnInstallHandler.test.ts @@ -29,7 +29,7 @@ const callHook = (isUpdate: boolean, pluginEnabled = true, pluginInstalledViaGUI }, repoApi, onPluginSettingsChange, - isUpdate + isUpdate, ); describe('useOnInstallHandler', () => { @@ -37,7 +37,7 @@ describe('useOnInstallHandler', () => { beforeAll(() => { (PluginService.instance as jest.Mock).mockReturnValue(pluginServiceInstance); (defaultPluginSetting as jest.Mock).mockImplementation( - jest.requireActual('@joplin/lib/services/plugins/PluginService').defaultPluginSetting + jest.requireActual('@joplin/lib/services/plugins/PluginService').defaultPluginSetting, ); }); diff --git a/packages/app-desktop/gui/DialogButtonRow.tsx b/packages/app-desktop/gui/DialogButtonRow.tsx index 96d70bcb9..3ece005e5 100644 --- a/packages/app-desktop/gui/DialogButtonRow.tsx +++ b/packages/app-desktop/gui/DialogButtonRow.tsx @@ -59,7 +59,7 @@ export default function DialogButtonRow(props: Props) { buttonComps.push( + , ); } } @@ -68,7 +68,7 @@ export default function DialogButtonRow(props: Props) { buttonComps.push( + , ); } @@ -76,7 +76,7 @@ export default function DialogButtonRow(props: Props) { buttonComps.push( + , ); } diff --git a/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx b/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx index 93331d2a8..3963594c8 100644 --- a/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx +++ b/packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx @@ -64,7 +64,7 @@ const EncryptionConfigScreen = (props: Props) => { {mk.id} - + , ); } @@ -309,7 +309,7 @@ const EncryptionConfigScreen = (props: Props) => { rows.push( {id} - + , ); } diff --git a/packages/app-desktop/gui/ErrorBoundary.tsx b/packages/app-desktop/gui/ErrorBoundary.tsx index a625f4fe9..0a6182c83 100644 --- a/packages/app-desktop/gui/ErrorBoundary.tsx +++ b/packages/app-desktop/gui/ErrorBoundary.tsx @@ -89,14 +89,14 @@ export default class ErrorBoundary extends React.Component {

Message

{this.state.error.message}

-
+ , ); output.push(

Version info

{versionInfo(packageInfo, this.state.plugins).message}
-
+ , ); if (this.state.pluginInfos.length) { @@ -104,7 +104,7 @@ export default class ErrorBoundary extends React.Component {

Plugins

{JSON.stringify(this.state.pluginInfos, null, 4)}
-
+ , ); } @@ -113,7 +113,7 @@ export default class ErrorBoundary extends React.Component {

Stack trace

{this.state.error.stack}
-
+ , ); } @@ -123,7 +123,7 @@ export default class ErrorBoundary extends React.Component {

Component stack

{this.state.errorInfo.componentStack}
-
+ , ); } } diff --git a/packages/app-desktop/gui/ExtensionBadge.tsx b/packages/app-desktop/gui/ExtensionBadge.tsx index c1c962c48..2b7c38e58 100644 --- a/packages/app-desktop/gui/ExtensionBadge.tsx +++ b/packages/app-desktop/gui/ExtensionBadge.tsx @@ -53,7 +53,7 @@ const styleSelector = createSelector( }; return output; - } + }, ); function platformAssets(type: string) { diff --git a/packages/app-desktop/gui/ImportScreen.tsx b/packages/app-desktop/gui/ImportScreen.tsx index b6f278e93..97b2ade15 100644 --- a/packages/app-desktop/gui/ImportScreen.tsx +++ b/packages/app-desktop/gui/ImportScreen.tsx @@ -42,7 +42,7 @@ class ImportScreenComponent extends React.Component { }, () => { void this.doImport(); - } + }, ); } } diff --git a/packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx b/packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx index e386c495c..1a54cf5c9 100644 --- a/packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx +++ b/packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx @@ -88,7 +88,7 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {
{accelerator.split('+').map(part => {part}).reduce( (accumulator, part) => (accumulator.length ? [...accumulator, ' + ', part] : [part]), - [] + [], )}
); diff --git a/packages/app-desktop/gui/KeymapConfig/utils/useCommandStatus.ts b/packages/app-desktop/gui/KeymapConfig/utils/useCommandStatus.ts index 3bfc3537d..ca0393f78 100644 --- a/packages/app-desktop/gui/KeymapConfig/utils/useCommandStatus.ts +++ b/packages/app-desktop/gui/KeymapConfig/utils/useCommandStatus.ts @@ -12,7 +12,7 @@ const useCommandStatus = (): [CommandStatus, (commandName: string)=> void, (comm keymapService.getCommandNames().reduce((accumulator: CommandStatus, command: string) => { accumulator[command] = false; return accumulator; - }, {}) + }, {}), ); const disableStatus = (commandName: string) => setStatus(prevStatus => ({ ...prevStatus, [commandName]: false })); diff --git a/packages/app-desktop/gui/MainScreen/MainScreen.tsx b/packages/app-desktop/gui/MainScreen/MainScreen.tsx index be895e56c..82eedd330 100644 --- a/packages/app-desktop/gui/MainScreen/MainScreen.tsx +++ b/packages/app-desktop/gui/MainScreen/MainScreen.tsx @@ -608,37 +608,37 @@ class MainScreenComponent extends React.Component { msg = this.renderNotificationMessage( _('Safe mode is currently active. Note rendering and all plugins are temporarily disabled.'), _('Disable safe mode and restart'), - onDisableSafeModeAndRestart + onDisableSafeModeAndRestart, ); } else if (this.props.hasMissingSyncCredentials) { msg = this.renderNotificationMessage( _('The synchronisation password is missing.'), _('Set the password'), - onViewSyncSettingsScreen + onViewSyncSettingsScreen, ); } else if (this.props.shouldUpgradeSyncTarget) { msg = this.renderNotificationMessage( _('The sync target needs to be upgraded before Joplin can sync. The operation may take a few minutes to complete and the app needs to be restarted. To proceed please click on the link.'), _('Restart and upgrade'), - onRestartAndUpgrade + onRestartAndUpgrade, ); } else if (this.props.hasDisabledEncryptionItems) { msg = this.renderNotificationMessage( _('Some items cannot be decrypted.'), _('View them now'), - onViewStatusScreen + onViewStatusScreen, ); } else if (this.props.showNeedUpgradingMasterKeyMessage) { msg = this.renderNotificationMessage( _('One of your master keys use an obsolete encryption method.'), _('View them now'), - onViewEncryptionConfigScreen + onViewEncryptionConfigScreen, ); } else if (this.props.showShouldReencryptMessage) { msg = this.renderNotificationMessage( _('The default encryption method has been changed, you should re-encrypt your data.'), _('More info'), - onViewEncryptionConfigScreen + onViewEncryptionConfigScreen, ); } else if (this.showShareInvitationNotification(this.props)) { const invitation = this.props.shareInvitations.find(inv => inv.status === 0); @@ -649,25 +649,25 @@ class MainScreenComponent extends React.Component { _('Accept'), () => onInvitationRespond(invitation.id, invitation.share.folder_id, invitation.master_key, true), _('Reject'), - () => onInvitationRespond(invitation.id, invitation.share.folder_id, invitation.master_key, false) + () => onInvitationRespond(invitation.id, invitation.share.folder_id, invitation.master_key, false), ); } else if (this.props.hasDisabledSyncItems) { msg = this.renderNotificationMessage( _('Some items cannot be synchronised.'), _('View them now'), - onViewStatusScreen + onViewStatusScreen, ); } else if (this.props.showMissingMasterKeyMessage) { msg = this.renderNotificationMessage( _('One or more master keys need a password.'), _('Set the password'), - onViewEncryptionConfigScreen + onViewEncryptionConfigScreen, ); } else if (this.props.showInstallTemplatesPlugin) { msg = this.renderNotificationMessage( 'The template feature has been moved to a plugin called "Templates".', 'Install plugin', - onViewPluginScreen + onViewPluginScreen, ); } diff --git a/packages/app-desktop/gui/MenuBar.tsx b/packages/app-desktop/gui/MenuBar.tsx index 7743c969b..b8e617805 100644 --- a/packages/app-desktop/gui/MenuBar.tsx +++ b/packages/app-desktop/gui/MenuBar.tsx @@ -301,7 +301,7 @@ function useMenu(props: Props) { return menuUtils.commandsToMenuItems( commandNames.concat(pluginCommandNames), (commandName: string) => onMenuItemClickRef.current(commandName), - props.locale + props.locale, ); // eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied }, [commandNames, pluginCommandNames, props.locale]); @@ -347,7 +347,7 @@ function useMenu(props: Props) { if (type === 'notes') { sortItems.push( { ...menuItemDic.toggleNotesSortOrderReverse, type: 'checkbox' }, - { ...menuItemDic.toggleNotesSortOrderField, visible: false } + { ...menuItemDic.toggleNotesSortOrderField, visible: false }, ); } else { sortItems.push({ @@ -391,7 +391,7 @@ function useMenu(props: Props) { { plugins: pluginsRef.current, customCss: props.customCss, - } + }, ); }, }); @@ -414,7 +414,7 @@ function useMenu(props: Props) { }); exportItems.push( - menuItemDic.exportPdf + menuItemDic.exportPdf, ); // We need a dummy entry, otherwise the ternary operator to show a diff --git a/packages/app-desktop/gui/MultiNoteActions.tsx b/packages/app-desktop/gui/MultiNoteActions.tsx index 6290ed35e..7d748171d 100644 --- a/packages/app-desktop/gui/MultiNoteActions.tsx +++ b/packages/app-desktop/gui/MultiNoteActions.tsx @@ -68,7 +68,7 @@ export default function MultiNoteActions(props: MultiNoteActionsProps) { itemComps.push( + , ); } diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx index a3a0cd24c..829129056 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.tsx @@ -838,7 +838,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { click: async () => { editorCutText(); }, - }) + }), ); menu.append( @@ -848,7 +848,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { click: async () => { editorCopyText(); }, - }) + }), ); menu.append( @@ -858,7 +858,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) { click: async () => { editorPaste(); }, - }) + }), ); const spellCheckerMenuItems = SpellCheckerService.instance().contextMenuItems(params.misspelledWord, params.dictionarySuggestions); diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx index 7258bffff..dced14c23 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx @@ -750,13 +750,13 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { ].concat( pluginAssets .filter((a: any) => a.mime === 'text/css') - .map((a: any) => a.path) + .map((a: any) => a.path), ); const allJsFiles = [].concat( pluginAssets .filter((a: any) => a.mime === 'application/javascript') - .map((a: any) => a.path) + .map((a: any) => a.path), ); diff --git a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts index 11c8e90d0..339349268 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts @@ -181,6 +181,6 @@ export async function processPastedHtml(html: string) { return mappedResources[src]; }), { allowedFilePrefixes: [Setting.value('resourceDir')], - } + }, ); } diff --git a/packages/app-desktop/gui/NotePropertiesDialog.tsx b/packages/app-desktop/gui/NotePropertiesDialog.tsx index 4054c7785..d97a4d22b 100644 --- a/packages/app-desktop/gui/NotePropertiesDialog.tsx +++ b/packages/app-desktop/gui/NotePropertiesDialog.tsx @@ -231,7 +231,7 @@ class NotePropertiesDialog extends React.Component { }, () => { resolve(); - } + }, ); }); } diff --git a/packages/app-desktop/gui/NoteRevisionViewer.tsx b/packages/app-desktop/gui/NoteRevisionViewer.tsx index 580008999..8eef140ab 100644 --- a/packages/app-desktop/gui/NoteRevisionViewer.tsx +++ b/packages/app-desktop/gui/NoteRevisionViewer.tsx @@ -88,7 +88,7 @@ class NoteRevisionViewerComponent extends React.PureComponent { }, () => { void this.reloadNote(); - } + }, ); } @@ -116,7 +116,7 @@ class NoteRevisionViewerComponent extends React.PureComponent { }, () => { void this.reloadNote(); - } + }, ); } } @@ -198,7 +198,7 @@ class NoteRevisionViewerComponent extends React.PureComponent { revisionListItems.push( + , ); } diff --git a/packages/app-desktop/gui/PromptDialog.tsx b/packages/app-desktop/gui/PromptDialog.tsx index f76a2a006..1e814c416 100644 --- a/packages/app-desktop/gui/PromptDialog.tsx +++ b/packages/app-desktop/gui/PromptDialog.tsx @@ -275,28 +275,28 @@ export default class PromptDialog extends React.Component { buttonComps.push( + , ); } if (buttonTypes.indexOf('ok') >= 0) { buttonComps.push( + , ); } if (buttonTypes.indexOf('cancel') >= 0) { buttonComps.push( + , ); } if (buttonTypes.indexOf('clear') >= 0) { buttonComps.push( + , ); } diff --git a/packages/app-desktop/gui/ResourceScreen.tsx b/packages/app-desktop/gui/ResourceScreen.tsx index 6bf7cb3e5..35a8db9e3 100644 --- a/packages/app-desktop/gui/ResourceScreen.tsx +++ b/packages/app-desktop/gui/ResourceScreen.tsx @@ -111,7 +111,7 @@ const ResourceTableComp = (props: ResourceTable) => { - + , )} diff --git a/packages/app-desktop/gui/Root.tsx b/packages/app-desktop/gui/Root.tsx index 0e7797a29..da1e4c061 100644 --- a/packages/app-desktop/gui/Root.tsx +++ b/packages/app-desktop/gui/Root.tsx @@ -267,5 +267,5 @@ root.render( - + , ); diff --git a/packages/app-desktop/gui/Sidebar/Sidebar.tsx b/packages/app-desktop/gui/Sidebar/Sidebar.tsx index fbff0a1f4..439263e08 100644 --- a/packages/app-desktop/gui/Sidebar/Sidebar.tsx +++ b/packages/app-desktop/gui/Sidebar/Sidebar.tsx @@ -280,7 +280,7 @@ const SidebarComponent = (props: Props) => { const menu = new Menu(); menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem('newFolder')) + new MenuItem(menuUtils.commandToStatefulMenuItem('newFolder')), ); menu.popup({ window: bridge().window() }); @@ -314,13 +314,13 @@ const SidebarComponent = (props: Props) => { if (itemType === BaseModel.TYPE_FOLDER && !item.encryption_applied) { menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem('newFolder', itemId)) + new MenuItem(menuUtils.commandToStatefulMenuItem('newFolder', itemId)), ); } if (itemType === BaseModel.TYPE_FOLDER) { menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem('deleteFolder', itemId)) + new MenuItem(menuUtils.commandToStatefulMenuItem('deleteFolder', itemId)), ); } else { menu.append( @@ -342,7 +342,7 @@ const SidebarComponent = (props: Props) => { }); } }, - }) + }), ); } @@ -364,7 +364,7 @@ const SidebarComponent = (props: Props) => { click: async () => { await InteropServiceHelper.export(props.dispatch, module, { sourceFolderIds: [itemId], plugins: pluginsRef.current }); }, - }) + }), ); } @@ -386,7 +386,7 @@ const SidebarComponent = (props: Props) => { new MenuItem({ label: _('Export'), submenu: exportMenu, - }) + }), ); if (Setting.value('notes.perFolderSortOrderEnabled')) { menu.append(new MenuItem({ @@ -404,13 +404,13 @@ const SidebarComponent = (props: Props) => { click: () => { clipboard.writeText(getFolderCallbackUrl(itemId)); }, - }) + }), ); } if (itemType === BaseModel.TYPE_TAG) { menu.append(new MenuItem( - menuUtils.commandToStatefulMenuItem('renameTag', itemId) + menuUtils.commandToStatefulMenuItem('renameTag', itemId), )); menu.append( new MenuItem({ @@ -418,7 +418,7 @@ const SidebarComponent = (props: Props) => { click: () => { clipboard.writeText(getTagCallbackUrl(itemId)); }, - }) + }), ); } @@ -431,7 +431,7 @@ const SidebarComponent = (props: Props) => { itemType === ModelType.Folder && location === MenuItemLocation.FolderContextMenu ) { menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem(view.commandName, itemId)) + new MenuItem(menuUtils.commandToStatefulMenuItem(view.commandName, itemId)), ); } } @@ -705,7 +705,7 @@ const SidebarComponent = (props: Props) => { onDrop: onFolderDrop_, ['data-folder-id']: '', toggleblock: 1, - }) + }), ); const foldersStyle = useMemo(() => { @@ -725,14 +725,14 @@ const SidebarComponent = (props: Props) => { style={foldersStyle} > {folderItems} - + , ); } items.push( renderHeader('tagHeader', _('Tags'), 'icon-tags', null, null, { toggleblock: 1, - }) + }), ); if (props.tags.length) { @@ -743,7 +743,7 @@ const SidebarComponent = (props: Props) => { items.push(
{tagItems} -
+ , ); } @@ -765,7 +765,7 @@ const SidebarComponent = (props: Props) => { syncReportText.push( {lines[i]} - + , ); } diff --git a/packages/app-desktop/gui/StatusScreen/StatusScreen.tsx b/packages/app-desktop/gui/StatusScreen/StatusScreen.tsx index 07f92aa09..dd224781b 100644 --- a/packages/app-desktop/gui/StatusScreen/StatusScreen.tsx +++ b/packages/app-desktop/gui/StatusScreen/StatusScreen.tsx @@ -133,14 +133,14 @@ function StatusScreen(props: Props) {
  • {text} {retryLink} -
  • + , ); } else { itemsHtml.push(
    {text} {retryLink} -
    + , ); } } diff --git a/packages/app-desktop/gui/note-viewer/lib.js b/packages/app-desktop/gui/note-viewer/lib.js index f9cf2ab85..eb55e77a6 100644 --- a/packages/app-desktop/gui/note-viewer/lib.js +++ b/packages/app-desktop/gui/note-viewer/lib.js @@ -112,7 +112,7 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => { return true; }, ...extraOptions, - } + }, ); }; diff --git a/packages/app-desktop/gui/style/ConfigMenuBar.js b/packages/app-desktop/gui/style/ConfigMenuBar.js index d1cf1d6a7..479a9779c 100644 --- a/packages/app-desktop/gui/style/ConfigMenuBar.js +++ b/packages/app-desktop/gui/style/ConfigMenuBar.js @@ -46,7 +46,7 @@ const style = createSelector( output.buttonLabelSelected = { ...output.buttonLabel, color: theme.color }; return output; - } + }, ); module.exports = style; diff --git a/packages/app-desktop/gui/utils/NoteListUtils.ts b/packages/app-desktop/gui/utils/NoteListUtils.ts index 1f36b52ef..c7c6e70ea 100644 --- a/packages/app-desktop/gui/utils/NoteListUtils.ts +++ b/packages/app-desktop/gui/utils/NoteListUtils.ts @@ -45,15 +45,15 @@ export default class NoteListUtils { if (!hasEncrypted) { menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem('setTags', noteIds)) + new MenuItem(menuUtils.commandToStatefulMenuItem('setTags', noteIds)), ); menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem('moveToFolder', noteIds)) + new MenuItem(menuUtils.commandToStatefulMenuItem('moveToFolder', noteIds)), ); menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem('duplicateNote', noteIds)) + new MenuItem(menuUtils.commandToStatefulMenuItem('duplicateNote', noteIds)), ); if (singleNoteId) { @@ -64,8 +64,8 @@ export default class NoteListUtils { if (noteIds.length <= 1) { menu.append( new MenuItem( - menuUtils.commandToStatefulMenuItem('toggleNoteType', noteIds) - ) + menuUtils.commandToStatefulMenuItem('toggleNoteType', noteIds), + ), ); } else { const switchNoteType = async (noteIds: string[], type: string) => { @@ -84,7 +84,7 @@ export default class NoteListUtils { click: async () => { await switchNoteType(noteIds, 'note'); }, - }) + }), ); menu.append( @@ -93,7 +93,7 @@ export default class NoteListUtils { click: async () => { await switchNoteType(noteIds, 'todo'); }, - }) + }), ); } @@ -108,7 +108,7 @@ export default class NoteListUtils { } clipboard.writeText(links.join(' ')); }, - }) + }), ); if (noteIds.length === 1) { @@ -118,15 +118,15 @@ export default class NoteListUtils { click: () => { clipboard.writeText(getNoteCallbackUrl(noteIds[0])); }, - }) + }), ); } if ([9, 10].includes(Setting.value('sync.target'))) { menu.append( new MenuItem( - menuUtils.commandToStatefulMenuItem('showShareNoteDialog', noteIds.slice()) - ) + menuUtils.commandToStatefulMenuItem('showShareNoteDialog', noteIds.slice()), + ), ); } @@ -150,14 +150,14 @@ export default class NoteListUtils { customCss: props.customCss, }); }, - }) + }), ); } exportMenu.append( new MenuItem( - menuUtils.commandToStatefulMenuItem('exportPdf', noteIds) - ) + menuUtils.commandToStatefulMenuItem('exportPdf', noteIds), + ), ); const exportMenuItem = new MenuItem({ label: _('Export'), submenu: exportMenu }); @@ -167,8 +167,8 @@ export default class NoteListUtils { menu.append( new MenuItem( - menuUtils.commandToStatefulMenuItem('deleteNote', noteIds) - ) + menuUtils.commandToStatefulMenuItem('deleteNote', noteIds), + ), ); const pluginViewInfos = pluginUtils.viewInfosByType(props.plugins, 'menuItem'); @@ -179,7 +179,7 @@ export default class NoteListUtils { if (cmdService.isEnabled(info.view.commandName)) { menu.append( - new MenuItem(menuUtils.commandToStatefulMenuItem(info.view.commandName, noteIds)) + new MenuItem(menuUtils.commandToStatefulMenuItem(info.view.commandName, noteIds)), ); } } diff --git a/packages/app-desktop/gulpfile.js b/packages/app-desktop/gulpfile.js index 5789d859b..1fec0b95f 100644 --- a/packages/app-desktop/gulpfile.js +++ b/packages/app-desktop/gulpfile.js @@ -31,7 +31,7 @@ const tasks = { fn: async () => { await compileSass( `${__dirname}/style.scss`, - `${__dirname}/style.min.css` + `${__dirname}/style.min.css`, ); }, }, diff --git a/packages/app-desktop/services/plugins/UserWebview.tsx b/packages/app-desktop/services/plugins/UserWebview.tsx index 544ab05d1..ecdada73a 100644 --- a/packages/app-desktop/services/plugins/UserWebview.tsx +++ b/packages/app-desktop/services/plugins/UserWebview.tsx @@ -108,7 +108,7 @@ function UserWebview(props: Props, ref: any) { frameWindow(), isReady, postMessage, - props.html + props.html, ); const contentSize = useContentSize( @@ -117,14 +117,14 @@ function UserWebview(props: Props, ref: any) { minWidth, minHeight, props.fitToContent, - isReady + isReady, ); useSubmitHandler( frameWindow(), props.onSubmit, props.onDismiss, - htmlHash + htmlHash, ); useWebviewToPluginMessages( @@ -132,14 +132,14 @@ function UserWebview(props: Props, ref: any) { isReady, props.pluginId, props.viewId, - postMessage + postMessage, ); useScriptLoader( postMessage, isReady, props.scripts, - cssFilePath + cssFilePath, ); return = ({ const theme = themeStyle(themeId); const addFolderChildren = ( - folders: FolderEntityWithChildren[], pickerItems: DropdownListItem[], indent: number + folders: FolderEntityWithChildren[], pickerItems: DropdownListItem[], indent: number, ) => { folders.sort((a, b) => { const aTitle = a && a.title ? a.title : ''; diff --git a/packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.tsx b/packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.tsx index 7a1519cdf..04d94c34d 100644 --- a/packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.tsx +++ b/packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.tsx @@ -43,12 +43,12 @@ export default function NoteBodyViewer(props: Props) { props.highlightedKeywords, props.noteResources, props.paddingBottom, - props.noteHash + props.noteHash, ); const onResourceLongPress = useOnResourceLongPress( props.onJoplinLinkClick, - dialogBoxRef + dialogBoxRef, ); const onMessage = useOnMessage( @@ -56,7 +56,7 @@ export default function NoteBodyViewer(props: Props) { props.noteBody, props.onMarkForDownload, props.onJoplinLinkClick, - onResourceLongPress + onResourceLongPress, ); const onLoadEnd = useCallback(() => { diff --git a/packages/app-mobile/components/NoteBodyViewer/hooks/useSource.ts b/packages/app-mobile/components/NoteBodyViewer/hooks/useSource.ts index b18e4efce..3cc37e5c3 100644 --- a/packages/app-mobile/components/NoteBodyViewer/hooks/useSource.ts +++ b/packages/app-mobile/components/NoteBodyViewer/hooks/useSource.ts @@ -125,7 +125,7 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number, noteMarkupLanguage, bodyToRender, rendererTheme, - mdOptions + mdOptions, ); if (cancelled) return; diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts index 16326ec45..658089471 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts @@ -51,7 +51,7 @@ interface CodeMirrorResult extends CodeMirrorControl { } export function initCodeMirror( - parentElement: any, initialText: string, settings: EditorSettings + parentElement: any, initialText: string, settings: EditorSettings, ): CodeMirrorResult { logMessage('Initializing CodeMirror...'); const theme = settings.themeData; diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts index c37c7ed84..c0e8c70b6 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts @@ -82,7 +82,7 @@ const computeDecorations = (view: EditorView) => { for (const { from, to } of view.visibleRanges) { ensureSyntaxTree( view.state, - to + to, )?.iterate({ from, to, enter: node => { diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.ts index b4e73e350..ff81ea4b6 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.ts @@ -11,35 +11,35 @@ describe('markdownCommands.bulletedVsChecklist', () => { it('should remove a checklist following a bulleted list without modifying the bulleted list', async () => { const editor = await createEditor( - initialDocText, EditorSelection.cursor(bulletedListPart.length + 5), expectedTags + initialDocText, EditorSelection.cursor(bulletedListPart.length + 5), expectedTags, ); toggleList(ListType.CheckList)(editor); expect(editor.state.doc.toString()).toBe( - `${bulletedListPart}\n\nThis is a checklist\nwith multiple items.\n☑` + `${bulletedListPart}\n\nThis is a checklist\nwith multiple items.\n☑`, ); }); it('should remove an unordered list following a checklist without modifying the checklist', async () => { const editor = await createEditor( - initialDocText, EditorSelection.cursor(bulletedListPart.length - 5), expectedTags + initialDocText, EditorSelection.cursor(bulletedListPart.length - 5), expectedTags, ); toggleList(ListType.UnorderedList)(editor); expect(editor.state.doc.toString()).toBe( - `Test\nThis is a test.\n3\n4\n5\n\n${checklistPart}` + `Test\nThis is a test.\n3\n4\n5\n\n${checklistPart}`, ); }); it('should replace a selection of unordered and task lists with a correctly-numbered list', async () => { const editor = await createEditor( - initialDocText, EditorSelection.range(0, initialDocText.length), expectedTags + initialDocText, EditorSelection.range(0, initialDocText.length), expectedTags, ); toggleList(ListType.OrderedList)(editor); expect(editor.state.doc.toString()).toBe( '1. Test\n2. This is a test.\n3. 3\n4. 4\n5. 5' - + '\n\n6. This is a checklist\n7. with multiple items.\n8. ☑' + + '\n\n6. This is a checklist\n7. with multiple items.\n8. ☑', ); }); }); diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.ts index 5f2d8f2f0..d7c44bd31 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.ts @@ -9,7 +9,7 @@ describe('markdownCommands', () => { it('should bold/italicize everything selected', async () => { const initialDocText = 'Testing...'; const editor = await createEditor( - initialDocText, EditorSelection.range(0, initialDocText.length), [] + initialDocText, EditorSelection.range(0, initialDocText.length), [], ); toggleBolded(editor); @@ -36,7 +36,7 @@ describe('markdownCommands', () => { it('for a cursor, bolding, then italicizing, should produce a bold-italic region', async () => { const initialDocText = ''; const editor = await createEditor( - initialDocText, EditorSelection.cursor(0), [] + initialDocText, EditorSelection.cursor(0), [], ); toggleBolded(editor); @@ -110,14 +110,14 @@ describe('markdownCommands', () => { const editor = await createEditor( initialDocText, EditorSelection.cursor('Testing...\n\n> This'.length), - ['Blockquote'] + ['Blockquote'], ); toggleHeaderLevel(1)(editor); const mainSel = editor.state.selection.main; expect(editor.state.doc.toString()).toBe( - 'Testing...\n\n> # This is a test.\n> ...a test' + 'Testing...\n\n> # This is a test.\n> ...a test', ); expect(mainSel.empty).toBe(true); expect(mainSel.from).toBe('Testing...\n\n> # This is a test.'.length); @@ -125,7 +125,7 @@ describe('markdownCommands', () => { toggleHeaderLevel(3)(editor); expect(editor.state.doc.toString()).toBe( - 'Testing...\n\n> ### This is a test.\n> ...a test' + 'Testing...\n\n> ### This is a test.\n> ...a test', ); }); @@ -135,9 +135,9 @@ describe('markdownCommands', () => { initialDocText, EditorSelection.range( 'Testing...\n\n> This'.length, - 'Testing...\n\n> This is a test.\n> y = mx + b'.length + 'Testing...\n\n> This is a test.\n> y = mx + b'.length, ), - ['Blockquote'] + ['Blockquote'], ); toggleMath(editor); @@ -145,7 +145,7 @@ describe('markdownCommands', () => { // Toggling math should surround the content in '$$'s const mainSel = editor.state.selection.main; expect(editor.state.doc.toString()).toEqual( - 'Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$\n> ...a test' + 'Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$\n> ...a test', ); expect(mainSel.from).toBe('Testing...\n\n'.length); expect(mainSel.to).toBe('Testing...\n\n> $$\n> This is a test.\n> y = mx + b\n> $$'.length); @@ -157,7 +157,7 @@ describe('markdownCommands', () => { const editor = await createEditor( initialDocText, EditorSelection.cursor('Testing...\n\n> $$\n> This is'.length), - ['Blockquote', blockMathTagName] + ['Blockquote', blockMathTagName], ); // Toggling math should remove the '$$'s @@ -174,12 +174,12 @@ describe('markdownCommands', () => { updateLink('bar', 'https://example.com/')(editor); expect(editor.state.doc.toString()).toBe( - '[bar](https://example.com/)' + '[bar](https://example.com/)', ); updateLink('', 'https://example.com/')(editor); expect(editor.state.doc.toString()).toBe( - 'https://example.com/' + 'https://example.com/', ); }); @@ -225,7 +225,7 @@ describe('markdownCommands', () => { toggleMath(editor); editor.dispatch(editor.state.replaceSelection('f(x) = ...')); expect(editor.state.doc.toString()).toBe( - '> Testing...> \n> \n> $$\n> f(x) = ...\n> $$' + '> Testing...> \n> \n> $$\n> f(x) = ...\n> $$', ); // If we toggle math again, everything from the start of the line with the first diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.ts index 8e04c658c..e2b85c21a 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.ts @@ -12,12 +12,12 @@ describe('markdownCommands.toggleList', () => { const editor = await createEditor( initialDocText, EditorSelection.cursor(5), - ['BulletList', 'InlineCode'] + ['BulletList', 'InlineCode'], ); toggleList(ListType.UnorderedList)(editor); expect(editor.state.doc.toString()).toBe( - 'testing\nthis is a `test`\n' + 'testing\nthis is a `test`\n', ); }); @@ -26,12 +26,12 @@ describe('markdownCommands.toggleList', () => { const editor = await createEditor( initialDocText, EditorSelection.cursor('Testing...\nThis is a'.length), - [] + [], ); toggleList(ListType.OrderedList)(editor); expect(editor.state.doc.toString()).toBe( - 'Testing...\n1. This is a test\nof list toggling...' + 'Testing...\n1. This is a test\nof list toggling...', ); editor.setState(EditorState.create({ @@ -41,7 +41,7 @@ describe('markdownCommands.toggleList', () => { toggleList(ListType.OrderedList)(editor); expect(editor.state.doc.toString()).toBe( - '1. Testing...\n2. This is a test\n3. of list toggling...' + '1. Testing...\n2. This is a test\n3. of list toggling...', ); }); @@ -51,12 +51,12 @@ describe('markdownCommands.toggleList', () => { const editor = await createEditor( unorderedListText, EditorSelection.cursor(unorderedListText.length), - ['BulletList'] + ['BulletList'], ); toggleList(ListType.OrderedList)(editor); expect(editor.state.doc.toString()).toBe( - '1. 1\n2. 2\n3. 3\n4. 4\n5. 5\n6. 6\n7. 7' + '1. 1\n2. 2\n3. 3\n4. 4\n5. 5\n6. 6\n7. 7', ); }); @@ -154,12 +154,12 @@ describe('markdownCommands.toggleList', () => { const editor = await createEditor( initialDocText, EditorSelection.cursor(0), - ['OrderedList', 'BulletList'] + ['OrderedList', 'BulletList'], ); toggleList(ListType.CheckList)(editor); expect(editor.state.doc.toString()).toBe( - '- [ ] Foo\n- [ ] Bar\n- [ ] Baz\n\t- Test\n\t- of\n\t- sublists\n- [ ] Foo' + '- [ ] Foo\n- [ ] Bar\n- [ ] Baz\n\t- Test\n\t- of\n\t- sublists\n- [ ] Foo', ); }); @@ -169,7 +169,7 @@ describe('markdownCommands.toggleList', () => { const editor = await createEditor( initialDocText, EditorSelection.cursor(initialDocText.length), - ['OrderedList'] + ['OrderedList'], ); increaseIndent(editor); @@ -177,12 +177,12 @@ describe('markdownCommands.toggleList', () => { toggleList(ListType.CheckList)(editor); expect(editor.state.doc.toString()).toBe( - '1. This\n2. is\n\t- [ ] ' + '1. This\n2. is\n\t- [ ] ', ); editor.dispatch(editor.state.replaceSelection('a test.')); expect(editor.state.doc.toString()).toBe( - '1. This\n2. is\n\t- [ ] a test.' + '1. This\n2. is\n\t- [ ] a test.', ); }); @@ -191,12 +191,12 @@ describe('markdownCommands.toggleList', () => { const initialDocText = `${preSubListText}> \t* a\n> \t* test\n> * of list toggling`; const editor = await createEditor( initialDocText, EditorSelection.cursor(preSubListText.length + 3), - ['BlockQuote', 'BulletList'] + ['BlockQuote', 'BulletList'], ); toggleList(ListType.OrderedList)(editor); expect(editor.state.doc.toString()).toBe( - '> # List test\n> * This\n> * is\n> \t1. a\n> \t2. test\n> * of list toggling' + '> # List test\n> * This\n> * is\n> \t1. a\n> \t2. test\n> * of list toggling', ); expect(editor.state.selection.main.from).toBe(preSubListText.length); }); diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.ts index 6c533bfc2..7f3c8edb8 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.ts @@ -250,7 +250,7 @@ export const toggleList = (listType: ListType): Command => { sel = EditorSelection.range( doc.line(newFromLineNo).from, - doc.line(newToLineNo).to + doc.line(newToLineNo).to, ); computeSelectionProps(); } @@ -299,7 +299,7 @@ export const toggleList = (listType: ListType): Command => { const containerMatch = lineContent.match(containerRegex); if (!containerMatch) { throw new Error( - 'Assertion failed: container regex does not match line content.' + 'Assertion failed: container regex does not match line content.', ); } @@ -336,7 +336,7 @@ export const toggleList = (listType: ListType): Command => { } else { sel = EditorSelection.range( sel.from, - sel.to + charsAdded + sel.to + charsAdded, ); } @@ -374,10 +374,10 @@ export const toggleHeaderLevel = (level: number): Command => { `${level - 1 >= 1 ? `(?:^[#]{1,${level - 1}}\\s)|` : '' // Check all number of #s higher than [level] - }(?:^[#]{${level + 1},}\\s)` + }(?:^[#]{${level + 1},}\\s)`, ), '', - matchEmpty + matchEmpty, ); view.dispatch(changes); @@ -387,7 +387,7 @@ export const toggleHeaderLevel = (level: number): Command => { // We want exactly [level] '#' characters. new RegExp(`^[#]{${level}} `), `${headerStr} `, - matchEmpty + matchEmpty, ); view.dispatch(changes); @@ -408,7 +408,7 @@ export const increaseIndent: Command = (view: EditorView): boolean => { matchNothing, // ...and thus always add indentUnit. indentUnit, - matchEmpty + matchEmpty, ); view.dispatch(changes); @@ -429,7 +429,7 @@ export const decreaseIndent: Command = (view: EditorView): boolean => { new RegExp(`^(?:[\\t]|[ ]{1,${getIndentUnit(view.state)}})`), // Don't add new text '', - matchEmpty + matchEmpty, ); view.dispatch(changes); diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.ts index eefd00cba..5e8d0910a 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.ts @@ -143,7 +143,7 @@ const BlockMathConfig: MarkdownConfig = { let stop; let endMatch = mathBlockEndRegex.exec( - line.text.substring(mathStartMatch[0].length) + line.text.substring(mathStartMatch[0].length), ); // If the math region ends immediately (on the same line), @@ -183,7 +183,7 @@ const BlockMathConfig: MarkdownConfig = { Math.min(lineEnd, stop + delimLen), // The child of the container element should be the content element - [contentElem] + [contentElem], ); cx.addElement(containerElement); diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.ts index 7aedba8e4..b4277a7d7 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.ts @@ -103,7 +103,7 @@ describe('markdownReformatter', () => { }); const changes = toggleRegionFormatGlobally( - initialState, inlineCodeRegionSpec, blockCodeRegionSpec + initialState, inlineCodeRegionSpec, blockCodeRegionSpec, ); const newState = initialState.update(changes).state; @@ -117,7 +117,7 @@ describe('markdownReformatter', () => { }); const changes = toggleRegionFormatGlobally( - initialState, inlineCodeRegionSpec, blockCodeRegionSpec + initialState, inlineCodeRegionSpec, blockCodeRegionSpec, ); const newState = initialState.update(changes).state; diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.ts index 306781637..7e95f78ea 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.ts @@ -84,7 +84,7 @@ export enum MatchSide { // Returns the length of a match for this in the given selection, // -1 if no match is found. export const findInlineMatch = ( - doc: DocumentText, spec: RegionSpec, sel: SelectionRange, side: MatchSide + doc: DocumentText, spec: RegionSpec, sel: SelectionRange, side: MatchSide, ): number => { const [regex, template] = (() => { if (side === MatchSide.Start) { @@ -182,7 +182,7 @@ export const isIndentationEquivalent = (state: EditorState, a: string, b: string // Expands and returns a copy of [sel] to the smallest container node with name in [nodeNames]. export const growSelectionToNode = ( - state: EditorState, sel: SelectionRange, nodeNames: string|string[]|null + state: EditorState, sel: SelectionRange, nodeNames: string|string[]|null, ): SelectionRange => { if (!nodeNames) { return sel; @@ -235,7 +235,7 @@ export const growSelectionToNode = ( // If the selection is already surrounded by these characters, they are // removed. const toggleInlineRegionSurrounded = ( - doc: DocumentText, sel: SelectionRange, spec: RegionSpec + doc: DocumentText, sel: SelectionRange, spec: RegionSpec, ): SelectionUpdate => { let content = doc.sliceString(sel.from, sel.to); const startMatchLen = findInlineMatch(doc, spec, sel, MatchSide.Start); @@ -291,7 +291,7 @@ const toggleInlineRegionSurrounded = ( // Returns updated selections: For all selections in the given `EditorState`, toggles // whether each is contained in an inline region of type [spec]. export const toggleInlineSelectionFormat = ( - state: EditorState, spec: RegionSpec, sel: SelectionRange + state: EditorState, spec: RegionSpec, sel: SelectionRange, ): SelectionUpdate => { const endMatchLen = findInlineMatch(state.doc, spec, sel, MatchSide.End); @@ -315,7 +315,7 @@ export const toggleInlineSelectionFormat = ( // Like toggleInlineSelectionFormat, but for all selections in [state]. export const toggleInlineFormatGlobally = ( - state: EditorState, spec: RegionSpec + state: EditorState, spec: RegionSpec, ): TransactionSpec => { const changes = state.changeByRange((sel: SelectionRange) => { return toggleInlineSelectionFormat(state, spec, sel); @@ -328,13 +328,13 @@ export const toggleRegionFormatGlobally = ( state: EditorState, inlineSpec: RegionSpec, - blockSpec: RegionSpec + blockSpec: RegionSpec, ): TransactionSpec => { const doc = state.doc; const preserveBlockQuotes = true; const getMatchEndPoints = ( - match: RegExpMatchArray, line: Line, inBlockQuote: boolean + match: RegExpMatchArray, line: Line, inBlockQuote: boolean, ): [startIdx: number, stopIdx: number] => { const startIdx = line.from + match.index; let stopIdx; @@ -499,7 +499,7 @@ export const toggleRegionFormatGlobally = ( // Selection should now encompass all lines that were changed. range: EditorSelection.range( - fromLine.from, toLine.to + charsAdded + fromLine.from, toLine.to + charsAdded, ), }; }); @@ -515,7 +515,7 @@ export const toggleSelectedLinesStartWith = ( matchEmpty: boolean, // Name associated with what [regex] matches (e.g. FencedCode) - nodeName?: string + nodeName?: string, ): TransactionSpec => { const ignoreBlockQuotes = true; const getLineContentStart = (line: Line): number => { @@ -701,7 +701,7 @@ export const renumberList = (state: EditorState, sel: SelectionRange): Selection } else { sel = EditorSelection.range( fromLine.from, - toLine.to + charsAdded + toLine.to + charsAdded, ); } diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts index 4b9d13bfd..aa2d85f94 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts @@ -229,7 +229,7 @@ for (const language of supportedLanguages) { name: language.name, alias: language.aliases, support, - }) + }), ); } diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/createEditor.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/createEditor.ts index 562c46f28..856a16b15 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/createEditor.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/createEditor.ts @@ -10,7 +10,7 @@ import loadLangauges from './loadLanguages'; // Creates and returns a minimal editor with markdown extensions. Waits to return the editor // until all syntax tree tags in `expectedSyntaxTreeTags` exist. const createEditor = async ( - initialText: string, initialSelection: SelectionRange, expectedSyntaxTreeTags: string[] + initialText: string, initialSelection: SelectionRange, expectedSyntaxTreeTags: string[], ): Promise => { await loadLangauges(); diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.ts index b757f71fb..e427864ab 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/testUtil/forceFullParse.ts @@ -10,7 +10,7 @@ const forceFullParse = (editorState: EditorState) => { if (!syntaxTreeAvailable(editorState)) { throw new Error( - `Unable to generate a syntax tree in ${timeout}. Is the editor configured to parse a language?` + `Unable to generate a syntax tree in ${timeout}. Is the editor configured to parse a language?`, ); } }; diff --git a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.tsx b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.tsx index fca9dbf90..23d1a4d9f 100644 --- a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.tsx +++ b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.tsx @@ -41,7 +41,7 @@ const Toolbar = (props: ToolbarProps) => { key={key.toString()} styleSheet={props.styleSheet} spec={spec} - /> + />, ); } @@ -49,7 +49,7 @@ const Toolbar = (props: ToolbarProps) => { const containerWidth = event.nativeEvent.layout.width; const maxButtonsTotal = Math.floor(containerWidth / buttonSize); setMaxButtonsEachSide(Math.floor( - Math.min((maxButtonsTotal - 1) / 2, allButtonSpecs.length / 2) + Math.min((maxButtonsTotal - 1) / 2, allButtonSpecs.length / 2), )); }, [allButtonSpecs.length]); diff --git a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.tsx b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.tsx index 1b12fd848..0145bc574 100644 --- a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.tsx +++ b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.tsx @@ -41,7 +41,7 @@ const ToolbarOverflowRows = (props: OverflowPopupProps) => { // After invoking this button's action, hide the overflow menu onActionComplete={props.onToggleOverflow} - /> + />, ); // Show the "hide overflow" button if in the center of the last row @@ -54,7 +54,7 @@ const ToolbarOverflowRows = (props: OverflowPopupProps) => { styleSheet={props.styleSheet} overflowVisible={true} onToggleOverflowVisible={props.onToggleOverflow} - /> + />, ); } } @@ -69,7 +69,7 @@ const ToolbarOverflowRows = (props: OverflowPopupProps) => { > {row} - + , ); } diff --git a/packages/app-mobile/components/NoteEditor/NoteEditor.tsx b/packages/app-mobile/components/NoteEditor/NoteEditor.tsx index 49a07d1a4..1e9540fbb 100644 --- a/packages/app-mobile/components/NoteEditor/NoteEditor.tsx +++ b/packages/app-mobile/components/NoteEditor/NoteEditor.tsx @@ -120,7 +120,7 @@ type OnSetVisibleCallback = (visible: boolean)=> void; type OnSearchStateChangeCallback = (state: SearchState)=> void; const useEditorControl = ( injectJS: OnInjectJSCallback, setLinkDialogVisible: OnSetVisibleCallback, - setSearchState: OnSearchStateChangeCallback, searchStateRef: RefObject + setSearchState: OnSearchStateChangeCallback, searchStateRef: RefObject, ): EditorControl => { return useMemo(() => { return { @@ -132,7 +132,7 @@ const useEditorControl = ( }, select(anchor: number, head: number) { injectJS( - `cm.select(${JSON.stringify(anchor)}, ${JSON.stringify(head)});` + `cm.select(${JSON.stringify(anchor)}, ${JSON.stringify(head)});`, ); }, insertText(text: string) { @@ -299,7 +299,7 @@ function NoteEditor(props: Props, ref: any) { }; const editorControl = useEditorControl( - injectJS, setLinkDialogVisible, setSearchState, searchStateRef + injectJS, setLinkDialogVisible, setSearchState, searchStateRef, ); useImperativeHandle(ref, () => { diff --git a/packages/app-mobile/components/NoteEditor/SearchPanel.tsx b/packages/app-mobile/components/NoteEditor/SearchPanel.tsx index f7c810eeb..bbea39bf4 100644 --- a/packages/app-mobile/components/NoteEditor/SearchPanel.tsx +++ b/packages/app-mobile/components/NoteEditor/SearchPanel.tsx @@ -39,7 +39,7 @@ interface ActionButtonProps { } const ActionButton = ( - props: ActionButtonProps + props: ActionButtonProps, ) => { return ( { // Creates a TextInut with the given parameters const createInput = ( - placeholder: string, value: string, onChange: OnChangeCallback, autoFocus: boolean + placeholder: string, value: string, onChange: OnChangeCallback, autoFocus: boolean, ) => { return ( { }, // Autofocus - true + true, ); const replaceTextInput = createInput( @@ -242,7 +242,7 @@ export const SearchPanel = (props: SearchPanelProps) => { }, // Don't autofocus - false + false, ); const labeledSearchInput = ( diff --git a/packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx b/packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx index e7b6f9118..4aea0e3f8 100644 --- a/packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx +++ b/packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx @@ -71,7 +71,7 @@ export default (props: Props) => { onPress: () => {}, style: 'cancel', }, - ] + ], ); }, []); @@ -108,7 +108,7 @@ export default (props: Props) => { onPress: () => {}, style: 'cancel', }, - ] + ], ); }, [profileConfig]); @@ -144,7 +144,7 @@ export default (props: Props) => { onPress: () => {}, style: 'cancel', }, - ] + ], ); }} /> diff --git a/packages/app-mobile/components/ScreenHeader.tsx b/packages/app-mobile/components/ScreenHeader.tsx index bb26aa167..b9a2cdbe6 100644 --- a/packages/app-mobile/components/ScreenHeader.tsx +++ b/packages/app-mobile/components/ScreenHeader.tsx @@ -333,7 +333,7 @@ class ScreenHeaderComponent extends PureComponent {o.title} - + , ); } } @@ -501,13 +501,13 @@ class ScreenHeaderComponent extends PureComponent this.deleteButton_press()} key={'menuOption_delete'} style={this.styles().contextMenuItem}> {_('Delete')} - + , ); menuOptionComponents.push( this.duplicateButton_press()} key={'menuOption_duplicate'} style={this.styles().contextMenuItem}> {_('Duplicate')} - + , ); } @@ -622,7 +622,7 @@ class ScreenHeaderComponent extends PureComponent { onPress: () => complete(false), style: 'cancel', }, - ] + ], ); }, [initialPromptDone, display, props.dispatch]); diff --git a/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx b/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx index dd9b53b74..63e1e7f61 100644 --- a/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx +++ b/packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx @@ -273,7 +273,7 @@ class ConfigScreenComponent extends BaseScreenComponent { { text: _('Discard changes'), onPress: goBack, - }] + }], ); return true; @@ -369,10 +369,10 @@ class ConfigScreenComponent extends BaseScreenComponent { 'sync.10.inboxEmail', _('Copy to clipboard'), () => Clipboard.setString(this.props.settings['sync.10.inboxEmail']), - { description } + { description }, ) } - + , ); } @@ -621,7 +621,7 @@ class ConfigScreenComponent extends BaseScreenComponent { {_('- Location: to allow attaching geo-location information to a note.')} - + , ); } @@ -636,7 +636,7 @@ class ConfigScreenComponent extends BaseScreenComponent { {_('Make a donation')} - + , ); settingComps.push( @@ -650,7 +650,7 @@ class ConfigScreenComponent extends BaseScreenComponent { {_('Joplin website')} - + , ); settingComps.push( @@ -664,31 +664,31 @@ class ConfigScreenComponent extends BaseScreenComponent { {_('Privacy Policy')} - + , ); settingComps.push( {`Joplin ${VersionInfo.appVersion}`} - + , ); settingComps.push( {_('Database v%s', reg.db().version())} - + , ); settingComps.push( {_('FTS enabled: %d', this.props.settings['db.ftsEnabled'])} - + , ); settingComps.push( {_('Hermes enabled: %d', (global as any).HermesInternal ? 1 : 0)} - + , ); return ( diff --git a/packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.tsx b/packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.tsx index 25d17656b..d1e34a190 100644 --- a/packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.tsx +++ b/packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/NoteExportButton.test.tsx @@ -40,7 +40,7 @@ describe('NoteExportButton', () => { await act(() => fireEvent.press(exportButton)); await waitFor(() => - expect(view.queryByText(_('Exported successfully!'))).not.toBeNull() + expect(view.queryByText(_('Exported successfully!'))).not.toBeNull(), ); // With the default folder setup, there should be no warnings diff --git a/packages/app-mobile/components/screens/Note.tsx b/packages/app-mobile/components/screens/Note.tsx index 33fca0f7d..cd6e6f80c 100644 --- a/packages/app-mobile/components/screens/Note.tsx +++ b/packages/app-mobile/components/screens/Note.tsx @@ -565,7 +565,7 @@ class NoteScreenComponent extends BaseScreenComponent { }, (error: any) => { reject(error); - } + }, ); }); } @@ -756,7 +756,7 @@ class NoteScreenComponent extends BaseScreenComponent { uri: data.uri, type: 'image/jpg', }, - 'image' + 'image', ); this.setState({ showCamera: false }); diff --git a/packages/app-mobile/components/screens/encryption-config.tsx b/packages/app-mobile/components/screens/encryption-config.tsx index 7c9e4603a..d4277c6b9 100644 --- a/packages/app-mobile/components/screens/encryption-config.tsx +++ b/packages/app-mobile/components/screens/encryption-config.tsx @@ -262,7 +262,7 @@ const EncryptionConfigScreen = (props: Props) => { rows.push( {id} - + , ); } diff --git a/packages/app-mobile/components/side-menu-content.tsx b/packages/app-mobile/components/side-menu-content.tsx index 282b0b2c0..5949e85f4 100644 --- a/packages/app-mobile/components/side-menu-content.tsx +++ b/packages/app-mobile/components/side-menu-content.tsx @@ -112,7 +112,7 @@ const SideMenuContentComponent = (props: Props) => { toValue: 1, duration: 3000, easing: Easing.linear, - }) + }), ); syncIconAnimation.start(); @@ -156,7 +156,7 @@ const SideMenuContentComponent = (props: Props) => { if (folder.id === props.inboxJopId) { return folderDeletion( - _('Delete the Inbox notebook?\n\nIf you delete the inbox notebook, any email that\'s recently been sent to it may be lost.') + _('Delete the Inbox notebook?\n\nIf you delete the inbox notebook, any email that\'s recently been sent to it may be lost.'), ); } return folderDeletion(_('Delete notebook "%s"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.', folder.title)); @@ -191,7 +191,7 @@ const SideMenuContentComponent = (props: Props) => { ], { cancelable: false, - } + }, ); }; @@ -456,7 +456,7 @@ const SideMenuContentComponent = (props: Props) => { items.push( {fullReport.join('\n')} - + , ); } @@ -464,7 +464,7 @@ const SideMenuContentComponent = (props: Props) => { items.push( { _('Mobile data - auto-sync disabled') } - + , ); } diff --git a/packages/app-mobile/gulpfile.ts b/packages/app-mobile/gulpfile.ts index d3ab6ff55..bc11dc54f 100644 --- a/packages/app-mobile/gulpfile.ts +++ b/packages/app-mobile/gulpfile.ts @@ -22,5 +22,5 @@ utils.registerGulpTasks(gulp, tasks); gulp.task('build', gulp.series( 'buildInjectedJs', 'encodeAssets', - 'podInstall' + 'podInstall', )); diff --git a/packages/app-mobile/metro.config.js b/packages/app-mobile/metro.config.js index 84da6483f..19c72bc81 100644 --- a/packages/app-mobile/metro.config.js +++ b/packages/app-mobile/metro.config.js @@ -72,7 +72,7 @@ module.exports = { } return path.join(process.cwd(), `node_modules/${name}`); }, - } + }, ), }, projectRoot: path.resolve(__dirname), diff --git a/packages/app-mobile/root.tsx b/packages/app-mobile/root.tsx index 9c6c34f9c..a74aa8f12 100644 --- a/packages/app-mobile/root.tsx +++ b/packages/app-mobile/root.tsx @@ -881,7 +881,7 @@ class AppComponent extends React.Component { this.unsubscribeScreenWidthChangeHandler_ = Dimensions.addEventListener('change', this.handleScreenWidthChange_); this.themeChangeListener_ = Appearance.addChangeListener( - ({ colorScheme }) => onSystemColorSchemeChange(colorScheme) + ({ colorScheme }) => onSystemColorSchemeChange(colorScheme), ); onSystemColorSchemeChange(Appearance.getColorScheme()); diff --git a/packages/app-mobile/tools/buildInjectedJs.ts b/packages/app-mobile/tools/buildInjectedJs.ts index 10820aa45..af2488520 100644 --- a/packages/app-mobile/tools/buildInjectedJs.ts +++ b/packages/app-mobile/tools/buildInjectedJs.ts @@ -36,7 +36,7 @@ class BundledFile { public constructor( public readonly bundleName: string, - private readonly sourceFilePath: string + private readonly sourceFilePath: string, ) { this.rootFileDirectory = dirname(sourceFilePath); this.bundleBaseName = basename(sourceFilePath, extname(sourceFilePath)); @@ -200,7 +200,7 @@ class BundledFile { const bundledFiles: BundledFile[] = [ new BundledFile( 'codeMirrorBundle', - `${mobileDir}/components/NoteEditor/CodeMirror/CodeMirror.ts` + `${mobileDir}/components/NoteEditor/CodeMirror/CodeMirror.ts`, ), ]; diff --git a/packages/app-mobile/utils/autodetectTheme.ts b/packages/app-mobile/utils/autodetectTheme.ts index b657f207d..df9e3f988 100644 --- a/packages/app-mobile/utils/autodetectTheme.ts +++ b/packages/app-mobile/utils/autodetectTheme.ts @@ -25,7 +25,7 @@ const autodetectTheme = () => { const colorScheme = systemColorScheme; logger.debug( 'Autodetecting theme. getColorScheme returns', Appearance.getColorScheme(), - 'and the expected theme is', systemColorScheme + 'and the expected theme is', systemColorScheme, ); if (colorScheme === 'dark') { diff --git a/packages/app-mobile/utils/database-driver-react-native.js b/packages/app-mobile/utils/database-driver-react-native.js index 56e33c4e4..4a901880f 100644 --- a/packages/app-mobile/utils/database-driver-react-native.js +++ b/packages/app-mobile/utils/database-driver-react-native.js @@ -16,7 +16,7 @@ class DatabaseDriverReactNative { }, error => { reject(error); - } + }, ); }); } @@ -35,7 +35,7 @@ class DatabaseDriverReactNative { }, error => { reject(error); - } + }, ); }); } @@ -66,7 +66,7 @@ class DatabaseDriverReactNative { }, error => { reject(error); - } + }, ); }); } diff --git a/packages/app-mobile/utils/geolocation-react.js b/packages/app-mobile/utils/geolocation-react.js index 15c4f01aa..121248448 100644 --- a/packages/app-mobile/utils/geolocation-react.js +++ b/packages/app-mobile/utils/geolocation-react.js @@ -33,7 +33,7 @@ class GeolocationReact { error => { reject(error); }, - options + options, ); }); } diff --git a/packages/generator-joplin/generators/app/index.js b/packages/generator-joplin/generators/app/index.js index c042a42e4..cac5cf1dc 100644 --- a/packages/generator-joplin/generators/app/index.js +++ b/packages/generator-joplin/generators/app/index.js @@ -150,7 +150,7 @@ module.exports = class extends Generator { const newContent = mergePackageKey(null, sourceContent, destContent); return JSON.stringify(newContent, null, 2); }, - } + }, ); } else if (this.options.update && destFile === 'plugin.config.json' && this.fs.exists(destFilePath)) { // Keep existing content for now. Maybe later we could merge the configs. @@ -163,20 +163,20 @@ module.exports = class extends Generator { process: (sourceBuffer) => { return mergeIgnoreFile(sourceBuffer.toString(), destContent); }, - } + }, ); } else { this.fs.copyTpl( this.templatePath(file), destFilePath, - this.props + this.props, ); } } this.fs.copy( this.templatePath('api'), - this.destinationPath('api') + this.destinationPath('api'), ); } diff --git a/packages/generator-joplin/generators/app/templates/webpack.config.js b/packages/generator-joplin/generators/app/templates/webpack.config.js index 67e8cb9d3..c58e4b0eb 100644 --- a/packages/generator-joplin/generators/app/templates/webpack.config.js +++ b/packages/generator-joplin/generators/app/templates/webpack.config.js @@ -132,7 +132,7 @@ function createPluginArchive(sourceDir, destPath) { cwd: sourceDir, sync: true, }, - distFiles + distFiles, ); console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`)); diff --git a/packages/lib/EventDispatcher.ts b/packages/lib/EventDispatcher.ts index 45ce3fb4e..eb5dac36d 100644 --- a/packages/lib/EventDispatcher.ts +++ b/packages/lib/EventDispatcher.ts @@ -43,7 +43,7 @@ export default class EventDispatcher otherCallback !== callback + otherCallback => otherCallback !== callback, ); } } diff --git a/packages/lib/JoplinDatabase.ts b/packages/lib/JoplinDatabase.ts index f9c98745d..96d750b02 100644 --- a/packages/lib/JoplinDatabase.ts +++ b/packages/lib/JoplinDatabase.ts @@ -547,7 +547,7 @@ export default class JoplinDatabase extends Database { encryption_cipher_text: 'TEXT NOT NULL DEFAULT ""', encryption_applied: 'INT NOT NULL DEFAULT 0', encryption_blob_encrypted: 'INT NOT NULL DEFAULT 0', - }) + }), ); } @@ -761,7 +761,7 @@ export default class JoplinDatabase extends Database { encryption_applied: 'INT NOT NULL DEFAULT 0', markup_language: 'INT NOT NULL DEFAULT 1', is_shared: 'INT NOT NULL DEFAULT 0', - }) + }), ); } diff --git a/packages/lib/Synchronizer.ts b/packages/lib/Synchronizer.ts index ff31bcf9e..7b13ac5d8 100644 --- a/packages/lib/Synchronizer.ts +++ b/packages/lib/Synchronizer.ts @@ -537,7 +537,7 @@ export default class Synchronizer { (fnName, ...args) => { return this.apiCall(fnName, ...args); }, - action => { return this.dispatch(action); } + action => { return this.dispatch(action); }, ); } // DELETE_REMOTE STEP @@ -768,7 +768,7 @@ export default class Synchronizer { local, syncTargetId, itemIsReadOnly, - (action: any) => this.dispatch(action) + (action: any) => this.dispatch(action), ); completeItemProcessing(path); diff --git a/packages/lib/components/shared/config/config-shared.js b/packages/lib/components/shared/config/config-shared.js index a4776ebe4..387ee803d 100644 --- a/packages/lib/components/shared/config/config-shared.js +++ b/packages/lib/components/shared/config/config-shared.js @@ -198,7 +198,7 @@ shared.settingsSections = createSelector( } return output; - } + }, ); shared.settingsToComponents2 = function(comp, device, settings, selectedSectionName = '') { diff --git a/packages/lib/file-api-driver-dropbox.js b/packages/lib/file-api-driver-dropbox.js index ad3c14afd..bb3bf19a1 100644 --- a/packages/lib/file-api-driver-dropbox.js +++ b/packages/lib/file-api-driver-dropbox.js @@ -138,7 +138,7 @@ class FileApiDriverDropbox { { 'Dropbox-API-Arg': JSON.stringify({ path: this.makePath_(path) }), }, - options + options, ); return response; } catch (error) { @@ -182,7 +182,7 @@ class FileApiDriverDropbox { mute: true, // Don't send a notification to user since there can be many of these updates }), }, - options + options, ); } catch (error) { if (this.hasErrorCode_(error, 'restricted_content')) { diff --git a/packages/lib/hooks/useEventListener.ts b/packages/lib/hooks/useEventListener.ts index a6d4e577b..c2b1304b4 100644 --- a/packages/lib/hooks/useEventListener.ts +++ b/packages/lib/hooks/useEventListener.ts @@ -4,7 +4,7 @@ const { useEffect, useRef } = shim.react(); function useEventListener( eventName: any, handler: any, - element?: any + element?: any, ) { // Create a ref that stores handler const savedHandler = useRef(); diff --git a/packages/lib/markJsUtils.js b/packages/lib/markJsUtils.js index ede5b7bef..f2fc5113e 100644 --- a/packages/lib/markJsUtils.js +++ b/packages/lib/markJsUtils.js @@ -56,7 +56,7 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => { return true; }, ...extraOptions, - } + }, ); }; diff --git a/packages/lib/models/BaseItem.ts b/packages/lib/models/BaseItem.ts index 0cedc6757..56a6a4b15 100644 --- a/packages/lib/models/BaseItem.ts +++ b/packages/lib/models/BaseItem.ts @@ -626,7 +626,7 @@ export default class BaseItem extends BaseModel { `, this.db().escapeField(ItemClass.tableName()), whereSql.join(' AND '), - limit + limit, ); const items = await ItemClass.modelSelectAll(sql); @@ -689,7 +689,7 @@ export default class BaseItem extends BaseModel { this.db().escapeField(ItemClass.tableName()), Number(syncTarget), extraWhere, - limit + limit, ); const neverSyncedItem = await ItemClass.modelSelectAll(sql); @@ -718,7 +718,7 @@ export default class BaseItem extends BaseModel { this.db().escapeField(ItemClass.tableName()), Number(syncTarget), extraWhere, - newLimit + newLimit, ); changedItems = await ItemClass.modelSelectAll(sql); @@ -855,7 +855,7 @@ export default class BaseItem extends BaseModel { SELECT id FROM %s WHERE encryption_applied = 0`, - this.db().escapeField(ItemClass.tableName()) + this.db().escapeField(ItemClass.tableName()), ); const items = await ItemClass.modelSelectAll(sql); @@ -918,7 +918,7 @@ export default class BaseItem extends BaseModel { this.getClass('Folder'), options.changeSource, BaseItem.syncShareCache, - o.parent_id + o.parent_id, ); } } diff --git a/packages/lib/models/NoteResource.ts b/packages/lib/models/NoteResource.ts index bf8478b24..92767c76b 100644 --- a/packages/lib/models/NoteResource.ts +++ b/packages/lib/models/NoteResource.ts @@ -119,7 +119,7 @@ export default class NoteResource extends BaseModel { queries.push({ sql: 'INSERT INTO note_resources (note_id, resource_id, is_associated, last_seen_time) VALUES (?, ?, ?, ?)', - params: ['', id, 0, lastSeenTime] } + params: ['', id, 0, lastSeenTime] }, ); } await this.db().transactionExecBatch(queries); @@ -141,7 +141,7 @@ export default class NoteResource extends BaseModel { AND last_seen_time < ? AND last_seen_time != 0 `, - [cutOffTime] + [cutOffTime], ); return output.map((r: any) => r.resource_id); } diff --git a/packages/lib/models/Setting.ts b/packages/lib/models/Setting.ts index 5b4bfa67b..99e1c1205 100644 --- a/packages/lib/models/Setting.ts +++ b/packages/lib/models/Setting.ts @@ -1312,7 +1312,7 @@ class Setting extends BaseModel { onClick: () => { shim.openOrCreateFile( this.customCssFilePath(Setting.customCssFilenames.RENDERED_MARKDOWN), - '/* For styling the rendered Markdown */' + '/* For styling the rendered Markdown */', ); }, type: SettingItemType.Button, @@ -1329,7 +1329,7 @@ class Setting extends BaseModel { onClick: () => { shim.openOrCreateFile( this.customCssFilePath(Setting.customCssFilenames.JOPLIN_APP), - `/* For styling the entire Joplin app (except the rendered Markdown, which is defined in \`${Setting.customCssFilenames.RENDERED_MARKDOWN}\`) */` + `/* For styling the entire Joplin app (except the rendered Markdown, which is defined in \`${Setting.customCssFilenames.RENDERED_MARKDOWN}\`) */`, ); }, type: SettingItemType.Button, diff --git a/packages/lib/models/Tag.ts b/packages/lib/models/Tag.ts index cbc6fb1fe..e21578a4b 100644 --- a/packages/lib/models/Tag.ts +++ b/packages/lib/models/Tag.ts @@ -32,7 +32,7 @@ export default class Tag extends BaseItem { return Note.previews( null, - { ...options, conditions: [`id IN ("${noteIds.join('","')}")`] } + { ...options, conditions: [`id IN ("${noteIds.join('","')}")`] }, ); } diff --git a/packages/lib/reducer.ts b/packages/lib/reducer.ts index 2ef91ecb4..6c42f498b 100644 --- a/packages/lib/reducer.ts +++ b/packages/lib/reducer.ts @@ -211,12 +211,12 @@ const createShallowArrayEqualSelector = createSelectorCreator( if (prev[i] !== next[i]) return false; } return true; - } + }, ); const selectArrayShallow = createCachedSelector( (state: any) => state.array, - (array: any[]) => array + (array: any[]) => array, )({ keySelector: (_state: any, cacheKey: any) => { return cacheKey; diff --git a/packages/lib/services/KeymapService.ts b/packages/lib/services/KeymapService.ts index a1f95ebda..f91a8aa98 100644 --- a/packages/lib/services/KeymapService.ts +++ b/packages/lib/services/KeymapService.ts @@ -350,7 +350,7 @@ export default class KeymapService extends BaseService { 'Accelerator "%s" is used for "%s" and "%s" commands. This may lead to unexpected behaviour.', itemAccelerator, originalItem.command, - itemCommand + itemCommand, )); } else if (itemAccelerator) { usedAccelerators.add(itemAccelerator); diff --git a/packages/lib/services/ResourceService.ts b/packages/lib/services/ResourceService.ts index ef0aa0ed1..99cf75f38 100644 --- a/packages/lib/services/ResourceService.ts +++ b/packages/lib/services/ResourceService.ts @@ -44,7 +44,7 @@ export default class ResourceService extends BaseService { AND id > ? ORDER BY id ASC LIMIT 10 - `, [BaseModel.TYPE_NOTE, Setting.value('resourceService.lastProcessedChangeId')] + `, [BaseModel.TYPE_NOTE, Setting.value('resourceService.lastProcessedChangeId')], ); if (!changes.length) break; diff --git a/packages/lib/services/RevisionService.ts b/packages/lib/services/RevisionService.ts index 8d19b12c3..45e130716 100644 --- a/packages/lib/services/RevisionService.ts +++ b/packages/lib/services/RevisionService.ts @@ -126,7 +126,7 @@ export default class RevisionService extends BaseService { ORDER BY id ASC LIMIT 10 `, - [BaseModel.TYPE_NOTE, ItemChange.SOURCE_SYNC, ItemChange.SOURCE_DECRYPTION, Setting.value('revisionService.lastProcessedChangeId')] + [BaseModel.TYPE_NOTE, ItemChange.SOURCE_SYNC, ItemChange.SOURCE_DECRYPTION, Setting.value('revisionService.lastProcessedChangeId')], ); if (!changes.length) break; diff --git a/packages/lib/services/commands/MenuUtils.ts b/packages/lib/services/commands/MenuUtils.ts index 9d71b14ed..f58b4e9e0 100644 --- a/packages/lib/services/commands/MenuUtils.ts +++ b/packages/lib/services/commands/MenuUtils.ts @@ -42,14 +42,14 @@ const createShallowObjectEqualSelector = createSelectorCreator( if (prev[n] !== next[n]) return false; } return true; - } + }, ); // This selector ensures that for the given command names, the same toolbar // button array is returned if the underlying toolbar buttons have not changed. const selectObjectByCommands = createCachedSelector( (state: any) => state.array, - (array: any[]) => array + (array: any[]) => array, )({ keySelector: (_state: any, commandNames: string[]) => { return commandNames.join('_'); diff --git a/packages/lib/services/interop/Module.test.ts b/packages/lib/services/interop/Module.test.ts index 7b90f0b0f..b8787fe99 100644 --- a/packages/lib/services/interop/Module.test.ts +++ b/packages/lib/services/interop/Module.test.ts @@ -13,7 +13,7 @@ describe('Module', () => { const importModuleMultiSource = makeImportModule( baseMetadata, - () => new InteropService_Importer_Base() + () => new InteropService_Importer_Base(), ); const importModuleSingleSource = makeImportModule({ diff --git a/packages/lib/services/interop/Module.ts b/packages/lib/services/interop/Module.ts index aea350fbe..eeb42c032 100644 --- a/packages/lib/services/interop/Module.ts +++ b/packages/lib/services/interop/Module.ts @@ -63,7 +63,7 @@ const moduleFullLabel = (metadata: ImportMetadata|ExportMetadata, moduleSource: }; export const makeImportModule = ( - metadata: Partial, factory: ()=> InteropService_Importer_Base + metadata: Partial, factory: ()=> InteropService_Importer_Base, ): ImportModule => { const importerDefaults: ImportMetadata = { ...defaultBaseMetadata, @@ -93,7 +93,7 @@ export const makeImportModule = ( }; export const makeExportModule = ( - metadata: Partial, factory: ()=> InteropService_Exporter_Base + metadata: Partial, factory: ()=> InteropService_Exporter_Base, ): ExportModule => { const exporterDefaults: ExportMetadata = { ...defaultBaseMetadata, diff --git a/packages/lib/services/plugins/api/JoplinSettings.ts b/packages/lib/services/plugins/api/JoplinSettings.ts index e88de5680..39ee61174 100644 --- a/packages/lib/services/plugins/api/JoplinSettings.ts +++ b/packages/lib/services/plugins/api/JoplinSettings.ts @@ -140,7 +140,7 @@ export default class JoplinSettings { this.plugin_.deprecationNotice( '1.8', 'joplin.settings.registerSetting() is deprecated in favour of joplin.settings.registerSettings()', - !registerSettingAllowedPluginIds.includes(this.plugin_.id) + !registerSettingAllowedPluginIds.includes(this.plugin_.id), ); await this.registerSettings({ [key]: settingItem }); diff --git a/packages/lib/services/searchengine/SearchEngine.ts b/packages/lib/services/searchengine/SearchEngine.ts index 26e21b658..872c97222 100644 --- a/packages/lib/services/searchengine/SearchEngine.ts +++ b/packages/lib/services/searchengine/SearchEngine.ts @@ -109,7 +109,7 @@ export default class SearchEngine { queries.push({ sql: ` INSERT INTO notes_normalized(${SearchEngine.relevantFields}) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - params: [n.id, n.title, n.body, n.user_created_time, n.user_updated_time, n.is_todo, n.todo_completed, n.todo_due, n.parent_id, n.latitude, n.longitude, n.altitude, n.source_url] } + params: [n.id, n.title, n.body, n.user_created_time, n.user_updated_time, n.is_todo, n.todo_completed, n.todo_due, n.parent_id, n.latitude, n.longitude, n.altitude, n.source_url] }, ); } @@ -174,7 +174,7 @@ export default class SearchEngine { ORDER BY id ASC LIMIT 10 `, - [BaseModel.TYPE_NOTE, lastChangeId] + [BaseModel.TYPE_NOTE, lastChangeId], ); if (!changes.length) break; @@ -184,7 +184,7 @@ export default class SearchEngine { const noteIds = changes.map(a => a.item_id); const notes = await Note.modelSelectAll(` SELECT ${SearchEngine.relevantFields} - FROM notes WHERE id IN ("${noteIds.join('","')}") AND is_conflict = 0 AND encryption_applied = 0` + FROM notes WHERE id IN ("${noteIds.join('","')}") AND is_conflict = 0 AND encryption_applied = 0`, ); for (let i = 0; i < changes.length; i++) { diff --git a/packages/lib/services/searchengine/queryBuilder.ts b/packages/lib/services/searchengine/queryBuilder.ts index 51087ccc3..3b6ac16c4 100644 --- a/packages/lib/services/searchengine/queryBuilder.ts +++ b/packages/lib/services/searchengine/queryBuilder.ts @@ -91,7 +91,7 @@ const filterByTableName = ( requirement: Requirement, withs: string[], tableName: string, - useFts: boolean + useFts: boolean, ) => { const operator: Operation = getOperator(requirement, relation); diff --git a/packages/lib/services/share/ShareService.ts b/packages/lib/services/share/ShareService.ts index 7f4c688dc..480f6f77c 100644 --- a/packages/lib/services/share/ShareService.ts +++ b/packages/lib/services/share/ShareService.ts @@ -337,7 +337,7 @@ export default class ShareService { this.encryptionService_, masterKey, getMasterPassword(), - recipientPublicKey + recipientPublicKey, ); } @@ -404,7 +404,7 @@ export default class ShareService { masterKey, localSyncInfo().ppk, getMasterPassword(), - getMasterPassword() + getMasterPassword(), ); logger.info('respondInvitation: Key has been reencrypted using master password', reencryptedMasterKey); diff --git a/packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.ts b/packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.ts index 0d11058d1..71d7b4b59 100644 --- a/packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.ts +++ b/packages/lib/services/synchronizer/gui/useSyncTargetUpgrade.ts @@ -30,7 +30,7 @@ export default function useSyncTargetUpgrade(): SyncTargetUpgradeResult { reg.db(), synchronizer.lockHandler(), appTypeToLockType(Setting.value('appType')), - Setting.value('clientId') + Setting.value('clientId'), ); reg.logger().info('useSyncTargetUpgrade: Start upgrade...'); diff --git a/packages/lib/versionInfo.test.ts b/packages/lib/versionInfo.test.ts index 6ba1f2aa5..cb0afd29c 100644 --- a/packages/lib/versionInfo.test.ts +++ b/packages/lib/versionInfo.test.ts @@ -58,7 +58,7 @@ describe('getPluginLists', () => { app_min_version: '1' }, '', () => {}, - '' + '', ); const plugins: Plugins = {}; @@ -82,7 +82,7 @@ describe('getPluginLists', () => { app_min_version: '1' }, '', () => {}, - '' + '', ); plugins[plugin.manifest.id] = plugin; } @@ -106,7 +106,7 @@ describe('getPluginLists', () => { app_min_version: '1' }, '', () => {}, - '' + '', ); plugins[plugin.manifest.id] = plugin; diff --git a/packages/pdf-viewer/VerticalPages.tsx b/packages/pdf-viewer/VerticalPages.tsx index 7906fb26c..60148c693 100644 --- a/packages/pdf-viewer/VerticalPages.tsx +++ b/packages/pdf-viewer/VerticalPages.tsx @@ -107,7 +107,7 @@ export default function VerticalPages(props: VerticalPagesProps) { onTextSelect={props.onTextSelect} onDoubleClick={props.onDoubleClick} isDarkTheme={props.isDarkTheme} scaledSize={scaledSize} container={props.container} key={i} />; - } + }, ) : '' } ); diff --git a/packages/plugins/ToggleSidebars/webpack.config.js b/packages/plugins/ToggleSidebars/webpack.config.js index 1c757c3ce..ddb28ed3b 100644 --- a/packages/plugins/ToggleSidebars/webpack.config.js +++ b/packages/plugins/ToggleSidebars/webpack.config.js @@ -89,7 +89,7 @@ function createPluginArchive(sourceDir, destPath) { cwd: sourceDir, sync: true, }, - distFiles + distFiles, ); console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`)); diff --git a/packages/react-native-alarm-notification/index.js b/packages/react-native-alarm-notification/index.js index 1f95be08e..91d32654a 100644 --- a/packages/react-native-alarm-notification/index.js +++ b/packages/react-native-alarm-notification/index.js @@ -28,7 +28,7 @@ ReactNativeAN.scheduleAlarm = async (details) => { const today = new Date(); if (past < today) { throw new Error( - 'failed to schedule alarm because fire date is in the past' + 'failed to schedule alarm because fire date is in the past', ); } diff --git a/packages/react-native-saf-x/src/index.ts b/packages/react-native-saf-x/src/index.ts index fc53c6b6a..ccd75943c 100644 --- a/packages/react-native-saf-x/src/index.ts +++ b/packages/react-native-saf-x/src/index.ts @@ -18,7 +18,7 @@ if (Platform.OS === 'android') { get() { throw new Error(LINKING_ERROR); }, - } + }, ) ) as SafxInterface; } else { @@ -133,7 +133,7 @@ export function exists(uriString: string) { /** Read contents of the given uri. uri must point to a file. */ export function readFile( uriString: string, - options?: Pick + options?: Pick, ) { if (!options) options = {}; const { encoding } = options; @@ -146,7 +146,7 @@ export function readFile( export function writeFile( uriString: string, data: string, - options?: FileOperationOptions + options?: FileOperationOptions, ) { if (!options) options = {}; const { encoding, append, mimeType } = options; @@ -157,7 +157,7 @@ export function writeFile( // Rejects if a file or directory exist at given uri. export function createFile( uriString: string, - options?: Pick + options?: Pick, ) { if (!options) options = {}; const { mimeType } = options; @@ -215,7 +215,7 @@ type FileTransferOptions = { export function copyFile( srcUri: string, destUri: string, - options?: FileTransferOptions + options?: FileTransferOptions, ) { if (!options) options = {}; const { replaceIfDestinationExists = false } = options; @@ -228,7 +228,7 @@ export function copyFile( export function moveFile( srcUri: string, destUri: string, - options?: FileTransferOptions + options?: FileTransferOptions, ) { if (!options) options = {}; const { replaceIfDestinationExists = false } = options; diff --git a/packages/server/src/middleware/notificationHandler.ts b/packages/server/src/middleware/notificationHandler.ts index f75ace2b3..60724743d 100644 --- a/packages/server/src/middleware/notificationHandler.ts +++ b/packages/server/src/middleware/notificationHandler.ts @@ -22,7 +22,7 @@ async function handleChangeAdminPasswordNotification(ctx: AppContext) { ctx.joplin.owner.id, NotificationKey.ChangeAdminPassword, NotificationLevel.Important, - _('The default admin password is insecure and has not been changed! [Change it now](%s)', profileUrl()) + _('The default admin password is insecure and has not been changed! [Change it now](%s)', profileUrl()), ); } else { await notificationModel.setRead(ctx.joplin.owner.id, NotificationKey.ChangeAdminPassword); diff --git a/packages/server/src/models/ItemModel.ts b/packages/server/src/models/ItemModel.ts index 95a0a6777..b0e49cde4 100644 --- a/packages/server/src/models/ItemModel.ts +++ b/packages/server/src/models/ItemModel.ts @@ -436,7 +436,7 @@ export default class ItemModel extends BaseModel { .whereIn('id', this.db(this.tableName) .select(['id']) .where('content', '!=', Buffer.from('')) - .limit(options.batchSize) + .limit(options.batchSize), ); totalDone += updatedRows.length; @@ -1037,7 +1037,7 @@ export default class ItemModel extends BaseModel { const userIds: Uuid[] = unique( userItems .map(u => u.user_id) - .concat(changes.map(c => c.user_id)) + .concat(changes.map(c => c.user_id)), ); const totalSizes: TotalSizeRow[] = []; diff --git a/packages/server/src/models/ShareModel.ts b/packages/server/src/models/ShareModel.ts index b9be180ec..cdc590480 100644 --- a/packages/server/src/models/ShareModel.ts +++ b/packages/server/src/models/ShareModel.ts @@ -130,7 +130,7 @@ export default class ShareModel extends BaseModel { .whereIn('id', this .db('share_users') .select('share_id') - .where('user_id', '=', userId) + .where('user_id', '=', userId), ); const query2 = this @@ -165,7 +165,7 @@ export default class ShareModel extends BaseModel { .whereIn('id', this.db('share_users') .select('share_id') .where('user_id', '=', userId) - .andWhere('status', '=', ShareUserStatus.Accepted + .andWhere('status', '=', ShareUserStatus.Accepted, )); if (type) void query.andWhere('type', '=', type); @@ -463,7 +463,7 @@ export default class ShareModel extends BaseModel { .whereIn('item_id', this.db('items') .select('id') - .where('jop_share_id', '=', shareId) + .where('jop_share_id', '=', shareId), ).groupBy('user_id') as any; } diff --git a/packages/server/src/models/SubscriptionModel.test.ts b/packages/server/src/models/SubscriptionModel.test.ts index 95ce35599..17c476809 100644 --- a/packages/server/src/models/SubscriptionModel.test.ts +++ b/packages/server/src/models/SubscriptionModel.test.ts @@ -23,7 +23,7 @@ describe('SubscriptionModel', () => { 'Toto', AccountType.Pro, 'STRIPE_USER_ID', - 'STRIPE_SUB_ID' + 'STRIPE_SUB_ID', ); const user = await models().user().loadByEmail('toto@example.com'); @@ -46,7 +46,7 @@ describe('SubscriptionModel', () => { 'Toto', AccountType.Pro, 'STRIPE_USER_ID', - 'STRIPE_SUB_ID' + 'STRIPE_SUB_ID', ); await models().user().save({ diff --git a/packages/server/src/models/UserModel.ts b/packages/server/src/models/UserModel.ts index ad41ae3a3..175d66278 100644 --- a/packages/server/src/models/UserModel.ts +++ b/packages/server/src/models/UserModel.ts @@ -219,7 +219,7 @@ export default class UserModel extends BaseModel { throw new ErrorPayloadTooLarge(_('Cannot save %s "%s" because it is larger than the allowed limit (%s)', isNote ? _('note') : _('attachment'), itemTitle ? itemTitle : item.name, - formatBytes(maxItemSize) + formatBytes(maxItemSize), )); } @@ -236,7 +236,7 @@ export default class UserModel extends BaseModel { throw new ErrorPayloadTooLarge(_('Cannot save %s "%s" because it would go over the total allowed size (%s) for this account', isNote ? _('note') : _('attachment'), itemTitle ? itemTitle : item.name, - formatBytes(maxTotalItemSize) + formatBytes(maxTotalItemSize), )); } } diff --git a/packages/server/src/models/items/storage/loadStorageDriver.test.ts b/packages/server/src/models/items/storage/loadStorageDriver.test.ts index bbac1dd0a..a5d4cc599 100644 --- a/packages/server/src/models/items/storage/loadStorageDriver.test.ts +++ b/packages/server/src/models/items/storage/loadStorageDriver.test.ts @@ -42,7 +42,7 @@ describe('loadStorageDriver', () => { connection_string: 'Type=Database', updated_time: Date.now(), created_time: Date.now(), - }) + }), ); }); diff --git a/packages/server/src/models/utils/user.test.ts b/packages/server/src/models/utils/user.test.ts index d219918cb..28afb9262 100644 --- a/packages/server/src/models/utils/user.test.ts +++ b/packages/server/src/models/utils/user.test.ts @@ -12,7 +12,7 @@ describe('isHashedPassword', () => { '123456', 'simple-password-that-takes-is-long', 'nuXUhqecx!RzK3wv6^xYaVEP%9fc$T%$E2k%9Q&TKvtDhR#2PUw3kA8KX3w2baAD8m#N9@52!DvfYn*X6hP#uAvpGF57*H9avcoePbR&4Q2XzckJnSW*EVm4G@a#YvnR', - ] + ], )('should be false if password starts with $2a$10: %', (password) => { expect(isHashedPassword(password)).toBe(false); }); diff --git a/packages/server/src/routes/admin/tasks.ts b/packages/server/src/routes/admin/tasks.ts index a34fe1a4b..f506c1d9d 100644 --- a/packages/server/src/routes/admin/tasks.ts +++ b/packages/server/src/routes/admin/tasks.ts @@ -64,7 +64,7 @@ router.post('admin/tasks', async (_path: SubPath, ctx: AppContext) => { user.id, NotificationKey.Any, NotificationLevel.Error, - `Some operations could not be performed: ${errors.join('. ')}` + `Some operations could not be performed: ${errors.join('. ')}`, ); } diff --git a/packages/server/src/routes/api/items.test.ts b/packages/server/src/routes/api/items.test.ts index ce0dbe01d..f40383e83 100644 --- a/packages/server/src/routes/api/items.test.ts +++ b/packages/server/src/routes/api/items.test.ts @@ -300,7 +300,7 @@ describe('api/items', () => { await expectHttpError( async () => putApi(session3.id, 'items/root:/.resource/000000000000000000000000000000E1:/content', {}, { query: { share_id: share.id } }), - ErrorForbidden.httpCode + ErrorForbidden.httpCode, ); }); @@ -325,7 +325,7 @@ describe('api/items', () => { async () => createNote(session1.id, { id: '00000000000000000000000000000002', body: '12345', - }) + }), ); } @@ -336,7 +336,7 @@ describe('api/items', () => { async () => createNote(session1.id, { id: '00000000000000000000000000000003', body: '12345', - }) + }), ); } }); @@ -352,7 +352,7 @@ describe('api/items', () => { id: '00000000000000000000000000000001', body: '12345', }), - ErrorPayloadTooLarge.httpCode + ErrorPayloadTooLarge.httpCode, ); } @@ -363,7 +363,7 @@ describe('api/items', () => { async () => createNote(session1.id, { id: '00000000000000000000000000000002', body: '12345', - }) + }), ); } @@ -374,7 +374,7 @@ describe('api/items', () => { async () => createNote(session1.id, { id: '00000000000000000000000000000003', body: '12345', - }) + }), ); } }); @@ -389,7 +389,7 @@ describe('api/items', () => { id: '00000000000000000000000000000001', body: '12345', }), - ErrorForbidden.httpCode + ErrorForbidden.httpCode, ); }); diff --git a/packages/server/src/routes/api/shares.folder.test.ts b/packages/server/src/routes/api/shares.folder.test.ts index f9d4aaebc..c9d8bd838 100644 --- a/packages/server/src/routes/api/shares.folder.test.ts +++ b/packages/server/src/routes/api/shares.folder.test.ts @@ -889,7 +889,7 @@ describe('shares.folder', () => { children: [], }, ]), - ErrorForbidden.httpCode + ErrorForbidden.httpCode, ); }); @@ -905,7 +905,7 @@ describe('shares.folder', () => { children: [], }, ]), - ErrorForbidden.httpCode + ErrorForbidden.httpCode, ); }); @@ -940,7 +940,7 @@ describe('shares.folder', () => { children: [], }, ]), - ErrorForbidden.httpCode + ErrorForbidden.httpCode, ); }); diff --git a/packages/server/src/routes/index/stripe.ts b/packages/server/src/routes/index/stripe.ts index 52473221a..3dc24b169 100644 --- a/packages/server/src/routes/index/stripe.ts +++ b/packages/server/src/routes/index/stripe.ts @@ -30,7 +30,7 @@ async function stripeEvent(stripe: Stripe, req: any): Promise { return stripe.webhooks.constructEvent( body, req.headers['stripe-signature'], - stripeConfig().webhookSecret + stripeConfig().webhookSecret, ); } @@ -115,7 +115,7 @@ export const handleSubscriptionCreated = async (stripe: Stripe, models: Models, customerName, accountType, stripeUserId, - stripeSubscriptionId + stripeSubscriptionId, ); } }; @@ -330,7 +330,7 @@ export const postHandlers: PostHandlers = { customer.email, accountType, stripeUserId, - stripeSubscriptionId + stripeSubscriptionId, ); }, diff --git a/packages/server/src/services/MustacheService.ts b/packages/server/src/services/MustacheService.ts index 419eb3e6f..b73b99716 100644 --- a/packages/server/src/services/MustacheService.ts +++ b/packages/server/src/services/MustacheService.ts @@ -234,7 +234,7 @@ export default class MustacheService { ...view.content, global: globalParams, }, - this.partials_ + this.partials_, ); } else if (ext === '.md') { const markdownIt = new MarkdownIt({ diff --git a/packages/server/src/services/UserDeletionService.ts b/packages/server/src/services/UserDeletionService.ts index cd91ec2c8..747cec8f7 100644 --- a/packages/server/src/services/UserDeletionService.ts +++ b/packages/server/src/services/UserDeletionService.ts @@ -71,7 +71,7 @@ export default class UserDeletionService extends BaseService { user, flags, }), - userId + userId, ); await this.models.userFlag().add(userId, UserFlagType.UserDeletionInProgress); @@ -130,7 +130,7 @@ export default class UserDeletionService extends BaseService { { processAccount: true, processData: true, - } + }, ); if (addedUserIds.length) { diff --git a/packages/server/src/tools/debugTools.ts b/packages/server/src/tools/debugTools.ts index dea5d55b7..1ab6f77de 100644 --- a/packages/server/src/tools/debugTools.ts +++ b/packages/server/src/tools/debugTools.ts @@ -69,7 +69,7 @@ export async function createTestUsers(db: DbConnection, config: Config, options: 'With Sub', AccountType.Basic, 'usr_111', - 'sub_111' + 'sub_111', ); await models.user().save({ id: user.id, password }); } @@ -80,7 +80,7 @@ export async function createTestUsers(db: DbConnection, config: Config, options: 'Failed Payment', AccountType.Basic, 'usr_222', - 'sub_222' + 'sub_222', ); await models.user().save({ id: user.id, password }); await models.subscription().handlePayment(subscription.stripe_subscription_id, false); diff --git a/packages/server/src/utils/auth.test.ts b/packages/server/src/utils/auth.test.ts index 4ff524126..8b69efa3f 100644 --- a/packages/server/src/utils/auth.test.ts +++ b/packages/server/src/utils/auth.test.ts @@ -10,7 +10,7 @@ describe('hashPassword', () => { 'nuXUhqecx!RzK3wv6^xYaVEP%9fc$T%$E2k%9Q&TKvtDhR#2PUw3kA8KX3w2baAD8m#N9@52!DvfYn*X6hP#uAvpGF57*H9avcoePbR&4Q2XzckJnSW*EVm4G@a#YvnR', '$2a$10', '$2a$10$LMKVPiNOWDZhtw9NizNIEuNGLsjOxQAcrwQJ0lnKuiaOtyFgZEnwO', - ] + ], )('should return a string that starts with $2a$10 for the password: %', async (plainText) => { expect(hashPassword(plainText).startsWith('$2a$10')).toBe(true); }); diff --git a/packages/tools/build-translation.js b/packages/tools/build-translation.js index b39d17c46..9819fe9c9 100644 --- a/packages/tools/build-translation.js +++ b/packages/tools/build-translation.js @@ -313,7 +313,7 @@ async function updateReadmeWithStats(stats) { `${rootDir}/README.md`, '\n', '\n', - translationStatusToMdTable(stats) + translationStatusToMdTable(stats), ); } diff --git a/packages/tools/gulp/tasks/buildCommandIndex.js b/packages/tools/gulp/tasks/buildCommandIndex.js index 6bc143d7a..767d1528a 100644 --- a/packages/tools/gulp/tasks/buildCommandIndex.js +++ b/packages/tools/gulp/tasks/buildCommandIndex.js @@ -39,7 +39,7 @@ async function processDirectory(dir) { destFile, '// AUTO-GENERATED using `gulp buildCommandIndex`', fileContent.join('\n'), - true + true, ); } diff --git a/packages/tools/update-readme-contributors.js b/packages/tools/update-readme-contributors.js index 17801e9bc..002f9a283 100644 --- a/packages/tools/update-readme-contributors.js +++ b/packages/tools/update-readme-contributors.js @@ -90,7 +90,7 @@ async function main() { readmePath, '\n', '\n', - tableHtml + tableHtml, ); } diff --git a/packages/tools/update-readme-sponsors.ts b/packages/tools/update-readme-sponsors.ts index b7f8e449e..e066451f5 100644 --- a/packages/tools/update-readme-sponsors.ts +++ b/packages/tools/update-readme-sponsors.ts @@ -64,14 +64,14 @@ async function main() { readmePath, '\n', '\n', - await createGitHubSponsorTable(sponsors.github) + await createGitHubSponsorTable(sponsors.github), ); await insertContentIntoFile( readmePath, '\n', '\n', - await createOrgSponsorTable(sponsors.orgs) + await createOrgSponsorTable(sponsors.orgs), ); } From b452a0a870551393b1438fc1d86a9d217fdeedc1 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 18:41:58 +0100 Subject: [PATCH 11/13] Desktop: Fixes #8706: Pasting a resource in Rich Text editor breaks the resource link --- packages/utils/url.test.ts | 31 ++++++++++++ packages/utils/url.ts | 98 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 packages/utils/url.test.ts create mode 100644 packages/utils/url.ts diff --git a/packages/utils/url.test.ts b/packages/utils/url.test.ts new file mode 100644 index 000000000..cec4d73db --- /dev/null +++ b/packages/utils/url.test.ts @@ -0,0 +1,31 @@ +import { fileUriToPath } from './url'; + +describe('utils/url', () => { + + it('should convert a file URI to a file path', (async () => { + // Tests imported from https://github.com/TooTallNate/file-uri-to-path/tree/master/test + const testCases = { + 'file://host/path': '//host/path', + 'file://localhost/etc/fstab': '/etc/fstab', + 'file:///etc/fstab': '/etc/fstab', + 'file:///c:/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', + 'file://localhost/c|/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', + 'file:///c|/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', + 'file://localhost/c:/WINDOWS/clock.avi': 'c:/WINDOWS/clock.avi', + 'file://hostname/path/to/the%20file.txt': '//hostname/path/to/the file.txt', + 'file:///c:/path/to/the%20file.txt': 'c:/path/to/the file.txt', + 'file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc': 'C:/Documents and Settings/davris/FileSchemeURIs.doc', + 'file:///C:/caf%C3%A9/%C3%A5r/d%C3%BCnn/%E7%89%9B%E9%93%83/Ph%E1%BB%9F/%F0%9F%98%B5.exe': 'C:/café/år/dünn/牛铃/Phở/😵.exe', + }; + + for (const [input, expected] of Object.entries(testCases)) { + const actual = fileUriToPath(input); + expect(actual).toBe(expected); + } + + expect(fileUriToPath('file://c:/not/quite/right')).toBe('c:/not/quite/right'); + expect(fileUriToPath('file:///d:/better')).toBe('d:/better'); + expect(fileUriToPath('file:///c:/AUTOEXEC.BAT', 'win32')).toBe('c:\\AUTOEXEC.BAT'); + })); + +}); diff --git a/packages/utils/url.ts b/packages/utils/url.ts new file mode 100644 index 000000000..54153cb1b --- /dev/null +++ b/packages/utils/url.ts @@ -0,0 +1,98 @@ +/* eslint-disable import/prefer-default-export */ + +// This is a modified version of the file-uri-to-path package: +// +// - It removes the dependency to the "path" package, which wouldn't work with +// React Native. +// +// - It always returns paths with forward slashes "/". This is normally handled +// properly everywhere. +// +// - Adds the "platform" parameter to optionall return paths with "\" for win32 +function fileUriToPath_(uri: string, platform: string) { + const sep = '/'; + + if ( + typeof uri !== 'string' || + uri.length <= 7 || + uri.substring(0, 7) !== 'file://' + ) { + throw new TypeError( + 'must pass in a file:// URI to convert to a file path', + ); + } + + const rest = decodeURI(uri.substring(7)); + const firstSlash = rest.indexOf('/'); + let host = rest.substring(0, firstSlash); + let path = rest.substring(firstSlash + 1); + + // 2. Scheme Definition + // As a special case, can be the string "localhost" or the empty + // string; this is interpreted as "the machine from which the URL is + // being interpreted". + if (host === 'localhost') { + host = ''; + } + + if (host) { + host = sep + sep + host; + } + + // 3.2 Drives, drive letters, mount points, file system root + // Drive letters are mapped into the top of a file URI in various ways, + // depending on the implementation; some applications substitute + // vertical bar ("|") for the colon after the drive letter, yielding + // "file:///c|/tmp/test.txt". In some cases, the colon is left + // unchanged, as in "file:///c:/tmp/test.txt". In other cases, the + // colon is simply omitted, as in "file:///c/tmp/test.txt". + path = path.replace(/^(.+)\|/, '$1:'); + + // for Windows, we need to invert the path separators from what a URI uses + // if (sep === '\\') { + // path = path.replace(/\//g, '\\'); + // } + + if (/^.+:/.test(path)) { + // has Windows drive at beginning of path + } else { + // unix path… + path = sep + path; + } + + if (platform === 'win32') { + return (host + path).replace(/\//g, '\\'); + } else { + return host + path; + } +} + +export const fileUriToPath = (path: string, platform = 'linux') => { + const output = fileUriToPath_(path, platform); + + // The file-uri-to-path module converts Windows path such as + // + // file://c:/autoexec.bat => \\c:\autoexec.bat + // + // Probably because a file:// that starts with only two slashes is not + // quite valid. If we use three slashes, it works: + // + // file:///c:/autoexec.bat => c:\autoexec.bat + // + // However there are various places in the app where we can find + // paths with only two slashes because paths are often constructed + // as `file://${resourcePath}` - which works in all OSes except + // Windows. + // + // So here we introduce a special case - if we detect that we have + // an invalid Windows path that starts with \\x:, we just remove + // the first two backslashes. + // + // https://github.com/laurent22/joplin/issues/5693 + + if (output.match(/^\/\/[a-zA-Z]:/)) { + return output.substr(2); + } + + return output; +}; From 8696ae1bb60283a9c13cc523abb619b87b6aa161 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 18:59:04 +0100 Subject: [PATCH 12/13] Desktop: Fixes #8706: Pasting a resource in Rich Text editor breaks the resource link --- packages/renderer/htmlUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/renderer/htmlUtils.ts b/packages/renderer/htmlUtils.ts index 1cfceea04..33e87e41d 100644 --- a/packages/renderer/htmlUtils.ts +++ b/packages/renderer/htmlUtils.ts @@ -1,4 +1,5 @@ -import { htmlentities } from '@joplin/utils/html'; +const Entities = require('html-entities').AllHtmlEntities; +const htmlentities = new Entities().encode; import { fileUriToPath } from '@joplin/utils/url'; const htmlparser2 = require('@joplin/fork-htmlparser2'); From d590bd7720777fcad70c4caa16984cd9a9dcd552 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 23 Aug 2023 19:03:00 +0100 Subject: [PATCH 13/13] Desktop release v2.12.14 --- packages/app-desktop/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-desktop/package.json b/packages/app-desktop/package.json index a6e4ff25a..0063b0ee4 100644 --- a/packages/app-desktop/package.json +++ b/packages/app-desktop/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/app-desktop", - "version": "2.12.13", + "version": "2.12.14", "description": "Joplin for Desktop", "main": "main.js", "private": true,