mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
parent
c2bfc526e7
commit
03bd77c107
@ -242,6 +242,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/Editor.js
|
|||||||
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
|
||||||
|
packages/app-desktop/gui/NoteEditor/NoteBody/PlainEditor/PlainEditor.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands.js
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -224,6 +224,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v5/Editor.js
|
|||||||
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
|
||||||
|
packages/app-desktop/gui/NoteEditor/NoteBody/PlainEditor/PlainEditor.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/styles/index.js
|
||||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands.js
|
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands.js
|
||||||
|
@ -740,7 +740,9 @@ class MainScreenComponent extends React.Component<Props, State> {
|
|||||||
editor: () => {
|
editor: () => {
|
||||||
let bodyEditor = this.props.settingEditorCodeView ? 'CodeMirror' : 'TinyMCE';
|
let bodyEditor = this.props.settingEditorCodeView ? 'CodeMirror' : 'TinyMCE';
|
||||||
|
|
||||||
if (this.props.settingEditorCodeView && this.props.enableBetaMarkdownEditor) {
|
if (this.props.isSafeMode) {
|
||||||
|
bodyEditor = 'PlainText';
|
||||||
|
} else if (this.props.settingEditorCodeView && this.props.enableBetaMarkdownEditor) {
|
||||||
bodyEditor = 'CodeMirror6';
|
bodyEditor = 'CodeMirror6';
|
||||||
}
|
}
|
||||||
return <NoteEditor key={key} bodyEditor={bodyEditor} />;
|
return <NoteEditor key={key} bodyEditor={bodyEditor} />;
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
// Used in safe mode
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import { ForwardedRef } from 'react';
|
||||||
|
import { useEffect, useCallback, useRef, forwardRef, useImperativeHandle } from 'react';
|
||||||
|
import { NoteBodyEditorProps, NoteBodyEditorRef } from '../../utils/types';
|
||||||
|
|
||||||
|
const PlainEditor = (props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditorRef>) => {
|
||||||
|
const editorRef = useRef<HTMLTextAreaElement>();
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => {
|
||||||
|
return {
|
||||||
|
content: () => editorRef.current?.value ?? '',
|
||||||
|
resetScroll: () => {
|
||||||
|
editorRef.current.scrollTop = 0;
|
||||||
|
},
|
||||||
|
scrollTo: () => {
|
||||||
|
// Not supported
|
||||||
|
},
|
||||||
|
|
||||||
|
supportsCommand: _name => {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
execCommand: async _command => {
|
||||||
|
// Not supported
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!editorRef.current) return;
|
||||||
|
|
||||||
|
if (editorRef.current.value !== props.content) {
|
||||||
|
editorRef.current.value = props.content;
|
||||||
|
}
|
||||||
|
}, [props.content]);
|
||||||
|
|
||||||
|
const onChange = useCallback((event: any) => {
|
||||||
|
props.onChange({ changeId: null, content: event.target.value });
|
||||||
|
}, [props.onChange]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={props.style}>
|
||||||
|
<textarea
|
||||||
|
ref={editorRef}
|
||||||
|
style={{ width: '100%', height: '100%' }}
|
||||||
|
defaultValue={props.content}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default forwardRef(PlainEditor);
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
// Kept only for reference
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import { useEffect, useCallback, useRef, forwardRef, useImperativeHandle } from 'react';
|
|
||||||
|
|
||||||
export interface OnChangeEvent {
|
|
||||||
changeId: number,
|
|
||||||
content: any,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PlainEditorProps {
|
|
||||||
style: any,
|
|
||||||
onChange(event: OnChangeEvent): void,
|
|
||||||
onWillChange(event:any): void,
|
|
||||||
markupToHtml: Function,
|
|
||||||
disabled: boolean,
|
|
||||||
}
|
|
||||||
|
|
||||||
const PlainEditor = (props:PlainEditorProps, ref:any) => {
|
|
||||||
const editorRef = useRef<any>();
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => {
|
|
||||||
return {
|
|
||||||
content: () => '',
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!editorRef.current) return;
|
|
||||||
editorRef.current.value = props.defaultEditorState.value;
|
|
||||||
}, [props.defaultEditorState]);
|
|
||||||
|
|
||||||
const onChange = useCallback((event:any) => {
|
|
||||||
props.onChange({ changeId: null, content: event.target.value });
|
|
||||||
}, [props.onWillChange, props.onChange]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={props.style}>
|
|
||||||
<textarea
|
|
||||||
ref={editorRef}
|
|
||||||
style={{ width: '100%', height: '100%' }}
|
|
||||||
defaultValue={props.defaultEditorState.value}
|
|
||||||
onChange={onChange}
|
|
||||||
/>;
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default forwardRef(PlainEditor);
|
|
||||||
|
|
@ -14,7 +14,7 @@ import useFormNote, { OnLoadEvent } from './utils/useFormNote';
|
|||||||
import useEffectiveNoteId from './utils/useEffectiveNoteId';
|
import useEffectiveNoteId from './utils/useEffectiveNoteId';
|
||||||
import useFolder from './utils/useFolder';
|
import useFolder from './utils/useFolder';
|
||||||
import styles_ from './styles';
|
import styles_ from './styles';
|
||||||
import { NoteEditorProps, FormNote, ScrollOptions, ScrollOptionTypes, OnChangeEvent, NoteBodyEditorProps, AllAssetsOptions } from './utils/types';
|
import { NoteEditorProps, FormNote, ScrollOptions, ScrollOptionTypes, OnChangeEvent, NoteBodyEditorProps, AllAssetsOptions, NoteBodyEditorRef } from './utils/types';
|
||||||
import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index';
|
import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index';
|
||||||
import CommandService from '@joplin/lib/services/CommandService';
|
import CommandService from '@joplin/lib/services/CommandService';
|
||||||
import ToolbarButton from '../ToolbarButton/ToolbarButton';
|
import ToolbarButton from '../ToolbarButton/ToolbarButton';
|
||||||
@ -45,6 +45,7 @@ import { ModelType } from '@joplin/lib/BaseModel';
|
|||||||
import BaseItem from '@joplin/lib/models/BaseItem';
|
import BaseItem from '@joplin/lib/models/BaseItem';
|
||||||
import { ErrorCode } from '@joplin/lib/errors';
|
import { ErrorCode } from '@joplin/lib/errors';
|
||||||
import ItemChange from '@joplin/lib/models/ItemChange';
|
import ItemChange from '@joplin/lib/models/ItemChange';
|
||||||
|
import PlainEditor from './NoteBody/PlainEditor/PlainEditor';
|
||||||
import CodeMirror6 from './NoteBody/CodeMirror/v6/CodeMirror';
|
import CodeMirror6 from './NoteBody/CodeMirror/v6/CodeMirror';
|
||||||
import CodeMirror5 from './NoteBody/CodeMirror/v5/CodeMirror';
|
import CodeMirror5 from './NoteBody/CodeMirror/v5/CodeMirror';
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ function NoteEditor(props: NoteEditorProps) {
|
|||||||
const [scrollWhenReady, setScrollWhenReady] = useState<ScrollOptions>(null);
|
const [scrollWhenReady, setScrollWhenReady] = useState<ScrollOptions>(null);
|
||||||
const [isReadOnly, setIsReadOnly] = useState<boolean>(false);
|
const [isReadOnly, setIsReadOnly] = useState<boolean>(false);
|
||||||
|
|
||||||
const editorRef = useRef<any>();
|
const editorRef = useRef<NoteBodyEditorRef>();
|
||||||
const titleInputRef = useRef<any>();
|
const titleInputRef = useRef<any>();
|
||||||
const isMountedRef = useRef(true);
|
const isMountedRef = useRef(true);
|
||||||
const noteSearchBarRef = useRef(null);
|
const noteSearchBarRef = useRef(null);
|
||||||
@ -462,6 +463,8 @@ function NoteEditor(props: NoteEditorProps) {
|
|||||||
|
|
||||||
if (props.bodyEditor === 'TinyMCE') {
|
if (props.bodyEditor === 'TinyMCE') {
|
||||||
editor = <TinyMCE {...editorProps}/>;
|
editor = <TinyMCE {...editorProps}/>;
|
||||||
|
} else if (props.bodyEditor === 'PlainText') {
|
||||||
|
editor = <PlainEditor {...editorProps}/>;
|
||||||
} else if (props.bodyEditor === 'CodeMirror') {
|
} else if (props.bodyEditor === 'CodeMirror') {
|
||||||
editor = <CodeMirror5 {...editorProps}/>;
|
editor = <CodeMirror5 {...editorProps}/>;
|
||||||
} else if (props.bodyEditor === 'CodeMirror6') {
|
} else if (props.bodyEditor === 'CodeMirror6') {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect } from 'react';
|
import { RefObject, useEffect } from 'react';
|
||||||
import { FormNote, ScrollOptionTypes } from './types';
|
import { FormNote, NoteBodyEditorRef, ScrollOptionTypes } from './types';
|
||||||
import editorCommandDeclarations, { enabledCondition } from '../editorCommandDeclarations';
|
import editorCommandDeclarations, { enabledCondition } from '../editorCommandDeclarations';
|
||||||
import CommandService, { CommandDeclaration, CommandRuntime, CommandContext } from '@joplin/lib/services/CommandService';
|
import CommandService, { CommandDeclaration, CommandRuntime, CommandContext } from '@joplin/lib/services/CommandService';
|
||||||
import time from '@joplin/lib/time';
|
import time from '@joplin/lib/time';
|
||||||
@ -12,6 +12,8 @@ const commandsWithDependencies = [
|
|||||||
require('../commands/pasteAsText'),
|
require('../commands/pasteAsText'),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
type SetFormNoteCallback = (callback: (prev: FormNote)=> FormNote)=> void;
|
||||||
|
|
||||||
interface HookDependencies {
|
interface HookDependencies {
|
||||||
formNote: FormNote;
|
formNote: FormNote;
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
||||||
@ -19,16 +21,18 @@ interface HookDependencies {
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
||||||
dispatch: Function;
|
dispatch: Function;
|
||||||
noteSearchBarRef: any;
|
noteSearchBarRef: any;
|
||||||
editorRef: any;
|
editorRef: RefObject<NoteBodyEditorRef>;
|
||||||
titleInputRef: any;
|
titleInputRef: any;
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
||||||
saveNoteAndWait: Function;
|
saveNoteAndWait: Function;
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
setFormNote: SetFormNoteCallback;
|
||||||
setFormNote: Function;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
function editorCommandRuntime(
|
||||||
function editorCommandRuntime(declaration: CommandDeclaration, editorRef: any, setFormNote: Function): CommandRuntime {
|
declaration: CommandDeclaration,
|
||||||
|
editorRef: RefObject<NoteBodyEditorRef>,
|
||||||
|
setFormNote: SetFormNoteCallback,
|
||||||
|
): CommandRuntime {
|
||||||
return {
|
return {
|
||||||
execute: async (_context: CommandContext, ...args: any[]) => {
|
execute: async (_context: CommandContext, ...args: any[]) => {
|
||||||
if (!editorRef.current) {
|
if (!editorRef.current) {
|
||||||
|
@ -12,8 +12,9 @@ export default function stateToWhenClauseContext(state: AppState, options: WhenC
|
|||||||
...libStateToWhenClauseContext(state, options),
|
...libStateToWhenClauseContext(state, options),
|
||||||
|
|
||||||
// UI elements
|
// UI elements
|
||||||
markdownEditorVisible: !!state.settings['editor.codeView'],
|
markdownEditorVisible: !!state.settings['editor.codeView'] && !state.settings['isSafeMode'],
|
||||||
richTextEditorVisible: !state.settings['editor.codeView'],
|
richTextEditorVisible: !state.settings['editor.codeView'] && !state.settings['isSafeMode'],
|
||||||
|
|
||||||
markdownEditorPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('editor'),
|
markdownEditorPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('editor'),
|
||||||
markdownViewerPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('viewer'),
|
markdownViewerPaneVisible: state.settings['editor.codeView'] && state.noteVisiblePanes.includes('viewer'),
|
||||||
modalDialogVisible: !!Object.keys(state.visibleDialogs).length,
|
modalDialogVisible: !!Object.keys(state.visibleDialogs).length,
|
||||||
|
Loading…
Reference in New Issue
Block a user