@tiptap/extension-link 2.6.2 → 3.0.0-next.1
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 +338 -325
- package/dist/index.cjs.map +1 -1
- package/dist/{packages/extension-link/src/link.d.ts → index.d.cts} +7 -5
- package/dist/index.d.ts +105 -0
- package/dist/index.js +321 -321
- package/dist/index.js.map +1 -1
- package/package.json +8 -10
- package/dist/index.umd.js +0 -350
- package/dist/index.umd.js.map +0 -1
- package/dist/packages/core/src/CommandManager.d.ts +0 -20
- package/dist/packages/core/src/Editor.d.ts +0 -163
- package/dist/packages/core/src/EventEmitter.d.ts +0 -11
- package/dist/packages/core/src/Extension.d.ts +0 -344
- package/dist/packages/core/src/ExtensionManager.d.ts +0 -55
- package/dist/packages/core/src/InputRule.d.ts +0 -42
- package/dist/packages/core/src/Mark.d.ts +0 -452
- package/dist/packages/core/src/Node.d.ts +0 -612
- package/dist/packages/core/src/NodePos.d.ts +0 -44
- package/dist/packages/core/src/NodeView.d.ts +0 -31
- package/dist/packages/core/src/PasteRule.d.ts +0 -50
- package/dist/packages/core/src/Tracker.d.ts +0 -11
- package/dist/packages/core/src/commands/blur.d.ts +0 -13
- package/dist/packages/core/src/commands/clearContent.d.ts +0 -14
- package/dist/packages/core/src/commands/clearNodes.d.ts +0 -13
- package/dist/packages/core/src/commands/command.d.ts +0 -18
- package/dist/packages/core/src/commands/createParagraphNear.d.ts +0 -13
- package/dist/packages/core/src/commands/cut.d.ts +0 -20
- package/dist/packages/core/src/commands/deleteCurrentNode.d.ts +0 -13
- package/dist/packages/core/src/commands/deleteNode.d.ts +0 -15
- package/dist/packages/core/src/commands/deleteRange.d.ts +0 -14
- package/dist/packages/core/src/commands/deleteSelection.d.ts +0 -13
- package/dist/packages/core/src/commands/enter.d.ts +0 -13
- package/dist/packages/core/src/commands/exitCode.d.ts +0 -13
- package/dist/packages/core/src/commands/extendMarkRange.d.ts +0 -25
- package/dist/packages/core/src/commands/first.d.ts +0 -14
- package/dist/packages/core/src/commands/focus.d.ts +0 -27
- package/dist/packages/core/src/commands/forEach.d.ts +0 -14
- package/dist/packages/core/src/commands/index.d.ts +0 -55
- package/dist/packages/core/src/commands/insertContent.d.ts +0 -34
- package/dist/packages/core/src/commands/insertContentAt.d.ts +0 -47
- package/dist/packages/core/src/commands/join.d.ts +0 -41
- package/dist/packages/core/src/commands/joinItemBackward.d.ts +0 -13
- package/dist/packages/core/src/commands/joinItemForward.d.ts +0 -13
- package/dist/packages/core/src/commands/joinTextblockBackward.d.ts +0 -12
- package/dist/packages/core/src/commands/joinTextblockForward.d.ts +0 -12
- package/dist/packages/core/src/commands/keyboardShortcut.d.ts +0 -14
- package/dist/packages/core/src/commands/lift.d.ts +0 -17
- package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +0 -13
- package/dist/packages/core/src/commands/liftListItem.d.ts +0 -15
- package/dist/packages/core/src/commands/newlineInCode.d.ts +0 -13
- package/dist/packages/core/src/commands/resetAttributes.d.ts +0 -16
- package/dist/packages/core/src/commands/scrollIntoView.d.ts +0 -13
- package/dist/packages/core/src/commands/selectAll.d.ts +0 -13
- package/dist/packages/core/src/commands/selectNodeBackward.d.ts +0 -13
- package/dist/packages/core/src/commands/selectNodeForward.d.ts +0 -13
- package/dist/packages/core/src/commands/selectParentNode.d.ts +0 -13
- package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +0 -13
- package/dist/packages/core/src/commands/selectTextblockStart.d.ts +0 -13
- package/dist/packages/core/src/commands/setContent.d.ts +0 -40
- package/dist/packages/core/src/commands/setMark.d.ts +0 -15
- package/dist/packages/core/src/commands/setMeta.d.ts +0 -16
- package/dist/packages/core/src/commands/setNode.d.ts +0 -16
- package/dist/packages/core/src/commands/setNodeSelection.d.ts +0 -14
- package/dist/packages/core/src/commands/setTextSelection.d.ts +0 -14
- package/dist/packages/core/src/commands/sinkListItem.d.ts +0 -15
- package/dist/packages/core/src/commands/splitBlock.d.ts +0 -17
- package/dist/packages/core/src/commands/splitListItem.d.ts +0 -16
- package/dist/packages/core/src/commands/toggleList.d.ts +0 -18
- package/dist/packages/core/src/commands/toggleMark.d.ts +0 -30
- package/dist/packages/core/src/commands/toggleNode.d.ts +0 -17
- package/dist/packages/core/src/commands/toggleWrap.d.ts +0 -16
- package/dist/packages/core/src/commands/undoInputRule.d.ts +0 -13
- package/dist/packages/core/src/commands/unsetAllMarks.d.ts +0 -13
- package/dist/packages/core/src/commands/unsetMark.d.ts +0 -25
- package/dist/packages/core/src/commands/updateAttributes.d.ts +0 -24
- package/dist/packages/core/src/commands/wrapIn.d.ts +0 -16
- package/dist/packages/core/src/commands/wrapInList.d.ts +0 -16
- package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +0 -5
- package/dist/packages/core/src/extensions/commands.d.ts +0 -3
- package/dist/packages/core/src/extensions/editable.d.ts +0 -2
- package/dist/packages/core/src/extensions/focusEvents.d.ts +0 -2
- package/dist/packages/core/src/extensions/index.d.ts +0 -6
- package/dist/packages/core/src/extensions/keymap.d.ts +0 -2
- package/dist/packages/core/src/extensions/tabindex.d.ts +0 -2
- package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +0 -10
- package/dist/packages/core/src/helpers/createChainableState.d.ts +0 -10
- package/dist/packages/core/src/helpers/createDocument.d.ts +0 -12
- package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +0 -15
- package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +0 -7
- package/dist/packages/core/src/helpers/findChildren.d.ts +0 -9
- package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +0 -10
- package/dist/packages/core/src/helpers/findParentNode.d.ts +0 -16
- package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +0 -17
- package/dist/packages/core/src/helpers/generateHTML.d.ts +0 -8
- package/dist/packages/core/src/helpers/generateJSON.d.ts +0 -8
- package/dist/packages/core/src/helpers/generateText.d.ts +0 -12
- package/dist/packages/core/src/helpers/getAttributes.d.ts +0 -9
- package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +0 -6
- package/dist/packages/core/src/helpers/getChangedRanges.d.ts +0 -11
- package/dist/packages/core/src/helpers/getDebugJSON.d.ts +0 -8
- package/dist/packages/core/src/helpers/getExtensionField.d.ts +0 -9
- package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +0 -2
- package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +0 -3
- package/dist/packages/core/src/helpers/getMarkRange.d.ts +0 -3
- package/dist/packages/core/src/helpers/getMarkType.d.ts +0 -2
- package/dist/packages/core/src/helpers/getMarksBetween.d.ts +0 -3
- package/dist/packages/core/src/helpers/getNodeAtPosition.d.ts +0 -11
- package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +0 -3
- package/dist/packages/core/src/helpers/getNodeType.d.ts +0 -2
- package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +0 -3
- package/dist/packages/core/src/helpers/getSchema.d.ts +0 -4
- package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +0 -10
- package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +0 -8
- package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +0 -8
- package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +0 -9
- package/dist/packages/core/src/helpers/getText.d.ts +0 -15
- package/dist/packages/core/src/helpers/getTextBetween.d.ts +0 -14
- package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +0 -8
- package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +0 -8
- package/dist/packages/core/src/helpers/index.d.ts +0 -50
- package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +0 -9
- package/dist/packages/core/src/helpers/isActive.d.ts +0 -2
- package/dist/packages/core/src/helpers/isAtEndOfNode.d.ts +0 -2
- package/dist/packages/core/src/helpers/isAtStartOfNode.d.ts +0 -2
- package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +0 -2
- package/dist/packages/core/src/helpers/isList.d.ts +0 -2
- package/dist/packages/core/src/helpers/isMarkActive.d.ts +0 -3
- package/dist/packages/core/src/helpers/isNodeActive.d.ts +0 -3
- package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +0 -14
- package/dist/packages/core/src/helpers/isNodeSelection.d.ts +0 -2
- package/dist/packages/core/src/helpers/isTextSelection.d.ts +0 -2
- package/dist/packages/core/src/helpers/posToDOMRect.d.ts +0 -2
- package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +0 -4
- package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +0 -2
- package/dist/packages/core/src/helpers/splitExtensions.d.ts +0 -9
- package/dist/packages/core/src/index.d.ts +0 -24
- package/dist/packages/core/src/inputRules/index.d.ts +0 -5
- package/dist/packages/core/src/inputRules/markInputRule.d.ts +0 -13
- package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +0 -23
- package/dist/packages/core/src/inputRules/textInputRule.d.ts +0 -10
- package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +0 -15
- package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +0 -28
- package/dist/packages/core/src/pasteRules/index.d.ts +0 -3
- package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +0 -13
- package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +0 -14
- package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +0 -10
- package/dist/packages/core/src/style.d.ts +0 -1
- package/dist/packages/core/src/types.d.ts +0 -253
- package/dist/packages/core/src/utilities/callOrReturn.d.ts +0 -9
- package/dist/packages/core/src/utilities/createStyleTag.d.ts +0 -1
- package/dist/packages/core/src/utilities/deleteProps.d.ts +0 -6
- package/dist/packages/core/src/utilities/elementFromString.d.ts +0 -1
- package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +0 -1
- package/dist/packages/core/src/utilities/findDuplicates.d.ts +0 -1
- package/dist/packages/core/src/utilities/fromString.d.ts +0 -1
- package/dist/packages/core/src/utilities/index.d.ts +0 -20
- package/dist/packages/core/src/utilities/isAndroid.d.ts +0 -1
- package/dist/packages/core/src/utilities/isEmptyObject.d.ts +0 -1
- package/dist/packages/core/src/utilities/isFunction.d.ts +0 -1
- package/dist/packages/core/src/utilities/isMacOS.d.ts +0 -1
- package/dist/packages/core/src/utilities/isNumber.d.ts +0 -1
- package/dist/packages/core/src/utilities/isPlainObject.d.ts +0 -1
- package/dist/packages/core/src/utilities/isRegExp.d.ts +0 -1
- package/dist/packages/core/src/utilities/isString.d.ts +0 -1
- package/dist/packages/core/src/utilities/isiOS.d.ts +0 -1
- package/dist/packages/core/src/utilities/mergeAttributes.d.ts +0 -1
- package/dist/packages/core/src/utilities/mergeDeep.d.ts +0 -1
- package/dist/packages/core/src/utilities/minMax.d.ts +0 -1
- package/dist/packages/core/src/utilities/objectIncludes.d.ts +0 -8
- package/dist/packages/core/src/utilities/removeDuplicates.d.ts +0 -8
- package/dist/packages/extension-link/src/helpers/autolink.d.ts +0 -14
- package/dist/packages/extension-link/src/helpers/clickHandler.d.ts +0 -7
- package/dist/packages/extension-link/src/helpers/pasteHandler.d.ts +0 -10
- package/dist/packages/extension-link/src/index.d.ts +0 -3
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 { MultiToken, tokenize } from 'linkifyjs'\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<ReturnType<MultiToken['toObject']>>) {\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}\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 = 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 => transaction.getMeta('preventAutolink'))\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 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 const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol))\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(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => options.validate(link.value))\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 if (!view.editable) {\n return false\n }\n\n let a = event.target as HTMLElement\n const els = []\n\n while (a.nodeName !== 'DIV') {\n els.push(a)\n a = a.parentNode as HTMLElement\n }\n\n if (!els.find(value => value.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 window.open(href, target)\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 defaultProtocol: string\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, { defaultProtocol: options.defaultProtocol }).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n options.editor.commands.setMark(options.type, {\n href: link.href,\n })\n\n return true\n },\n },\n })\n}\n","import {\n Mark, markPasteRule, mergeAttributes, PasteRuleMatch,\n} 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 /**\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 = /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<LinkProtocolOptions | string>\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 * 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 * HTML attributes to add to the link element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\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 * @param attributes The link attributes\n * @example editor.commands.setLink({ href: 'https://tiptap.dev' })\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => 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: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n * @example editor.commands.unsetLink()\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\n// From DOMPurify\n// https://github.com/cure53/DOMPurify/blob/main/src/regexp.js\nconst ATTR_WHITESPACE = /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\nconst IS_ALLOWED_URI = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n\nfunction isAllowedUri(uri: string | undefined) {\n return !uri || uri.replace(ATTR_WHITESPACE, '').match(IS_ALLOWED_URI)\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<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n exitable: true,\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 defaultProtocol: 'http',\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: url => !!url,\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 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 [{\n tag: 'a[href]',\n getAttrs: dom => {\n const href = (dom as HTMLElement).getAttribute('href')\n\n // prevent XSS attacks\n if (!href || !isAllowedUri(href)) {\n return false\n }\n return null\n },\n }]\n },\n\n renderHTML({ HTMLAttributes }) {\n // prevent XSS attacks\n if (!isAllowedUri(HTMLAttributes.href)) {\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 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 => {\n const foundLinks: PasteRuleMatch[] = []\n\n if (text) {\n const { validate } = this.options\n const links = find(text).filter(item => item.isLink && validate(item.value))\n\n if (links.length) {\n links.forEach(link => (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 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\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n defaultProtocol: this.options.defaultProtocol,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick === true) {\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 defaultProtocol: this.options.defaultProtocol,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/link.ts","../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/index.ts"],"sourcesContent":["import {\n Mark, markPasteRule, mergeAttributes, PasteRuleMatch,\n} 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 /**\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 = /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<LinkProtocolOptions | string>\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 * 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 * HTML attributes to add to the link element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\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 * @param attributes The link attributes\n * @example editor.commands.setLink({ href: 'https://tiptap.dev' })\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => 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: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n * @example editor.commands.unsetLink()\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\n// From DOMPurify\n// https://github.com/cure53/DOMPurify/blob/main/src/regexp.js\nconst ATTR_WHITESPACE = /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\nconst IS_ALLOWED_URI = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n\nfunction isAllowedUri(uri: string | undefined) {\n return !uri || uri.replace(ATTR_WHITESPACE, '').match(IS_ALLOWED_URI)\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<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n exitable: true,\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 defaultProtocol: 'http',\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: url => !!url,\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 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 [{\n tag: 'a[href]',\n getAttrs: dom => {\n const href = (dom as HTMLElement).getAttribute('href')\n\n // prevent XSS attacks\n if (!href || !isAllowedUri(href)) {\n return false\n }\n return null\n },\n }]\n },\n\n renderHTML({ HTMLAttributes }) {\n // prevent XSS attacks\n if (!isAllowedUri(HTMLAttributes.href)) {\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 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 => {\n const foundLinks: PasteRuleMatch[] = []\n\n if (text) {\n const { validate } = this.options\n const links = find(text).filter(item => item.isLink && validate(item.value))\n\n if (links.length) {\n links.forEach(link => (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 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\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n defaultProtocol: this.options.defaultProtocol,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick === true) {\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 defaultProtocol: this.options.defaultProtocol,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n","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 { MultiToken, tokenize } from 'linkifyjs'\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<ReturnType<MultiToken['toObject']>>) {\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}\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 = 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 => transaction.getMeta('preventAutolink'))\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 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 const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol))\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(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => options.validate(link.value))\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 if (!view.editable) {\n return false\n }\n\n let a = event.target as HTMLElement\n const els = []\n\n while (a.nodeName !== 'DIV') {\n els.push(a)\n a = a.parentNode as HTMLElement\n }\n\n if (!els.find(value => value.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 window.open(href, target)\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 defaultProtocol: string\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, { defaultProtocol: options.defaultProtocol }).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n options.editor.commands.setMark(options.type, {\n href: link.href,\n })\n\n return true\n },\n },\n })\n}\n","import { Link } from './link.js'\n\nexport * from './link.js'\n\nexport default Link\n"],"mappings":"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","names":["find","Plugin","PluginKey","Plugin","PluginKey","find"]}
|
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": "
|
|
4
|
+
"version": "3.0.0-next.1",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -15,15 +15,14 @@
|
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
|
-
"types": "./dist/
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
19
|
"import": "./dist/index.js",
|
|
20
20
|
"require": "./dist/index.cjs"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"main": "dist/index.cjs",
|
|
24
24
|
"module": "dist/index.js",
|
|
25
|
-
"
|
|
26
|
-
"types": "dist/packages/extension-link/src/index.d.ts",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
27
26
|
"files": [
|
|
28
27
|
"src",
|
|
29
28
|
"dist"
|
|
@@ -32,12 +31,12 @@
|
|
|
32
31
|
"linkifyjs": "^4.1.0"
|
|
33
32
|
},
|
|
34
33
|
"devDependencies": {
|
|
35
|
-
"@tiptap/core": "^
|
|
36
|
-
"@tiptap/pm": "^
|
|
34
|
+
"@tiptap/core": "^3.0.0-next.1",
|
|
35
|
+
"@tiptap/pm": "^3.0.0-next.1"
|
|
37
36
|
},
|
|
38
37
|
"peerDependencies": {
|
|
39
|
-
"@tiptap/core": "^
|
|
40
|
-
"@tiptap/pm": "^
|
|
38
|
+
"@tiptap/core": "^3.0.0-next.1",
|
|
39
|
+
"@tiptap/pm": "^3.0.0-next.1"
|
|
41
40
|
},
|
|
42
41
|
"repository": {
|
|
43
42
|
"type": "git",
|
|
@@ -45,7 +44,6 @@
|
|
|
45
44
|
"directory": "packages/extension-link"
|
|
46
45
|
},
|
|
47
46
|
"scripts": {
|
|
48
|
-
"
|
|
49
|
-
"build": "npm run clean && rollup -c"
|
|
47
|
+
"build": "tsup"
|
|
50
48
|
}
|
|
51
49
|
}
|
package/dist/index.umd.js
DELETED
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('linkifyjs'), require('@tiptap/pm/state')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', 'linkifyjs', '@tiptap/pm/state'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-link"] = {}, global.core, global.linkifyjs, global.state));
|
|
5
|
-
})(this, (function (exports, core, linkifyjs, state) { 'use strict';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Check if the provided tokens form a valid link structure, which can either be a single link token
|
|
9
|
-
* or a link token surrounded by parentheses or square brackets.
|
|
10
|
-
*
|
|
11
|
-
* This ensures that only complete and valid text is hyperlinked, preventing cases where a valid
|
|
12
|
-
* top-level domain (TLD) is immediately followed by an invalid character, like a number. For
|
|
13
|
-
* example, with the `find` method from Linkify, entering `example.com1` would result in
|
|
14
|
-
* `example.com` being linked and the trailing `1` left as plain text. By using the `tokenize`
|
|
15
|
-
* method, we can perform more comprehensive validation on the input text.
|
|
16
|
-
*/
|
|
17
|
-
function isValidLinkStructure(tokens) {
|
|
18
|
-
if (tokens.length === 1) {
|
|
19
|
-
return tokens[0].isLink;
|
|
20
|
-
}
|
|
21
|
-
if (tokens.length === 3 && tokens[1].isLink) {
|
|
22
|
-
return ['()', '[]'].includes(tokens[0].value + tokens[2].value);
|
|
23
|
-
}
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* This plugin allows you to automatically add links to your editor.
|
|
28
|
-
* @param options The plugin options
|
|
29
|
-
* @returns The plugin instance
|
|
30
|
-
*/
|
|
31
|
-
function autolink(options) {
|
|
32
|
-
return new state.Plugin({
|
|
33
|
-
key: new state.PluginKey('autolink'),
|
|
34
|
-
appendTransaction: (transactions, oldState, newState) => {
|
|
35
|
-
/**
|
|
36
|
-
* Does the transaction change the document?
|
|
37
|
-
*/
|
|
38
|
-
const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc);
|
|
39
|
-
/**
|
|
40
|
-
* Prevent autolink if the transaction is not a document change or if the transaction has the meta `preventAutolink`.
|
|
41
|
-
*/
|
|
42
|
-
const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'));
|
|
43
|
-
/**
|
|
44
|
-
* Prevent autolink if the transaction is not a document change
|
|
45
|
-
* or if the transaction has the meta `preventAutolink`.
|
|
46
|
-
*/
|
|
47
|
-
if (!docChanges || preventAutolink) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const { tr } = newState;
|
|
51
|
-
const transform = core.combineTransactionSteps(oldState.doc, [...transactions]);
|
|
52
|
-
const changes = core.getChangedRanges(transform);
|
|
53
|
-
changes.forEach(({ newRange }) => {
|
|
54
|
-
// Now let’s see if we can add new links.
|
|
55
|
-
const nodesInChangedRanges = core.findChildrenInRange(newState.doc, newRange, node => node.isTextblock);
|
|
56
|
-
let textBlock;
|
|
57
|
-
let textBeforeWhitespace;
|
|
58
|
-
if (nodesInChangedRanges.length > 1) {
|
|
59
|
-
// Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).
|
|
60
|
-
textBlock = nodesInChangedRanges[0];
|
|
61
|
-
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, textBlock.pos + textBlock.node.nodeSize, undefined, ' ');
|
|
62
|
-
}
|
|
63
|
-
else if (nodesInChangedRanges.length
|
|
64
|
-
// We want to make sure to include the block seperator argument to treat hard breaks like spaces.
|
|
65
|
-
&& newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')) {
|
|
66
|
-
textBlock = nodesInChangedRanges[0];
|
|
67
|
-
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, ' ');
|
|
68
|
-
}
|
|
69
|
-
if (textBlock && textBeforeWhitespace) {
|
|
70
|
-
const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '');
|
|
71
|
-
if (wordsBeforeWhitespace.length <= 0) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1];
|
|
75
|
-
const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace);
|
|
76
|
-
if (!lastWordBeforeSpace) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
const linksBeforeSpace = linkifyjs.tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol));
|
|
80
|
-
if (!isValidLinkStructure(linksBeforeSpace)) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
linksBeforeSpace
|
|
84
|
-
.filter(link => link.isLink)
|
|
85
|
-
// Calculate link position.
|
|
86
|
-
.map(link => ({
|
|
87
|
-
...link,
|
|
88
|
-
from: lastWordAndBlockOffset + link.start + 1,
|
|
89
|
-
to: lastWordAndBlockOffset + link.end + 1,
|
|
90
|
-
}))
|
|
91
|
-
// ignore link inside code mark
|
|
92
|
-
.filter(link => {
|
|
93
|
-
if (!newState.schema.marks.code) {
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
97
|
-
})
|
|
98
|
-
// validate link
|
|
99
|
-
.filter(link => options.validate(link.value))
|
|
100
|
-
// Add link mark.
|
|
101
|
-
.forEach(link => {
|
|
102
|
-
if (core.getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
tr.addMark(link.from, link.to, options.type.create({
|
|
106
|
-
href: link.href,
|
|
107
|
-
}));
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
if (!tr.steps.length) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
return tr;
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function clickHandler(options) {
|
|
120
|
-
return new state.Plugin({
|
|
121
|
-
key: new state.PluginKey('handleClickLink'),
|
|
122
|
-
props: {
|
|
123
|
-
handleClick: (view, pos, event) => {
|
|
124
|
-
var _a, _b;
|
|
125
|
-
if (event.button !== 0) {
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
if (!view.editable) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
let a = event.target;
|
|
132
|
-
const els = [];
|
|
133
|
-
while (a.nodeName !== 'DIV') {
|
|
134
|
-
els.push(a);
|
|
135
|
-
a = a.parentNode;
|
|
136
|
-
}
|
|
137
|
-
if (!els.find(value => value.nodeName === 'A')) {
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
const attrs = core.getAttributes(view.state, options.type.name);
|
|
141
|
-
const link = event.target;
|
|
142
|
-
const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href;
|
|
143
|
-
const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target;
|
|
144
|
-
if (link && href) {
|
|
145
|
-
window.open(href, target);
|
|
146
|
-
return true;
|
|
147
|
-
}
|
|
148
|
-
return false;
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function pasteHandler(options) {
|
|
155
|
-
return new state.Plugin({
|
|
156
|
-
key: new state.PluginKey('handlePasteLink'),
|
|
157
|
-
props: {
|
|
158
|
-
handlePaste: (view, event, slice) => {
|
|
159
|
-
const { state } = view;
|
|
160
|
-
const { selection } = state;
|
|
161
|
-
const { empty } = selection;
|
|
162
|
-
if (empty) {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
let textContent = '';
|
|
166
|
-
slice.content.forEach(node => {
|
|
167
|
-
textContent += node.textContent;
|
|
168
|
-
});
|
|
169
|
-
const link = linkifyjs.find(textContent, { defaultProtocol: options.defaultProtocol }).find(item => item.isLink && item.value === textContent);
|
|
170
|
-
if (!textContent || !link) {
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
options.editor.commands.setMark(options.type, {
|
|
174
|
-
href: link.href,
|
|
175
|
-
});
|
|
176
|
-
return true;
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const pasteRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi;
|
|
183
|
-
// From DOMPurify
|
|
184
|
-
// https://github.com/cure53/DOMPurify/blob/main/src/regexp.js
|
|
185
|
-
const ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g; // eslint-disable-line no-control-regex
|
|
186
|
-
const IS_ALLOWED_URI = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape
|
|
187
|
-
function isAllowedUri(uri) {
|
|
188
|
-
return !uri || uri.replace(ATTR_WHITESPACE, '').match(IS_ALLOWED_URI);
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* This extension allows you to create links.
|
|
192
|
-
* @see https://www.tiptap.dev/api/marks/link
|
|
193
|
-
*/
|
|
194
|
-
const Link = core.Mark.create({
|
|
195
|
-
name: 'link',
|
|
196
|
-
priority: 1000,
|
|
197
|
-
keepOnSplit: false,
|
|
198
|
-
exitable: true,
|
|
199
|
-
onCreate() {
|
|
200
|
-
this.options.protocols.forEach(protocol => {
|
|
201
|
-
if (typeof protocol === 'string') {
|
|
202
|
-
linkifyjs.registerCustomProtocol(protocol);
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
linkifyjs.registerCustomProtocol(protocol.scheme, protocol.optionalSlashes);
|
|
206
|
-
});
|
|
207
|
-
},
|
|
208
|
-
onDestroy() {
|
|
209
|
-
linkifyjs.reset();
|
|
210
|
-
},
|
|
211
|
-
inclusive() {
|
|
212
|
-
return this.options.autolink;
|
|
213
|
-
},
|
|
214
|
-
addOptions() {
|
|
215
|
-
return {
|
|
216
|
-
openOnClick: true,
|
|
217
|
-
linkOnPaste: true,
|
|
218
|
-
autolink: true,
|
|
219
|
-
protocols: [],
|
|
220
|
-
defaultProtocol: 'http',
|
|
221
|
-
HTMLAttributes: {
|
|
222
|
-
target: '_blank',
|
|
223
|
-
rel: 'noopener noreferrer nofollow',
|
|
224
|
-
class: null,
|
|
225
|
-
},
|
|
226
|
-
validate: url => !!url,
|
|
227
|
-
};
|
|
228
|
-
},
|
|
229
|
-
addAttributes() {
|
|
230
|
-
return {
|
|
231
|
-
href: {
|
|
232
|
-
default: null,
|
|
233
|
-
parseHTML(element) {
|
|
234
|
-
return element.getAttribute('href');
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
target: {
|
|
238
|
-
default: this.options.HTMLAttributes.target,
|
|
239
|
-
},
|
|
240
|
-
rel: {
|
|
241
|
-
default: this.options.HTMLAttributes.rel,
|
|
242
|
-
},
|
|
243
|
-
class: {
|
|
244
|
-
default: this.options.HTMLAttributes.class,
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
},
|
|
248
|
-
parseHTML() {
|
|
249
|
-
return [{
|
|
250
|
-
tag: 'a[href]',
|
|
251
|
-
getAttrs: dom => {
|
|
252
|
-
const href = dom.getAttribute('href');
|
|
253
|
-
// prevent XSS attacks
|
|
254
|
-
if (!href || !isAllowedUri(href)) {
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
return null;
|
|
258
|
-
},
|
|
259
|
-
}];
|
|
260
|
-
},
|
|
261
|
-
renderHTML({ HTMLAttributes }) {
|
|
262
|
-
// prevent XSS attacks
|
|
263
|
-
if (!isAllowedUri(HTMLAttributes.href)) {
|
|
264
|
-
// strip out the href
|
|
265
|
-
return ['a', core.mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: '' }), 0];
|
|
266
|
-
}
|
|
267
|
-
return ['a', core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
|
268
|
-
},
|
|
269
|
-
addCommands() {
|
|
270
|
-
return {
|
|
271
|
-
setLink: attributes => ({ chain }) => {
|
|
272
|
-
return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run();
|
|
273
|
-
},
|
|
274
|
-
toggleLink: attributes => ({ chain }) => {
|
|
275
|
-
return chain()
|
|
276
|
-
.toggleMark(this.name, attributes, { extendEmptyMarkRange: true })
|
|
277
|
-
.setMeta('preventAutolink', true)
|
|
278
|
-
.run();
|
|
279
|
-
},
|
|
280
|
-
unsetLink: () => ({ chain }) => {
|
|
281
|
-
return chain()
|
|
282
|
-
.unsetMark(this.name, { extendEmptyMarkRange: true })
|
|
283
|
-
.setMeta('preventAutolink', true)
|
|
284
|
-
.run();
|
|
285
|
-
},
|
|
286
|
-
};
|
|
287
|
-
},
|
|
288
|
-
addPasteRules() {
|
|
289
|
-
return [
|
|
290
|
-
core.markPasteRule({
|
|
291
|
-
find: text => {
|
|
292
|
-
const foundLinks = [];
|
|
293
|
-
if (text) {
|
|
294
|
-
const { validate } = this.options;
|
|
295
|
-
const links = linkifyjs.find(text).filter(item => item.isLink && validate(item.value));
|
|
296
|
-
if (links.length) {
|
|
297
|
-
links.forEach(link => (foundLinks.push({
|
|
298
|
-
text: link.value,
|
|
299
|
-
data: {
|
|
300
|
-
href: link.href,
|
|
301
|
-
},
|
|
302
|
-
index: link.start,
|
|
303
|
-
})));
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return foundLinks;
|
|
307
|
-
},
|
|
308
|
-
type: this.type,
|
|
309
|
-
getAttributes: match => {
|
|
310
|
-
var _a;
|
|
311
|
-
return {
|
|
312
|
-
href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href,
|
|
313
|
-
};
|
|
314
|
-
},
|
|
315
|
-
}),
|
|
316
|
-
];
|
|
317
|
-
},
|
|
318
|
-
addProseMirrorPlugins() {
|
|
319
|
-
const plugins = [];
|
|
320
|
-
if (this.options.autolink) {
|
|
321
|
-
plugins.push(autolink({
|
|
322
|
-
type: this.type,
|
|
323
|
-
defaultProtocol: this.options.defaultProtocol,
|
|
324
|
-
validate: this.options.validate,
|
|
325
|
-
}));
|
|
326
|
-
}
|
|
327
|
-
if (this.options.openOnClick === true) {
|
|
328
|
-
plugins.push(clickHandler({
|
|
329
|
-
type: this.type,
|
|
330
|
-
}));
|
|
331
|
-
}
|
|
332
|
-
if (this.options.linkOnPaste) {
|
|
333
|
-
plugins.push(pasteHandler({
|
|
334
|
-
editor: this.editor,
|
|
335
|
-
defaultProtocol: this.options.defaultProtocol,
|
|
336
|
-
type: this.type,
|
|
337
|
-
}));
|
|
338
|
-
}
|
|
339
|
-
return plugins;
|
|
340
|
-
},
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
exports.Link = Link;
|
|
344
|
-
exports.default = Link;
|
|
345
|
-
exports.pasteRegex = pasteRegex;
|
|
346
|
-
|
|
347
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
348
|
-
|
|
349
|
-
}));
|
|
350
|
-
//# sourceMappingURL=index.umd.js.map
|
package/dist/index.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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 { MultiToken, tokenize } from 'linkifyjs'\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<ReturnType<MultiToken['toObject']>>) {\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}\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 = 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 => transaction.getMeta('preventAutolink'))\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 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 const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject(options.defaultProtocol))\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(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => options.validate(link.value))\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 if (!view.editable) {\n return false\n }\n\n let a = event.target as HTMLElement\n const els = []\n\n while (a.nodeName !== 'DIV') {\n els.push(a)\n a = a.parentNode as HTMLElement\n }\n\n if (!els.find(value => value.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 window.open(href, target)\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 defaultProtocol: string\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, { defaultProtocol: options.defaultProtocol }).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n options.editor.commands.setMark(options.type, {\n href: link.href,\n })\n\n return true\n },\n },\n })\n}\n","import {\n Mark, markPasteRule, mergeAttributes, PasteRuleMatch,\n} 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 /**\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 = /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<LinkProtocolOptions | string>\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 * 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 * HTML attributes to add to the link element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\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 * @param attributes The link attributes\n * @example editor.commands.setLink({ href: 'https://tiptap.dev' })\n */\n setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => 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: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType\n /**\n * Unset a link mark\n * @example editor.commands.unsetLink()\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\n// From DOMPurify\n// https://github.com/cure53/DOMPurify/blob/main/src/regexp.js\nconst ATTR_WHITESPACE = /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\nconst IS_ALLOWED_URI = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n\nfunction isAllowedUri(uri: string | undefined) {\n return !uri || uri.replace(ATTR_WHITESPACE, '').match(IS_ALLOWED_URI)\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<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n exitable: true,\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 defaultProtocol: 'http',\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: url => !!url,\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 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 [{\n tag: 'a[href]',\n getAttrs: dom => {\n const href = (dom as HTMLElement).getAttribute('href')\n\n // prevent XSS attacks\n if (!href || !isAllowedUri(href)) {\n return false\n }\n return null\n },\n }]\n },\n\n renderHTML({ HTMLAttributes }) {\n // prevent XSS attacks\n if (!isAllowedUri(HTMLAttributes.href)) {\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 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 => {\n const foundLinks: PasteRuleMatch[] = []\n\n if (text) {\n const { validate } = this.options\n const links = find(text).filter(item => item.isLink && validate(item.value))\n\n if (links.length) {\n links.forEach(link => (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 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\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n defaultProtocol: this.options.defaultProtocol,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick === true) {\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 defaultProtocol: this.options.defaultProtocol,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","tokenize","getMarksBetween","getAttributes","find","Mark","registerCustomProtocol","reset","mergeAttributes","markPasteRule"],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { EditorState, Transaction } from '@tiptap/pm/state';
|
|
2
|
-
import { Editor } from './Editor.js';
|
|
3
|
-
import { AnyCommands, CanCommands, ChainedCommands, CommandProps, SingleCommands } from './types.js';
|
|
4
|
-
export declare class CommandManager {
|
|
5
|
-
editor: Editor;
|
|
6
|
-
rawCommands: AnyCommands;
|
|
7
|
-
customState?: EditorState;
|
|
8
|
-
constructor(props: {
|
|
9
|
-
editor: Editor;
|
|
10
|
-
state?: EditorState;
|
|
11
|
-
});
|
|
12
|
-
get hasCustomState(): boolean;
|
|
13
|
-
get state(): EditorState;
|
|
14
|
-
get commands(): SingleCommands;
|
|
15
|
-
get chain(): () => ChainedCommands;
|
|
16
|
-
get can(): () => CanCommands;
|
|
17
|
-
createChain(startTr?: Transaction, shouldDispatch?: boolean): ChainedCommands;
|
|
18
|
-
createCan(startTr?: Transaction): CanCommands;
|
|
19
|
-
buildProps(tr: Transaction, shouldDispatch?: boolean): CommandProps;
|
|
20
|
-
}
|