@tiptap/extension-link 2.1.10 → 2.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -119,73 +119,29 @@ function pasteHandler(options) {
119
119
  key: new state.PluginKey('handlePasteLink'),
120
120
  props: {
121
121
  handlePaste: (view, event, slice) => {
122
- var _a, _b;
122
+ var _a;
123
123
  const { state } = view;
124
124
  const { selection } = state;
125
- // Do not proceed if in code block.
126
- if (state.doc.resolve(selection.from).parent.type.spec.code) {
125
+ const { empty } = selection;
126
+ if (empty) {
127
127
  return false;
128
128
  }
129
129
  let textContent = '';
130
130
  slice.content.forEach(node => {
131
131
  textContent += node.textContent;
132
132
  });
133
- let isAlreadyLink = false;
134
- slice.content.descendants(node => {
135
- if (node.marks.some(mark => mark.type.name === options.type.name)) {
136
- isAlreadyLink = true;
137
- }
138
- });
139
- if (isAlreadyLink) {
140
- return;
141
- }
142
133
  const link = linkifyjs.find(textContent).find(item => item.isLink && item.value === textContent);
143
- if (!selection.empty && options.linkOnPaste) {
144
- const pastedLink = (link === null || link === void 0 ? void 0 : link.href) || null;
145
- if (pastedLink) {
146
- options.editor.commands.setMark(options.type, { href: pastedLink });
147
- return true;
148
- }
149
- }
150
- const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
151
- const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
152
- if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
134
+ if (!textContent || !link) {
153
135
  return false;
154
136
  }
155
- if (link && selection.empty) {
156
- options.editor.commands.insertContent(`<a href="${link.href}">${link.href}</a>`);
157
- return true;
158
- }
159
- const { tr } = state;
160
- let deleteOnly = false;
161
- if (!selection.empty) {
162
- deleteOnly = true;
163
- tr.delete(selection.from, selection.to);
164
- }
165
- let currentPos = selection.from;
166
- let fragmentLinks = [];
167
- slice.content.forEach(node => {
168
- fragmentLinks = linkifyjs.find(node.textContent);
169
- tr.insert(currentPos - 1, node);
170
- if (fragmentLinks.length > 0) {
171
- deleteOnly = false;
172
- fragmentLinks.forEach(fragmentLink => {
173
- const linkStart = currentPos + fragmentLink.start;
174
- const linkEnd = currentPos + fragmentLink.end;
175
- const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type);
176
- if (!hasMark) {
177
- tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }));
178
- }
179
- });
180
- }
181
- currentPos += node.nodeSize;
137
+ const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
138
+ const hrefRegex = /href="([^"]*)"/;
139
+ const existingLink = html === null || html === void 0 ? void 0 : html.match(hrefRegex);
140
+ const url = existingLink ? existingLink[1] : link.href;
141
+ options.editor.commands.setMark(options.type, {
142
+ href: url,
182
143
  });
183
- const hasFragmentLinks = fragmentLinks.length > 0;
184
- if (tr.docChanged && !deleteOnly && hasFragmentLinks) {
185
- options.editor.view.dispatch(tr);
186
- return true;
187
- }
188
- return false;
144
+ return true;
189
145
  },
190
146
  },
191
147
  });
@@ -265,6 +221,40 @@ const Link = core.Mark.create({
265
221
  },
266
222
  };
267
223
  },
224
+ addPasteRules() {
225
+ return [
226
+ core.markPasteRule({
227
+ find: text => linkifyjs.find(text)
228
+ .filter(link => {
229
+ if (this.options.validate) {
230
+ return this.options.validate(link.value);
231
+ }
232
+ return true;
233
+ })
234
+ .filter(link => link.isLink)
235
+ .map(link => ({
236
+ text: link.value,
237
+ index: link.start,
238
+ data: link,
239
+ })),
240
+ type: this.type,
241
+ getAttributes: (match, pasteEvent) => {
242
+ var _a, _b;
243
+ const html = (_a = pasteEvent === null || pasteEvent === void 0 ? void 0 : pasteEvent.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
244
+ const hrefRegex = /href="([^"]*)"/;
245
+ const existingLink = html === null || html === void 0 ? void 0 : html.match(hrefRegex);
246
+ if (existingLink) {
247
+ return {
248
+ href: existingLink[1],
249
+ };
250
+ }
251
+ return {
252
+ href: (_b = match.data) === null || _b === void 0 ? void 0 : _b.href,
253
+ };
254
+ },
255
+ }),
256
+ ];
257
+ },
268
258
  addProseMirrorPlugins() {
269
259
  const plugins = [];
270
260
  if (this.options.autolink) {
@@ -278,11 +268,12 @@ const Link = core.Mark.create({
278
268
  type: this.type,
279
269
  }));
280
270
  }
281
- plugins.push(pasteHandler({
282
- editor: this.editor,
283
- type: this.type,
284
- linkOnPaste: this.options.linkOnPaste,
285
- }));
271
+ if (this.options.linkOnPaste) {
272
+ plugins.push(pasteHandler({
273
+ editor: this.editor,
274
+ type: this.type,
275
+ }));
276
+ }
286
277
  return plugins;
