{"version":3,"file":"index.cjs","names":["getMarksBetween","Plugin","PluginKey","combineTransactionSteps","isHistoryTransaction","ReplaceStep","getChangedRanges","findChildrenInRange","tokenize","getMarksBetween","Plugin","PluginKey","getAttributes","markInputRule","InputRule","markPasteRule","PasteRule","Plugin","PluginKey","find","Mark","mergeAttributes","find","markPasteRule"],"sources":["../src/helpers/whitespace.ts","../src/helpers/unlinkTrailingWhitespace.ts","../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/markdownLink.ts","../src/helpers/pasteHandler.ts","../src/link.ts","../src/index.ts"],"sourcesContent":["// From DOMPurify\n// https://github.com/cure53/DOMPurify/blob/main/src/regexp.ts\nconst UNICODE_WHITESPACE_PATTERN = '[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]'\n\nexport const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN)\nexport const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`)\nexport const UNICODE_WHITESPACE_REGEX_TRAILING = new RegExp(`${UNICODE_WHITESPACE_PATTERN}+$`)\nexport const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, 'g')\n","import type { Range } from '@tiptap/core'\nimport { getMarksBetween } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\nimport type { Transaction } from '@tiptap/pm/state'\n\nimport { UNICODE_WHITESPACE_REGEX_TRAILING } from './whitespace.js'\n\nexport function unlinkTrailingWhitespace(tr: Transaction, range: Range, type: MarkType) {\n const rangeEnd = tr.doc.resolve(range.to)\n\n if (!rangeEnd.nodeBefore?.isText) {\n return\n }\n\n // Keep inline atoms from being mistaken for whitespace.\n const insertedText = tr.doc.textBetween(range.from, range.to, '\\uFFFC', '\\uFFFC')\n const trailingWhitespace = insertedText.match(UNICODE_WHITESPACE_REGEX_TRAILING)?.[0]\n\n if (!trailingWhitespace) {\n return\n }\n\n const whitespaceFrom = range.to - trailingWhitespace.length\n const linkMarks = getMarksBetween(whitespaceFrom, range.to, tr.doc).filter(\n item => item.mark.type === type,\n )\n\n if (!linkMarks.length) {\n return\n }\n\n const { nodeAfter } = rangeEnd\n const linkContinues = !!nodeAfter && linkMarks.some(item => item.mark.isInSet(nodeAfter.marks))\n\n if (linkContinues) {\n return\n }\n\n const storedMarks = tr.storedMarks\n tr.removeMark(whitespaceFrom, range.to, type)\n tr.setStoredMarks(storedMarks)\n\n if (tr.selection.empty && tr.selection.from === range.to) {\n tr.removeStoredMark(type)\n }\n}\n","import type { NodeWithPos, Range } from '@tiptap/core'\nimport {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n} from '@tiptap/core'\nimport { isHistoryTransaction } from '@tiptap/pm/history'\nimport type { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { ReplaceStep } from '@tiptap/pm/transform'\nimport type { MultiToken } from 'linkifyjs'\nimport { tokenize } from 'linkifyjs'\n\nimport { unlinkTrailingWhitespace } from './unlinkTrailingWhitespace.js'\nimport { UNICODE_WHITESPACE_REGEX, UNICODE_WHITESPACE_REGEX_END } from './whitespace.js'\n\n/**\n * Check if the provided tokens form a valid link structure, which can either be a single link token\n * or a link token surrounded by parentheses or square brackets.\n *\n * This ensures that only complete and valid text is hyperlinked, preventing cases where a valid\n * top-level domain (TLD) is immediately followed by an invalid character, like a number. For\n * example, with the `find` method from Linkify, entering `example.com1` would result in\n * `example.com` being linked and the trailing `1` left as plain text. By using the `tokenize`\n * method, we can perform more comprehensive validation on the input text.\n */\nfunction isValidLinkStructure(tokens: Array>) {\n if (tokens.length === 1) {\n return tokens[0].isLink\n }\n\n if (tokens.length === 3 && tokens[1].isLink) {\n return ['()', '[]'].includes(tokens[0].value + tokens[2].value)\n }\n\n return false\n}\n\ntype AutolinkOptions = {\n type: MarkType\n defaultProtocol: string\n validate: (url: string) => boolean\n shouldAutoLink: (url: string) => boolean\n}\n\n/**\n * This plugin allows you to automatically add links to your editor.\n * @param options The plugin options\n * @returns The plugin instance\n */\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n /**\n * Does the transaction change the document?\n */\n const docChanges =\n transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n\n /**\n * Prevent autolink if the transaction is not a document change or if the transaction has the meta `preventAutolink`.\n */\n const preventAutolink = transactions.some(transaction =>\n transaction.getMeta('preventAutolink'),\n )\n\n /**\n * Prevent autolink if the transaction is not a document change\n * or if the transaction has the meta `preventAutolink`.\n */\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n if (!transactions.some(isHistoryTransaction)) {\n const insertedRanges: Range[] = []\n\n transform.steps.forEach((step, index) => {\n if (!(step instanceof ReplaceStep) || !step.slice.size) {\n return\n }\n\n const mapping = transform.mapping.slice(index + 1)\n const from = mapping.map(step.from, 1)\n const to = mapping.map(step.from + step.slice.size, -1)\n\n if (from < to) {\n insertedRanges.push({ from, to })\n }\n })\n\n // Unlink later spaces before checking whether earlier spaces end a link.\n insertedRanges.sort((left, right) => right.to - left.to)\n insertedRanges.forEach(range => unlinkTrailingWhitespace(tr, range, options.type))\n }\n\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 (nodesInChangedRanges.length) {\n const endText = newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ')\n if (!UNICODE_WHITESPACE_REGEX_END.test(endText)) {\n return\n }\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\n .split(UNICODE_WHITESPACE_REGEX)\n .filter(Boolean)\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset =\n textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t =>\n t.toObject(options.defaultProtocol),\n )\n\n if (!isValidLinkStructure(linksBeforeSpace)) {\n return false\n }\n\n linksBeforeSpace\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(link.from, link.to, newState.schema.marks.code)\n })\n // validate link\n .filter(link => options.validate(link.value))\n // check whether should autolink\n .filter(link => options.shouldAutoLink(link.value))\n // Add link mark.\n .forEach(link => {\n if (\n getMarksBetween(link.from, link.to, newState.doc).some(\n item => item.mark.type === options.type,\n )\n ) {\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 type { Editor } from '@tiptap/core'\nimport { getAttributes } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n editor: Editor\n openOnClick?: boolean\n enableClickSelection?: boolean\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 if (!view.editable) {\n return false\n }\n\n let link: HTMLAnchorElement | null = null\n\n if (event.target instanceof HTMLAnchorElement) {\n link = event.target\n } else {\n const target = event.target as HTMLElement | null\n if (!target) {\n return false\n }\n\n const root = options.editor.view.dom\n\n // Tntentionally limit the lookup to the editor root.\n // Using tag names like DIV as boundaries breaks with custom NodeViews,\n link = target.closest('a')\n\n if (link && !root.contains(link)) {\n link = null\n }\n }\n\n if (!link) {\n return false\n }\n\n let handled = false\n\n if (options.enableClickSelection) {\n const commandResult = options.editor.commands.extendMarkRange(options.type.name)\n handled = commandResult\n }\n\n if (options.openOnClick) {\n const attrs = getAttributes(view.state, options.type.name)\n const href = link.href ?? attrs.href\n const target = link.target ?? attrs.target\n\n if (href) {\n window.open(href, target)\n handled = true\n }\n }\n\n return handled\n },\n },\n })\n}\n","import type { InputRuleMatch, PasteRuleMatch } from '@tiptap/core'\nimport { InputRule, markInputRule, markPasteRule, PasteRule } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\n\n/**\n * Matches a Markdown link with an optional quoted title.\n * for ex: [Tiptap](https://tiptap.dev) or [Tiptap](https://tiptap.dev \"some title\")\n * the URL may also contain one level of balanced parentheses, as in CommonMark\n * (titles accept curly quotes too, the Typography extension swaps them in while typing)\n * the title delimiters must come in matching pairs\n */\nconst MARKDOWN_LINK_INPUT_REGEX =\n /\\[([^[\\]]+)\\]\\(((?:[^\\s()]|\\([^\\s()]*\\))+)(?:\\s+(?:([\"'])(.*?)\\3|“(.*?)”|‘(.*?)’))?\\)$/\n\n/**\n * Same as the input regex but global, to find every Markdown link in pasted text.\n */\nconst MARKDOWN_LINK_PASTE_REGEX =\n /\\[([^[\\]]+)\\]\\(((?:[^\\s()]|\\([^\\s()]*\\))+)(?:\\s+(?:([\"'])(.*?)\\3|“(.*?)”|‘(.*?)’))?\\)/g\n\nexport interface MarkdownLinkRuleConfig {\n type: MarkType\n\n /**\n * Return `false` to leave the Markdown syntax untouched.\n */\n isAllowedHref: (href: string) => boolean\n}\n\nexport interface MarkdownLinkPasteRuleConfig extends MarkdownLinkRuleConfig {\n /**\n * Finds plain URLs to link in the same pass. Matches overlapping a\n * converted Markdown link are dropped so its href is kept.\n */\n findPlainUrls?: (text: string) => PasteRuleMatch[]\n}\n\nfunction isEscaped(text: string, index: number): boolean {\n let backslashes = 0\n\n for (let position = index - 1; position >= 0 && text[position] === '\\\\'; position -= 1) {\n backslashes += 1\n }\n\n return backslashes % 2 === 1\n}\n\n/**\n * Pairs the backtick runs before the match by length, as CommonMark does.\n * A run left open means the match sits in an unfinished code span.\n */\nfunction isInsideCodeSpan(text: string, matchIndex: number): boolean {\n let openRunLength = 0\n let index = 0\n\n while (index < matchIndex) {\n if (text[index] !== '`') {\n index += 1\n continue\n }\n\n // escapes only apply outside code spans\n if (openRunLength === 0 && isEscaped(text, index)) {\n index += 1\n continue\n }\n\n let runLength = 0\n\n while (index < matchIndex && text[index] === '`') {\n runLength += 1\n index += 1\n }\n\n if (openRunLength === 0) {\n openRunLength = runLength\n } else if (runLength === openRunLength) {\n openRunLength = 0\n }\n }\n\n return openRunLength > 0\n}\n\nfunction isConvertibleLink(\n text: string,\n match: RegExpMatchArray,\n isAllowedHref: MarkdownLinkRuleConfig['isAllowedHref'],\n): boolean {\n const [, linkText, href] = match\n const characterBefore = match.index ? text[match.index - 1] : undefined\n\n // `!` is the Markdown image syntax, `\\` may escape the opening bracket\n if (characterBefore === '!' || isEscaped(text, match.index ?? 0)) {\n return false\n }\n\n if (isInsideCodeSpan(text, match.index ?? 0)) {\n return false\n }\n\n return !!linkText.trim() && isAllowedHref(href)\n}\n\nfunction toRuleMatch(match: RegExpMatchArray): InputRuleMatch & PasteRuleMatch {\n const [linkSyntax, linkText, href, , straightQuotedTitle, curlyDoubleTitle, curlySingleTitle] =\n match\n const title = straightQuotedTitle ?? curlyDoubleTitle ?? curlySingleTitle\n\n return {\n index: match.index ?? 0,\n text: linkSyntax,\n replaceWith: linkText,\n data: {\n href,\n // an empty title (\"\") counts as no title, as in CommonMark\n title: title || null,\n markdown: true,\n },\n }\n}\n\nfunction matchesOverlap(a: PasteRuleMatch, b: PasteRuleMatch): boolean {\n return a.index < b.index + b.text.length && b.index < a.index + a.text.length\n}\n\nfunction getMarkdownLinkAttributes(match: { data?: Record }) {\n return {\n href: match.data?.href,\n title: match.data?.title ?? null,\n }\n}\n\n/**\n * Turns typed Markdown link syntax into a link mark as soon as the closing `)` comes in.\n * The transaction gets flagged so autolink doesn't touch the converted text again.\n */\nexport function markdownLinkInputRule(config: MarkdownLinkRuleConfig): InputRule {\n const rule = markInputRule({\n find: text => {\n const match = MARKDOWN_LINK_INPUT_REGEX.exec(text)\n\n if (!match || !isConvertibleLink(text, match, config.isAllowedHref)) {\n return null\n }\n\n return toRuleMatch(match)\n },\n type: config.type,\n getAttributes: getMarkdownLinkAttributes,\n })\n\n return new InputRule({\n find: rule.find,\n handler: props => {\n const result = rule.handler(props)\n\n if (result !== null && props.state.tr.steps.length) {\n props.state.tr.setMeta('preventAutolink', true)\n }\n\n return result\n },\n })\n}\n\n/**\n * Same for pasting, converts every Markdown link found in the pasted text\n * and links the plain URLs from `findPlainUrls`.\n */\nexport function markdownLinkPasteRule(config: MarkdownLinkPasteRuleConfig): PasteRule {\n const rule = markPasteRule({\n find: text => {\n const markdownMatches: PasteRuleMatch[] = []\n\n for (const match of text.matchAll(MARKDOWN_LINK_PASTE_REGEX)) {\n if (isConvertibleLink(text, match, config.isAllowedHref)) {\n markdownMatches.push(toRuleMatch(match))\n }\n }\n\n const plainUrlMatches = (config.findPlainUrls?.(text) ?? []).filter(\n urlMatch => !markdownMatches.some(markdownMatch => matchesOverlap(markdownMatch, urlMatch)),\n )\n\n return [...markdownMatches, ...plainUrlMatches]\n },\n type: config.type,\n getAttributes: getMarkdownLinkAttributes,\n })\n\n return new PasteRule({\n find: rule.find,\n handler: props => {\n const result = rule.handler(props)\n\n // only Markdown conversions suppress autolink\n if (result !== null && props.state.tr.steps.length && props.match.data?.markdown) {\n props.state.tr.setMeta('preventAutolink', true)\n }\n\n return result\n },\n })\n}\n","import type { Editor } from '@tiptap/core'\nimport type { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\nimport type { LinkOptions } from '../link.js'\n\ntype PasteHandlerOptions = {\n editor: Editor\n defaultProtocol: string\n type: MarkType\n shouldAutoLink?: LinkOptions['shouldAutoLink']\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 { shouldAutoLink } = options\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, { defaultProtocol: options.defaultProtocol }).find(\n item => item.isLink && item.value === textContent,\n )\n\n if (\n !textContent ||\n !link ||\n (shouldAutoLink !== undefined && !shouldAutoLink(link.value))\n ) {\n return false\n }\n\n return options.editor.commands.setMark(options.type, {\n href: link.href,\n })\n },\n },\n })\n}\n","import type { PasteRuleMatch } from '@tiptap/core'\nimport { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport type { 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 { markdownLinkInputRule, markdownLinkPasteRule } from './helpers/markdownLink.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\nimport { UNICODE_WHITESPACE_REGEX_GLOBAL } from './helpers/whitespace.js'\n\nexport interface LinkProtocolOptions {\n /**\n * The protocol scheme to be registered.\n * @default '''\n * @example 'ftp'\n * @example 'git'\n */\n scheme: string\n\n /**\n * If enabled, it allows optional slashes after the protocol.\n * @default false\n * @example true\n */\n optionalSlashes?: boolean\n}\n\nexport const pasteRegex =\n /https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z]{2,}\\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi\n\n/**\n * @deprecated The default behavior is now to open links when the editor is not editable.\n */\ntype DeprecatedOpenWhenNotEditable = 'whenNotEditable'\n\nexport interface LinkOptions {\n /**\n * If enabled, the extension will automatically add links as you type.\n * @default true\n * @example false\n */\n autolink: boolean\n\n /**\n * An array of custom protocols to be registered with linkifyjs.\n * @default []\n * @example ['ftp', 'git']\n */\n protocols: Array\n\n /**\n * Default protocol to use when no protocol is specified.\n * @default 'http'\n */\n defaultProtocol: string\n /**\n * If enabled, links will be opened on click.\n * @default true\n * @example false\n */\n openOnClick: boolean | DeprecatedOpenWhenNotEditable\n /**\n * If enabled, the link will be selected when clicked.\n * @default false\n * @example true\n */\n enableClickSelection: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n * @default true\n * @example false\n */\n linkOnPaste: boolean\n\n /**\n * If enabled, typing or pasting the Markdown link syntax, e.g. `[Tiptap](https://tiptap.dev)`\n * or `[Tiptap](https://tiptap.dev \"Rich text editor\")`, converts it into a link.\n * @default false\n * @example true\n */\n markdownLinks: boolean\n\n /**\n * HTML attributes to add to the link element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record\n\n /**\n * @deprecated Use the `shouldAutoLink` option instead.\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 /**\n * A validation function which is used for configuring link verification for preventing XSS attacks.\n * Only modify this if you know what you're doing.\n *\n * @returns {boolean} `true` if the URL is valid, `false` otherwise.\n *\n * @example\n * isAllowedUri: (url, { defaultValidate, protocols, defaultProtocol }) => {\n * return url.startsWith('./') || defaultValidate(url)\n * }\n */\n isAllowedUri: (\n /**\n * The URL to be validated.\n */\n url: string,\n ctx: {\n /**\n * The default validation function.\n */\n defaultValidate: (url: string) => boolean\n /**\n * An array of allowed protocols for the URL (e.g., \"http\", \"https\"). As defined in the `protocols` option.\n */\n protocols: Array\n /**\n * A string that represents the default protocol (e.g., 'http'). As defined in the `defaultProtocol` option.\n */\n defaultProtocol: string\n },\n ) => boolean\n\n /**\n * Determines whether a valid link should be automatically linked in the content.\n *\n * @param {string} url - The URL that has already been validated.\n * @returns {boolean} - True if the link should be auto-linked; false if it should not be auto-linked.\n */\n shouldAutoLink: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands {\n link: {\n /**\n * Set a link mark\n * @param attributes The link attributes\n * @example editor.commands.setLink({ href: 'https://tiptap.dev' })\n */\n setLink: (attributes: {\n href: string\n target?: string | null\n rel?: string | null\n class?: string | null\n title?: string | null\n }) => ReturnType\n /**\n * Toggle a link mark\n * @param attributes The link attributes\n * @example editor.commands.toggleLink({ href: 'https://tiptap.dev' })\n */\n toggleLink: (attributes?: {\n href: string\n target?: string | null\n rel?: string | null\n class?: string | null\n title?: string | null\n }) => ReturnType\n /**\n * Unset a link mark\n * @example editor.commands.unsetLink()\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport function isAllowedUri(uri: string | undefined, protocols?: LinkOptions['protocols']) {\n const allowedProtocols: string[] = [\n 'http',\n 'https',\n 'ftp',\n 'ftps',\n 'mailto',\n 'tel',\n 'callto',\n 'sms',\n 'cid',\n 'xmpp',\n ]\n\n if (protocols) {\n protocols.forEach(protocol => {\n const nextProtocol = typeof protocol === 'string' ? protocol : protocol.scheme\n\n if (nextProtocol) {\n allowedProtocols.push(nextProtocol)\n }\n })\n }\n\n return (\n !uri ||\n uri\n .replace(UNICODE_WHITESPACE_REGEX_GLOBAL, '')\n .match(\n new RegExp(\n `^(?:(?:${allowedProtocols\n .map(protocol => protocol.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&'))\n .join('|')}):|[^a-z]|[a-z0-9+.\\\\-]+(?:[^a-z+.\\\\-:]|$))`,\n 'i',\n ),\n )\n )\n}\n\n/**\n * This extension allows you to create links.\n * @see https://www.tiptap.dev/api/marks/link\n */\nexport const Link = Mark.create({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n exitable: true,\n\n onCreate() {\n // TODO: v4 - remove validate option\n if (this.options.validate && !this.options.shouldAutoLink) {\n // Copy the validate function to the shouldAutoLink option\n this.options.shouldAutoLink = this.options.validate\n console.warn(\n 'The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.',\n )\n }\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 enableClickSelection: false,\n linkOnPaste: true,\n markdownLinks: false, // TODO (major) - default to true on next major version\n autolink: true,\n protocols: [],\n defaultProtocol: 'http',\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n isAllowedUri: (url, ctx) => !!isAllowedUri(url, ctx.protocols),\n validate: url => !!url,\n shouldAutoLink: url => {\n // URLs with explicit protocols (e.g., https://) should be auto-linked\n // But not if @ appears before :// (that would be userinfo like user:pass@host)\n const hasProtocol = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(url)\n const hasMaybeProtocol = /^[a-z][a-z0-9+.-]*:/i.test(url)\n\n if (hasProtocol || (hasMaybeProtocol && !url.includes('@'))) {\n return true\n }\n // Strip userinfo (user:pass@) if present, then extract hostname\n const urlWithoutUserinfo = url.includes('@') ? url.split('@').pop()! : url\n const hostname = urlWithoutUserinfo.split(/[/?#:]/)[0]\n\n // Don't auto-link IP addresses without protocol\n if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(hostname)) {\n return false\n }\n // Don't auto-link single-word hostnames without TLD (e.g., \"localhost\")\n if (!/\\./.test(hostname)) {\n return false\n }\n return true\n },\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n parseHTML(element) {\n return element.getAttribute('href')\n },\n },\n target: {\n // Coerce `undefined` to `null` because `undefined` is an invalid attribute value\n default: this.options.HTMLAttributes.target ?? null,\n },\n rel: {\n // Coerce `undefined` to `null` because `undefined` is an invalid attribute value\n default: this.options.HTMLAttributes.rel ?? null,\n },\n class: {\n // Coerce `undefined` to `null` because `undefined` is an invalid attribute value\n default: this.options.HTMLAttributes.class ?? null,\n },\n title: {\n default: null,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[href]',\n getAttrs: dom => {\n const href = (dom as HTMLElement).getAttribute('href')\n\n // prevent XSS attacks\n if (\n !href ||\n !this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n return false\n }\n return null\n },\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n // prevent XSS attacks\n if (\n !this.options.isAllowedUri(HTMLAttributes.href, {\n defaultValidate: href => !!isAllowedUri(href, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n // strip out the href\n return ['a', mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: '' }), 0]\n }\n\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n markdownTokenName: 'link',\n\n parseMarkdown: (token, helpers) => {\n return helpers.applyMark('link', helpers.parseInline(token.tokens || []), {\n href: token.href,\n title: token.title || null,\n })\n },\n\n renderMarkdown: (node, h) => {\n const href = node.attrs?.href ?? ''\n const title = node.attrs?.title ?? ''\n const text = h.renderChildren(node)\n\n return title ? `[${text}](${href} \"${title}\")` : `[${text}](${href})`\n },\n\n addCommands() {\n return {\n setLink:\n attributes =>\n ({ chain }) => {\n const { href } = attributes\n\n if (\n !this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n return false\n }\n\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes =>\n ({ chain }) => {\n const { href } = attributes || {}\n\n if (\n href &&\n !this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n })\n ) {\n return false\n }\n\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () =>\n ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addInputRules() {\n if (!this.options.markdownLinks) {\n return []\n }\n\n return [\n markdownLinkInputRule({\n type: this.type,\n isAllowedHref: href =>\n this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n }),\n }),\n ]\n },\n\n addPasteRules() {\n const findPlainUrls = (text: string): PasteRuleMatch[] => {\n const foundLinks: PasteRuleMatch[] = []\n\n if (text) {\n const { protocols, defaultProtocol } = this.options\n const links = find(text).filter(\n item =>\n item.isLink &&\n this.options.isAllowedUri(item.value, {\n defaultValidate: href => !!isAllowedUri(href, protocols),\n protocols,\n defaultProtocol,\n }),\n )\n\n links.forEach(link => {\n if (!this.options.shouldAutoLink(link.value)) {\n return\n }\n\n foundLinks.push({\n text: link.value,\n data: {\n href: link.href,\n },\n index: link.start,\n })\n })\n }\n\n return foundLinks\n }\n\n if (this.options.markdownLinks) {\n return [\n markdownLinkPasteRule({\n type: this.type,\n isAllowedHref: href =>\n this.options.isAllowedUri(href, {\n defaultValidate: url => !!isAllowedUri(url, this.options.protocols),\n protocols: this.options.protocols,\n defaultProtocol: this.options.defaultProtocol,\n }),\n findPlainUrls,\n }),\n ]\n }\n\n return [\n markPasteRule({\n find: findPlainUrls,\n type: this.type,\n getAttributes: match => {\n return {\n href: match.data?.href,\n }\n },\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n const { protocols, defaultProtocol } = this.options\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n defaultProtocol: this.options.defaultProtocol,\n validate: url =>\n this.options.isAllowedUri(url, {\n defaultValidate: href => !!isAllowedUri(href, protocols),\n protocols,\n defaultProtocol,\n }),\n shouldAutoLink: this.options.shouldAutoLink,\n }),\n )\n }\n\n plugins.push(\n clickHandler({\n type: this.type,\n editor: this.editor,\n openOnClick:\n this.options.openOnClick === 'whenNotEditable' ? true : this.options.openOnClick,\n enableClickSelection: this.options.enableClickSelection,\n }),\n )\n\n if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n defaultProtocol: this.options.defaultProtocol,\n type: this.type,\n shouldAutoLink: this.options.shouldAutoLink,\n }),\n )\n }\n\n return plugins\n },\n})\n","import { Link } from './link.js'\n\nexport * from './link.js'\n\nexport default Link\n"],"mappings":"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"}