1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Desktop: Allow 'Paste as Text' on the Rich Text Editor (#7751)

This commit is contained in:
pedr 2023-02-13 16:16:33 -03:00 committed by GitHub
parent d55d4d42e5
commit c706b8dd2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 43 additions and 1 deletions

View File

@ -228,6 +228,7 @@ packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
packages/app-desktop/gui/NoteEditor/commands/index.js packages/app-desktop/gui/NoteEditor/commands/index.js
packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js
packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js
packages/app-desktop/gui/NoteEditor/commands/showRevisions.js packages/app-desktop/gui/NoteEditor/commands/showRevisions.js
packages/app-desktop/gui/NoteEditor/editorCommandDeclarations.js packages/app-desktop/gui/NoteEditor/editorCommandDeclarations.js

1
.gitignore vendored
View File

@ -216,6 +216,7 @@ packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
packages/app-desktop/gui/NoteEditor/commands/index.js packages/app-desktop/gui/NoteEditor/commands/index.js
packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js
packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js packages/app-desktop/gui/NoteEditor/commands/showLocalSearch.js
packages/app-desktop/gui/NoteEditor/commands/showRevisions.js packages/app-desktop/gui/NoteEditor/commands/showRevisions.js
packages/app-desktop/gui/NoteEditor/editorCommandDeclarations.js packages/app-desktop/gui/NoteEditor/editorCommandDeclarations.js

View File

@ -634,6 +634,7 @@ function useMenu(props: Props) {
menuItemDic.textCopy, menuItemDic.textCopy,
menuItemDic.textCut, menuItemDic.textCut,
menuItemDic.textPaste, menuItemDic.textPaste,
menuItemDic.pasteAsText,
menuItemDic.textSelectAll, menuItemDic.textSelectAll,
separator(), separator(),
// Using the generic "undo"/"redo" roles mean the menu // Using the generic "undo"/"redo" roles mean the menu

View File

@ -76,6 +76,16 @@ function stripMarkup(markupLanguage: number, markup: string, options: any = null
return markupToHtml_.stripMarkup(markupLanguage, markup, options); return markupToHtml_.stripMarkup(markupLanguage, markup, options);
} }
function createSyntheticClipboardEventWithoutHTML(): ClipboardEvent {
const clipboardData = new DataTransfer();
for (const format of clipboard.availableFormats()) {
if (format !== 'text/html') {
clipboardData.setData(format, clipboard.read(format));
}
}
return new ClipboardEvent('paste', { clipboardData });
}
interface TinyMceCommand { interface TinyMceCommand {
name: string; name: string;
value?: any; value?: any;
@ -260,6 +270,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
// https://github.com/tinymce/tinymce/issues/3745 // https://github.com/tinymce/tinymce/issues/3745
window.requestAnimationFrame(() => editor.undoManager.add()); window.requestAnimationFrame(() => editor.undoManager.add());
}, },
pasteAsText: () => editor.fire('pasteAsText'),
}; };
if (additionalCommands[cmd.name]) { if (additionalCommands[cmd.name]) {
@ -992,7 +1003,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
} }
} }
async function onPaste(event: any) { async function onPaste(event: ClipboardEvent) {
// We do not use the default pasting behaviour because the input has // We do not use the default pasting behaviour because the input has
// to be processed in various ways. // to be processed in various ways.
event.preventDefault(); event.preventDefault();
@ -1070,10 +1081,15 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
} }
} }
async function onPasteAsText() {
await onPaste(createSyntheticClipboardEventWithoutHTML());
}
editor.on('keyup', onKeyUp); editor.on('keyup', onKeyUp);
editor.on('keydown', onKeyDown); editor.on('keydown', onKeyDown);
editor.on('keypress', onKeypress); editor.on('keypress', onKeypress);
editor.on('paste', onPaste); editor.on('paste', onPaste);
editor.on('pasteAsText', onPasteAsText);
editor.on('copy', onCopy); editor.on('copy', onCopy);
// `compositionend` means that a user has finished entering a Chinese // `compositionend` means that a user has finished entering a Chinese
// (or other languages that require IME) character. // (or other languages that require IME) character.
@ -1090,6 +1106,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
editor.off('keydown', onKeyDown); editor.off('keydown', onKeyDown);
editor.off('keypress', onKeypress); editor.off('keypress', onKeypress);
editor.off('paste', onPaste); editor.off('paste', onPaste);
editor.off('pasteAsText', onPasteAsText);
editor.off('copy', onCopy); editor.off('copy', onCopy);
editor.off('compositionend', onChangeHandler); editor.off('compositionend', onChangeHandler);
editor.off('cut', onCut); editor.off('cut', onCut);

