mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-02 12:47:41 +02:00
Desktop: Fixes #11274: Fix content dropped into the Markdown editor is missing a cursor preview or dropped at the wrong location (#11289)
This commit is contained in:
parent
2974465882
commit
612d72d765
@ -1,10 +1,10 @@
|
||||
|
||||
import { RefObject, useMemo } from 'react';
|
||||
import { CommandValue } from '../../../utils/types';
|
||||
import { CommandValue, DropCommandValue } from '../../../utils/types';
|
||||
import { commandAttachFileToBody } from '../../../utils/resourceHandling';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import dialogs from '../../../../dialogs';
|
||||
import { EditorCommandType } from '@joplin/editor/types';
|
||||
import { EditorCommandType, UserEventSource } from '@joplin/editor/types';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
import CodeMirrorControl from '@joplin/editor/CodeMirror/CodeMirrorControl';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
@ -38,13 +38,22 @@ const useEditorCommands = (props: Props) => {
|
||||
};
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
dropItems: async (cmd: any) => {
|
||||
dropItems: async (cmd: DropCommandValue) => {
|
||||
let pos = cmd.pos && editorRef.current.editor.posAtCoords({ x: cmd.pos.clientX, y: cmd.pos.clientY });
|
||||
if (cmd.type === 'notes') {
|
||||
editorRef.current.insertText(cmd.markdownTags.join('\n'));
|
||||
const text = cmd.markdownTags.join('\n');
|
||||
if ((pos ?? null) !== null) {
|
||||
editorRef.current.select(pos, pos);
|
||||
}
|
||||
|
||||
editorRef.current.insertText(text, UserEventSource.Drop);
|
||||
} else if (cmd.type === 'files') {
|
||||
const pos = props.selectionRange.from;
|
||||
const newBody = await commandAttachFileToBody(props.editorContent, cmd.paths, { createFileURL: !!cmd.createFileURL, position: pos, markupLanguage: props.contentMarkupLanguage });
|
||||
pos ??= props.selectionRange.from;
|
||||
const newBody = await commandAttachFileToBody(props.editorContent, cmd.paths, {
|
||||
createFileURL: !!cmd.createFileURL,
|
||||
position: pos,
|
||||
markupLanguage: props.contentMarkupLanguage,
|
||||
});
|
||||
editorRef.current.updateBody(newBody);
|
||||
} else {
|
||||
logger.warn('CodeMirror: unsupported drop item: ', cmd);
|
||||
|
@ -252,3 +252,19 @@ export interface CommandValue {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
value?: any; // For TinyMCE only
|
||||
}
|
||||
|
||||
type DropCommandBase = {
|
||||
pos: {
|
||||
clientX: number;
|
||||
clientY: number;
|
||||
}|undefined;
|
||||
};
|
||||
|
||||
export type DropCommandValue = ({
|
||||
type: 'notes';
|
||||
markdownTags: string[];
|
||||
}|{
|
||||
type: 'files';
|
||||
paths: string[];
|
||||
createFileURL: boolean;
|
||||
}) & DropCommandBase;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useCallback } from 'react';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import { DragEvent as ReactDragEvent } from 'react';
|
||||
import { DropCommandValue } from './types';
|
||||
|
||||
interface HookDependencies {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
@ -19,6 +20,11 @@ export default function useDropHandler(dependencies: HookDependencies): DropHand
|
||||
const dt = event.dataTransfer;
|
||||
const createFileURL = event.altKey;
|
||||
|
||||
const eventPosition = {
|
||||
clientX: event.clientX,
|
||||
clientY: event.clientY,
|
||||
};
|
||||
|
||||
if (dt.types.indexOf('text/x-jop-note-ids') >= 0) {
|
||||
const noteIds = JSON.parse(dt.getData('text/x-jop-note-ids'));
|
||||
|
||||
@ -29,12 +35,15 @@ export default function useDropHandler(dependencies: HookDependencies): DropHand
|
||||
noteMarkdownTags.push(Note.markdownTag(note));
|
||||
}
|
||||
|
||||
const props: DropCommandValue = {
|
||||
type: 'notes',
|
||||
pos: eventPosition,
|
||||
markdownTags: noteMarkdownTags,
|
||||
};
|
||||
|
||||
editorRef.current.execCommand({
|
||||
name: 'dropItems',
|
||||
value: {
|
||||
type: 'notes',
|
||||
markdownTags: noteMarkdownTags,
|
||||
},
|
||||
value: props,
|
||||
});
|
||||
};
|
||||
void dropNotes();
|
||||
@ -51,13 +60,16 @@ export default function useDropHandler(dependencies: HookDependencies): DropHand
|
||||
paths.push(file.path);
|
||||
}
|
||||
|
||||
const props: DropCommandValue = {
|
||||
type: 'files',
|
||||
pos: eventPosition,
|
||||
paths: paths,
|
||||
createFileURL: createFileURL,
|
||||
};
|
||||
|
||||
editorRef.current.execCommand({
|
||||
name: 'dropItems',
|
||||
value: {
|
||||
type: 'files',
|
||||
paths: paths,
|
||||
createFileURL: createFileURL,
|
||||
},
|
||||
value: props,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import { classHighlighter } from '@lezer/highlight';
|
||||
|
||||
import {
|
||||
EditorView, drawSelection, highlightSpecialChars, ViewUpdate, Command, rectangularSelection,
|
||||
dropCursor,
|
||||
} from '@codemirror/view';
|
||||
import { history, undoDepth, redoDepth, standardKeymap } from '@codemirror/commands';
|
||||
|
||||
@ -253,6 +254,8 @@ const createEditor = (
|
||||
|
||||
// Apply styles to entire lines (block-display decorations)
|
||||
decoratorExtension,
|
||||
dropCursor(),
|
||||
|
||||
biDirectionalTextExtension,
|
||||
|
||||
// Adds additional CSS classes to tokens (the default CSS classes are
|
||||
|
@ -90,6 +90,7 @@ export interface ContentScriptData {
|
||||
// Intended to correspond with https://codemirror.net/docs/ref/#state.Transaction%5EuserEvent
|
||||
export enum UserEventSource {
|
||||
Paste = 'input.paste',
|
||||
Drop = 'input.drop',
|
||||
}
|
||||
|
||||
export interface EditorControl {
|
||||
|
Loading…
Reference in New Issue
Block a user