287
278
  },
288
279
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const eventTarget = event.target as HTMLElement\n\n if (eventTarget.nodeName !== 'A') {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n let isAlreadyLink = false\n\n slice.content.descendants(node => {\n if (node.marks.some(mark => mark.type.name === options.type.name)) {\n isAlreadyLink = true\n }\n })\n\n if (isAlreadyLink) {\n return\n }\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","find","getMarksBetween","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const eventTarget = event.target as HTMLElement\n\n if (eventTarget.nodeName !== 'A') {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n const { empty } = selection\n\n if (empty) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n const html = event.clipboardData?.getData('text/html')\n\n const hrefRegex = /href=\"([^\"]*)\"/\n\n const existingLink = html?.match(hrefRegex)\n\n const url = existingLink ? existingLink[1] : link.href\n\n options.editor.commands.setMark(options.type, {\n href: url,\n })\n\n return true\n },\n },\n })\n}\n","import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { find, registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\n .filter(link => {\n if (this.options.validate) {\n return this.options.validate(link.value)\n }\n\n return true\n })\n .filter(link => link.isLink)\n .map(link => ({\n text: link.value,\n index: link.start,\n data: link,\n })),\n type: this.type,\n getAttributes: (match, pasteEvent) => {\n const html = pasteEvent?.clipboardData?.getData('text/html')\n const hrefRegex = /href=\"([^\"]*)\"/\n\n const existingLink = html?.match(hrefRegex)\n\n if (existingLink) {\n return {\n href: existingLink[1],\n }\n }\n\n return {\n href: match.data?.href,\n }\n },\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","find","getMarksBetween","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes","markPasteRule"],"mappings":";;;;;;;;AAgBM,SAAU,QAAQ,CAAC,OAAwB,EAAA;IAC/C,OAAO,IAAIA,YAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAIC,eAAS,CAAC,UAAU,CAAC;QAC9B,iBAAiB,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAI;YACtD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AAC7G,YAAA,MAAM,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAEhG,YAAA,IAAI,CAAC,UAAU,IAAI,eAAe,EAAE;gBAClC,OAAM;AACP,aAAA;AAED,YAAA,MAAM,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAA;AACvB,YAAA,MAAM,SAAS,GAAGC,4BAAuB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAA;AAC1E,YAAA,MAAM,OAAO,GAAGC,qBAAgB,CAAC,SAAS,CAAC,CAAA;YAE3C,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAI;;AAE/B,gBAAA,MAAM,oBAAoB,GAAGC,wBAAmB,CAC9C,QAAQ,CAAC,GAAG,EACZ,QAAQ,EACR,IAAI,IAAI,IAAI,CAAC,WAAW,CACzB,CAAA;AAED,gBAAA,IAAI,SAAkC,CAAA;AACtC,gBAAA,IAAI,oBAAwC,CAAA;AAE5C,gBAAA,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;;AAEnC,oBAAA,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;oBACnC,oBAAoB,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC7C,SAAS,CAAC,GAAG,EACb,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EACvC,SAAS,EACT,GAAG,CACJ,CAAA;AACF,iBAAA;qBAAM,IACL,oBAAoB,CAAC,MAAM;;uBAExB,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC/E;AACA,oBAAA,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;AACnC,oBAAA,oBAAoB,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC7C,SAAS,CAAC,GAAG,EACb,QAAQ,CAAC,EAAE,EACX,SAAS,EACT,GAAG,CACJ,CAAA;AACF,iBAAA;gBAED,IAAI,SAAS,IAAI,oBAAoB,EAAE;AACrC,oBAAA,MAAM,qBAAqB,GAAG,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;AAEnF,oBAAA,IAAI,qBAAqB,CAAC,MAAM,IAAI,CAAC,EAAE;AACrC,wBAAA,OAAO,KAAK,CAAA;AACb,qBAAA;oBAED,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACnF,oBAAA,MAAM,sBAAsB,GAAG,SAAS,CAAC,GAAG,GAAG,oBAAoB,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAA;oBAEpG,IAAI,CAAC,mBAAmB,EAAE;AACxB,wBAAA,OAAO,KAAK,CAAA;AACb,qBAAA;oBAEDC,cAAI,CAAC,mBAAmB,CAAC;yBACtB,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;;AAE3B,yBAAA,GAAG,CAAC,IAAI,KAAK;AACZ,wBAAA,GAAG,IAAI;AACP,wBAAA,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;AAC7C,wBAAA,EAAE,EAAE,sBAAsB,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;AAC1C,qBAAA,CAAC,CAAC;;yBAEF,MAAM,CAAC,IAAI,IAAG;wBACb,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE;AAC/B,4BAAA,OAAO,IAAI,CAAA;AACZ,yBAAA;wBAED,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAC/B,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAC3B,CAAA;AACH,qBAAC,CAAC;;yBAED,MAAM,CAAC,IAAI,IAAG;wBACb,IAAI,OAAO,CAAC,QAAQ,EAAE;4BACpB,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACpC,yBAAA;AACD,wBAAA,OAAO,IAAI,CAAA;AACb,qBAAC,CAAC;;yBAED,OAAO,CAAC,IAAI,IAAG;AACd,wBAAA,IAAIC,oBAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE;4BACnG,OAAM;AACP,yBAAA;AAED,wBAAA,EAAE,CAAC,OAAO,CACR,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;4BAClB,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,yBAAA,CAAC,CACH,CAAA;AACH,qBAAC,CAAC,CAAA;AACL,iBAAA;AACH,aAAC,CAAC,CAAA;AAEF,YAAA,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE;gBACpB,OAAM;AACP,aAAA;AAED,YAAA,OAAO,EAAE,CAAA;SACV;AACF,KAAA,CAAC,CAAA;AACJ;;AC1HM,SAAU,YAAY,CAAC,OAA4B,EAAA;IACvD,OAAO,IAAIN,YAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAIC,eAAS,CAAC,iBAAiB,CAAC;AACrC,QAAA,KAAK,EAAE;YACL,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,KAAI;;AAChC,gBAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AACtB,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;AAED,gBAAA,MAAM,WAAW,GAAG,KAAK,CAAC,MAAqB,CAAA;AAE/C,gBAAA,IAAI,WAAW,CAAC,QAAQ,KAAK,GAAG,EAAE;AAChC,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;AAED,gBAAA,MAAM,KAAK,GAAGM,kBAAa,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC1D,gBAAA,MAAM,IAAI,GAAI,KAAK,CAAC,MAA0B,CAAA;AAE9C,gBAAA,MAAM,IAAI,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC,IAAI,CAAA;AACrC,gBAAA,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC,MAAM,CAAA;gBAE3C,IAAI,IAAI,IAAI,IAAI,EAAE;oBAChB,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,wBAAA,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AAC1B,qBAAA;AAED,oBAAA,OAAO,IAAI,CAAA;AACZ,iBAAA;AAED,gBAAA,OAAO,KAAK,CAAA;aACb;AACF,SAAA;AACF,KAAA,CAAC,CAAA;AACJ;;AC/BM,SAAU,YAAY,CAAC,OAA4B,EAAA;IACvD,OAAO,IAAIP,YAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAIC,eAAS,CAAC,iBAAiB,CAAC;AACrC,QAAA,KAAK,EAAE;YACL,WAAW,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,KAAI;;AAClC,gBAAA,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;AACtB,gBAAA,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;AAC3B,gBAAA,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAA;AAE3B,gBAAA,IAAI,KAAK,EAAE;AACT,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;gBAED,IAAI,WAAW,GAAG,EAAE,CAAA;AAEpB,gBAAA,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAG;AAC3B,oBAAA,WAAW,IAAI,IAAI,CAAC,WAAW,CAAA;AACjC,iBAAC,CAAC,CAAA;gBAEF,MAAM,IAAI,GAAGI,cAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,CAAA;AAEtF,gBAAA,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE;AACzB,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;gBAED,MAAM,IAAI,GAAG,CAAA,EAAA,GAAA,KAAK,CAAC,aAAa,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,OAAO,CAAC,WAAW,CAAC,CAAA;gBAEtD,MAAM,SAAS,GAAG,gBAAgB,CAAA;AAElC,gBAAA,MAAM,YAAY,GAAG,IAAI,KAAA,IAAA,IAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,KAAK,CAAC,SAAS,CAAC,CAAA;AAE3C,gBAAA,MAAM,GAAG,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAA;gBAEtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;AAC5C,oBAAA,IAAI,EAAE,GAAG;AACV,iBAAA,CAAC,CAAA;AAEF,gBAAA,OAAO,IAAI,CAAA;aACZ;AACF,SAAA;AACF,KAAA,CAAC,CAAA;AACJ;;ACUa,MAAA,IAAI,GAAGG,SAAI,CAAC,MAAM,CAAc;AAC3C,IAAA,IAAI,EAAE,MAAM;AAEZ,IAAA,QAAQ,EAAE,IAAI;AAEd,IAAA,WAAW,EAAE,KAAK;IAElB,QAAQ,GAAA;QACN,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,IAAG;AACxC,YAAA,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;gBAChCC,gCAAsB,CAAC,QAAQ,CAAC,CAAA;gBAChC,OAAM;AACP,aAAA;YACDA,gCAAsB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;AACnE,SAAC,CAAC,CAAA;KACH;IAED,SAAS,GAAA;AACP,QAAAC,eAAK,EAAE,CAAA;KACR;IAED,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;KAC7B;IAED,UAAU,GAAA;QACR,OAAO;AACL,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,QAAQ,EAAE,IAAI;AACd,YAAA,SAAS,EAAE,EAAE;AACb,YAAA,cAAc,EAAE;AACd,gBAAA,MAAM,EAAE,QAAQ;AAChB,gBAAA,GAAG,EAAE,8BAA8B;AACnC,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;AACD,YAAA,QAAQ,EAAE,SAAS;SACpB,CAAA;KACF;IAED,aAAa,GAAA;QACX,OAAO;AACL,YAAA,IAAI,EAAE;AACJ,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM;AAC5C,aAAA;AACD,YAAA,GAAG,EAAE;AACH,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG;AACzC,aAAA;AACD,YAAA,KAAK,EAAE;AACL,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK;AAC3C,aAAA;SACF,CAAA;KACF;IAED,SAAS,GAAA;AACP,QAAA,OAAO,CAAC,EAAE,GAAG,EAAE,wCAAwC,EAAE,CAAC,CAAA;KAC3D;IAED,UAAU,CAAC,EAAE,cAAc,EAAE,EAAA;AAC3B,QAAA,OAAO,CAAC,GAAG,EAAEC,oBAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;KAC9E;IAED,WAAW,GAAA;QACT,OAAO;YACL,OAAO,EACL,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,KAAI;gBAC1B,OAAO,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAA;aACrF;YAEH,UAAU,EACR,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,KAAI;AAC1B,gBAAA,OAAO,KAAK,EAAE;AACX,qBAAA,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;AACjE,qBAAA,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;AAChC,qBAAA,GAAG,EAAE,CAAA;aACT;YAEH,SAAS,EACP,MAAM,CAAC,EAAE,KAAK,EAAE,KAAI;AAClB,gBAAA,OAAO,KAAK,EAAE;qBACX,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;AACpD,qBAAA,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;AAChC,qBAAA,GAAG,EAAE,CAAA;aACT;SACJ,CAAA;KACF;IAED,aAAa,GAAA;QACX,OAAO;AACL,YAAAC,kBAAa,CAAC;gBACZ,IAAI,EAAE,IAAI,IAAIP,cAAI,CAAC,IAAI,CAAC;qBACrB,MAAM,CAAC,IAAI,IAAG;AACb,oBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;wBACzB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACzC,qBAAA;AAED,oBAAA,OAAO,IAAI,CAAA;AACb,iBAAC,CAAC;qBACD,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;AAC3B,qBAAA,GAAG,CAAC,IAAI,KAAK;oBACZ,IAAI,EAAE,IAAI,CAAC,KAAK;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;AACjB,oBAAA,IAAI,EAAE,IAAI;AACX,iBAAA,CAAC,CAAC;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,gBAAA,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,KAAI;;AACnC,oBAAA,MAAM,IAAI,GAAG,CAAA,EAAA,GAAA,UAAU,aAAV,UAAU,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAV,UAAU,CAAE,aAAa,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,OAAO,CAAC,WAAW,CAAC,CAAA;oBAC5D,MAAM,SAAS,GAAG,gBAAgB,CAAA;AAElC,oBAAA,MAAM,YAAY,GAAG,IAAI,KAAA,IAAA,IAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,KAAK,CAAC,SAAS,CAAC,CAAA;AAE3C,oBAAA,IAAI,YAAY,EAAE;wBAChB,OAAO;AACL,4BAAA,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;yBACtB,CAAA;AACF,qBAAA;oBAED,OAAO;AACL,wBAAA,IAAI,EAAE,CAAA,EAAA,GAAA,KAAK,CAAC,IAAI,0CAAE,IAAI;qBACvB,CAAA;iBACF;aACF,CAAC;SACH,CAAA;KACF;IAED,qBAAqB,GAAA;QACnB,MAAM,OAAO,GAAa,EAAE,CAAA;AAE5B,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;AACzB,YAAA,OAAO,CAAC,IAAI,CACV,QAAQ,CAAC;gBACP,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAChC,aAAA,CAAC,CACH,CAAA;AACF,SAAA;AAED,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;AAC5B,YAAA,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,aAAA,CAAC,CACH,CAAA;AACF,SAAA;AAED,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;AAC5B,YAAA,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;gBACX,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,aAAA,CAAC,CACH,CAAA;AACF,SAAA;AAED,QAAA,OAAO,OAAO,CAAA;KACf;AACF,CAAA;;;;;"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { combineTransactionSteps, getChangedRanges, findChildrenInRange, getMarksBetween, getAttributes, Mark, mergeAttributes } from '@tiptap/core';
1
+ import { combineTransactionSteps, getChangedRanges, findChildrenInRange, getMarksBetween, getAttributes, Mark, mergeAttributes, markPasteRule } from '@tiptap/core';
2
2
  import { find, registerCustomProtocol, reset } from 'linkifyjs';
3
3
  import { Plugin, PluginKey } from '@tiptap/pm/state';
4
4
 
@@ -115,73 +115,29 @@ function pasteHandler(options) {
115
115
  key: new PluginKey('handlePasteLink'),
116
116
  props: {
117
117
  handlePaste: (view, event, slice) => {
118
- var _a, _b;
118
+ var _a;
119
119
  const { state } = view;
120
120
  const { selection } = state;
121
- // Do not proceed if in code block.
122
- if (state.doc.resolve(selection.from).parent.type.spec.code) {
121
+ const { empty } = selection;
122
+ if (empty) {
123
123
  return false;
124
124
  }
125
125
  let textContent = '';
126
126
  slice.content.forEach(node => {
127
127
  textContent += node.textContent;
128
128
  });
129
- let isAlreadyLink = false;
130
- slice.content.descendants(node => {
131
- if (node.marks.some(mark => mark.type.name === options.type.name)) {
132
- isAlreadyLink = true;
133
- }
134
- });
135
- if (isAlreadyLink) {
136
- return;
137
- }
138
129
  const link = find(textContent).find(item => item.isLink && item.value === textContent);
139
- if (!selection.empty && options.linkOnPaste) {
140
- const pastedLink = (link === null || link === void 0 ? void 0 : link.href) || null;
141
- if (pastedLink) {
142
- options.editor.commands.setMark(options.type, { href: pastedLink });
143
- return true;
144
- }
145
- }
146
- const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
147
- const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
148
- if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
130
+ if (!textContent || !link) {
149
131
  return false;
150
132
  }
151
- if (link && selection.empty) {
152
- options.editor.commands.insertContent(`<a href="${link.href}">${link.href}</a>`);
153
- return true;
154
- }
155
- const { tr } = state;
156
- let deleteOnly = false;
157
- if (!selection.empty) {
158
- deleteOnly = true;
159
- tr.delete(selection.from, selection.to);
160
- }
161
- let currentPos = selection.from;
162
- let fragmentLinks = [];
163
- slice.content.forEach(node => {
164
- fragmentLinks = find(node.textContent);
165
- tr.insert(currentPos - 1, node);
166
- if (fragmentLinks.length > 0) {
167
- deleteOnly = false;
168
- fragmentLinks.forEach(fragmentLink => {
169
- const linkStart = currentPos + fragmentLink.start;
170
- const linkEnd = currentPos + fragmentLink.end;
171
- const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type);
172
- if (!hasMark) {
173
- tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }));
174
- }
175
- });
176
- }
177
- currentPos += node.nodeSize;
133
+ const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
134
+ const hrefRegex = /href="([^"]*)"/;
135
+ const existingLink = html === null || html === void 0 ? void 0 : html.match(hrefRegex);
136
+ const url = existingLink ? existingLink[1] : link.href;
137
+ options.editor.commands.setMark(options.type, {
138
+ href: url,
178
139
  });
179
- const hasFragmentLinks = fragmentLinks.length > 0;
180
- if (tr.docChanged && !deleteOnly && hasFragmentLinks) {
181
- options.editor.view.dispatch(tr);
182
- return true;
183
- }
184
- return false;
140
+ return true;
185
141
  },