View File

@ -1,12 +1,14 @@
// AUTO-GENERATED using `gulp buildCommandIndex` // AUTO-GENERATED using `gulp buildCommandIndex`
import * as focusElementNoteBody from './focusElementNoteBody'; import * as focusElementNoteBody from './focusElementNoteBody';
import * as focusElementNoteTitle from './focusElementNoteTitle'; import * as focusElementNoteTitle from './focusElementNoteTitle';
import * as pasteAsText from './pasteAsText';
import * as showLocalSearch from './showLocalSearch'; import * as showLocalSearch from './showLocalSearch';
import * as showRevisions from './showRevisions'; import * as showRevisions from './showRevisions';
const index:any[] = [ const index:any[] = [
focusElementNoteBody, focusElementNoteBody,
focusElementNoteTitle, focusElementNoteTitle,
pasteAsText,
showLocalSearch, showLocalSearch,
showRevisions, showRevisions,
]; ];

View File

@ -0,0 +1,16 @@
import { CommandRuntime, CommandDeclaration } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
export const declaration: CommandDeclaration = {
name: 'pasteAsText',
label: () => _('Paste as text'),
};
export const runtime = (comp: any): CommandRuntime => {
return {
execute: async () => {
comp.editorRef.current.execCommand({ name: 'pasteAsText' });
},
enabledCondition: 'oneNoteSelected && richTextEditorVisible',
};
};

View File

@ -9,6 +9,7 @@ const commandsWithDependencies = [
require('../commands/showLocalSearch'), require('../commands/showLocalSearch'),
require('../commands/focusElementNoteTitle'), require('../commands/focusElementNoteTitle'),
require('../commands/focusElementNoteBody'), require('../commands/focusElementNoteBody'),
require('../commands/pasteAsText'),
]; ];
interface HookDependencies { interface HookDependencies {

View File

@ -65,5 +65,6 @@ export default function() {
'switchProfile1', 'switchProfile1',
'switchProfile2', 'switchProfile2',
'switchProfile3', 'switchProfile3',
'pasteAsText',
]; ];
} }

View File

@ -23,6 +23,7 @@ const defaultKeymapItems = {
{ accelerator: 'Cmd+C', command: 'textCopy' }, { accelerator: 'Cmd+C', command: 'textCopy' },
{ accelerator: 'Cmd+X', command: 'textCut' }, { accelerator: 'Cmd+X', command: 'textCut' },
{ accelerator: 'Cmd+V', command: 'textPaste' }, { accelerator: 'Cmd+V', command: 'textPaste' },
{ accelerator: 'Cmd+Shift+V', command: 'pasteAsText' },
{ accelerator: 'Cmd+A', command: 'textSelectAll' }, { accelerator: 'Cmd+A', command: 'textSelectAll' },
{ accelerator: 'Cmd+B', command: 'textBold' }, { accelerator: 'Cmd+B', command: 'textBold' },
{ accelerator: 'Cmd+I', command: 'textItalic' }, { accelerator: 'Cmd+I', command: 'textItalic' },
@ -67,6 +68,7 @@ const defaultKeymapItems = {
{ accelerator: 'Ctrl+C', command: 'textCopy' }, { accelerator: 'Ctrl+C', command: 'textCopy' },
{ accelerator: 'Ctrl+X', command: 'textCut' }, { accelerator: 'Ctrl+X', command: 'textCut' },
{ accelerator: 'Ctrl+V', command: 'textPaste' }, { accelerator: 'Ctrl+V', command: 'textPaste' },
{ accelerator: 'Ctrl+Shift+V', command: 'pasteAsText' },
{ accelerator: 'Ctrl+A', command: 'textSelectAll' }, { accelerator: 'Ctrl+A', command: 'textSelectAll' },
{ accelerator: 'Ctrl+B', command: 'textBold' }, { accelerator: 'Ctrl+B', command: 'textBold' },
{ accelerator: 'Ctrl+I', command: 'textItalic' }, { accelerator: 'Ctrl+I', command: 'textItalic' },