{"version":3,"file":"linkify.mjs","sources":["../../../../../../node_modules/markdown-it/lib/rules_core/linkify.mjs"],"sourcesContent":["// Replace link-like texts with link nodes.\n//\n// Currently restricted by `md.validateLink()` to http/https/ftp\n//\n\nimport { arrayReplaceAt } from '../common/utils.mjs'\n\nfunction isLinkOpen (str) {\n  return /^<a[>\\s]/i.test(str)\n}\nfunction isLinkClose (str) {\n  return /^<\\/a\\s*>/i.test(str)\n}\n\nexport default function linkify (state) {\n  const blockTokens = state.tokens\n\n  if (!state.md.options.linkify) { return }\n\n  for (let j = 0, l = blockTokens.length; j < l; j++) {\n    if (blockTokens[j].type !== 'inline' ||\n        !state.md.linkify.pretest(blockTokens[j].content)) {\n      continue\n    }\n\n    let tokens = blockTokens[j].children\n\n    let htmlLinkLevel = 0\n\n    // We scan from the end, to keep position when new tags added.\n    // Use reversed logic in links start/end match\n    for (let i = tokens.length - 1; i >= 0; i--) {\n      const currentToken = tokens[i]\n\n      // Skip content of markdown links\n      if (currentToken.type === 'link_close') {\n        i--\n        while (tokens[i].level !== currentToken.level && tokens[i].type !== 'link_open') {\n          i--\n        }\n        continue\n      }\n\n      // Skip content of html tag links\n      if (currentToken.type === 'html_inline') {\n        if (isLinkOpen(currentToken.content) && htmlLinkLevel > 0) {\n          htmlLinkLevel--\n        }\n        if (isLinkClose(currentToken.content)) {\n          htmlLinkLevel++\n        }\n      }\n      if (htmlLinkLevel > 0) { continue }\n\n      if (currentToken.type === 'text' && state.md.linkify.test(currentToken.content)) {\n        const text = currentToken.content\n        let links = state.md.linkify.match(text)\n\n        // Now split string to nodes\n        const nodes = []\n        let level = currentToken.level\n        let lastPos = 0\n\n        // forbid escape sequence at the start of the string,\n        // this avoids http\\://example.com/ from being linkified as\n        // http:<a href=\"//example.com/\">//example.com/</a>\n        if (links.length > 0 &&\n            links[0].index === 0 &&\n            i > 0 &&\n            tokens[i - 1].type === 'text_special') {\n          links = links.slice(1)\n        }\n\n        for (let ln = 0; ln < links.length; ln++) {\n          const url = links[ln].url\n          const fullUrl = state.md.normalizeLink(url)\n          if (!state.md.validateLink(fullUrl)) { continue }\n\n          let urlText = links[ln].text\n\n          // Linkifier might send raw hostnames like \"example.com\", where url\n          // starts with domain name. So we prepend http:// in those cases,\n          // and remove it afterwards.\n          //\n          if (!links[ln].schema) {\n            urlText = state.md.normalizeLinkText('http://' + urlText).replace(/^http:\\/\\//, '')\n          } else if (links[ln].schema === 'mailto:' && !/^mailto:/i.test(urlText)) {\n            urlText = state.md.normalizeLinkText('mailto:' + urlText).replace(/^mailto:/, '')\n          } else {\n            urlText = state.md.normalizeLinkText(urlText)\n          }\n\n          const pos = links[ln].index\n\n          if (pos > lastPos) {\n            const token   = new state.Token('text', '', 0)\n            token.content = text.slice(lastPos, pos)\n            token.level   = level\n            nodes.push(token)\n          }\n\n          const token_o   = new state.Token('link_open', 'a', 1)\n          token_o.attrs   = [['href', fullUrl]]\n          token_o.level   = level++\n          token_o.markup  = 'linkify'\n          token_o.info    = 'auto'\n          nodes.push(token_o)\n\n          const token_t   = new state.Token('text', '', 0)\n          token_t.content = urlText\n          token_t.level   = level\n          nodes.push(token_t)\n\n          const token_c   = new state.Token('link_close', 'a', -1)\n          token_c.level   = --level\n          token_c.markup  = 'linkify'\n          token_c.info    = 'auto'\n          nodes.push(token_c)\n\n          lastPos = links[ln].lastIndex\n        }\n        if (lastPos < text.length) {\n          const token   = new state.Token('text', '', 0)\n          token.content = text.slice(lastPos)\n          token.level   = level\n          nodes.push(token)\n        }\n\n        // replace current node\n        blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes)\n      }\n    }\n  }\n}\n"],"names":["isLinkOpen","str","isLinkClose","linkify","state","blockTokens","j","l","tokens","htmlLinkLevel","i","currentToken","text","links","nodes","level","lastPos","ln","url","fullUrl","urlText","pos","token","token_o","token_t","token_c","arrayReplaceAt"],"mappings":"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","x_google_ignoreList":[0]}