186
142
  },
187
143
  });
@@ -261,6 +217,40 @@ const Link = Mark.create({
261
217
  },
262
218
  };
263
219
  },
220
+ addPasteRules() {
221
+ return [
222
+ markPasteRule({
223
+ find: text => find(text)
224
+ .filter(link => {
225
+ if (this.options.validate) {
226
+ return this.options.validate(link.value);
227
+ }
228
+ return true;
229
+ })
230
+ .filter(link => link.isLink)
231
+ .map(link => ({
232
+ text: link.value,
233
+ index: link.start,
234
+ data: link,
235
+ })),
236
+ type: this.type,
237
+ getAttributes: (match, pasteEvent) => {
238
+ var _a, _b;
239
+ const html = (_a = pasteEvent === null || pasteEvent === void 0 ? void 0 : pasteEvent.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
240
+ const hrefRegex = /href="([^"]*)"/;
241
+ const existingLink = html === null || html === void 0 ? void 0 : html.match(hrefRegex);
242
+ if (existingLink) {
243
+ return {
244
+ href: existingLink[1],
245
+ };
246
+ }
247
+ return {
248
+ href: (_b = match.data) === null || _b === void 0 ? void 0 : _b.href,
249
+ };
250
+ },
251
+ }),
252
+ ];
253
+ },
264
254
  addProseMirrorPlugins() {
265
255
  const plugins = [];
266
256
  if (this.options.autolink) {
@@ -274,11 +264,12 @@ const Link = Mark.create({
274
264
  type: this.type,
275
265
  }));
276
266
  }
