mirror of https://github.com/laurent22/joplin.git
parent
cffea3ea1e
commit
5962b0813e
|
@ -19,6 +19,8 @@ interface CodeMirrorResult {
|
|||
editor: EditorView;
|
||||
undo: Function;
|
||||
redo: Function;
|
||||
select: (anchor: number, head: number)=> void;
|
||||
insertText: (text: string)=> void;
|
||||
}
|
||||
|
||||
function postMessage(name: string, data: any) {
|
||||
|
@ -180,6 +182,13 @@ export function initCodeMirror(parentElement: any, initialText: string, theme: a
|
|||
postMessage('onChange', { value: editor.state.doc.toString() });
|
||||
schedulePostUndoRedoDepthChange(editor);
|
||||
}
|
||||
|
||||
if (!viewUpdate.state.selection.eq(viewUpdate.startState.selection)) {
|
||||
const mainRange = viewUpdate.state.selection.main;
|
||||
const selStart = mainRange.from;
|
||||
const selEnd = mainRange.to;
|
||||
postMessage('onSelectionChange', { selection: { start: selStart, end: selEnd } });
|
||||
}
|
||||
}),
|
||||
],
|
||||
doc: initialText,
|
||||
|
@ -197,5 +206,14 @@ export function initCodeMirror(parentElement: any, initialText: string, theme: a
|
|||
redo(editor);
|
||||
schedulePostUndoRedoDepthChange(editor, true);
|
||||
},
|
||||
select: (anchor: number, head: number) => {
|
||||
editor.dispatch(editor.state.update({
|
||||
selection: { anchor, head },
|
||||
scrollIntoView: true,
|
||||
}));
|
||||
},
|
||||
insertText: (text: string) => {
|
||||
editor.dispatch(editor.state.replaceSelection(text));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,14 +15,27 @@ export interface UndoRedoDepthChangeEvent {
|
|||
redoDepth: number;
|
||||
}
|
||||
|
||||
export interface Selection {
|
||||
start: number;
|
||||
end: number;
|
||||
}
|
||||
|
||||
export interface SelectionChangeEvent {
|
||||
selection: Selection;
|
||||
}
|
||||
|
||||
type ChangeEventHandler = (event: ChangeEvent)=> void;
|
||||
type UndoRedoDepthChangeHandler = (event: UndoRedoDepthChangeEvent)=> void;
|
||||
type SelectionChangeEventHandler = (event: SelectionChangeEvent)=> void;
|
||||
|
||||
interface Props {
|
||||
themeId: number;
|
||||
initialText: string;
|
||||
initialSelection?: Selection;
|
||||
style: any;
|
||||
|
||||
onChange: ChangeEventHandler;
|
||||
onSelectionChange: SelectionChangeEventHandler;
|
||||
onUndoRedoDepthChange: UndoRedoDepthChangeHandler;
|
||||
}
|
||||
|
||||
|
@ -212,11 +225,15 @@ function NoteEditor(props: Props, ref: any) {
|
|||
const [source, setSource] = useState(undefined);
|
||||
const webviewRef = useRef(null);
|
||||
|
||||
const setInitialSelectionJS = props.initialSelection ? `
|
||||
cm.select(${props.initialSelection.start}, ${props.initialSelection.end});
|
||||
` : '';
|
||||
|
||||
const injectedJavaScript = `
|
||||
function postMessage(name, data) {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({
|
||||
data,
|
||||
name,
|
||||
name,
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -227,7 +244,7 @@ function NoteEditor(props: Props, ref: any) {
|
|||
// This variable is not used within this script
|
||||
// but is called using "injectJavaScript" from
|
||||
// the wrapper component.
|
||||
let cm = null;
|
||||
window.cm = null;
|
||||
|
||||
try {
|
||||
${shim.injectedJs('codeMirrorBundle')};
|
||||
|
@ -237,6 +254,7 @@ function NoteEditor(props: Props, ref: any) {
|
|||
const initialText = ${JSON.stringify(props.initialText)};
|
||||
|
||||
cm = codeMirrorBundle.initCodeMirror(parentElement, initialText, theme);
|
||||
${setInitialSelectionJS}
|
||||
} catch (e) {
|
||||
window.ReactNativeWebView.postMessage("error:" + e.message + ": " + JSON.stringify(e))
|
||||
} finally {
|
||||
|
@ -255,6 +273,14 @@ function NoteEditor(props: Props, ref: any) {
|
|||
redo: function() {
|
||||
webviewRef.current.injectJavaScript('cm.redo(); true;');
|
||||
},
|
||||
select: (anchor: number, head: number) => {
|
||||
webviewRef.current.injectJavaScript(
|
||||
`cm.select(${JSON.stringify(anchor)}, ${JSON.stringify(head)}); true;`
|
||||
);
|
||||
},
|
||||
insertText: (text: string) => {
|
||||
webviewRef.current.injectJavaScript(`cm.insertText(${JSON.stringify(text)}); true;`);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -301,6 +327,10 @@ function NoteEditor(props: Props, ref: any) {
|
|||
console.info('onUndoRedoDepthChange', event);
|
||||
props.onUndoRedoDepthChange(event);
|
||||
},
|
||||
|
||||
onSelectionChange: (event: SelectionChangeEvent) => {
|
||||
props.onSelectionChange(event);
|
||||
},
|
||||
};
|
||||
|
||||
if (handlers[msg.name]) {
|
||||
|
|
|
@ -488,7 +488,11 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||
}
|
||||
|
||||
body_selectionChange(event: any) {
|
||||
this.selection = event.nativeEvent.selection;
|
||||
if (this.useEditorBeta()) {
|
||||
this.selection = event.selection;
|
||||
} else {
|
||||
this.selection = event.nativeEvent.selection;
|
||||
}
|
||||
}
|
||||
|
||||
makeSaveAction() {
|
||||
|
@ -708,9 +712,17 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||
const newNote = Object.assign({}, this.state.note);
|
||||
|
||||
if (this.state.mode == 'edit' && !!this.selection) {
|
||||
const newText = `\n${resourceTag}\n`;
|
||||
|
||||
const prefix = newNote.body.substring(0, this.selection.start);
|
||||
const suffix = newNote.body.substring(this.selection.end);
|
||||
newNote.body = `${prefix}\n${resourceTag}\n${suffix}`;
|
||||
newNote.body = `${prefix}${newText}${suffix}`;
|
||||
|
||||
if (this.useEditorBeta()) {
|
||||
// The beta editor needs to be explicitly informed of changes
|
||||
// to the note's body
|
||||
this.editorRef.current.insertText(newText);
|
||||
}
|
||||
} else {
|
||||
newNote.body += `\n${resourceTag}`;
|
||||
}
|
||||
|
@ -879,11 +891,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||
output.push({
|
||||
title: _('Attach...'),
|
||||
onPress: async () => {
|
||||
if (this.state.mode === 'edit' && this.useEditorBeta()) {
|
||||
alert('Attaching files from the beta editor is not yet supported. You may do so from the viewer mode instead.');
|
||||
return;
|
||||
}
|
||||
|
||||
const buttons = [];
|
||||
|
||||
// On iOS, it will show "local files", which means certain files saved from the browser
|
||||
|
@ -1125,7 +1132,9 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||
ref={this.editorRef}
|
||||
themeId={this.props.themeId}
|
||||
initialText={note.body}
|
||||
initialSelection={this.selection}
|
||||
onChange={this.onBodyChange}
|
||||
onSelectionChange={this.body_selectionChange}
|
||||
onUndoRedoDepthChange={this.onUndoRedoDepthChange}
|
||||
style={this.styles().bodyTextInput}
|
||||
/>;
|
||||
|
|
Loading…
Reference in New Issue