fix: Improved pasting behavior from Dropbox Paper
This commit is contained in:
@@ -40,8 +40,8 @@ export default class Code extends Mark {
|
||||
get schema(): MarkSpec {
|
||||
return {
|
||||
excludes: "_",
|
||||
parseDOM: [{ tag: "code", preserveWhitespace: true }],
|
||||
toDOM: () => ["code", { spellCheck: "false" }],
|
||||
parseDOM: [{ tag: "code.inline", preserveWhitespace: true }],
|
||||
toDOM: () => ["code", { class: "inline", spellCheck: "false" }],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,11 @@ export default class Blockquote extends Node {
|
||||
content: "block+",
|
||||
group: "block",
|
||||
defining: true,
|
||||
parseDOM: [{ tag: "blockquote" }],
|
||||
parseDOM: [
|
||||
{ tag: "blockquote" },
|
||||
// Dropbox Paper parsing, yes their quotes are actually lists
|
||||
{ tag: "ul.listtype-quote", contentElement: "li" },
|
||||
],
|
||||
toDOM: () => ["blockquote", 0],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ export default class CodeFence extends Node {
|
||||
defining: true,
|
||||
draggable: false,
|
||||
parseDOM: [
|
||||
{ tag: "code" },
|
||||
{ tag: "pre", preserveWhitespace: "full" },
|
||||
{
|
||||
tag: ".code-block",
|
||||
|
||||
@@ -7,6 +7,12 @@ import isUrl from "../lib/isUrl";
|
||||
import selectionIsInCode from "../queries/isInCode";
|
||||
import { LANGUAGES } from "./Prism";
|
||||
|
||||
function isDropboxPaper(html: string): boolean {
|
||||
// The best we have to detect if a paste is likely coming from Paper
|
||||
// In this case it's actually better to use the text version
|
||||
return html?.includes("usually-unique-id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add support for additional syntax that users paste even though it isn't
|
||||
* supported by the markdown parser directly by massaging the text content.
|
||||
@@ -14,13 +20,16 @@ import { LANGUAGES } from "./Prism";
|
||||
* @param text The incoming pasted plain text
|
||||
*/
|
||||
function normalizePastedMarkdown(text: string): string {
|
||||
// find checkboxes not contained in a list and wrap them in list items
|
||||
const CHECKBOX_REGEX = /^\s?(\[(X|\s|_|-)\]\s(.*)?)/gim;
|
||||
|
||||
// find checkboxes not contained in a list and wrap them in list items
|
||||
while (text.match(CHECKBOX_REGEX)) {
|
||||
text = text.replace(CHECKBOX_REGEX, (match) => `- ${match.trim()}`);
|
||||
}
|
||||
|
||||
// find multiple newlines and insert a hard break to ensure they are respected
|
||||
text = text.replace(/\n{2,}/g, "\n\n\\\n");
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -33,6 +42,13 @@ export default class PasteHandler extends Extension {
|
||||
return [
|
||||
new Plugin({
|
||||
props: {
|
||||
transformPastedHTML(html: string) {
|
||||
if (isDropboxPaper(html)) {
|
||||
// Fixes double paragraphs when pasting from Dropbox Paper
|
||||
html = html.replace(/<div><br><\/div>/gi, "<p></p>");
|
||||
}
|
||||
return html;
|
||||
},
|
||||
handlePaste: (view, event: ClipboardEvent) => {
|
||||
if (view.props.editable && !view.props.editable(view.state)) {
|
||||
return false;
|
||||
@@ -125,7 +141,7 @@ export default class PasteHandler extends Extension {
|
||||
// If the text on the clipboard looks like Markdown OR there is no
|
||||
// html on the clipboard then try to parse content as Markdown
|
||||
if (
|
||||
isMarkdown(text) ||
|
||||
(isMarkdown(text) && !isDropboxPaper(html)) ||
|
||||
html.length === 0 ||
|
||||
pasteCodeLanguage === "markdown"
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user