277
- plugins.push(pasteHandler({
278
- editor: this.editor,
279
- type: this.type,
280
- linkOnPaste: this.options.linkOnPaste,
281
- }));
267
+ if (this.options.linkOnPaste) {
268
+ plugins.push(pasteHandler({
269
+ editor: this.editor,
270
+ type: this.type,
271
+ }));
272
+ }
282
273
  return plugins;
283
274
  },
284
275
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const eventTarget = event.target as HTMLElement\n\n if (eventTarget.nodeName !== 'A') {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n let isAlreadyLink = false\n\n slice.content.descendants(node => {\n if (node.marks.some(mark => mark.type.name === options.type.name)) {\n isAlreadyLink = true\n }\n })\n\n if (isAlreadyLink) {\n return\n }\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const eventTarget = event.target as HTMLElement\n\n if (eventTarget.nodeName !== 'A') {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n const { empty } = selection\n\n if (empty) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n const html = event.clipboardData?.getData('text/html')\n\n const hrefRegex = /href=\"([^\"]*)\"/\n\n const existingLink = html?.match(hrefRegex)\n\n const url = existingLink ? existingLink[1] : link.href\n\n options.editor.commands.setMark(options.type, {\n href: url,\n })\n\n return true\n },\n },\n })\n}\n","import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { find, registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\n .filter(link => {\n if (this.options.validate) {\n return this.options.validate(link.value)\n }\n\n return true\n })\n .filter(link => link.isLink)\n .map(link => ({\n text: link.value,\n index: link.start,\n data: link,\n })),\n type: this.type,\n getAttributes: (match, pasteEvent) => {\n const html = pasteEvent?.clipboardData?.getData('text/html')\n const hrefRegex = /href=\"([^\"]*)\"/\n\n const existingLink = html?.match(hrefRegex)\n\n if (existingLink) {\n return {\n href: existingLink[1],\n }\n }\n\n return {\n href: match.data?.href,\n }\n },\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":[],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -117,73 +117,29 @@
117
117
  key: new state.PluginKey('handlePasteLink'),
118
118
  props: {
119
119
  handlePaste: (view, event, slice) => {
120
- var _a, _b;
120
+ var _a;
121
121
  const { state } = view;
122
122
  const { selection } = state;
123
- // Do not proceed if in code block.
124
- if (state.doc.resolve(selection.from).parent.type.spec.code) {
123
+ const { empty } = selection;
124
+ if (empty) {
125
125
  return false;
126
126
  }
127
127
  let textContent = '';
128
128
  slice.content.forEach(node => {
129
129
  textContent += node.textContent;
130
130
  });
131
- let isAlreadyLink = false;
132
- slice.content.descendants(node => {
133
- if (node.marks.some(mark => mark.type.name === options.type.name)) {
134
- isAlreadyLink = true;
135
- }
136
- });
137
- if (isAlreadyLink) {
138
- return;
139
- }
140
131
  const link = linkifyjs.find(textContent).find(item => item.isLink && item.value === textContent);
141
- if (!selection.empty && options.linkOnPaste) {
142
- const pastedLink = (link === null || link === void 0 ? void 0 : link.href) || null;
143
- if (pastedLink) {
144
- options.editor.commands.setMark(options.type, { href: pastedLink });
145
- return true;
146
- }
147
- }
148
- const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
149
- const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
150
- if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
132
+ if (!textContent || !link) {
151
133
  return false;
152
134
  }
153
- if (link && selection.empty) {
154
- options.editor.commands.insertContent(`<a href="${link.href}">${link.href}</a>`);
155
- return true;
156
- }
157
- const { tr } = state;
158
- let deleteOnly = false;
159
- if (!selection.empty) {
160
- deleteOnly = true;
161
- tr.delete(selection.from, selection.to);
162
- }
163
- let currentPos = selection.from;
164
- let fragmentLinks = [];
165
- slice.content.forEach(node => {
166
- fragmentLinks = linkifyjs.find(node.textContent);
167
- tr.insert(currentPos - 1, node);
168
- if (fragmentLinks.length > 0) {
169
- deleteOnly = false;
170
- fragmentLinks.forEach(fragmentLink => {
171
- const linkStart = currentPos + fragmentLink.start;
172
- const linkEnd = currentPos + fragmentLink.end;
173
- const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type);
174
- if (!hasMark) {
175
- tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }));
176
- }
177
- });
178
- }
179
- currentPos += node.nodeSize;
135
+ const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
136
+ const hrefRegex = /href="([^"]*)"/;
137
+ const existingLink = html === null || html === void 0 ? void 0 : html.match(hrefRegex);
138
+ const url = existingLink ? existingLink[1] : link.href;
139
+ options.editor.commands.setMark(options.type, {
140
+ href: url,
180
141
  });
181
- const hasFragmentLinks = fragmentLinks.length > 0;
182
- if (tr.docChanged && !deleteOnly && hasFragmentLinks) {
183
- options.editor.view.dispatch(tr);
184
- return true;
185
- }
186
- return false;
142
+ return true;
187
143
  },
