1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-23 22:36:32 +02:00

Mobile: Rich Text Editor: Enable syntax highlighting and auto-indent in the code block editor (#12909)

This commit is contained in:
Henry Heino
2025-08-19 23:29:30 -07:00
committed by GitHub
parent 8a811b9e78
commit af5c0135dc
20 changed files with 294 additions and 88 deletions

View File

@@ -7,6 +7,8 @@ import '@joplin/editor/ProseMirror/styles';
import readFileToBase64 from '../../utils/readFileToBase64';
import { EditorLanguageType } from '@joplin/editor/types';
import convertHtmlToMarkdown from './convertHtmlToMarkdown';
import { ExportedWebViewGlobals as MarkdownEditorWebViewGlobals } from '../../markdownEditorBundle/types';
import { EditorEventType } from '@joplin/editor/events';
const postprocessHtml = (html: HTMLElement) => {
// Fix resource URLs
@@ -35,13 +37,16 @@ const htmlToMarkdown = (html: HTMLElement): string => {
return convertHtmlToMarkdown(html);
};
export const initialize = async ({
settings,
initialText,
initialNoteId,
parentElementClassName,
initialSearch,
}: EditorProps) => {
export const initialize = async (
{
settings,
initialText,
initialNoteId,
parentElementClassName,
initialSearch,
}: EditorProps,
markdownEditorApi: MarkdownEditorWebViewGlobals,
) => {
const messenger = new WebViewToRNMessenger<EditorProcessApi, MainProcessApi>('rich-text-editor', null);
const parentElement = document.getElementsByClassName(parentElementClassName)[0];
if (!parentElement) throw new Error('Parent element not found');
@@ -109,6 +114,18 @@ export const initialize = async ({
return postprocessHtml(html).outerHTML;
}
},
}, (parent, language, onChange) => {
return markdownEditorApi.createEditorWithParent({
initialText: '',
initialNoteId: '',
parentElementOrClassName: parent,
settings: { ...editor.getSettings(), language },
onEvent: (event) => {
if (event.kind === EditorEventType.Change) {
onChange(event.value);
}
},
});
});
editor.setSearchState(initialSearch);

View File

@@ -4,6 +4,7 @@ import { SetUpResult } from '../types';
import { EditorControl, EditorSettings } from '@joplin/editor/types';
import RNToWebViewMessenger from '../../utils/ipc/RNToWebViewMessenger';
import { EditorProcessApi, EditorProps, MainProcessApi } from './types';
import useMarkdownEditorSetup from '../markdownEditorBundle/useWebViewSetup';
import useRendererSetup from '../rendererBundle/useWebViewSetup';
import { EditorEvent } from '@joplin/editor/events';
import Logger from '@joplin/utils/Logger';
@@ -92,7 +93,10 @@ const useMessenger = (props: UseMessengerProps) => {
}, [props.webviewRef]);
};
type UseSourceProps = Props & { renderer: SetUpResult<RendererControl> };
type UseSourceProps = Props & {
renderer: SetUpResult<RendererControl>;
markdownEditor: SetUpResult<unknown>;
};
const useSource = (props: UseSourceProps) => {
const propsRef = useRef(props);
@@ -100,6 +104,8 @@ const useSource = (props: UseSourceProps) => {
const rendererJs = props.renderer.pageSetup.js;
const rendererCss = props.renderer.pageSetup.css;
const markdownEditorJs = props.markdownEditor.pageSetup.js;
const markdownEditorCss = props.markdownEditor.pageSetup.css;
return useMemo(() => {
const editorOptions: EditorProps = {
@@ -117,6 +123,7 @@ const useSource = (props: UseSourceProps) => {
css: `
${shim.injectedCss('richTextEditorBundle')}
${rendererCss}
${markdownEditorCss}
/* Increase the size of the editor to make it easier to focus the editor. */
.prosemirror-editor {
@@ -125,19 +132,23 @@ const useSource = (props: UseSourceProps) => {
`,
js: `
${rendererJs}
${markdownEditorJs}
if (!window.richTextEditorCreated) {
window.richTextEditorCreated = true;
${shim.injectedJs('richTextEditorBundle')}
richTextEditorBundle.setUpLogger();
richTextEditorBundle.initialize(${JSON.stringify(editorOptions)}).then(function(editor) {
richTextEditorBundle.initialize(
${JSON.stringify(editorOptions)},
window,
).then(function(editor) {
/* For testing */
window.joplinRichTextEditor_ = editor;
});
}
`,
};
}, [rendererJs, rendererCss]);
}, [rendererJs, rendererCss, markdownEditorCss, markdownEditorJs]);
};
const useWebViewSetup = (props: Props): SetUpResult<EditorControl> => {
@@ -148,8 +159,23 @@ const useWebViewSetup = (props: Props): SetUpResult<EditorControl> => {
pluginStates: props.pluginStates,
themeId: props.themeId,
});
const markdownEditor = useMarkdownEditorSetup({
webviewRef: props.webviewRef,
onAttachFile: props.onAttachFile,
initialSelection: null,
noteHash: '',
globalSearch: props.globalSearch,
editorOptions: {
settings: props.settings,
initialNoteId: null,
parentElementOrClassName: '',
initialText: '',
},
onEditorEvent: (_event)=>{},
pluginStates: props.pluginStates,
});
const messenger = useMessenger({ ...props, renderer });
const pageSetup = useSource({ ...props, renderer });
const pageSetup = useSource({ ...props, renderer, markdownEditor });
useEffect(() => {
void messenger.remoteApi.editor.updateSettings(props.settings);
@@ -163,14 +189,16 @@ const useWebViewSetup = (props: Props): SetUpResult<EditorControl> => {
onLoadEnd: () => {
messenger.onWebViewLoaded();
renderer.webViewEventHandlers.onLoadEnd();
markdownEditor.webViewEventHandlers.onLoadEnd();
},
onMessage: (event) => {
messenger.onWebViewMessage(event);
renderer.webViewEventHandlers.onMessage(event);
markdownEditor.webViewEventHandlers.onMessage(event);
},
},
};
}, [messenger, pageSetup, renderer.webViewEventHandlers]);
}, [messenger, pageSetup, renderer.webViewEventHandlers, markdownEditor.webViewEventHandlers]);
};
export default useWebViewSetup;