diff --git a/.eslintignore b/.eslintignore
index 812906926..df44b7f2d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -294,6 +294,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/markupRenderOptions.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
diff --git a/.gitignore b/.gitignore
index bb5e41ae4..eeb871ef5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -274,6 +274,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/markupRenderOptions.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
diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.tsx
index 717f300de..5136f4141 100644
--- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.tsx
+++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import { useState, useEffect, useRef, forwardRef, useCallback, useImperativeHandle, useMemo, ForwardedRef } from 'react';
// eslint-disable-next-line no-unused-vars
-import { EditorCommand, NoteBodyEditorProps, NoteBodyEditorRef } from '../../../utils/types';
+import { EditorCommand, MarkupToHtmlOptions, NoteBodyEditorProps, NoteBodyEditorRef } from '../../../utils/types';
import { commandAttachFileToBody, getResourcesFromPasteEvent } from '../../../utils/resourceHandling';
import { ScrollOptions, ScrollOptionTypes } from '../../../utils/types';
import { CommandValue } from '../../../utils/types';
@@ -29,7 +29,6 @@ const debounce = require('debounce');
import { reg } from '@joplin/lib/registry';
import ErrorBoundary from '../../../../ErrorBoundary';
-import { MarkupToHtmlOptions } from '../../../utils/useMarkupToHtml';
import useStyles from '../utils/useStyles';
import useContextMenu from '../utils/useContextMenu';
import useWebviewIpcMessage from '../utils/useWebviewIpcMessage';
diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx
index 2c2dd24b3..e678c0657 100644
--- a/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx
+++ b/packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import { useState, useEffect, useRef, forwardRef, useCallback, useImperativeHandle, useMemo, ForwardedRef } from 'react';
-import { EditorCommand, NoteBodyEditorProps, NoteBodyEditorRef, OnChangeEvent } from '../../../utils/types';
+import { EditorCommand, MarkupToHtmlOptions, NoteBodyEditorProps, NoteBodyEditorRef, OnChangeEvent } from '../../../utils/types';
import { getResourcesFromPasteEvent } from '../../../utils/resourceHandling';
import { ScrollOptions, ScrollOptionTypes } from '../../../utils/types';
import NoteTextViewer from '../../../../NoteTextViewer';
@@ -16,7 +16,6 @@ import { MarkupToHtml } from '@joplin/renderer';
const { clipboard } = require('electron');
import { reg } from '@joplin/lib/registry';
import ErrorBoundary from '../../../../ErrorBoundary';
-import { MarkupToHtmlOptions } from '../../../utils/useMarkupToHtml';
import { EditorKeymap, EditorLanguageType, EditorSettings } from '@joplin/editor/types';
import useStyles from '../utils/useStyles';
import { EditorEvent, EditorEventType } from '@joplin/editor/events';
diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx
index 1f178ad6d..61b900bd7 100644
--- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx
+++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle } from 'react';
-import { ScrollOptions, ScrollOptionTypes, EditorCommand, NoteBodyEditorProps, ResourceInfos } from '../../utils/types';
+import { ScrollOptions, ScrollOptionTypes, EditorCommand, NoteBodyEditorProps, ResourceInfos, HtmlToMarkdownHandler } from '../../utils/types';
import { resourcesStatus, commandAttachFileToBody, getResourcesFromPasteEvent, processPastedHtml, attachedResources } from '../../utils/resourceHandling';
import useScroll from './utils/useScroll';
import styles_ from './styles';
@@ -20,7 +20,6 @@ import BaseItem from '@joplin/lib/models/BaseItem';
import setupToolbarButtons from './utils/setupToolbarButtons';
import { plainTextToHtml } from '@joplin/lib/htmlUtils';
import openEditDialog from './utils/openEditDialog';
-import { MarkupToHtmlOptions } from '../../utils/useMarkupToHtml';
import { themeStyle } from '@joplin/lib/theme';
import { loadScript } from '../../../utils/loadScript';
import bridge from '../../../../services/bridge';
@@ -30,25 +29,11 @@ import { joplinCommandToTinyMceCommands, TinyMceCommand } from './utils/joplinCo
import shouldPasteResources from './utils/shouldPasteResources';
import lightTheme from '@joplin/lib/themes/light';
import { Options as NoteStyleOptions } from '@joplin/renderer/noteStyle';
+import markupRenderOptions from '../../utils/markupRenderOptions';
const md5 = require('md5');
const { clipboard } = require('electron');
const supportedLocales = require('./supportedLocales');
-function markupRenderOptions(override: MarkupToHtmlOptions = null): MarkupToHtmlOptions {
- return {
- plugins: {
- checkbox: {
- checkboxRenderingType: 2,
- },
- link_open: {
- linkRenderingType: 2,
- },
- },
- replaceResourceInternalToExternalLinks: true,
- ...override,
- };
-}
-
// In TinyMCE 5.2, when setting the body to '
',
// it would end up as '
' once rendered
// (an additional
was inserted).
@@ -123,7 +108,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
const { scrollToPercent } = useScroll({ editor, onScroll: props.onScroll });
usePluginServiceRegistration(ref);
- useContextMenu(editor, props.plugins, props.dispatch);
+ useContextMenu(editor, props.plugins, props.dispatch, props.htmlToMarkdown, props.markupToHtml);
const dispatchDidUpdate = (editor: any) => {
if (dispatchDidUpdateIID_) shim.clearTimeout(dispatchDidUpdateIID_);
@@ -978,7 +963,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
props_onChangeRef.current = props.onChange;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
- const prop_htmlToMarkdownRef = useRef();
+ const prop_htmlToMarkdownRef = useRef();
prop_htmlToMarkdownRef.current = props.htmlToMarkdown;
const nextOnChangeEventInfo = useRef(null);
@@ -1136,7 +1121,11 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
editor.insertContent(result.html);
} else { // Paste regular text
if (pastedHtml) { // Handles HTML
- const modifiedHtml = await processPastedHtml(pastedHtml);
+ const modifiedHtml = await processPastedHtml(
+ pastedHtml,
+ prop_htmlToMarkdownRef.current,
+ markupToHtml.current,
+ );
editor.insertContent(modifiedHtml);
} else { // Handles plain text
pasteAsPlainText(pastedText);
diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts
index 85559ebd4..527ed15b9 100644
--- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts
+++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts
@@ -12,6 +12,7 @@ import Setting from '@joplin/lib/models/Setting';
import Resource from '@joplin/lib/models/Resource';
import { TinyMceEditorEvents } from './types';
+import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from '../../../utils/types';
const menuUtils = new MenuUtils(CommandService.instance());
@@ -42,11 +43,11 @@ interface ContextMenuActionOptions {
const contextMenuActionOptions: ContextMenuActionOptions = { current: null };
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
-export default function(editor: any, plugins: PluginStates, dispatch: Function) {
+export default function(editor: any, plugins: PluginStates, dispatch: Function, htmlToMd: HtmlToMarkdownHandler, mdToHtml: MarkupToHtmlHandler) {
useEffect(() => {
if (!editor) return () => {};
- const contextMenuItems = menuItems(dispatch);
+ const contextMenuItems = menuItems(dispatch, htmlToMd, mdToHtml);
function onContextMenu(_event: any, params: any) {
const element = contextMenuElement(editor, params.x, params.y);
@@ -82,6 +83,8 @@ export default function(editor: any, plugins: PluginStates, dispatch: Function)
fireEditorEvent: (event: TinyMceEditorEvents) => {
editor.fire(event);
},
+ htmlToMd,
+ mdToHtml,
};
let template = [];
@@ -118,5 +121,5 @@ export default function(editor: any, plugins: PluginStates, dispatch: Function)
bridge().window().webContents.off('context-menu', onContextMenu);
}
};
- }, [editor, plugins, dispatch]);
+ }, [editor, plugins, dispatch, htmlToMd, mdToHtml]);
}
diff --git a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx
index 2a9795b99..de9185b38 100644
--- a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx
+++ b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx
@@ -341,7 +341,7 @@ function NoteEditor(props: NoteEditorProps) {
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [formNote, handleProvisionalFlag]);
- const onMessage = useMessageHandler(scrollWhenReady, setScrollWhenReady, editorRef, setLocalSearchResultCount, props.dispatch, formNote);
+ const onMessage = useMessageHandler(scrollWhenReady, setScrollWhenReady, editorRef, setLocalSearchResultCount, props.dispatch, formNote, htmlToMarkdown, markupToHtml);
const externalEditWatcher_noteChange = useCallback((event: any) => {
if (event.id === formNote.id) {
diff --git a/packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts b/packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts
index 0ef3a6b63..d9cf11afd 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts
@@ -14,6 +14,7 @@ import { TinyMceEditorEvents } from '../NoteBody/TinyMCE/utils/types';
import { itemIsReadOnlySync, ItemSlice } from '@joplin/lib/models/utils/readOnly';
import Setting from '@joplin/lib/models/Setting';
import ItemChange from '@joplin/lib/models/ItemChange';
+import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
const fs = require('fs-extra');
const { writeFile } = require('fs-extra');
const { clipboard } = require('electron');
@@ -77,7 +78,7 @@ export async function openItemById(itemId: string, dispatch: Function, hash = ''
}
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
-export function menuItems(dispatch: Function): ContextMenuItems {
+export function menuItems(dispatch: Function, htmlToMd: HtmlToMarkdownHandler, mdToHtml: MarkupToHtmlHandler): ContextMenuItems {
return {
open: {
label: _('Open...'),
@@ -179,7 +180,7 @@ export function menuItems(dispatch: Function): ContextMenuItems {
let content = pastedHtml ? pastedHtml : clipboard.readText();
if (pastedHtml) {
- content = await processPastedHtml(pastedHtml);
+ content = await processPastedHtml(pastedHtml, htmlToMd, mdToHtml);
}
options.insertContent(content);
@@ -207,7 +208,7 @@ export function menuItems(dispatch: Function): ContextMenuItems {
export default async function contextMenu(options: ContextMenuOptions, dispatch: Function) {
const menu = new Menu();
- const items = menuItems(dispatch);
+ const items = menuItems(dispatch, options.htmlToMd, options.mdToHtml);
if (!('readyOnly' in options)) options.isReadOnly = true;
for (const itemKey in items) {
diff --git a/packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.ts b/packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.ts
index 613d5a9cd..94f3c0b38 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.ts
@@ -1,6 +1,9 @@
import Resource from '@joplin/lib/models/Resource';
import Logger from '@joplin/utils/Logger';
+import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
+
const logger = Logger.create('contextMenuUtils');
+
export enum ContextMenuItemType {
None = '',
Image = 'image',
@@ -22,6 +25,8 @@ export interface ContextMenuOptions {
isReadOnly?: boolean;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
fireEditorEvent: Function;
+ htmlToMd: HtmlToMarkdownHandler;
+ mdToHtml: MarkupToHtmlHandler;
}
export interface ContextMenuItem {
diff --git a/packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.ts b/packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.ts
new file mode 100644
index 000000000..f3e39db64
--- /dev/null
+++ b/packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.ts
@@ -0,0 +1,16 @@
+import { MarkupToHtmlOptions } from './types';
+
+export default (override: MarkupToHtmlOptions = null): MarkupToHtmlOptions => {
+ return {
+ plugins: {
+ checkbox: {
+ checkboxRenderingType: 2,
+ },
+ link_open: {
+ linkRenderingType: 2,
+ },
+ },
+ replaceResourceInternalToExternalLinks: true,
+ ...override,
+ };
+};
diff --git a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts
index 7df618d26..b758c3a3a 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.ts
@@ -1,5 +1,8 @@
import Setting from '@joplin/lib/models/Setting';
import { processPastedHtml } from './resourceHandling';
+import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
+import HtmlToMd from '@joplin/lib/HtmlToMd';
+import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
describe('resourceHandling', () => {
it('should sanitize pasted HTML', async () => {
@@ -19,7 +22,32 @@ describe('resourceHandling', () => {
];
for (const [html, expected] of testCases) {
- expect(await processPastedHtml(html)).toBe(expected);
+ expect(await processPastedHtml(html, null, null)).toBe(expected);
}
});
+
+ it('should clean up pasted HTML', async () => {
+ const markupToHtml: MarkupToHtmlHandler = async (markupLanguage, markup, options) => {
+ const conv = markupLanguageUtils.newMarkupToHtml({}, {
+ resourceBaseUrl: `file://${Setting.value('resourceDir')}/`,
+ customCss: '',
+ });
+ return conv.render(markupLanguage, markup, {}, options);
+ };
+
+ const htmlToMd: HtmlToMarkdownHandler = async (_markupLanguage, html, _originalCss) => {
+ const conv = new HtmlToMd();
+ return conv.parse(html);
+ };
+
+ const testCases = [
+ ['Hello
World
', 'Hello
\nWorld
\n'],
+ ['', ''],
+ ];
+
+ for (const [html, expected] of testCases) {
+ expect(await processPastedHtml(html, htmlToMd, markupToHtml)).toBe(expected);
+ }
+ });
+
});
diff --git a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts
index efdefced0..836bddf13 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/resourceHandling.ts
@@ -10,6 +10,8 @@ import rendererHtmlUtils, { extractHtmlBody } from '@joplin/renderer/htmlUtils';
import Logger from '@joplin/utils/Logger';
import { fileUriToPath } from '@joplin/utils/url';
import { MarkupLanguage } from '@joplin/renderer';
+import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
+import markupRenderOptions from './markupRenderOptions';
const joplinRendererUtils = require('@joplin/renderer').utils;
const { clipboard } = require('electron');
const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
@@ -135,7 +137,7 @@ export async function getResourcesFromPasteEvent(event: any) {
return output;
}
-export async function processPastedHtml(html: string) {
+export async function processPastedHtml(html: string, htmlToMd: HtmlToMarkdownHandler | null, mdToHtml: MarkupToHtmlHandler | null) {
const allImageUrls: string[] = [];
const mappedResources: Record = {};
@@ -179,6 +181,15 @@ export async function processPastedHtml(html: string) {
}
}
+ // TinyMCE can accept any type of HTML, including HTML that may not be preserved once saved as
+ // Markdown. For example the content may have a dark background which would be supported by
+ // TinyMCE, but lost once the note is saved. So here we convert the HTML to Markdown then back
+ // to HTML to ensure that the content we paste will be handled correctly by the app.
+ if (htmlToMd && mdToHtml) {
+ const md = await htmlToMd(MarkupLanguage.Markdown, html, '');
+ html = (await mdToHtml(MarkupLanguage.Markdown, md, markupRenderOptions({ bodyOnly: true }))).html;
+ }
+
return extractHtmlBody(rendererHtmlUtils.sanitizeHtml(
htmlUtils.replaceImageUrls(html, (src: string) => {
return mappedResources[src];
diff --git a/packages/app-desktop/gui/NoteEditor/utils/types.ts b/packages/app-desktop/gui/NoteEditor/utils/types.ts
index 5a4029610..3ac9422a8 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/types.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/types.ts
@@ -3,7 +3,6 @@ import { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUt
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { MarkupLanguage } from '@joplin/renderer';
import { RenderResult, RenderResultPluginAsset } from '@joplin/renderer/types';
-import { MarkupToHtmlOptions } from './useMarkupToHtml';
import { Dispatch } from 'redux';
import { ProcessResultsRow } from '@joplin/lib/services/search/SearchEngine';
@@ -61,6 +60,24 @@ export interface NoteBodyEditorRef {
execCommand(command: CommandValue): Promise;
}
+export interface MarkupToHtmlOptions {
+ replaceResourceInternalToExternalLinks?: boolean;
+ resourceInfos?: ResourceInfos;
+ contentMaxWidth?: number;
+ plugins?: Record;
+ bodyOnly?: boolean;
+ mapsToLine?: boolean;
+ useCustomPdfViewer?: boolean;
+ noteId?: string;
+ vendorDir?: string;
+ platformName?: string;
+ allowedFilePrefixes?: string[];
+ whiteBackgroundNoteRendering?: boolean;
+}
+
+export type MarkupToHtmlHandler = (markupLanguage: MarkupLanguage, markup: string, options: MarkupToHtmlOptions)=> Promise;
+export type HtmlToMarkdownHandler = (markupLanguage: number, html: string, originalCss: string)=> Promise;
+
export interface NoteBodyEditorProps {
style: any;
ref: any;
@@ -81,9 +98,8 @@ export interface NoteBodyEditorProps {
onWillChange(event: any): void;
onMessage(event: any): void;
onScroll(event: { percent: number }): void;
- markupToHtml: (markupLanguage: MarkupLanguage, markup: string, options: MarkupToHtmlOptions)=> Promise;
- // eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
- htmlToMarkdown: Function;
+ markupToHtml: MarkupToHtmlHandler;
+ htmlToMarkdown: HtmlToMarkdownHandler;
allAssets: (markupLanguage: MarkupLanguage, options: AllAssetsOptions)=> Promise;
disabled: boolean;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
diff --git a/packages/app-desktop/gui/NoteEditor/utils/useMarkupToHtml.ts b/packages/app-desktop/gui/NoteEditor/utils/useMarkupToHtml.ts
index 8c1ee70ad..e591c1b53 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/useMarkupToHtml.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/useMarkupToHtml.ts
@@ -1,12 +1,12 @@
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { useCallback, useMemo } from 'react';
-import { ResourceInfos } from './types';
import markupLanguageUtils from '../../../utils/markupLanguageUtils';
import Setting from '@joplin/lib/models/Setting';
import shim from '@joplin/lib/shim';
const { themeStyle } = require('@joplin/lib/theme');
import Note from '@joplin/lib/models/Note';
+import { MarkupToHtmlOptions } from './types';
interface HookDependencies {
themeId: number;
@@ -16,21 +16,6 @@ interface HookDependencies {
whiteBackgroundNoteRendering: boolean;
}
-export interface MarkupToHtmlOptions {
- replaceResourceInternalToExternalLinks?: boolean;
- resourceInfos?: ResourceInfos;
- contentMaxWidth?: number;
- plugins?: Record;
- bodyOnly?: boolean;
- mapsToLine?: boolean;
- useCustomPdfViewer?: boolean;
- noteId?: string;
- vendorDir?: string;
- platformName?: string;
- allowedFilePrefixes?: string[];
- whiteBackgroundNoteRendering?: boolean;
-}
-
export default function useMarkupToHtml(deps: HookDependencies) {
const { themeId, customCss, plugins, whiteBackgroundNoteRendering } = deps;
diff --git a/packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.ts b/packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.ts
index 57c9a8c71..341619ab4 100644
--- a/packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.ts
+++ b/packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.ts
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
-import { FormNote } from './types';
+import { FormNote, HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
import contextMenu from './contextMenu';
import CommandService from '@joplin/lib/services/CommandService';
import PostMessageService from '@joplin/lib/services/PostMessageService';
@@ -8,7 +8,7 @@ import { reg } from '@joplin/lib/registry';
const bridge = require('@electron/remote').require('./bridge').default;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
-export default function useMessageHandler(scrollWhenReady: any, setScrollWhenReady: Function, editorRef: any, setLocalSearchResultCount: Function, dispatch: Function, formNote: FormNote) {
+export default function useMessageHandler(scrollWhenReady: any, setScrollWhenReady: Function, editorRef: any, setLocalSearchResultCount: Function, dispatch: Function, formNote: FormNote, htmlToMd: HtmlToMarkdownHandler, mdToHtml: MarkupToHtmlHandler) {
return useCallback(async (event: any) => {
const msg = event.channel ? event.channel : '';
const args = event.args;
@@ -44,6 +44,8 @@ export default function useMessageHandler(scrollWhenReady: any, setScrollWhenRea
htmlToCopy: '',
insertContent: () => { console.warn('insertContent() not implemented'); },
fireEditorEvent: () => { console.warn('fireEditorEvent() not implemented'); },
+ htmlToMd,
+ mdToHtml,
}, dispatch);
menu.popup({ window: bridge().window() });
diff --git a/packages/app-desktop/gui/PdfViewer.tsx b/packages/app-desktop/gui/PdfViewer.tsx
index b8acd71b0..792eae65c 100644
--- a/packages/app-desktop/gui/PdfViewer.tsx
+++ b/packages/app-desktop/gui/PdfViewer.tsx
@@ -61,6 +61,8 @@ export default function PdfViewer(props: Props) {
htmlToCopy: '',
insertContent: () => { console.warn('insertContent() not implemented'); },
fireEditorEvent: () => { console.warn('fireEditorEvent() not implemented'); },
+ htmlToMd: async (_a, b, _c) => b,
+ mdToHtml: async (_a, b, _c) => { return { html: b, pluginAssets: [], cssStrings: [] }; },
} as ContextMenuOptions, props.dispatch);
menu.popup({ window: bridge().window() });