188
144
  },
189
145
  });
@@ -263,6 +219,40 @@
263
219
  },
264
220
  };
265
221
  },
222
+ addPasteRules() {
223
+ return [
224
+ core.markPasteRule({
225
+ find: text => linkifyjs.find(text)
226
+ .filter(link => {
227
+ if (this.options.validate) {
228
+ return this.options.validate(link.value);
229
+ }
230
+ return true;
231
+ })
232
+ .filter(link => link.isLink)
233
+ .map(link => ({
234
+ text: link.value,
235
+ index: link.start,
236
+ data: link,
237
+ })),
238
+ type: this.type,
239
+ getAttributes: (match, pasteEvent) => {
240
+ var _a, _b;
241
+ const html = (_a = pasteEvent === null || pasteEvent === void 0 ? void 0 : pasteEvent.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
242
+ const hrefRegex = /href="([^"]*)"/;
243
+ const existingLink = html === null || html === void 0 ? void 0 : html.match(hrefRegex);
244
+ if (existingLink) {
245
+ return {
246
+ href: existingLink[1],
247
+ };
248
+ }
249
+ return {
250
+ href: (_b = match.data) === null || _b === void 0 ? void 0 : _b.href,
251
+ };
252
+ },
253
+ }),
254
+ ];
255
+ },
266
256
  addProseMirrorPlugins() {
267
257
  const plugins = [];
268
258
  if (this.options.autolink) {
@@ -276,11 +266,12 @@
276
266
  type: this.type,
277
267
  }));
