diff --git a/lib/plugins/helper/toc.js b/lib/plugins/helper/toc.js index 51d0ef33e0..01aa7c9fbf 100644 --- a/lib/plugins/helper/toc.js +++ b/lib/plugins/helper/toc.js @@ -1,15 +1,21 @@ 'use strict'; -let cheerio; const { escapeHTML } = require('hexo-util'); +const { DomHandler, DomUtils, Parser } = require('htmlparser2'); + +const parseHtml = (html) => { + const handler = new DomHandler(null, {}); + new Parser(handler, {}).end(html); + return handler.dom; +}; function tocHelper(str, options = {}) { - if (!cheerio) cheerio = require('cheerio'); + const dom = parseHtml(str); - const $ = cheerio.load(str); const headingsMaxDepth = Object.prototype.hasOwnProperty.call(options, 'max_depth') ? options.max_depth : 6; const headingsSelector = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].slice(0, headingsMaxDepth).join(','); - const headings = $(headingsSelector); + + const headings = DomUtils.find(el => headingsSelector.includes(el.tagName), dom, true); if (!headings.length) return ''; @@ -21,15 +27,15 @@ function tocHelper(str, options = {}) { let lastLevel = 0; function getId(ele) { - const id = $(ele).attr('id'); - const $parent = $(ele).parent(); - return id || ($parent.length < 1 ? null : getId($parent)); + const { id } = ele.attribs; + const { parent } = ele; + return id || (parent.length < 1 ? null : getId(parent)); } - headings.each(function() { - const level = +this.name[1]; - const id = getId(this); - const text = escapeHTML($(this).text()); + for (const el of headings) { + const level = +el.name[1]; + const id = getId(el); + const text = escapeHTML(DomUtils.getText(el)); lastNumber[level - 1]++; @@ -67,7 +73,7 @@ function tocHelper(str, options = {}) { result += `${text}`; lastLevel = level; - }); + } for (let i = firstLevel - 1; i < lastLevel; i++) { result += ''; diff --git a/package.json b/package.json index 98eba926f9..37405f93d3 100644 --- a/package.json +++ b/package.json @@ -39,13 +39,13 @@ "archy": "^1.0.0", "bluebird": "^3.5.2", "chalk": "^2.4.1", - "cheerio": "0.22.0", "hexo-cli": "^3.0.0", "hexo-front-matter": "^1.0.0", "hexo-fs": "^2.0.0", "hexo-i18n": "^1.0.0", "hexo-log": "^1.0.0", "hexo-util": "^1.5.0", + "htmlparser2": "^4.0.0", "js-yaml": "^3.12.0", "lodash": "^4.17.11", "micromatch": "^4.0.2", @@ -67,6 +67,7 @@ "@easyops/git-exec-and-restage": "^1.0.4", "chai": "^4.1.2", "chai-as-promised": "^7.1.1", + "cheerio": "0.22.0", "eslint": "^6.0.1", "eslint-config-hexo": "^3.0.0", "hexo-renderer-marked": "^2.0.0",