diff --git a/package-lock.json b/package-lock.json index 9c805dca1e..7370a5e491 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "cheerio-select": "^1.5.0", "dom-serializer": "^1.3.2", "domhandler": "^4.2.0", + "domutils": "^2.7.0", "htmlparser2": "^6.1.0", "parse5": "^6.0.1", "parse5-htmlparser2-tree-adapter": "^6.0.1", diff --git a/package.json b/package.json index bf4a839307..32bda081c3 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "cheerio-select": "^1.5.0", "dom-serializer": "^1.3.2", "domhandler": "^4.2.0", + "domutils": "^2.7.0", "htmlparser2": "^6.1.0", "parse5": "^6.0.1", "parse5-htmlparser2-tree-adapter": "^6.0.1", diff --git a/src/api/manipulation.ts b/src/api/manipulation.ts index 74a7719ebc..31a7a339ad 100644 --- a/src/api/manipulation.ts +++ b/src/api/manipulation.ts @@ -1,15 +1,14 @@ -import { hasChildren } from 'domhandler'; /** * Methods for modifying the DOM structure. * * @module cheerio/manipulation */ -import { Node, NodeWithChildren, Element, Text } from 'domhandler'; +import { Node, NodeWithChildren, Element, Text, hasChildren } from 'domhandler'; import { default as parse, update as updateDOM } from '../parse'; import { html as staticHtml, text as staticText } from '../static'; import { domEach, cloneDom, isTag, isHtml, isCheerio } from '../utils'; -import { DomUtils } from 'htmlparser2'; +import { removeElement } from 'domutils'; import type { Cheerio } from '../cheerio'; import type { BasicAcceptedElems, AcceptedElems } from '../types'; @@ -279,7 +278,7 @@ function _wrap( const [wrapperDom] = this._makeDomArray(wrap, i < lastIdx); - if (!wrapperDom || !DomUtils.hasChildren(wrapperDom)) continue; + if (!wrapperDom || !hasChildren(wrapperDom)) continue; let elInsertLocation = wrapperDom; @@ -587,7 +586,7 @@ export function after( return domEach(this, (el, i) => { const { parent } = el; - if (!DomUtils.hasChildren(el) || !parent) { + if (!hasChildren(el) || !parent) { return; } @@ -701,7 +700,7 @@ export function before( return domEach(this, (el, i) => { const { parent } = el; - if (!DomUtils.hasChildren(el) || !parent) { + if (!hasChildren(el) || !parent) { return; } @@ -807,7 +806,7 @@ export function remove( const elems = selector ? this.filter(selector) : this; domEach(elems, (el) => { - DomUtils.removeElement(el); + removeElement(el); el.prev = el.next = el.parent = null; }); @@ -884,7 +883,7 @@ export function replaceWith( */ export function empty(this: Cheerio): Cheerio { return domEach(this, (el) => { - if (!DomUtils.hasChildren(el)) return; + if (!hasChildren(el)) return; el.children.forEach((child) => { child.next = child.prev = child.parent = null; }); @@ -923,7 +922,7 @@ export function html( ): Cheerio | string | null { if (str === undefined) { const el = this[0]; - if (!el || !DomUtils.hasChildren(el)) return null; + if (!el || !hasChildren(el)) return null; return staticHtml(el.children, this.options); } @@ -931,7 +930,7 @@ export function html( const opts = { ...this.options, context: null as NodeWithChildren | null }; return domEach(this, (el) => { - if (!DomUtils.hasChildren(el)) return; + if (!hasChildren(el)) return; el.children.forEach((child) => { child.next = child.prev = child.parent = null; }); @@ -1000,7 +999,7 @@ export function text( // Append text node to each selected elements return domEach(this, (el) => { - if (!DomUtils.hasChildren(el)) return; + if (!hasChildren(el)) return; el.children.forEach((child) => { child.next = child.prev = child.parent = null; }); diff --git a/src/api/traversing.ts b/src/api/traversing.ts index 8bc3bb9a84..d1f012ca85 100644 --- a/src/api/traversing.ts +++ b/src/api/traversing.ts @@ -9,9 +9,14 @@ import type { Cheerio } from '../cheerio'; import * as select from 'cheerio-select'; import { domEach, isTag, isCheerio } from '../utils'; import { contains } from '../static'; -import { DomUtils } from 'htmlparser2'; +import { + getChildren, + getSiblings, + nextElementSibling, + prevElementSibling, + uniqueSort, +} from 'domutils'; import type { FilterFunction, AcceptedFilters } from '../types'; -const { uniqueSort } = DomUtils; const reSiblingSelector = /^\s*[~+]/; /** @@ -331,7 +336,7 @@ export function closest( * @returns The next nodes. * @see {@link https://api.jquery.com/next/} */ -export const next = _singleMatcher((elem) => DomUtils.nextElementSibling(elem)); +export const next = _singleMatcher((elem) => nextElementSibling(elem)); /** * Gets all the following siblings of the first selected element, optionally @@ -378,7 +383,7 @@ export const nextAll = _matcher((elem) => { * @see {@link https://api.jquery.com/nextUntil/} */ export const nextUntil = _matchUntil( - (el) => DomUtils.nextElementSibling(el), + (el) => nextElementSibling(el), _removeDuplicates ); @@ -398,7 +403,7 @@ export const nextUntil = _matchUntil( * @returns The previous nodes. * @see {@link https://api.jquery.com/prev/} */ -export const prev = _singleMatcher((elem) => DomUtils.prevElementSibling(elem)); +export const prev = _singleMatcher((elem) => prevElementSibling(elem)); /** * Gets all the preceding siblings of the first selected element, optionally @@ -446,7 +451,7 @@ export const prevAll = _matcher((elem) => { * @see {@link https://api.jquery.com/prevUntil/} */ export const prevUntil = _matchUntil( - (el) => DomUtils.prevElementSibling(el), + (el) => prevElementSibling(el), _removeDuplicates ); @@ -471,9 +476,7 @@ export const prevUntil = _matchUntil( */ export const siblings = _matcher( (elem) => - DomUtils.getSiblings(elem).filter( - (el): el is Element => isTag(el) && el !== elem - ), + getSiblings(elem).filter((el): el is Element => isTag(el) && el !== elem), uniqueSort ); @@ -496,7 +499,7 @@ export const siblings = _matcher( * @see {@link https://api.jquery.com/children/} */ export const children = _matcher( - (elem) => DomUtils.getChildren(elem).filter(isTag), + (elem) => getChildren(elem).filter(isTag), _removeDuplicates ); diff --git a/src/parse.ts b/src/parse.ts index 9d57d30d2c..36e29138a3 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,4 +1,4 @@ -import { DomUtils } from 'htmlparser2'; +import { removeElement } from 'domutils'; import { parse as parseWithHtmlparser2 } from './parsers/htmlparser2-adapter'; import { parse as parseWithParse5 } from './parsers/parse5-adapter'; import { @@ -70,7 +70,7 @@ export function update( // Cleanly remove existing nodes from their previous structures. if (node.parent && node.parent.children !== arr) { - DomUtils.removeElement(node); + removeElement(node); } if (parent) { diff --git a/src/static.ts b/src/static.ts index b233a40b4f..b5b2508fcb 100644 --- a/src/static.ts +++ b/src/static.ts @@ -1,5 +1,5 @@ import type { CheerioAPI, Cheerio } from '.'; -import { Node, Document } from 'domhandler'; +import { Node, Document, isText, hasChildren } from 'domhandler'; import { InternalOptions, CheerioOptions, @@ -7,7 +7,7 @@ import { flatten as flattenOptions, } from './options'; import { select } from 'cheerio-select'; -import { ElementType, DomUtils } from 'htmlparser2'; +import { ElementType } from 'htmlparser2'; import { render as renderWithParse5 } from './parsers/parse5-adapter'; import { render as renderWithHtmlparser2 } from './parsers/htmlparser2-adapter'; @@ -137,9 +137,9 @@ export function text( for (let i = 0; i < elems.length; i++) { const elem = elems[i]; - if (DomUtils.isText(elem)) ret += elem.data; + if (isText(elem)) ret += elem.data; else if ( - DomUtils.hasChildren(elem) && + hasChildren(elem) && elem.type !== ElementType.Comment && elem.type !== ElementType.Script && elem.type !== ElementType.Style diff --git a/src/utils.ts b/src/utils.ts index 00c5a7578d..d2e0caa809 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,3 @@ -import { DomUtils } from 'htmlparser2'; import { Node, cloneNode, Document } from 'domhandler'; import type { Cheerio } from './cheerio'; @@ -12,7 +11,7 @@ import type { Cheerio } from './cheerio'; * @param type - DOM node to check. * @returns Whether the node is a tag. */ -export const { isTag } = DomUtils; +export { isTag } from 'domhandler'; /** * Checks if an object is a Cheerio instance.