278
268
  }
279
- plugins.push(pasteHandler({
280
- editor: this.editor,
281
- type: this.type,
282
- linkOnPaste: this.options.linkOnPaste,
283
- }));
269
+ if (this.options.linkOnPaste) {
270
+ plugins.push(pasteHandler({
271
+ editor: this.editor,
272
+ type: this.type,
273
+ }));
274
+ }
284
275
  return plugins;
285
276
  },
286
277
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const eventTarget = event.target as HTMLElement\n\n if (eventTarget.nodeName !== 'A') {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n let isAlreadyLink = false\n\n slice.content.descendants(node => {\n if (node.marks.some(mark => mark.type.name === options.type.name)) {\n isAlreadyLink = true\n }\n })\n\n if (isAlreadyLink) {\n return\n }\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","find","getMarksBetween","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n if (!newState.schema.marks.code) {\n return true\n }\n\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const eventTarget = event.target as HTMLElement\n\n if (eventTarget.nodeName !== 'A') {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n const { empty } = selection\n\n if (empty) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n const html = event.clipboardData?.getData('text/html')\n\n const hrefRegex = /href=\"([^\"]*)\"/\n\n const existingLink = html?.match(hrefRegex)\n\n const url = existingLink ? existingLink[1] : link.href\n\n options.editor.commands.setMark(options.type, {\n href: url,\n })\n\n return true\n },\n },\n })\n}\n","import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { find, registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\n .filter(link => {\n if (this.options.validate) {\n return this.options.validate(link.value)\n }\n\n return true\n })\n .filter(link => link.isLink)\n .map(link => ({\n text: link.value,\n index: link.start,\n data: link,\n })),\n type: this.type,\n getAttributes: (match, pasteEvent) => {\n const html = pasteEvent?.clipboardData?.getData('text/html')\n const hrefRegex = /href=\"([^\"]*)\"/\n\n const existingLink = html?.match(hrefRegex)\n\n if (existingLink) {\n return {\n href: existingLink[1],\n }\n }\n\n return {\n href: match.data?.href,\n }\n },\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","find","getMarksBetween","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes","markPasteRule"],"mappings":"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"}
@@ -4,7 +4,6 @@ import { Plugin } from '@tiptap/pm/state';
4
4
  declare type PasteHandlerOptions = {
5
5
  editor: Editor;
6
6
  type: MarkType;
7
- linkOnPaste?: boolean;
8
7
  };
