mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: WYSIWYG: Allow pasting images in editor
This commit is contained in:
parent
dacf6377ae
commit
05adb06aeb
@ -3,7 +3,7 @@ import { useState, useEffect, useRef, forwardRef, useCallback, useImperativeHand
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { EditorCommand, NoteBodyEditorProps } from '../../utils/types';
|
||||
import { commandAttachFileToBody } from '../../utils/resourceHandling';
|
||||
import { commandAttachFileToBody, handlePasteEvent } from '../../utils/resourceHandling';
|
||||
import { ScrollOptions, ScrollOptionTypes } from '../../utils/types';
|
||||
import { textOffsetToCursorPosition, useScrollHandler, useRootWidth, usePrevious, lineLeftSpaces, selectionRangeCurrentLine, selectionRangePreviousLine, currentTextOffset, textOffsetSelection, selectedText, useSelectionRange } from './utils';
|
||||
import useListIdent from './utils/useListIdent';
|
||||
@ -15,12 +15,9 @@ const AceEditorReact = require('react-ace').default;
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { clipboard } = require('electron');
|
||||
const mimeUtils = require('lib/mime-utils.js').mime;
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const NoteTextViewer = require('../../../NoteTextViewer.min');
|
||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||
const md5 = require('md5');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const Menu = bridge().Menu;
|
||||
const MenuItem = bridge().MenuItem;
|
||||
const markdownUtils = require('lib/markdownUtils');
|
||||
@ -332,29 +329,10 @@ function AceEditor(props: NoteBodyEditorProps, ref: any) {
|
||||
}, [editor, props.content, addListItem, wrapSelectionWithStrings, selectionRangeCurrentLine, aceEditor_change, setEditorPercentScroll, setViewerPercentScroll, resetScroll, renderedBody]);
|
||||
|
||||
const onEditorPaste = useCallback(async (event: any = null) => {
|
||||
const formats = clipboard.availableFormats();
|
||||
for (let i = 0; i < formats.length; i++) {
|
||||
const format = formats[i].toLowerCase();
|
||||
const formatType = format.split('/')[0];
|
||||
|
||||
const position = currentTextOffset(editor, props.content);
|
||||
|
||||
if (formatType === 'image') {
|
||||
if (event) event.preventDefault();
|
||||
|
||||
const image = clipboard.readImage();
|
||||
|
||||
const fileExt = mimeUtils.toFileExtension(format);
|
||||
const filePath = `${Setting.value('tempDir')}/${md5(Date.now())}.${fileExt}`;
|
||||
|
||||
await shim.writeImageToFile(image, format, filePath);
|
||||
const newBody = await commandAttachFileToBody(props.content, [filePath], { position });
|
||||
await shim.fsDriver().remove(filePath);
|
||||
|
||||
aceEditor_change(newBody);
|
||||
}
|
||||
}
|
||||
}, [editor, props.content, aceEditor_change]);
|
||||
const resourceMds = await handlePasteEvent(event);
|
||||
if (!resourceMds.length) return;
|
||||
wrapSelectionWithStrings('', '', resourceMds.join('\n'));
|
||||
}, [wrapSelectionWithStrings]);
|
||||
|
||||
const onEditorKeyDown = useCallback((event: any) => {
|
||||
setLastKeys(prevLastKeys => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle } from 'react';
|
||||
import { ScrollOptions, ScrollOptionTypes, EditorCommand, NoteBodyEditorProps } from '../../utils/types';
|
||||
import { resourcesStatus, commandAttachFileToBody } from '../../utils/resourceHandling';
|
||||
import { resourcesStatus, commandAttachFileToBody, handlePasteEvent } from '../../utils/resourceHandling';
|
||||
import useScroll from './utils/useScroll';
|
||||
import { menuItems, ContextMenuOptions, ContextMenuItemType } from '../../utils/contextMenu';
|
||||
const { MarkupToHtml } = require('lib/joplin-renderer');
|
||||
@ -879,18 +879,24 @@ const TinyMCE = (props:NoteBodyEditorProps, ref:any) => {
|
||||
}
|
||||
|
||||
async function onPaste(event:any) {
|
||||
const pastedText = event.clipboardData.getData('text');
|
||||
|
||||
if (BaseItem.isMarkdownTag(pastedText)) { // Paste a link to a note
|
||||
event.preventDefault();
|
||||
const result = await markupToHtml.current(MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN, pastedText, markupRenderOptions({ bodyOnly: true }));
|
||||
const resourceMds = await handlePasteEvent(event);
|
||||
if (resourceMds.length) {
|
||||
const result = await markupToHtml.current(MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN, resourceMds.join('\n'), markupRenderOptions({ bodyOnly: true }));
|
||||
editor.insertContent(result.html);
|
||||
} else { // Paste regular text
|
||||
// HACK: TinyMCE doesn't add an undo step when pasting, for unclear reasons
|
||||
// so we manually add it here. We also can't do it immediately it seems, or
|
||||
// else nothing is added to the stack, so do it on the next frame.
|
||||
window.requestAnimationFrame(() => editor.undoManager.add());
|
||||
onChangeHandler();
|
||||
} else {
|
||||
const pastedText = event.clipboardData.getData('text');
|
||||
|
||||
if (BaseItem.isMarkdownTag(pastedText)) { // Paste a link to a note
|
||||
event.preventDefault();
|
||||
const result = await markupToHtml.current(MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN, pastedText, markupRenderOptions({ bodyOnly: true }));
|
||||
editor.insertContent(result.html);
|
||||
} else { // Paste regular text
|
||||
// HACK: TinyMCE doesn't add an undo step when pasting, for unclear reasons
|
||||
// so we manually add it here. We also can't do it immediately it seems, or
|
||||
// else nothing is added to the stack, so do it on the next frame.
|
||||
window.requestAnimationFrame(() => editor.undoManager.add());
|
||||
onChangeHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,9 @@ const { bridge } = require('electron').remote.require('./bridge');
|
||||
const ResourceFetcher = require('lib/services/ResourceFetcher.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const joplinRendererUtils = require('lib/joplin-renderer').utils;
|
||||
const { clipboard } = require('electron');
|
||||
const mimeUtils = require('lib/mime-utils.js').mime;
|
||||
const md5 = require('md5');
|
||||
|
||||
export async function handleResourceDownloadMode(noteBody: string) {
|
||||
if (noteBody && Setting.value('sync.resourceDownloadMode') === 'auto') {
|
||||
@ -97,3 +100,28 @@ export function resourcesStatus(resourceInfos: any) {
|
||||
}
|
||||
return joplinRendererUtils.resourceStatusName(lowestIndex);
|
||||
}
|
||||
|
||||
export async function handlePasteEvent(event:any) {
|
||||
const output = [];
|
||||
const formats = clipboard.availableFormats();
|
||||
for (let i = 0; i < formats.length; i++) {
|
||||
const format = formats[i].toLowerCase();
|
||||
const formatType = format.split('/')[0];
|
||||
|
||||
if (formatType === 'image') {
|
||||
if (event) event.preventDefault();
|
||||
|
||||
const image = clipboard.readImage();
|
||||
|
||||
const fileExt = mimeUtils.toFileExtension(format);
|
||||
const filePath = `${Setting.value('tempDir')}/${md5(Date.now())}.${fileExt}`;
|
||||
|
||||
await shim.writeImageToFile(image, format, filePath);
|
||||
const md = await commandAttachFileToBody('', [filePath]);
|
||||
await shim.fsDriver().remove(filePath);
|
||||
|
||||
output.push(md);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user