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/focusElementNoteTitle.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/showRevisions.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/focusElementNoteTitle.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/showRevisions.js
packages/app-desktop/gui/NoteEditor/editorCommandDeclarations.js

View File

@ -634,6 +634,7 @@ function useMenu(props: Props) {
menuItemDic.textCopy,
menuItemDic.textCut,
menuItemDic.textPaste,
menuItemDic.pasteAsText,
menuItemDic.textSelectAll,
separator(),
// 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);
}
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 {
name: string;
value?: any;
@ -260,6 +270,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
// https://github.com/tinymce/tinymce/issues/3745
window.requestAnimationFrame(() => editor.undoManager.add());
},
pasteAsText: () => editor.fire('pasteAsText'),
};
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
// to be processed in various ways.
event.preventDefault();
@ -1070,10 +1081,15 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
}
}
async function onPasteAsText() {
await onPaste(createSyntheticClipboardEventWithoutHTML());
}
editor.on('keyup', onKeyUp);
editor.on('keydown', onKeyDown);
editor.on('keypress', onKeypress);
editor.on('paste', onPaste);
editor.on('pasteAsText', onPasteAsText);
editor.on('copy', onCopy);
// `compositionend` means that a user has finished entering a Chinese
// (or other languages that require IME) character.
@ -1090,6 +1106,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
editor.off('keydown', onKeyDown);
editor.off('keypress', onKeypress);
editor.off('paste', onPaste);
editor.off('pasteAsText', onPasteAsText);
editor.off('copy', onCopy);
editor.off('compositionend', onChangeHandler);
editor.off('cut', onCut);

View File

@ -1,12 +1,14 @@
// AUTO-GENERATED using `gulp buildCommandIndex`
import * as focusElementNoteBody from './focusElementNoteBody';
import * as focusElementNoteTitle from './focusElementNoteTitle';
import * as pasteAsText from './pasteAsText';
import * as showLocalSearch from './showLocalSearch';
import * as showRevisions from './showRevisions';
const index:any[] = [
focusElementNoteBody,
focusElementNoteTitle,
pasteAsText,
showLocalSearch,
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/focusElementNoteTitle'),
require('../commands/focusElementNoteBody'),
require('../commands/pasteAsText'),
];
interface HookDependencies {

View File

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

View File

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