You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
5.5 KiB
185 lines
5.5 KiB
import { textContent } from 'domutils'; |
|
import { default as defaultOptions, flatten as flattenOptions, } from './options.js'; |
|
/** |
|
* Helper function to render a DOM. |
|
* |
|
* @param that - Cheerio instance to render. |
|
* @param dom - The DOM to render. Defaults to `that`'s root. |
|
* @param options - Options for rendering. |
|
* @returns The rendered document. |
|
*/ |
|
function render(that, dom, options) { |
|
if (!that) |
|
return ''; |
|
return that(dom !== null && dom !== void 0 ? dom : that._root.children, null, undefined, options).toString(); |
|
} |
|
/** |
|
* Checks if a passed object is an options object. |
|
* |
|
* @param dom - Object to check if it is an options object. |
|
* @returns Whether the object is an options object. |
|
*/ |
|
function isOptions(dom, options) { |
|
return (!options && |
|
typeof dom === 'object' && |
|
dom != null && |
|
!('length' in dom) && |
|
!('type' in dom)); |
|
} |
|
export function html(dom, options) { |
|
/* |
|
* Be flexible about parameters, sometimes we call html(), |
|
* with options as only parameter |
|
* check dom argument for dom element specific properties |
|
* assume there is no 'length' or 'type' properties in the options object |
|
*/ |
|
const toRender = isOptions(dom) ? ((options = dom), undefined) : dom; |
|
/* |
|
* Sometimes `$.html()` is used without preloading html, |
|
* so fallback non-existing options to the default ones. |
|
*/ |
|
const opts = { |
|
...defaultOptions, |
|
...this === null || this === void 0 ? void 0 : this._options, |
|
...flattenOptions(options !== null && options !== void 0 ? options : {}), |
|
}; |
|
return render(this, toRender, opts); |
|
} |
|
/** |
|
* Render the document as XML. |
|
* |
|
* @param dom - Element to render. |
|
* @returns THe rendered document. |
|
*/ |
|
export function xml(dom) { |
|
const options = { ...this._options, xmlMode: true }; |
|
return render(this, dom, options); |
|
} |
|
/** |
|
* Render the document as text. |
|
* |
|
* This returns the `textContent` of the passed elements. The result will |
|
* include the contents of `script` and `stype` elements. To avoid this, use |
|
* `.prop('innerText')` instead. |
|
* |
|
* @param elements - Elements to render. |
|
* @returns The rendered document. |
|
*/ |
|
export function text(elements) { |
|
const elems = elements ? elements : this ? this.root() : []; |
|
let ret = ''; |
|
for (let i = 0; i < elems.length; i++) { |
|
ret += textContent(elems[i]); |
|
} |
|
return ret; |
|
} |
|
export function parseHTML(data, context, keepScripts = typeof context === 'boolean' ? context : false) { |
|
if (!data || typeof data !== 'string') { |
|
return null; |
|
} |
|
if (typeof context === 'boolean') { |
|
keepScripts = context; |
|
} |
|
const parsed = this.load(data, defaultOptions, false); |
|
if (!keepScripts) { |
|
parsed('script').remove(); |
|
} |
|
/* |
|
* The `children` array is used by Cheerio internally to group elements that |
|
* share the same parents. When nodes created through `parseHTML` are |
|
* inserted into previously-existing DOM structures, they will be removed |
|
* from the `children` array. The results of `parseHTML` should remain |
|
* constant across these operations, so a shallow copy should be returned. |
|
*/ |
|
return parsed.root()[0].children.slice(); |
|
} |
|
/** |
|
* Sometimes you need to work with the top-level root element. To query it, you |
|
* can use `$.root()`. |
|
* |
|
* @example |
|
* |
|
* ```js |
|
* $.root().append('<ul id="vegetables"></ul>').html(); |
|
* //=> <ul id="fruits">...</ul><ul id="vegetables"></ul> |
|
* ``` |
|
* |
|
* @returns Cheerio instance wrapping the root node. |
|
* @alias Cheerio.root |
|
*/ |
|
export function root() { |
|
return this(this._root); |
|
} |
|
/** |
|
* Checks to see if the `contained` DOM element is a descendant of the |
|
* `container` DOM element. |
|
* |
|
* @param container - Potential parent node. |
|
* @param contained - Potential child node. |
|
* @returns Indicates if the nodes contain one another. |
|
* @alias Cheerio.contains |
|
* @see {@link https://api.jquery.com/jQuery.contains/} |
|
*/ |
|
export function contains(container, contained) { |
|
// According to the jQuery API, an element does not "contain" itself |
|
if (contained === container) { |
|
return false; |
|
} |
|
/* |
|
* Step up the descendants, stopping when the root element is reached |
|
* (signaled by `.parent` returning a reference to the same object) |
|
*/ |
|
let next = contained; |
|
while (next && next !== next.parent) { |
|
next = next.parent; |
|
if (next === container) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
/** |
|
* $.merge(). |
|
* |
|
* @param arr1 - First array. |
|
* @param arr2 - Second array. |
|
* @returns `arr1`, with elements of `arr2` inserted. |
|
* @alias Cheerio.merge |
|
* @see {@link https://api.jquery.com/jQuery.merge/} |
|
*/ |
|
export function merge(arr1, arr2) { |
|
if (!isArrayLike(arr1) || !isArrayLike(arr2)) { |
|
return; |
|
} |
|
let newLength = arr1.length; |
|
const len = +arr2.length; |
|
for (let i = 0; i < len; i++) { |
|
arr1[newLength++] = arr2[i]; |
|
} |
|
arr1.length = newLength; |
|
return arr1; |
|
} |
|
/** |
|
* Checks if an object is array-like. |
|
* |
|
* @param item - Item to check. |
|
* @returns Indicates if the item is array-like. |
|
*/ |
|
function isArrayLike(item) { |
|
if (Array.isArray(item)) { |
|
return true; |
|
} |
|
if (typeof item !== 'object' || |
|
!Object.prototype.hasOwnProperty.call(item, 'length') || |
|
typeof item.length !== 'number' || |
|
item.length < 0) { |
|
return false; |
|
} |
|
for (let i = 0; i < item.length; i++) { |
|
if (!(i in item)) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
//# sourceMappingURL=static.js.map
|