9
8
  export declare function pasteHandler(options: PasteHandlerOptions): Plugin;
10
9
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-link",
3
3
  "description": "link extension for tiptap",
4
- "version": "2.1.10",
4
+ "version": "2.1.12",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -32,8 +32,8 @@
32
32
  "linkifyjs": "^4.1.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@tiptap/core": "^2.1.10",
36
- "@tiptap/pm": "^2.1.10"
35
+ "@tiptap/core": "^2.1.12",
36
+ "@tiptap/pm": "^2.1.12"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@tiptap/core": "^2.0.0",
@@ -6,7 +6,6 @@ import { find } from 'linkifyjs'
6
6
  type PasteHandlerOptions = {
7
7
  editor: Editor
8
8
  type: MarkType
9
- linkOnPaste?: boolean
10
9
  }
11
10
 
12
11
  export function pasteHandler(options: PasteHandlerOptions): Plugin {
@@ -16,9 +15,9 @@ export function pasteHandler(options: PasteHandlerOptions): Plugin {
16
15
  handlePaste: (view, event, slice) => {
17
16
  const { state } = view
18
17
  const { selection } = state
18
+ const { empty } = selection
19
19
 
20
- // Do not proceed if in code block.
21
- if (state.doc.resolve(selection.from).parent.type.spec.code) {
20
+ if (empty) {
22
21
  return false
23
22
  }
24
23
 
@@ -28,86 +27,25 @@ export function pasteHandler(options: PasteHandlerOptions): Plugin {
28
27
  textContent += node.textContent
29
28
  })
30
29
 
31
- let isAlreadyLink = false
32
-
33
- slice.content.descendants(node => {
34
- if (node.marks.some(mark => mark.type.name === options.type.name)) {
35
- isAlreadyLink = true
36
- }
37
- })
38
-
39
- if (isAlreadyLink) {
40
- return
41
- }
42
-
43
30
  const link = find(textContent).find(item => item.isLink && item.value === textContent)
44
31
 
45
- if (!selection.empty && options.linkOnPaste) {
46
- const pastedLink = link?.href || null
47
-
48
- if (pastedLink) {
49
- options.editor.commands.setMark(options.type, { href: pastedLink })
50
-
51
- return true
52
- }
53
- }
54
-
55
- const firstChildIsText = slice.content.firstChild?.type.name === 'text'
56
- const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)
57
-
58
- if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
32
+ if (!textContent || !link) {
59
33
  return false
60
34
  }
61
35
 
62
- if (link && selection.empty) {
63
- options.editor.commands.insertContent(`<a href="${link.href}">${link.href}</a>`)
64
-
65
- return true
66
- }
67
-
68
- const { tr } = state
69
- let deleteOnly = false
70
-
71
- if (!selection.empty) {
72
- deleteOnly = true
73
-
74
- tr.delete(selection.from, selection.to)
75
- }
76
-
77
- let currentPos = selection.from
78
- let fragmentLinks = []
79
-
80
- slice.content.forEach(node => {
81
- fragmentLinks = find(node.textContent)
82
-
83
- tr.insert(currentPos - 1, node)
36
+ const html = event.clipboardData?.getData('text/html')
84
37
 
85
- if (fragmentLinks.length > 0) {
86
- deleteOnly = false
38
+ const hrefRegex = /href="([^"]*)"/
87
39
 
88
- fragmentLinks.forEach(fragmentLink => {
89
- const linkStart = currentPos + fragmentLink.start
90
- const linkEnd = currentPos + fragmentLink.end
91
- const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)
40
+ const existingLink = html?.match(hrefRegex)
92
41
 
93
- if (!hasMark) {
94
- tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))
95
- }
96
- })
42
+ const url = existingLink ? existingLink[1] : link.href
97
43
 
