mirror of
https://github.com/Shadowfita/docmost.git
synced 2025-11-09 20:12:00 +10:00
fix: link paste handler (#609)
* feat: support pasting markdown * fix link paste handler
This commit is contained in:
@ -65,6 +65,7 @@
|
|||||||
"fractional-indexing-jittered": "^0.9.1",
|
"fractional-indexing-jittered": "^0.9.1",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
|
"linkifyjs": "^4.2.0",
|
||||||
"marked": "^13.0.3",
|
"marked": "^13.0.3",
|
||||||
"uuid": "^11.0.3",
|
"uuid": "^11.0.3",
|
||||||
"y-indexeddb": "^9.0.12",
|
"y-indexeddb": "^9.0.12",
|
||||||
|
|||||||
@ -10,11 +10,35 @@ export const LinkExtension = TiptapLink.extend({
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
tag: 'a[href]:not([data-type="button"]):not([href *= "javascript:" i])',
|
tag: 'a[href]:not([data-type="button"]):not([href *= "javascript:" i])',
|
||||||
|
getAttrs: (element) => {
|
||||||
|
if (
|
||||||
|
element
|
||||||
|
.getAttribute("href")
|
||||||
|
?.toLowerCase()
|
||||||
|
.startsWith("javascript:")
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
renderHTML({ HTMLAttributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
|
if (HTMLAttributes.href?.toLowerCase().startsWith("javascript:")) {
|
||||||
|
return [
|
||||||
|
"a",
|
||||||
|
mergeAttributes(
|
||||||
|
this.options.HTMLAttributes,
|
||||||
|
{ ...HTMLAttributes, href: "" },
|
||||||
|
{ class: "link" },
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"a",
|
"a",
|
||||||
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
|
||||||
|
|||||||
@ -3,9 +3,15 @@ import { Extension } from "@tiptap/core";
|
|||||||
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
||||||
import { DOMParser } from "@tiptap/pm/model";
|
import { DOMParser } from "@tiptap/pm/model";
|
||||||
import { markdownToHtml } from "./utils/marked.utils";
|
import { markdownToHtml } from "./utils/marked.utils";
|
||||||
|
import { find } from "linkifyjs";
|
||||||
|
|
||||||
export const MarkdownClipboard = Extension.create({
|
export const MarkdownClipboard = Extension.create({
|
||||||
name: "markdownClipboard",
|
name: "markdownClipboard",
|
||||||
|
priority: 50,
|
||||||
|
|
||||||
|
export const MarkdownClipboard = Extension.create({
|
||||||
|
name: "markdownClipboard",
|
||||||
|
|
||||||
addOptions() {
|
addOptions() {
|
||||||
return {
|
return {
|
||||||
transformPastedText: false,
|
transformPastedText: false,
|
||||||
@ -17,9 +23,17 @@ export const MarkdownClipboard = Extension.create({
|
|||||||
key: new PluginKey("markdownClipboard"),
|
key: new PluginKey("markdownClipboard"),
|
||||||
props: {
|
props: {
|
||||||
clipboardTextParser: (text, context, plainText) => {
|
clipboardTextParser: (text, context, plainText) => {
|
||||||
if (plainText || !this.options.transformPastedText) {
|
|
||||||
return null; // pasting with shift key prevents formatting
|
const link = find(text, {
|
||||||
|
defaultProtocol: "http",
|
||||||
|
}).find((item) => item.isLink && item.value === text);
|
||||||
|
|
||||||
|
if (plainText || !this.options.transformPastedText || link) {
|
||||||
|
// don't parse plaintext link to allow link paste handler to work
|
||||||
|
// pasting with shift key prevents formatting
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsed = markdownToHtml(text);
|
const parsed = markdownToHtml(text);
|
||||||
return DOMParser.fromSchema(this.editor.schema).parseSlice(
|
return DOMParser.fromSchema(this.editor.schema).parseSlice(
|
||||||
elementFromString(parsed),
|
elementFromString(parsed),
|
||||||
|
|||||||
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@ -160,6 +160,9 @@ importers:
|
|||||||
jszip:
|
jszip:
|
||||||
specifier: ^3.10.1
|
specifier: ^3.10.1
|
||||||
version: 3.10.1
|
version: 3.10.1
|
||||||
|
linkifyjs:
|
||||||
|
specifier: ^4.2.0
|
||||||
|
version: 4.2.0
|
||||||
marked:
|
marked:
|
||||||
specifier: ^13.0.3
|
specifier: ^13.0.3
|
||||||
version: 13.0.3
|
version: 13.0.3
|
||||||
@ -6459,8 +6462,8 @@ packages:
|
|||||||
linkify-it@5.0.0:
|
linkify-it@5.0.0:
|
||||||
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
|
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
|
||||||
|
|
||||||
linkifyjs@4.1.3:
|
linkifyjs@4.2.0:
|
||||||
resolution: {integrity: sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==}
|
resolution: {integrity: sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==}
|
||||||
|
|
||||||
loader-runner@4.3.0:
|
loader-runner@4.3.0:
|
||||||
resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
|
resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
|
||||||
@ -12349,7 +12352,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 2.10.3(@tiptap/pm@2.10.3)
|
'@tiptap/core': 2.10.3(@tiptap/pm@2.10.3)
|
||||||
'@tiptap/pm': 2.10.3
|
'@tiptap/pm': 2.10.3
|
||||||
linkifyjs: 4.1.3
|
linkifyjs: 4.2.0
|
||||||
|
|
||||||
'@tiptap/extension-list-item@2.10.3(@tiptap/core@2.10.3(@tiptap/pm@2.10.3))':
|
'@tiptap/extension-list-item@2.10.3(@tiptap/core@2.10.3(@tiptap/pm@2.10.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -15922,7 +15925,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
uc.micro: 2.1.0
|
uc.micro: 2.1.0
|
||||||
|
|
||||||
linkifyjs@4.1.3: {}
|
linkifyjs@4.2.0: {}
|
||||||
|
|
||||||
loader-runner@4.3.0: {}
|
loader-runner@4.3.0: {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user