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.
122 lines
5.1 KiB
122 lines
5.1 KiB
import { default as defaultOptions, flatten as flattenOptions, } from './options.js'; |
|
import * as staticMethods from './static.js'; |
|
import { Cheerio } from './cheerio.js'; |
|
import { isHtml, isCheerio } from './utils.js'; |
|
export function getLoad(parse, render) { |
|
/** |
|
* Create a querying function, bound to a document created from the provided markup. |
|
* |
|
* Note that similar to web browser contexts, this operation may introduce |
|
* `<html>`, `<head>`, and `<body>` elements; set `isDocument` to `false` to |
|
* switch to fragment mode and disable this. |
|
* |
|
* @param content - Markup to be loaded. |
|
* @param options - Options for the created instance. |
|
* @param isDocument - Allows parser to be switched to fragment mode. |
|
* @returns The loaded document. |
|
* @see {@link https://cheerio.js.org#loading} for additional usage information. |
|
*/ |
|
return function load(content, options, isDocument = true) { |
|
if (content == null) { |
|
throw new Error('cheerio.load() expects a string'); |
|
} |
|
const internalOpts = { ...defaultOptions, ...flattenOptions(options) }; |
|
const initialRoot = parse(content, internalOpts, isDocument, null); |
|
/** Create an extended class here, so that extensions only live on one instance. */ |
|
class LoadedCheerio extends Cheerio { |
|
_make(selector, context) { |
|
const cheerio = initialize(selector, context); |
|
cheerio.prevObject = this; |
|
return cheerio; |
|
} |
|
_parse(content, options, isDocument, context) { |
|
return parse(content, options, isDocument, context); |
|
} |
|
_render(dom) { |
|
return render(dom, this.options); |
|
} |
|
} |
|
function initialize(selector, context, root = initialRoot, opts) { |
|
// $($) |
|
if (selector && isCheerio(selector)) |
|
return selector; |
|
const options = { |
|
...internalOpts, |
|
...flattenOptions(opts), |
|
}; |
|
const r = typeof root === 'string' |
|
? [parse(root, options, false, null)] |
|
: 'length' in root |
|
? root |
|
: [root]; |
|
const rootInstance = isCheerio(r) |
|
? r |
|
: new LoadedCheerio(r, null, options); |
|
// Add a cyclic reference, so that calling methods on `_root` never fails. |
|
rootInstance._root = rootInstance; |
|
// $(), $(null), $(undefined), $(false) |
|
if (!selector) { |
|
return new LoadedCheerio(undefined, rootInstance, options); |
|
} |
|
const elements = typeof selector === 'string' && isHtml(selector) |
|
? // $(<html>) |
|
parse(selector, options, false, null).children |
|
: isNode(selector) |
|
? // $(dom) |
|
[selector] |
|
: Array.isArray(selector) |
|
? // $([dom]) |
|
selector |
|
: undefined; |
|
const instance = new LoadedCheerio(elements, rootInstance, options); |
|
if (elements) { |
|
return instance; |
|
} |
|
if (typeof selector !== 'string') { |
|
throw new Error('Unexpected type of selector'); |
|
} |
|
// We know that our selector is a string now. |
|
let search = selector; |
|
const searchContext = !context |
|
? // If we don't have a context, maybe we have a root, from loading |
|
rootInstance |
|
: typeof context === 'string' |
|
? isHtml(context) |
|
? // $('li', '<ul>...</ul>') |
|
new LoadedCheerio([parse(context, options, false, null)], rootInstance, options) |
|
: // $('li', 'ul') |
|
((search = `${context} ${search}`), rootInstance) |
|
: isCheerio(context) |
|
? // $('li', $) |
|
context |
|
: // $('li', node), $('li', [nodes]) |
|
new LoadedCheerio(Array.isArray(context) ? context : [context], rootInstance, options); |
|
// If we still don't have a context, return |
|
if (!searchContext) |
|
return instance; |
|
/* |
|
* #id, .class, tag |
|
*/ |
|
return searchContext.find(search); |
|
} |
|
// Add in static methods & properties |
|
Object.assign(initialize, staticMethods, { |
|
load, |
|
// `_root` and `_options` are used in static methods. |
|
_root: initialRoot, |
|
_options: internalOpts, |
|
// Add `fn` for plugins |
|
fn: LoadedCheerio.prototype, |
|
// Add the prototype here to maintain `instanceof` behavior. |
|
prototype: LoadedCheerio.prototype, |
|
}); |
|
return initialize; |
|
}; |
|
} |
|
function isNode(obj) { |
|
return (!!obj.name || |
|
obj.type === 'root' || |
|
obj.type === 'text' || |
|
obj.type === 'comment'); |
|
} |
|
//# sourceMappingURL=load.js.map
|