{"version":3,"sources":["../src/index.ts","../src/code-block-lowlight.ts","../src/lowlight-plugin.ts"],"sourcesContent":["import { CodeBlockLowlight } from './code-block-lowlight.js'\n\nexport * from './code-block-lowlight.js'\n\nexport default CodeBlockLowlight\n","import type { CodeBlockOptions } from '@tiptap/extension-code-block'\nimport { CodeBlock } from '@tiptap/extension-code-block'\n\nimport { LowlightPlugin } from './lowlight-plugin.js'\n\nexport interface CodeBlockLowlightOptions extends CodeBlockOptions {\n  /**\n   * The lowlight instance.\n   */\n  lowlight: any\n}\n\n/**\n * This extension allows you to highlight code blocks with lowlight.\n * @see https://tiptap.dev/api/nodes/code-block-lowlight\n */\nexport const CodeBlockLowlight = CodeBlock.extend<CodeBlockLowlightOptions>({\n  addOptions() {\n    return {\n      ...this.parent?.(),\n      lowlight: {},\n      languageClassPrefix: 'language-',\n      exitOnTripleEnter: true,\n      exitOnArrowDown: true,\n      defaultLanguage: null,\n      enableTabIndentation: false,\n      tabSize: 4,\n      HTMLAttributes: {},\n    }\n  },\n\n  addProseMirrorPlugins() {\n    return [\n      ...(this.parent?.() || []),\n      LowlightPlugin({\n        name: this.name,\n        lowlight: this.options.lowlight,\n        defaultLanguage: this.options.defaultLanguage,\n      }),\n    ]\n  },\n})\n","import { findChildren } from '@tiptap/core'\nimport type { Node as ProsemirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n// @ts-ignore\nimport highlight from 'highlight.js/lib/core'\n\nfunction parseNodes(nodes: any[], className: string[] = []): { text: string; classes: string[] }[] {\n  return nodes.flatMap(node => {\n    const classes = [...className, ...(node.properties ? node.properties.className : [])]\n\n    if (node.children) {\n      return parseNodes(node.children, classes)\n    }\n\n    return {\n      text: node.value,\n      classes,\n    }\n  })\n}\n\nfunction getHighlightNodes(result: any) {\n  // `.value` for lowlight v1, `.children` for lowlight v2\n  return result.value || result.children || []\n}\n\nfunction registered(aliasOrLanguage: string) {\n  return Boolean(highlight.getLanguage(aliasOrLanguage))\n}\n\nfunction getDecorations({\n  doc,\n  name,\n  lowlight,\n  defaultLanguage,\n}: {\n  doc: ProsemirrorNode\n  name: string\n  lowlight: any\n  defaultLanguage: string | null | undefined\n}) {\n  const decorations: Decoration[] = []\n\n  findChildren(doc, node => node.type.name === name).forEach(block => {\n    let from = block.pos + 1\n    const language = block.node.attrs.language || defaultLanguage\n    const languages = lowlight.listLanguages()\n\n    const nodes =\n      language && (languages.includes(language) || registered(language) || lowlight.registered?.(language))\n        ? getHighlightNodes(lowlight.highlight(language, block.node.textContent))\n        : getHighlightNodes(lowlight.highlightAuto(block.node.textContent))\n\n    parseNodes(nodes).forEach(node => {\n      const to = from + node.text.length\n\n      if (node.classes.length) {\n        const decoration = Decoration.inline(from, to, {\n          class: node.classes.join(' '),\n        })\n\n        decorations.push(decoration)\n      }\n\n      from = to\n    })\n  })\n\n  return DecorationSet.create(doc, decorations)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction isFunction(param: any): param is Function {\n  return typeof param === 'function'\n}\n\nexport function LowlightPlugin({\n  name,\n  lowlight,\n  defaultLanguage,\n}: {\n  name: string\n  lowlight: any\n  defaultLanguage: string | null | undefined\n}) {\n  if (!['highlight', 'highlightAuto', 'listLanguages'].every(api => isFunction(lowlight[api]))) {\n    throw Error('You should provide an instance of lowlight to use the code-block-lowlight extension')\n  }\n\n  const lowlightPlugin: Plugin<any> = new Plugin({\n    key: new PluginKey('lowlight'),\n\n    state: {\n      init: (_, { doc }) =>\n        getDecorations({\n          doc,\n          name,\n          lowlight,\n          defaultLanguage,\n        }),\n      apply: (transaction, decorationSet, oldState, newState) => {\n        const oldNodeName = oldState.selection.$head.parent.type.name\n        const newNodeName = newState.selection.$head.parent.type.name\n        const oldNodes = findChildren(oldState.doc, node => node.type.name === name)\n        const newNodes = findChildren(newState.doc, node => node.type.name === name)\n\n        if (\n          transaction.docChanged &&\n          // Apply decorations if:\n          // selection includes named node,\n          ([oldNodeName, newNodeName].includes(name) ||\n            // OR transaction adds/removes named node,\n            newNodes.length !== oldNodes.length ||\n            // OR transaction has changes that completely encapsulte a node\n            // (for example, a transaction that affects the entire document).\n            // Such transactions can happen during collab syncing via y-prosemirror, for example.\n            transaction.steps.some(step => {\n              // @ts-ignore\n              return (\n                // @ts-ignore\n                step.from !== undefined &&\n                // @ts-ignore\n                step.to !== undefined &&\n                oldNodes.some(node => {\n                  // @ts-ignore\n                  return (\n                    // @ts-ignore\n                    node.pos >= step.from &&\n                    // @ts-ignore\n                    node.pos + node.node.nodeSize <= step.to\n                  )\n                })\n              )\n            }))\n        ) {\n          return getDecorations({\n            doc: transaction.doc,\n            name,\n            lowlight,\n            defaultLanguage,\n          })\n        }\n\n        return decorationSet.map(transaction.mapping, transaction.doc)\n      },\n    },\n\n    props: {\n      decorations(state) {\n        return lowlightPlugin.getState(state)\n      },\n    },\n  })\n\n  return lowlightPlugin\n}\n"],"mappings":"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","names":["import_core","highlight"]}