98
- }
99
- currentPos += node.nodeSize
44
+ options.editor.commands.setMark(options.type, {
45
+ href: url,
100
46
  })
101
47
 
102
- const hasFragmentLinks = fragmentLinks.length > 0
103
-
104
- if (tr.docChanged && !deleteOnly && hasFragmentLinks) {
105
- options.editor.view.dispatch(tr)
106
-
107
- return true
108
- }
109
-
110
- return false
48
+ return true
111
49
  },
112
50
  },
113
51
  })
package/src/link.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { Mark, mergeAttributes } from '@tiptap/core'
1
+ import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'
2
2
  import { Plugin } from '@tiptap/pm/state'
3
- import { registerCustomProtocol, reset } from 'linkifyjs'
3
+ import { find, registerCustomProtocol, reset } from 'linkifyjs'
4
4
 
5
5
  import { autolink } from './helpers/autolink.js'
6
6
  import { clickHandler } from './helpers/clickHandler.js'
@@ -149,6 +149,44 @@ export const Link = Mark.create<LinkOptions>({
149
149
  }
150
150
  },
151
151
 
152
+ addPasteRules() {
153
+ return [
154
+ markPasteRule({
155
+ find: text => find(text)
156
+ .filter(link => {
157
+ if (this.options.validate) {
158
+ return this.options.validate(link.value)
159
+ }
160
+
161
+ return true
162
+ })
163
+ .filter(link => link.isLink)
164
+ .map(link => ({
165
+ text: link.value,
166
+ index: link.start,
167
+ data: link,
168
+ })),
169
+ type: this.type,
170
+ getAttributes: (match, pasteEvent) => {
171
+ const html = pasteEvent?.clipboardData?.getData('text/html')
172
+ const hrefRegex = /href="([^"]*)"/
173
+
174
+ const existingLink = html?.match(hrefRegex)
175
+
176
+ if (existingLink) {
177
+ return {
178
+ href: existingLink[1],
179
+ }
180
+ }
181
+
182
+ return {
183
+ href: match.data?.href,
184
+ }
185
+ },
186
+ }),
187
+ ]
188
+ },
189
+
152
190
  addProseMirrorPlugins() {
153
191
  const plugins: Plugin[] = []
154
192
 
@@ -169,13 +207,14 @@ export const Link = Mark.create<LinkOptions>({
169
207
  )
170
208
  }
171
209
 
172
- plugins.push(
173
- pasteHandler({
174
- editor: this.editor,
175
- type: this.type,
176
- linkOnPaste: this.options.linkOnPaste,
177
- }),
178
- )
210
+ if (this.options.linkOnPaste) {
211
+ plugins.push(
212
+ pasteHandler({
213
+ editor: this.editor,
214
+ type: this.type,
215
+ }),
216
+ )
217
+ }
179
218
 
180
219
  return plugins
181
220
  },