1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-12-26 23:38:08 +02:00

Compare commits

...

38 Commits

Author SHA1 Message Date
Laurent Cozic
6001e07cbc update 2023-07-31 19:00:21 +01:00
Laurent Cozic
6210d85192 Merge branch 'dev' into mobile_plugins_2 2023-07-31 11:12:44 +01:00
Laurent Cozic
2633bcef69 Doc: Shortened section about carbon neutrality and mentioned data being in France 2023-07-31 11:12:32 +01:00
renovate[bot]
772c8abdcf Update dependency react-native-safe-area-context to v4.6.0 (#8586)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-31 10:31:31 +01:00
Joplin Bot
ac098759ea Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-07-31 00:44:28 +00:00
Naoki Kawamukai
349dda30b8 All: Translation: Update ja_JP.po (#8580) 2023-07-30 18:35:37 -04:00
renovate[bot]
cbbd9b9a61 Update dependency react-native-image-picker to v5.6.0 (#8582)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-30 15:22:23 +01:00
github-actions[bot]
14ef0d725b @kna has signed the CLA in laurent22/joplin#8580 2023-07-30 02:10:58 +00:00
Laurent Cozic
0c981ae4a7 fixed module import 2023-07-29 19:19:01 +01:00
Laurent Cozic
401eee568a fixed JoplinWindow 2023-07-29 17:43:58 +01:00
Laurent Cozic
0b85e16125 Merge branch 'dev' into mobile_plugins_2 2023-07-29 17:34:12 +01:00
Laurent Cozic
40b89f61bd Desktop release v2.12.10 2023-07-29 16:53:15 +01:00
Laurent Cozic
23c4020eea udpate 2023-07-29 16:52:24 +01:00
Laurent Cozic
5ba374c03b Doc: Change Reddit links to Lemmy 2023-07-29 16:47:46 +01:00
Henry Heino
f76ae86204 Chore: Mobile: Tests: Fix CodeMirror-related error messages (#8569) 2023-07-29 16:33:39 +01:00
Henry Heino
46ccd94514 Desktop: Fixes: #8370: Fix note drag-drop into markdown editor (#8571) 2023-07-29 16:32:52 +01:00
Henry Heino
7140675181 Chore: Desktop: Fixes #8572: Fix warning when pasting images with data URI srcs (#8574) 2023-07-29 16:31:36 +01:00
Laurent Cozic
0368c26ead init 2023-07-28 21:21:13 +01:00
Laurent Cozic
31f8e725dd Fixed mobile build 2023-07-28 11:31:59 +01:00
Laurent Cozic
5edbdb2466 Fix tests 2023-07-28 10:46:40 +01:00
Joplin Bot
83cf5eb617 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-07-27 18:18:52 +00:00
Oleksandr Popov
5b0c332477 Translation: Updating Ukrainian translation file (#8565) 2023-07-27 16:35:42 +01:00
Oleksandr Popov
21a5feb322 Translation: Updating Russian translation file (#8560) 2023-07-27 16:35:30 +01:00
Laurent Cozic
16c87c36da Chore: Move Logger from lib to utils package 2023-07-27 16:08:11 +01:00
Henry Heino
a0ec928fca Merge pull request from GHSA-m59c-9rrj-c399
* Sanitize HTML in processPastedHtml

* Add test
2023-07-27 15:41:57 +01:00
Laurent Cozic
b9659bb9c1 Desktop: Fixes #8476: Text that is pasted in Rich Text editor had extra new lines 2023-07-27 14:48:41 +01:00
Henry Heino
35f375d756 Desktop: Fixes #6055: Preserve empty newlines created by pressing Enter repeatedly in the rich text editor (#8549) 2023-07-27 11:52:41 +01:00
Mr-Kanister
04c80fe00e Update de_DE.po (#8551) 2023-07-27 11:39:38 +01:00
Joplin Bot
06732d8b8a Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-07-26 18:16:56 +00:00
pedr
8fc1e71fb3 Doc: Email to Note (#8527) 2023-07-26 18:07:29 +01:00
Henry Heino
aebfa6e96d Desktop: Fixes #8535: Fix CodeMirror context menu not containing correct items (#8543) 2023-07-26 18:07:00 +01:00
Henry Heino
3453abb670 Desktop: Fixes #8535: Upgrade to electron 25.3.1 (#8550) 2023-07-26 18:00:46 +01:00
Laurent Cozic
637a0eac7f Desktop: Fixes #8485: Note imported from Web Clipper is broken after being saved from the Rich Text editor 2023-07-26 17:37:24 +01:00
github-actions[bot]
abe479d03f @popovoleksandr has signed the CLA in laurent22/joplin#8560 2023-07-26 16:17:15 +00:00
Myst
d1558d84b1 Fix typo french translation (#8554) 2023-07-26 16:25:16 +01:00
Laurent Cozic
36e9e0a33c Server: Support setting an instance name 2023-07-26 14:42:35 +01:00
Laurent Cozic
d78ab16021 Server: Add support for separate admin instance 2023-07-26 14:36:50 +01:00
Laurent Cozic
c718706f9c Server: Remove event-based services 2023-07-26 10:40:56 +01:00
207 changed files with 17332 additions and 926 deletions

View File

@@ -76,6 +76,7 @@ plugin_types/
readme/
packages/react-native-vosk/lib/
packages/lib/countable/Countable.js
packages/app-mobile/plugins
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
packages/app-cli/app/LinkSelector.js
@@ -253,6 +254,7 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.js
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
packages/app-desktop/gui/NoteEditor/utils/index.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.js
packages/app-desktop/gui/NoteEditor/utils/types.js
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
@@ -442,6 +444,7 @@ packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
packages/app-mobile/services/e2ee/RSA.react-native.js
packages/app-mobile/services/plugins/PluginRunner.js
packages/app-mobile/services/profiles/index.js
packages/app-mobile/services/voiceTyping/vosk.android.js
packages/app-mobile/services/voiceTyping/vosk.ios.js
@@ -455,6 +458,7 @@ packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/createRootStyle.js
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/markupLanguageUtils.js
packages/app-mobile/utils/setupNotifications.js
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/types.js
@@ -492,7 +496,6 @@ packages/lib/InMemoryCache.js
packages/lib/JoplinDatabase.js
packages/lib/JoplinError.js
packages/lib/JoplinServerApi.js
packages/lib/Logger.js
packages/lib/ObjectUtils.js
packages/lib/PoorManIntervals.js
packages/lib/RotatingLogs.test.js
@@ -845,6 +848,7 @@ packages/plugins/ToggleSidebars/api/index.js
packages/plugins/ToggleSidebars/api/types.js
packages/plugins/ToggleSidebars/src/index.js
packages/react-native-saf-x/src/index.js
packages/renderer/HtmlToHtml.test.js
packages/renderer/HtmlToHtml.js
packages/renderer/InMemoryCache.js
packages/renderer/MarkupToHtml.js

5
.gitignore vendored
View File

@@ -238,6 +238,7 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.js
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
packages/app-desktop/gui/NoteEditor/utils/index.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.js
packages/app-desktop/gui/NoteEditor/utils/types.js
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
@@ -427,6 +428,7 @@ packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
packages/app-mobile/services/e2ee/RSA.react-native.js
packages/app-mobile/services/plugins/PluginRunner.js
packages/app-mobile/services/profiles/index.js
packages/app-mobile/services/voiceTyping/vosk.android.js
packages/app-mobile/services/voiceTyping/vosk.ios.js
@@ -440,6 +442,7 @@ packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/createRootStyle.js
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/markupLanguageUtils.js
packages/app-mobile/utils/setupNotifications.js
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/types.js
@@ -477,7 +480,6 @@ packages/lib/InMemoryCache.js
packages/lib/JoplinDatabase.js
packages/lib/JoplinError.js
packages/lib/JoplinServerApi.js
packages/lib/Logger.js
packages/lib/ObjectUtils.js
packages/lib/PoorManIntervals.js
packages/lib/RotatingLogs.test.js
@@ -830,6 +832,7 @@ packages/plugins/ToggleSidebars/api/index.js
packages/plugins/ToggleSidebars/api/types.js
packages/plugins/ToggleSidebars/src/index.js
packages/react-native-saf-x/src/index.js
packages/renderer/HtmlToHtml.test.js
packages/renderer/HtmlToHtml.js
packages/renderer/InMemoryCache.js
packages/renderer/MarkupToHtml.js

View File

@@ -789,7 +789,7 @@ footer .bottom-links-row p {
}
#menu-mobile .social-links .social-link-mastodon,
#menu-mobile .social-links .social-link-reddit,
#menu-mobile .social-links .social-link-lemmy,
#menu-mobile .social-links .social-link-linkedin,
#menu-mobile .social-links .social-link-patreon {
display: none;

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -5,7 +5,7 @@
<a class="social-link-patreon" href="https://www.patreon.com/joplin" title="Joplin Patreon"><i class="fab fa-patreon"></i></a>
<a class="social-link-discord" href="https://discord.gg/VSj7AFHvpq" title="Joplin Discord chat"><i class="fab fa-discord"></i></a>
<a class="social-link-linkedin" href="https://www.linkedin.com/company/joplin" title="Joplin LinkedIn Feed"><i class="fab fa-linkedin"></i></a>
<a class="social-link-reddit" href="https://www.reddit.com/r/joplinapp/" title="Joplin Subreddit"><i class="fab fa-reddit"></i></a>
<a class="social-link-lemmy" href="https://sopuli.xyz/c/joplinapp" title="Joplin Lemmy Community"><i class="fas fa-otter"></i></a>
<a class="social-link-github" href="https://github.com/laurent22/joplin/" title="Joplin GitHub repository"><i class="fab fa-github"></i></a>
</div>
</div>

View File

@@ -107,6 +107,7 @@ A community maintained list of these distributions can be found here: [Unofficia
- [Sharing a notebook](https://github.com/laurent22/joplin/blob/dev/readme/share_notebook.md)
- [Publishing a note](https://github.com/laurent22/joplin/blob/dev/readme/publish_note.md)
- [Email to Note](https://github.com/laurent22/joplin/blob/dev/readme/email_to_note.md)
- Joplin API - Get Started
@@ -511,7 +512,7 @@ Name | Description
[Patreon page](https://www.patreon.com/joplin) |The latest news are often posted there
[Discord server](https://discord.gg/VSj7AFHvpq) | Our chat server
[LinkedIn](https://www.linkedin.com/company/joplin) | Our LinkedIn page
[Sub-reddit](https://www.reddit.com/r/joplinapp/) | Also a good place to get help
[Lemmy Community](https://sopuli.xyz/c/joplinapp) | Also a good place to get help
# Contributing

View File

@@ -1,4 +1,4 @@
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const { findAvailablePort } = require('@joplin/lib/net-utils');
const http = require('http');

View File

@@ -1,4 +1,4 @@
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const Folder = require('@joplin/lib/models/Folder').default;
const BaseItem = require('@joplin/lib/models/BaseItem').default;
const Tag = require('@joplin/lib/models/Tag').default;

View File

@@ -3,7 +3,7 @@
/* eslint-disable no-console */
const fs = require('fs-extra');
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const { dirname } = require('@joplin/lib/path-utils');
const { DatabaseDriverNode } = require('@joplin/lib/database-driver-node.js');
const JoplinDatabase = require('@joplin/lib/JoplinDatabase').default;

View File

@@ -2,7 +2,7 @@ const yargParser = require('yargs-parser');
const { _ } = require('@joplin/lib/locale');
const time = require('@joplin/lib/time').default;
const stringPadding = require('string-padding');
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const cliUtils = {};

View File

@@ -1,7 +1,7 @@
const BaseCommand = require('./base-command').default;
const { _ } = require('@joplin/lib/locale');
const Setting = require('@joplin/lib/models/Setting').default;
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const shim = require('@joplin/lib/shim').default;
class Command extends BaseCommand {

View File

@@ -1,7 +1,7 @@
'use strict';
const time = require('@joplin/lib/time').default;
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const Resource = require('@joplin/lib/models/Resource').default;
const { dirname } = require('@joplin/lib/path-utils');
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;

View File

@@ -20,7 +20,7 @@ const NoteTag = require('@joplin/lib/models/NoteTag').default;
const MasterKey = require('@joplin/lib/models/MasterKey').default;
const Setting = require('@joplin/lib/models/Setting').default;
const Revision = require('@joplin/lib/models/Revision').default;
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
const sharp = require('sharp');
const { shimInit } = require('@joplin/lib/shim-init-node.js');

View File

@@ -0,0 +1,3 @@
<p>Paragraphs with a single nonbreaking space should be preserved:</p>
<p>&nbsp;</p>
<p>&nbsp;</p>

View File

@@ -0,0 +1,5 @@
Paragraphs with a single nonbreaking space should be preserved:
&nbsp;
&nbsp;

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { PluginMessage } from './services/plugins/PluginRunner';
import shim from '@joplin/lib/shim';
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';

View File

@@ -4,7 +4,7 @@ import { defaultState, State } from '@joplin/lib/reducer';
import iterateItems from './gui/ResizableLayout/utils/iterateItems';
import { LayoutItem } from './gui/ResizableLayout/utils/types';
import validateLayout from './gui/ResizableLayout/utils/validateLayout';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('app.reducer');

View File

@@ -8,7 +8,7 @@ import PlatformImplementation from './services/plugins/PlatformImplementation';
import shim from '@joplin/lib/shim';
import AlarmService from '@joplin/lib/services/AlarmService';
import AlarmServiceDriverNode from '@joplin/lib/services/AlarmServiceDriverNode';
import Logger, { TargetType } from '@joplin/lib/Logger';
import Logger, { TargetType } from '@joplin/utils/Logger';
import Setting from '@joplin/lib/models/Setting';
import actionApi from '@joplin/lib/services/rest/actionApi.desktop';
import BaseApplication from '@joplin/lib/BaseApplication';
@@ -262,6 +262,8 @@ class Application extends BaseApplication {
if (this.initPluginServiceDone_) return;
this.initPluginServiceDone_ = true;
PlatformImplementation.instance().initialize((action: any) => this.dispatch(action));
const service = PluginService.instance();
const pluginRunner = new PluginRunner();

View File

@@ -96,11 +96,7 @@ export class Bridge {
electronApp: this.electronApp(),
shouldShowMenu: (_event: any, params: any) => {
// params.inputFieldType === 'none' when right-clicking the text
// editor. This is a bit of a hack to detect it because in this
// case we don't want to use the built-in context menu but a
// custom one.
return params.isEditable && params.inputFieldType !== 'none';
return params.isEditable;
},
// menu: (actions: any, props: any) => {

View File

@@ -1,5 +1,5 @@
import shim from '@joplin/lib/shim';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { _ } from '@joplin/lib/locale';
import bridge from './services/bridge';
import KvStore from '@joplin/lib/services/KvStore';

View File

@@ -13,7 +13,7 @@ import { PluginItem } from './PluginBox';
import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi';
import Setting from '@joplin/lib/models/Setting';
import useOnInstallHandler, { OnPluginSettingChangeEvent } from './useOnInstallHandler';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import StyledMessage from '../../../style/StyledMessage';
import StyledLink from '../../../style/StyledLink';
const { space } = require('styled-system');

View File

@@ -2,7 +2,7 @@ import { useCallback } from 'react';
import PluginService, { defaultPluginSetting, PluginSettings } from '@joplin/lib/services/plugins/PluginService';
import produce from 'immer';
import { _ } from '@joplin/lib/locale';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { ItemEvent } from './PluginBox';
const logger = Logger.create('useOnInstallHandler');

View File

@@ -1,7 +1,7 @@
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
import ShareService from '@joplin/lib/services/share/ShareService';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('leaveSharedFolder');

View File

@@ -40,6 +40,7 @@ import ErrorBoundary from '../../../ErrorBoundary';
import { MarkupToHtmlOptions } from '../../utils/useMarkupToHtml';
import eventManager from '@joplin/lib/eventManager';
import { EditContextMenuFilterObject } from '@joplin/lib/services/plugins/api/JoplinWorkspace';
import type { ContextMenuEvent, ContextMenuParams } from 'electron';
const menuUtils = new MenuUtils(CommandService.instance());
@@ -782,20 +783,50 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
// It might be buggy, refer to the below issue
// https://github.com/laurent22/joplin/pull/3974#issuecomment-718936703
useEffect(() => {
function pointerInsideEditor(params: any) {
const x = params.x, y = params.y, isEditable = params.isEditable, inputFieldType = params.inputFieldType;
const isAncestorOfCodeMirrorEditor = (elem: HTMLElement) => {
for (; elem.parentElement; elem = elem.parentElement) {
if (elem.classList.contains('codeMirrorEditor')) {
return true;
}
}
return false;
};
let lastInCodeMirrorContextMenuTimestamp = 0;
// The browser's contextmenu event provides additional information about the
// target of the event, not provided by the Electron context-menu event.
const onBrowserContextMenu = (event: Event) => {
if (isAncestorOfCodeMirrorEditor(event.target as HTMLElement)) {
lastInCodeMirrorContextMenuTimestamp = Date.now();
}
};
function pointerInsideEditor(params: ContextMenuParams) {
const x = params.x, y = params.y, isEditable = params.isEditable;
const elements = document.getElementsByClassName('codeMirrorEditor');
// inputFieldType: The input field type of CodeMirror is "textarea" so the inputFieldType = "none",
// and any single-line input above codeMirror has inputFieldType value according to the type of input e.g.(text = plainText, password = password, ...).
if (!elements.length || !isEditable || inputFieldType !== 'none') return null;
// Note: We can't check inputFieldType here. When spellcheck is enabled,
// params.inputFieldType is "none". When spellcheck is disabled,
// params.inputFieldType is "plainText". Thus, such a check would be inconsistent.
if (!elements.length || !isEditable) return false;
const maximumMsSinceBrowserEvent = 100;
if (Date.now() - lastInCodeMirrorContextMenuTimestamp > maximumMsSinceBrowserEvent) {
return false;
}
const rect = convertToScreenCoordinates(Setting.value('windowContentZoomFactor'), elements[0].getBoundingClientRect());
return rect.x < x && rect.y < y && rect.right > x && rect.bottom > y;
}
async function onContextMenu(_event: any, params: any) {
async function onContextMenu(event: ContextMenuEvent, params: ContextMenuParams) {
if (!pointerInsideEditor(params)) return;
// Don't show the default menu.
event.preventDefault();
const menu = new Menu();
const hasSelectedText = editorRef.current && !!editorRef.current.getSelection() ;
@@ -872,10 +903,15 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
menu.popup();
}
bridge().window().webContents.on('context-menu', onContextMenu);
// Prepend the event listener so that it gets called before
// the listener that shows the default menu.
bridge().window().webContents.prependListener('context-menu', onContextMenu);
window.addEventListener('contextmenu', onBrowserContextMenu);
return () => {
bridge().window().webContents.off('context-menu', onContextMenu);
window.removeEventListener('contextmenu', onBrowserContextMenu);
};
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [props.plugins]);

View File

@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import shim from '@joplin/lib/shim';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('useEditorSearch');

View File

@@ -91,7 +91,7 @@ let dispatchDidUpdateIID_: any = null;
let changeId_ = 1;
const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
const [editor, setEditor] = useState(null);
const [editor, setEditor] = useState<Editor|null>(null);
const [scriptLoaded, setScriptLoaded] = useState(false);
const [editorReady, setEditorReady] = useState(false);
const [draggingStarted, setDraggingStarted] = useState(false);
@@ -578,7 +578,12 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
icons_url: 'gui/NoteEditor/NoteBody/TinyMCE/icons.js',
plugins: 'noneditable link joplinLists hr searchreplace codesample table',
noneditable_noneditable_class: 'joplin-editable', // Can be a regex too
valid_elements: '*[*]', // We already filter in sanitize_html
// #p: Pad empty paragraphs with &nbsp; to prevent them from being removed.
// *[*]: Allow all elements and attributes -- we already filter in sanitize_html
// See https://www.tiny.cloud/docs/configure/content-filtering/#controlcharacters
valid_elements: '#p,*[*]',
menubar: false,
relative_urls: false,
branding: false,

View File

@@ -1,5 +1,5 @@
import Resource from '@joplin/lib/models/Resource';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('contextMenuUtils');
export enum ContextMenuItemType {
None = '',

View File

@@ -0,0 +1,20 @@
import { processPastedHtml } from './resourceHandling';
describe('resourceHandling', () => {
it('should sanitize pasted HTML', async () => {
const testCases = [
['Test: <style onload="evil()"></style>', 'Test: <style></style>'],
['<a href="javascript: alert()">test</a>', '<a href="#">test</a>'],
['<script >evil()</script>', ''],
['<script>evil()</script>', ''],
[
'<img onload="document.body.innerHTML = evil;" src="data:image/svg+xml;base64,=="/>',
'<img src="data:image/svg+xml;base64,=="/>',
],
];
for (const [html, expected] of testCases) {
expect(await processPastedHtml(html)).toBe(expected);
}
});
});

View File

@@ -6,7 +6,8 @@ import Resource from '@joplin/lib/models/Resource';
const bridge = require('@electron/remote').require('./bridge').default;
import ResourceFetcher from '@joplin/lib/services/ResourceFetcher';
import htmlUtils from '@joplin/lib/htmlUtils';
import Logger from '@joplin/lib/Logger';
import rendererHtmlUtils from '@joplin/renderer/htmlUtils';
import Logger from '@joplin/utils/Logger';
const { fileUriToPath } = require('@joplin/lib/urlUtils');
const joplinRendererUtils = require('@joplin/renderer').utils;
const { clipboard } = require('electron');
@@ -159,6 +160,8 @@ export async function processPastedHtml(html: string) {
const createdResource = await shim.createResourceFromPath(imageFilePath);
mappedResources[imageSrc] = `file://${encodeURI(Resource.fullPath(createdResource))}`;
}
} else if (imageSrc.startsWith('data:')) { // Data URIs
mappedResources[imageSrc] = imageSrc;
} else {
const filePath = `${Setting.value('tempDir')}/${md5(Date.now() + Math.random())}`;
await shim.fetchBlob(imageSrc, { path: filePath });
@@ -173,7 +176,9 @@ export async function processPastedHtml(html: string) {
}
}
return htmlUtils.replaceImageUrls(html, (src: string) => {
return mappedResources[src];
});
return rendererHtmlUtils.sanitizeHtml(
htmlUtils.replaceImageUrls(html, (src: string) => {
return mappedResources[src];
})
);
}

View File

@@ -3,7 +3,7 @@ import { FormNote, defaultFormNote, ResourceInfos } from './types';
import { clearResourceCache, attachedResources } from './resourceHandling';
import AsyncActionQueue from '@joplin/lib/AsyncActionQueue';
import { handleResourceDownloadMode } from './resourceHandling';
import HtmlToHtml from '@joplin/renderer/HtmlToHtml';
import { splitHtml } from '@joplin/renderer/HtmlToHtml';
import Setting from '@joplin/lib/models/Setting';
import usePrevious from '../../hooks/usePrevious';
import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index';
@@ -73,8 +73,7 @@ export default function useFormNote(dependencies: HookDependencies) {
let originalCss = '';
if (n.markup_language === MarkupToHtml.MARKUP_LANGUAGE_HTML) {
const htmlToHtml = new HtmlToHtml();
const splitted = htmlToHtml.splitHtml(n.body);
const splitted = splitHtml(n.body);
originalCss = splitted.css;
}

View File

@@ -1,5 +1,5 @@
import { useState, useCallback, MutableRefObject, useEffect } from 'react';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { SearchMarkers } from './useSearchMarkers';
const CommandService = require('@joplin/lib/services/CommandService').default;

View File

@@ -246,7 +246,10 @@ const NoteListComponent = (props: Props) => {
event.dataTransfer.setDragImage(new Image(), 1, 1);
event.dataTransfer.clearData();
event.dataTransfer.setData('text/x-jop-note-ids', JSON.stringify(noteIds));
event.dataTransfer.effectAllowed = 'move';
// While setting
// event.dataTransfer.effectAllowed = 'move';
// causes the drag cursor to have a "move", rather than an "add", icon,
// this breaks note drag and drop into the markdown editor.
return true;
}, [props.parentFolderIsReadOnly, props.selectedNoteIds]);

View File

@@ -10,7 +10,7 @@ import styled from 'styled-components';
import StyledFormLabel from '../style/StyledFormLabel';
import StyledInput from '../style/StyledInput';
import Button, { ButtonSize } from '../Button/Button';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import StyledMessage from '../style/StyledMessage';
import { SharePermissions, ShareUserStatus, StateShare, StateShareUser } from '@joplin/lib/services/share/reducer';
import { State } from '@joplin/lib/reducer';

View File

@@ -19,7 +19,7 @@ import BaseModel from '@joplin/lib/BaseModel';
import Folder from '@joplin/lib/models/Folder';
import Note from '@joplin/lib/models/Note';
import Tag from '@joplin/lib/models/Tag';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { FolderEntity, FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext';
import { store } from '@joplin/lib/reducer';

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
// Can't upgrade beyond 2.x because it doesn't work with Electron. If trying to
// upgrade again, check that adding a link from the CodeMirror editor works/

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('loadScript');

View File

@@ -116,7 +116,7 @@ module.exports = {
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
setupFilesAfterEnv: [`${__dirname}/jest.setup.js`],
// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,

View File

@@ -0,0 +1,19 @@
const { default: Logger, TargetType } = require('@joplin/utils/Logger');
// TODO: Some libraries required by test-utils.js seem to fail to import with the
// jsdom environment.
//
// Thus, require('@joplin/lib/testing/test-utils.js') fails and some setup must be
// copied.
const logger = new Logger();
logger.addTarget(TargetType.Console);
logger.setLevel(Logger.LEVEL_WARN);
Logger.initializeGlobalLogger(logger);
// @electron/remote requires electron to be running. Mock it.
jest.mock('@electron/remote', () => {
return { require };
});

View File

@@ -20,7 +20,7 @@ const NoteTag = require('@joplin/lib/models/NoteTag').default;
const MasterKey = require('@joplin/lib/models/MasterKey').default;
const Setting = require('@joplin/lib/models/Setting').default;
const Revision = require('@joplin/lib/models/Revision').default;
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
const shim = require('@joplin/lib/shim').default;
const { shimInit } = require('@joplin/lib/shim-init-node.js');

View File

@@ -4,7 +4,7 @@ const electronApp = require('electron').app;
require('@electron/remote/main').initialize();
const ElectronAppWrapper = require('./ElectronAppWrapper').default;
const { initBridge } = require('./bridge');
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
const envFromArgs = require('@joplin/lib/envFromArgs');
const packageInfo = require('./packageInfo.js');

View File

@@ -1,6 +1,6 @@
{
"name": "@joplin/app-desktop",
"version": "2.12.9",
"version": "2.12.10",
"description": "Joplin for Desktop",
"main": "main.js",
"private": true,
@@ -115,7 +115,7 @@
"@types/react": "16.14.41",
"@types/react-redux": "7.1.25",
"@types/styled-components": "5.1.26",
"electron": "25.2.0",
"electron": "25.3.1",
"electron-builder": "24.4.0",
"glob": "10.2.7",
"gulp": "4.0.2",
@@ -138,6 +138,7 @@
"@joeattardi/emoji-button": "4.6.4",
"@joplin/lib": "~2.12",
"@joplin/renderer": "~2.12",
"@joplin/utils": "~2.12",
"async-mutex": "0.4.0",
"codemirror": "5.65.9",
"color": "3.2.1",

View File

@@ -18,7 +18,7 @@ const { surroundKeywords, nextWhitespaceIndex, removeDiacritics } = require('@jo
import { mergeOverlappingIntervals } from '@joplin/lib/ArrayUtils';
import markupLanguageUtils from '../utils/markupLanguageUtils';
import focusEditorIfEditorCommand from '@joplin/lib/services/commands/focusEditorIfEditorCommand';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { MarkupToHtml } from '@joplin/renderer';
const logger = Logger.create('GotoAnything');

View File

@@ -42,6 +42,11 @@ const create = (win, options) => {
return;
}
// If another listener has called .preventDefault, don't show the default context menu.
if (event.defaultPrevented) {
return;
}
const { editFlags } = props;
const hasText = props.selectionText.trim().length > 0;
const isLink = Boolean(props.linkURL);

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import time from '@joplin/lib/time';
const logger = Logger.create('BackOffHandler');

View File

@@ -5,6 +5,8 @@ import { VersionInfo } from '@joplin/lib/services/plugins/api/types';
import Setting from '@joplin/lib/models/Setting';
import { reg } from '@joplin/lib/registry';
import BasePlatformImplementation, { Joplin } from '@joplin/lib/services/plugins/BasePlatformImplementation';
import { Dispatch } from 'redux';
import { readFile } from 'fs-extra';
const { clipboard, nativeImage } = require('electron');
const packageInfo = require('../../packageInfo');
@@ -20,12 +22,17 @@ export default class PlatformImplementation extends BasePlatformImplementation {
private static instance_: PlatformImplementation;
private joplin_: Joplin;
private components_: Components;
private dispatch_: Dispatch|null = null;
public static instance(): PlatformImplementation {
if (!this.instance_) this.instance_ = new PlatformImplementation();
return this.instance_;
}
public initialize(dispatch: Dispatch) {
this.dispatch_ = dispatch;
}
public get versionInfo(): VersionInfo {
return {
version: packageInfo.version,
@@ -45,6 +52,14 @@ export default class PlatformImplementation extends BasePlatformImplementation {
public get window(): WindowImplementation {
return {
injectCustomStyles: injectCustomStyles,
loadNoteCssFile: async (filePath) => {
const cssString = await readFile(filePath, 'utf8');
this.dispatch_({
type: 'CUSTOM_CSS_APPEND',
css: cssString,
});
},
};
}

View File

@@ -6,7 +6,7 @@ import bridge from '../bridge';
import Setting from '@joplin/lib/models/Setting';
import { EventHandlers } from '@joplin/lib/services/plugins/utils/mapEventHandlersToIds';
import shim from '@joplin/lib/shim';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
// import BackOffHandler from './BackOffHandler';
const ipcRenderer = require('electron').ipcRenderer;

View File

@@ -7,7 +7,7 @@ import useSubmitHandler from './hooks/useSubmitHandler';
import useHtmlLoader from './hooks/useHtmlLoader';
import useWebviewToPluginMessages from './hooks/useWebviewToPluginMessages';
import useScriptLoader from './hooks/useScriptLoader';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import styled from 'styled-components';
const logger = Logger.create('UserWebview');

View File

@@ -1,5 +1,5 @@
import ShareService from '@joplin/lib/services/share/ShareService';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import Folder from '@joplin/lib/models/Folder';
import { reg } from '@joplin/lib/registry';
import { _ } from '@joplin/lib/locale';

View File

@@ -2,7 +2,7 @@
import SpellCheckerServiceDriverBase from '@joplin/lib/services/spellChecker/SpellCheckerServiceDriverBase';
import bridge from '../bridge';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { languageCodeOnly, localesFromLanguageCode } from '@joplin/lib/locale';
const logger = Logger.create('SpellCheckerServiceDriverNative');

View File

@@ -47,7 +47,7 @@ react {
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
//
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
// hermesFlags = ["-O", "-output-source-map"]
hermesFlags = ["-O", "-output-source-map"]
}
/**

View File

@@ -2,8 +2,8 @@ import { useEffect, useState, useMemo, useRef } from 'react';
import shim from '@joplin/lib/shim';
import Setting from '@joplin/lib/models/Setting';
const { themeStyle } = require('../../global-style.js');
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
import Logger from '@joplin/lib/Logger';
import markupLanguageUtils from '../../../utils/markupLanguageUtils';
import Logger from '@joplin/utils/Logger';
const { assetsToHeaders } = require('@joplin/renderer');
const logger = Logger.create('NoteBodyViewer/useSource');

View File

@@ -1,7 +1,3 @@
/**
* @jest-environment jsdom
*/
import { EditorSelection } from '@codemirror/state';
import { ListType } from '../types';
import createEditor from './testUtil/createEditor';

View File

@@ -1,7 +1,3 @@
/**
* @jest-environment jsdom
*/
import { EditorSelection } from '@codemirror/state';
import {
toggleBolded, toggleCode, toggleHeaderLevel, toggleItalicized, toggleMath, updateLink,

View File

@@ -1,7 +1,3 @@
/**
* @jest-environment jsdom
*/
import { EditorSelection, EditorState } from '@codemirror/state';
import {
increaseIndent, toggleList,

View File

@@ -1,6 +1,3 @@
/**
* @jest-environment jsdom
*/
import { syntaxTree } from '@codemirror/language';
import { SyntaxNode } from '@lezer/common';
import { EditorSelection, EditorState } from '@codemirror/state';

View File

@@ -4,7 +4,7 @@ import { useEffect, useMemo, useState } from 'react';
import { View, Dimensions, Alert, Button } from 'react-native';
import { SensorInfo } from './sensorInfo';
import { _ } from '@joplin/lib/locale';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import biometricAuthenticate from './biometricAuthenticate';
const logger = Logger.create('BiometricPopup');

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import FingerprintScanner, { Errors } from 'react-native-fingerprint-scanner';
import { _ } from '@joplin/lib/locale';

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import Setting from '@joplin/lib/models/Setting';
import FingerprintScanner from 'react-native-fingerprint-scanner';
const logger = Logger.create('sensorInfo');

View File

@@ -1,12 +1,4 @@
/**
* @jest-environment jsdom
*/
import * as React from 'react';
import { setImmediate } from 'timers';
// Required by some libraries (setImmediate is not supported in most browsers,
// so is removed by jsdom).
window.setImmediate = setImmediate;
import { _ } from '@joplin/lib/locale';
import { act, fireEvent, render, waitFor } from '@testing-library/react-native';

View File

@@ -1,7 +1,7 @@
import * as React from 'react';
import { Text, Alert, View } from 'react-native';
import { _ } from '@joplin/lib/locale';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { ProgressBar } from 'react-native-paper';
import { FunctionComponent, useCallback, useState } from 'react';
import shim from '@joplin/lib/shim';

View File

@@ -43,7 +43,7 @@ import SelectDateTimeDialog from '../SelectDateTimeDialog';
import ShareExtension from '../../utils/ShareExtension.js';
import CameraView from '../CameraView';
import { NoteEntity } from '@joplin/lib/services/database/types';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import VoiceTypingDialog from '../voiceTyping/VoiceTypingDialog';
import { voskEnabled } from '../../services/voiceTyping/vosk';
import { isSupportedLanguage } from '../../services/voiceTyping/vosk.android';

View File

@@ -6,7 +6,7 @@ const { reg } = require('@joplin/lib/registry.js');
const { ScreenHeader } = require('../ScreenHeader');
const time = require('@joplin/lib/time').default;
const { themeStyle } = require('../global-style.js');
const Logger = require('@joplin/lib/Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const { BaseScreenComponent } = require('../base-screen.js');
const { _ } = require('@joplin/lib/locale');

View File

@@ -328,7 +328,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=/usr/local/bin/node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
shellScript = "export NODE_BINARY=/usr/local/bin/node\nexport SOURCEMAP_FILE=\"$(pwd)/../main.jsbundle.map\";\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
027E2AA6B101F8CFCA582EC1 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;

View File

@@ -475,9 +475,9 @@ PODS:
- React-Core
- RNFS (2.20.0):
- React-Core
- RNGestureHandler (2.11.0):
- RNGestureHandler (2.12.0):
- React-Core
- RNLocalize (3.0.1):
- RNLocalize (3.0.2):
- React-Core
- RNQuickAction (0.3.13):
- React
@@ -854,8 +854,8 @@ SPEC CHECKSUMS:
RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNGestureHandler: 026038a97d4c8649ce397a22e162ca58b4e6c230
RNLocalize: 6dd9226886fa61bf0cefc7644e3f9620770b1a31
RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5
RNLocalize: dbea38dcb344bf80ff18a1757b1becf11f70cae4
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
RNReanimated: 9976fbaaeb8a188c36026154c844bf374b3b7eeb
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef

View File

@@ -12,6 +12,7 @@ module.exports = {
'\\.(ts|tsx)$': 'ts-jest',
},
testEnvironment: 'jsdom',
testMatch: ['**/*.test.(ts|tsx)'],
testPathIgnorePatterns: ['<rootDir>/node_modules/'],

View File

@@ -8,6 +8,29 @@ const { tmpdir } = require('os');
const uuid = require('@joplin/lib/uuid').default;
const sqlite3 = require('sqlite3');
import { setImmediate } from 'timers';
// Required by some libraries (setImmediate is not supported in most browsers,
// so is removed by jsdom).
window.setImmediate = setImmediate;
// Prevents the CodeMirror error "getClientRects is undefined".
// See https://github.com/jsdom/jsdom/issues/3002#issue-652790925
document.createRange = () => {
const range = new Range();
range.getBoundingClientRect = jest.fn();
range.getClientRects = () => {
return {
length: 0,
item: () => null,
[Symbol.iterator]: jest.fn(),
};
};
return range;
};
shimInit({ nodeSqlite: sqlite3 });

View File

@@ -13,15 +13,17 @@
const path = require('path');
const localPackages = {
'@joplin/fork-htmlparser2': path.resolve(__dirname, '../fork-htmlparser2/'),
'@joplin/fork-sax': path.resolve(__dirname, '../fork-sax/'),
'@joplin/fork-uslug': path.resolve(__dirname, '../fork-uslug/'),
'@joplin/lib': path.resolve(__dirname, '../lib/'),
'@joplin/react-native-alarm-notification': path.resolve(__dirname, '../react-native-alarm-notification/'),
'@joplin/react-native-saf-x': path.resolve(__dirname, '../react-native-saf-x/'),
'@joplin/renderer': path.resolve(__dirname, '../renderer/'),
'@joplin/tools': path.resolve(__dirname, '../tools/'),
'@joplin/fork-htmlparser2': path.resolve(__dirname, '../fork-htmlparser2/'),
'@joplin/fork-uslug': path.resolve(__dirname, '../fork-uslug/'),
'@joplin/react-native-saf-x': path.resolve(__dirname, '../react-native-saf-x/'),
'@joplin/react-native-alarm-notification': path.resolve(__dirname, '../react-native-alarm-notification/'),
'@joplin/fork-sax': path.resolve(__dirname, '../fork-sax/'),
'@joplin/turndown-plugin-gfm': path.resolve(__dirname, '../turndown-plugin-gfm/'),
'@joplin/turndown': path.resolve(__dirname, '../turndown/'),
'@joplin/utils': path.resolve(__dirname, '../utils/'),
};
const remappedPackages = {
@@ -32,7 +34,12 @@ const remappedPackages = {
// versions. For example, this allows us to `import {resolve} from 'path'` rather than
// `const { resolve } = require('path-browserify')` ('path-browerify' doesn't have its own type
// definitions).
const browserifiedPackages = ['path'];
const browserifiedPackages = [
'http',
'https',
'os',
'path',
];
for (const package of browserifiedPackages) {
remappedPackages[package] = path.resolve(__dirname, `./node_modules/${package}-browserify/`);
}
@@ -74,6 +81,30 @@ module.exports = {
},
}
),
// Documentation at https://facebook.github.io/metro/docs/configuration/
resolveRequest: (context, moduleName, platform) => {
// console.info('Module: ' + moduleName + ' / ' + context.originModulePath);
// This can be used to allow importing a module that requires `fs`
// somewhere. For example, the `css` package which is used to parse
// CSS strings has a `loadFile()` function that we don't need, but
// that makes it import the `fs` package.
//
// So by having this here, we can use those packages as long as we
// don't use the specific methods that require `fs`. It's something
// to keep in mind if we get weird-related fs errors - it may be
// because the package is trying to access the mocked `fs` package.
if (moduleName === 'fs') {
return {
filePath: path.resolve(__dirname, 'mock-fs.js'),
type: 'sourceFile',
};
}
// Default resolver
return context.resolveRequest(context, moduleName, platform);
},
},
projectRoot: path.resolve(__dirname),
watchFolders: watchedFolders,

View File

@@ -0,0 +1,13 @@
function traceMethodCalls(obj) {
const handler = {
get(_target, propKey, _receiver) {
if (propKey === '$$typeof') return 'object';
throw new Error(`Trying to access member of mocked fs package: \`fs.${propKey}\``);
},
};
return new Proxy(obj, handler);
}
const mockFs = {};
module.exports = traceMethodCalls(mockFs);

View File

@@ -22,6 +22,7 @@
"@joplin/react-native-alarm-notification": "~2.12",
"@joplin/react-native-saf-x": "~2.12",
"@joplin/renderer": "~2.12",
"@joplin/utils": "~2.12",
"@react-native-community/clipboard": "1.5.1",
"@react-native-community/datetimepicker": "7.1.0",
"@react-native-community/geolocation": "3.0.6",
@@ -34,9 +35,12 @@
"crypto-browserify": "3.12.0",
"deprecated-react-native-prop-types": "4.0.0",
"events": "3.3.0",
"http-browserify": "1.7.0",
"https-browserify": "1.0.0",
"jsc-android": "241213.1.0",
"lodash": "4.17.21",
"md5": "2.3.0",
"os-browserify": "0.3.0",
"path-browserify": "1.0.1",
"prop-types": "15.8.1",
"punycode": "2.3.0",
@@ -55,7 +59,7 @@
"react-native-fs": "2.20.0",
"react-native-gesture-handler": "2.12.0",
"react-native-get-random-values": "1.9.0",
"react-native-image-picker": "5.4.2",
"react-native-image-picker": "5.6.0",
"react-native-image-resizer": "1.4.5",
"react-native-localize": "3.0.2",
"react-native-modal-datetime-picker": "15.0.1",
@@ -64,7 +68,7 @@
"react-native-quick-actions": "0.3.13",
"react-native-reanimated": "3.3.0",
"react-native-rsa-native": "2.0.5",
"react-native-safe-area-context": "4.5.5",
"react-native-safe-area-context": "4.6.0",
"react-native-securerandom": "1.0.1",
"react-native-share": "8.2.2",
"react-native-sqlite-storage": "6.0.1",

View File

@@ -0,0 +1,7 @@
const initPlugin = joplin => {
!function(t){var e={};function o(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,o),r.l=!0,r.exports}o.m=t,o.c=e,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)o.d(n,r,function(e){return t[e]}.bind(null,r));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=0)}([function(t,e,o){"use strict";var n=this&&this.__awaiter||function(t,e,o,n){return new(o||(o=Promise))((function(r,i){function u(t){try{c(n.next(t))}catch(t){i(t)}}function l(t){try{c(n.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof o?e:new o((function(t){t(e)}))).then(u,l)}c((n=n.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0});const r=o(1),i=o(2);r.default.plugins.register({onStart:function(){return n(this,void 0,void 0,(function*(){yield r.default.contentScripts.register(i.ContentScriptType.MarkdownItPlugin,"todoTxtMd","./todoTxtMdRule.js"),yield r.default.contentScripts.register(i.ContentScriptType.CodeMirrorPlugin,"todoTxtMdCtrl","./todoTxtMdCtrl.js"),yield r.default.contentScripts.onMessage("todoTxtMd",t=>{r.default.commands.execute("editor.execCommand",{name:"todoTxtAction",args:[t]}),r.default.commands.execute("editor.focus")})}))}})},function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=joplin},function(t,e,o){"use strict";var n;Object.defineProperty(e,"__esModule",{value:!0}),e.ContentScriptType=e.SettingStorage=e.AppType=e.SettingItemType=e.ToolbarButtonLocation=e.isContextMenuItemLocation=e.MenuItemLocation=e.ImportModuleOutputFormat=e.FileSystemItem=void 0,function(t){t.File="file",t.Directory="directory"}(e.FileSystemItem||(e.FileSystemItem={})),function(t){t.Markdown="md",t.Html="html"}(e.ImportModuleOutputFormat||(e.ImportModuleOutputFormat={})),function(t){t.File="file",t.Edit="edit",t.View="view",t.Note="note",t.Tools="tools",t.Help="help",t.Context="context",t.NoteListContextMenu="noteListContextMenu",t.EditorContextMenu="editorContextMenu",t.FolderContextMenu="folderContextMenu",t.TagContextMenu="tagContextMenu"}(n=e.MenuItemLocation||(e.MenuItemLocation={})),e.isContextMenuItemLocation=function(t){return[n.Context,n.NoteListContextMenu,n.EditorContextMenu,n.FolderContextMenu,n.TagContextMenu].includes(t)},function(t){t.NoteToolbar="noteToolbar",t.EditorToolbar="editorToolbar"}(e.ToolbarButtonLocation||(e.ToolbarButtonLocation={})),function(t){t[t.Int=1]="Int",t[t.String=2]="String",t[t.Bool=3]="Bool",t[t.Array=4]="Array",t[t.Object=5]="Object",t[t.Button=6]="Button"}(e.SettingItemType||(e.SettingItemType={})),function(t){t.Desktop="desktop",t.Mobile="mobile",t.Cli="cli"}(e.AppType||(e.AppType={})),function(t){t[t.Database=1]="Database",t[t.File=2]="File"}(e.SettingStorage||(e.SettingStorage={})),function(t){t.MarkdownItPlugin="markdownItPlugin",t.CodeMirrorPlugin="codeMirrorPlugin"}(e.ContentScriptType||(e.ContentScriptType={}))}]);
}
module.exports = { initPlugin };

View File

@@ -0,0 +1,12 @@
{
"manifest_version": 1,
"id": "com.hieuthi.joplin.metis",
"app_min_version": "2.2",
"version": "0.1.5",
"name": "Metis",
"description": "A Simple Task Manager Plugin for Joplin based on Todo.txt Specification",
"author": "Hieu-Thi Luong",
"homepage_url": "https://github.com/hieuthi/joplin-plugin-metis",
"repository_url": "https://github.com/hieuthi/joplin-plugin-metis",
"keywords": ["joplin-plugin","todo","todotxt","task management"]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,163 @@
ul.todotxt {
--color-default: #999;
--color-faded: #999;
--color-A: rgb(247, 210, 110); /* yellow* */
--color-B: rgb(152, 104, 1); /* red */
--color-C: rgb(80, 161, 79); /* green */
--color-D: rgb(21, 91, 218); /* blue */
--project-background-color: rgb(247, 210, 110);
--project-color: black;
--context-color: rgb(152, 104, 1);
--transition-duration: 0.15s;
}
ul.todotxt { list-style:none; }
ul.todotxt li {
list-style-type:none;
border-bottom: dashed 1px;
margin-bottom: 4px;
line-height: 1.2em;
}
ul.todotxt li.todotxt-header {
font-size: 10px;
}
.todo-priority {
display: inline-block;
width: 1.2em;
overflow: hidden;
color: var(--color-default);
vertical-align: text-bottom;
}
.todo-priority select {
appearance: none;
background-color: transparent;
border-color: transparent;
color: inherit;
font-size: inherit;
font-weight: 700;
cursor: pointer;
}
.todo-priority select:focus-visible {
outline: none;
}
.todo-priority select:hover {
text-decoration: underline;
}
.todo-panel {
display: block;
font-size: 12px;
line-height: 1em;
text-align: right;
margin: 2px 0 4px 0;
color: var(--color-faded);
}
.todo-completion, .todo-creation {
display: inline-block;
min-width: 6em;
}
.todo-project {
background-color: var(--project-background-color);
color: var(--project-color);
border-radius: 2px;
}
.todo-context {
color: var(--context-color);
}
.todo-count {
color: var(--color-faded);
}
.todo-count::before{
content: '/';
}
.todo-meta {
color: var(--color-faded);
}
.todo-select {
display: inline-block;
min-width: 3em;
text-decoration: none;
}
.todo-checkbox {
margin-left: -1.9em;
margin-right: 0.5em;
display: inline-block;
vertical-align: text-top;
position: relative;
cursor: pointer;
user-select: none;
}
.todo-checkbox input {
position: absolute;
display: none;
}
.todo-checkbox .todo-checkmark {
width : 1.2em;
height: 1.2em;
position: relative;
display : inline-block;
overflow: hidden;
text-align: center;
color: white;
border: solid 1px var(--color-default);
border-radius: 100%;
transition: background-color var(--transition-duration) ease-in;
}
.todo-checkbox input:checked ~ .todo-checkmark {
background-color: var(--color-default);
}
.todo-checkbox .todo-checkmark:after {
content: '×';
position: relative;
display: inline-block;
transition: opacity var(--transition-duration);
opacity: 0;
}
.todo-checkbox input:checked ~ .todo-checkmark:after {
opacity: 1.0;
}
/* Color scheme */
.prior-A .todo-priority {
color: var(--color-A);
}
.prior-A .todo-checkbox .todo-checkmark {
border-color: var(--color-A);
color: black;
}
.prior-A .todo-checkbox input:checked ~ .todo-checkmark {
background-color: var(--color-A);
}
.prior-B .todo-priority {
color: var(--color-B);
}
.prior-B .todo-checkbox .todo-checkmark {
border-color: var(--color-B);
}
.prior-B .todo-checkbox input:checked ~ .todo-checkmark {
background-color: var(--color-B);
}
.prior-C .todo-priority {
color: var(--color-C);
}
.prior-C .todo-checkbox .todo-checkmark {
border-color: var(--color-C);
}
.prior-C .todo-checkbox input:checked ~ .todo-checkmark {
background-color: var(--color-C);
}
.prior-D .todo-priority {
color: var(--color-D);
}
.prior-D .todo-checkbox .todo-checkmark {
border-color: var(--color-D);
}
.prior-D .todo-checkbox input:checked ~ .todo-checkmark {
background-color: var(--color-D);
}

View File

@@ -0,0 +1,38 @@
document.addEventListener('joplin-noteDidUpdate', makeTodoViewActionable );
if (/WebKit/i.test(navigator.userAgent)) { // sniff
var _timer_todotxt = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
makeTodoViewActionable()
}
}, 10);
}
function makeTodoViewActionable() {
if (_timer_todotxt) clearInterval(_timer_todotxt);
const todoTxts = document.getElementsByClassName('todotxt');
for (var i=0; i<todoTxts.length; i++){
const todoTxt = todoTxts[i];
const todos = todoTxt.getElementsByClassName('todo');
for (var j=0; j<todos.length; j++){
const todo = todos[j];
const lineIdx = todo.getAttribute("data-lineIdx");
const checkbox = todo.getElementsByClassName('todo-checkbox')[0].getElementsByTagName('input')[0];
const priority = todo.getElementsByClassName('todo-priority')[0].getElementsByTagName('select')[0];
const selectButton = todo.getElementsByClassName('todo-select')[0];
checkbox.onclick = function (){
setTimeout(()=> {webviewApi.postMessage('todoTxtMd', `toggleStatus:${lineIdx}`)}, 170);
}
priority.onchange = function(option) {
var value = option.target.value;
webviewApi.postMessage('todoTxtMd', `changePriority:${lineIdx}:${value}`);
}
selectButton.onclick = function () {
webviewApi.postMessage('todoTxtMd', `selectLine:${lineIdx}`);
}
}
}
}

View File

@@ -0,0 +1,17 @@
const initPlugin = joplin => {
joplin.plugins.register({
onStart: async function() {
await joplin.contentScripts.register(
'markdownItPlugin',
'abc_music_sheet',
'./markdownItPlugin.js'
);
},
});
//!function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";var o=this&&this.__awaiter||function(t,e,n,o){return new(n||(n=Promise))((function(r,i){function u(t){try{c(o.next(t))}catch(t){i(t)}}function l(t){try{c(o.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(u,l)}c((o=o.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0});const r=n(1),i=n(2);r.default.plugins.register({onStart:function(){return o(this,void 0,void 0,(function*(){yield r.default.contentScripts.register(i.ContentScriptType.MarkdownItPlugin,"abc_music_sheet","./markdownItPlugin.js"),setInterval(()=>{console.log("AAAAAAAAAAAAAAA")},1e3)}))}})},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=joplin},function(t,e,n){"use strict";var o;Object.defineProperty(e,"__esModule",{value:!0}),e.ContentScriptType=e.SettingStorage=e.AppType=e.SettingItemType=e.ToolbarButtonLocation=e.isContextMenuItemLocation=e.MenuItemLocation=e.ImportModuleOutputFormat=e.FileSystemItem=void 0,function(t){t.File="file",t.Directory="directory"}(e.FileSystemItem||(e.FileSystemItem={})),function(t){t.Markdown="md",t.Html="html"}(e.ImportModuleOutputFormat||(e.ImportModuleOutputFormat={})),function(t){t.File="file",t.Edit="edit",t.View="view",t.Note="note",t.Tools="tools",t.Help="help",t.Context="context",t.NoteListContextMenu="noteListContextMenu",t.EditorContextMenu="editorContextMenu",t.FolderContextMenu="folderContextMenu",t.TagContextMenu="tagContextMenu"}(o=e.MenuItemLocation||(e.MenuItemLocation={})),e.isContextMenuItemLocation=function(t){return[o.Context,o.NoteListContextMenu,o.EditorContextMenu,o.FolderContextMenu,o.TagContextMenu].includes(t)},function(t){t.NoteToolbar="noteToolbar",t.EditorToolbar="editorToolbar"}(e.ToolbarButtonLocation||(e.ToolbarButtonLocation={})),function(t){t[t.Int=1]="Int",t[t.String=2]="String",t[t.Bool=3]="Bool",t[t.Array=4]="Array",t[t.Object=5]="Object",t[t.Button=6]="Button"}(e.SettingItemType||(e.SettingItemType={})),function(t){t.Desktop="desktop",t.Mobile="mobile",t.Cli="cli"}(e.AppType||(e.AppType={})),function(t){t[t.Database=1]="Database",t[t.File=2]="File"}(e.SettingStorage||(e.SettingStorage={})),function(t){t.MarkdownItPlugin="markdownItPlugin",t.CodeMirrorPlugin="codeMirrorPlugin"}(e.ContentScriptType||(e.ContentScriptType={}))}]);
}
module.exports = { initPlugin };

View File

@@ -0,0 +1,16 @@
{
"manifest_version": 1,
"id": "org.joplinapp.plugins.AbcSheetMusic",
"app_min_version": "2.2",
"version": "1.0.2",
"name": "ABC Sheet Music Plugin",
"description": "Turns ABC text notation into sheet music",
"author": "Laurent Cozic",
"homepage_url": "https://github.com/joplin/plugin-abc-sheet-music",
"repository_url": "https://github.com/joplin/plugin-abc-sheet-music",
"keywords": [
"sheet music",
"abc",
"notation"
]
}

View File

@@ -0,0 +1,14 @@
const initPlugin = joplin => {
joplin.plugins.register({
onStart: async function() {
// eslint-disable-next-line no-console
console.info('RUNNING AS PLUGIN 1: ', await joplin.plugins.id()); // await joplin.plugins.id());
// const folder = await joplin.data.post(['folders'], null, { title: "my plugin folder" });
// await joplin.data.post(['notes'], null, { parent_id: folder.id, title: "testing plugin!" });
},
});
}
module.exports = { initPlugin };

View File

@@ -0,0 +1,12 @@
{
"id": "org.joplinapp.plugins.Simple",
"manifest_version": 1,
"app_min_version": "1.4",
"name": "Joplin Simple Plugin",
"version": "1.0.0",
"description": "To test loading and running a plugin",
"homepage_url": "https://joplinapp.org",
"permissions": [
"model"
]
}

View File

@@ -0,0 +1,14 @@
const initPlugin = joplin => {
joplin.plugins.register({
onStart: async function() {
// eslint-disable-next-line no-console
console.info('RUNNING AS PLUGIN 2: ', await joplin.plugins.id());
// const folder = await joplin.data.post(['folders'], null, { title: "my plugin folder" });
// await joplin.data.post(['notes'], null, { parent_id: folder.id, title: "testing plugin!" });
},
});
}
module.exports = { initPlugin };

View File

@@ -0,0 +1,12 @@
{
"id": "org.joplinapp.plugins.Simple2",
"manifest_version": 1,
"app_min_version": "1.4",
"name": "Joplin Simple Plugin",
"version": "1.0.0",
"description": "To test loading and running a plugin",
"homepage_url": "https://joplinapp.org",
"permissions": [
"model"
]
}

View File

@@ -7,7 +7,7 @@ import PluginAssetsLoader from './PluginAssetsLoader';
import AlarmService from '@joplin/lib/services/AlarmService';
import Alarm from '@joplin/lib/models/Alarm';
import time from '@joplin/lib/time';
import Logger, { TargetType } from '@joplin/lib/Logger';
import Logger, { TargetType } from '@joplin/utils/Logger';
import BaseModel from '@joplin/lib/BaseModel';
import BaseService from '@joplin/lib/services/BaseService';
import ResourceService from '@joplin/lib/services/ResourceService';
@@ -85,6 +85,7 @@ const SyncTargetWebDAV = require('@joplin/lib/SyncTargetWebDAV.js');
const SyncTargetDropbox = require('@joplin/lib/SyncTargetDropbox.js');
const SyncTargetAmazonS3 = require('@joplin/lib/SyncTargetAmazonS3.js');
import BiometricPopup from './components/biometrics/BiometricPopup';
import PluginService from '@joplin/lib/services/plugins/PluginService';
SyncTargetRegistry.addClass(SyncTargetNone);
SyncTargetRegistry.addClass(SyncTargetOneDrive);
@@ -120,6 +121,7 @@ import { ReactNode } from 'react';
import userFetcher, { initializeUserFetcher } from '@joplin/lib/utils/userFetcher';
import { parseShareCache } from '@joplin/lib/services/share/reducer';
import autodetectTheme, { onSystemColorSchemeChange } from './utils/autodetectTheme';
import PluginRunner from './services/plugins/PluginRunner';
type SideMenuPosition = 'left' | 'right';
@@ -438,6 +440,97 @@ const initializeTempDir = async () => {
return tempDir;
};
const simplePlugin1 = require('./plugins/org.joplinapp.plugins.Simple/index.js');
const simplePluginManifest1 = `{
"id": "org.joplinapp.plugins.Simple",
"manifest_version": 1,
"app_min_version": "1.4",
"name": "Joplin Simple Plugin",
"version": "1.0.0",
"description": "To test loading and running a plugin",
"homepage_url": "https://joplinapp.org",
"permissions": [
"model"
]
}`;
const simplePlugin2 = require('./plugins/org.joplinapp.plugins.Simple2/index.js');
const simplePluginManifest2 = `{
"id": "org.joplinapp.plugins.Simple2",
"manifest_version": 1,
"app_min_version": "1.4",
"name": "Joplin Simple Plugin",
"version": "1.0.0",
"description": "To test loading and running a plugin",
"homepage_url": "https://joplinapp.org",
"permissions": [
"model"
]
}`;
// const abcPlugin = require('./plugins/org.joplinapp.plugins.AbcSheetMusic/index.js');
// const abcPluginManifest = `{
// "manifest_version": 1,
// "id": "org.joplinapp.plugins.AbcSheetMusic",
// "app_min_version": "2.2",
// "version": "1.0.2",
// "name": "ABC Sheet Music Plugin",
// "description": "Turns ABC text notation into sheet music",
// "author": "Laurent Cozic",
// "homepage_url": "https://github.com/joplin/plugin-abc-sheet-music",
// "repository_url": "https://github.com/joplin/plugin-abc-sheet-music",
// "keywords": [
// "sheet music",
// "abc",
// "notation"
// ]
// }`;
// const abcPluginContentScript = require('./plugins/org.joplinapp.plugins.AbcSheetMusic/markdownItPlugin.js');
const metisPlugin = require('./plugins/com.hieuthi.joplin.metis/index.js');
const metisManifest = `{
"manifest_version": 1,
"id": "com.hieuthi.joplin.metis",
"app_min_version": "2.2",
"version": "0.1.5",
"name": "Metis",
"description": "A Simple Task Manager Plugin for Joplin based on Todo.txt Specification",
"author": "Hieu-Thi Luong",
"homepage_url": "https://github.com/hieuthi/joplin-plugin-metis",
"repository_url": "https://github.com/hieuthi/joplin-plugin-metis",
"keywords": ["joplin-plugin","todo","todotxt","task management"]
}`;
const metisContentScript = require('./plugins/com.hieuthi.joplin.metis/todoTxtMdRule.js');
const initPluginService = async () => {
const service = PluginService.instance();
const runner = new PluginRunner();
service.initialize(
'2.12.1',
{
joplin: {},
},
runner,
{
dispatch: () => {},
getState: () => {},
}
);
const plugin1 = await PluginService.instance().loadPluginFromModule({ main: simplePlugin1 }, simplePluginManifest1);
await PluginService.instance().runPlugin(plugin1);
const plugin2 = await PluginService.instance().loadPluginFromModule({ main: simplePlugin2 }, simplePluginManifest2);
await PluginService.instance().runPlugin(plugin2);
// const plugin3 = await PluginService.instance().loadPluginFromModule({ main: abcPlugin, contentScripts: { ['markdownItPlugin.js']: abcPluginContentScript } }, abcPluginManifest);
// await PluginService.instance().runPlugin(plugin3);
const plugin4 = await PluginService.instance().loadPluginFromModule({ main: metisPlugin, contentScripts: { ['todoTxtMdView.js']: metisContentScript } }, metisManifest);
await PluginService.instance().runPlugin(plugin4);
};
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
async function initialize(dispatch: Function) {
shimInit();
@@ -705,6 +798,8 @@ async function initialize(dispatch: Function) {
// and it cannot collect anything when the app is not active.
RevisionService.instance().runInBackground(1000 * 30);
await initPluginService();
// ----------------------------------------------------------------------------
// Keep this below to test react-native-rsa-native
// ----------------------------------------------------------------------------

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import { Notification } from '@joplin/lib/models/Alarm';
const ReactNativeAN = require('@joplin/react-native-alarm-notification').default;

View File

@@ -1,5 +1,5 @@
import { Notification } from '@joplin/lib/models/Alarm';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const PushNotificationIOS = require('@react-native-community/push-notification-ios').default;
export default class AlarmServiceDriver {

View File

@@ -0,0 +1,15 @@
import Global from '@joplin/lib/services/plugins/api/Global';
import BasePluginRunner from '@joplin/lib/services/plugins/BasePluginRunner';
import Plugin from '@joplin/lib/services/plugins/Plugin';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('PluginRunner');
export default class PluginRunner extends BasePluginRunner {
public async run(plugin: Plugin, sandbox: Global): Promise<void> {
logger.info(`Run plugin: ${plugin.id}`);
plugin.module.main.initPlugin(sandbox.joplin);
}
}

View File

@@ -1,5 +1,5 @@
import { languageCodeOnly } from '@joplin/lib/locale';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import Setting from '@joplin/lib/models/Setting';
import { rtrimSlashes } from '@joplin/lib/path-utils';
import shim from '@joplin/lib/shim';

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
import Setting from '@joplin/lib/models/Setting';
import { Appearance, ColorSchemeName } from 'react-native';

View File

@@ -1,4 +1,4 @@
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const { Platform, PermissionsAndroid } = require('react-native');
const logger = Logger.create('checkPermissions');

View File

@@ -8,7 +8,7 @@ import { Platform } from 'react-native';
import * as tar from 'tar-stream';
import { resolve } from 'path';
import { Buffer } from 'buffer';
import Logger from '@joplin/lib/Logger';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('fs-driver-rn');
@@ -256,12 +256,8 @@ export default class FsDriverRN extends FsDriverBase {
return output ? output : null;
}
public resolve(path: string) {
throw new Error(`Not implemented: resolve(): ${path}`);
}
public resolveRelativePathWithinDir(_baseDir: string, relativePath: string) {
throw new Error(`Not implemented: resolveRelativePathWithinDir(): ${relativePath}`);
public resolve(...pathSegments: string[]) {
return resolve(...pathSegments);
}
public async md5File(path: string): Promise<string> {

View File

@@ -0,0 +1,21 @@
import { MarkupLanguageUtils as BaseMarkupLanguageUtils } from '@joplin/lib/markupLanguageUtils';
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { contentScriptsToRendererRules } from '@joplin/lib/services/plugins/utils/loadContentScripts';
import { Options } from '@joplin/renderer/MarkupToHtml';
class MarkupLanguageUtils extends BaseMarkupLanguageUtils {
public newMarkupToHtml(plugins: PluginStates = null, options: Options = null) {
plugins = plugins || {};
return super.newMarkupToHtml(null, {
extraRendererRules: contentScriptsToRendererRules(plugins),
...options,
});
}
}
const markupLanguageUtils = new MarkupLanguageUtils();
export default markupLanguageUtils;

View File

@@ -1,5 +1,5 @@
import Setting, { Env } from './models/Setting';
import Logger, { TargetType, LoggerWrapper } from './Logger';
import Logger, { TargetType, LoggerWrapper } from '@joplin/utils/Logger';
import shim from './shim';
const { setupProxySettings } = require('./shim-init-node');
import BaseService from './services/BaseService';

View File

@@ -1,4 +1,4 @@
import Logger from './Logger';
import Logger from '@joplin/utils/Logger';
import Synchronizer from './Synchronizer';
import EncryptionService from './services/e2ee/EncryptionService';
import shim from './shim';

View File

@@ -1,5 +1,5 @@
import Setting from './models/Setting';
import Logger from './Logger';
import Logger from '@joplin/utils/Logger';
import Api, { RequestFile } from './services/rest/Api';
import ApiResponse from './services/rest/ApiResponse';
const urlParser = require('url');

View File

@@ -1,4 +1,4 @@
const Logger = require('./Logger').default;
const Logger = require('@joplin/utils/Logger').default;
const shim = require('./shim').default;
const JoplinError = require('./JoplinError').default;
const time = require('./time').default;

View File

@@ -3,7 +3,7 @@ import { _ } from './locale';
const { rtrimSlashes } = require('./path-utils.js');
import JoplinError from './JoplinError';
import { Env } from './models/Setting';
import Logger from './Logger';
import Logger from '@joplin/utils/Logger';
import personalizedUserContentBaseUrl from './services/joplinServer/personalizedUserContentBaseUrl';
import { getHttpStatusMessage } from './net-utils';
const { stringify } = require('query-string');

View File

@@ -5,7 +5,7 @@ import { _ } from './locale.js';
import JoplinServerApi from './JoplinServerApi';
import BaseSyncTarget from './BaseSyncTarget';
import { FileApi } from './file-api';
import Logger from './Logger';
import Logger from '@joplin/utils/Logger';
const staticLogger = Logger.create('SyncTargetJoplinServer');

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