static.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { textContent } from 'domutils';
  2. import { default as defaultOptions, flatten as flattenOptions, } from './options.js';
  3. /**
  4. * Helper function to render a DOM.
  5. *
  6. * @param that - Cheerio instance to render.
  7. * @param dom - The DOM to render. Defaults to `that`'s root.
  8. * @param options - Options for rendering.
  9. * @returns The rendered document.
  10. */
  11. function render(that, dom, options) {
  12. if (!that)
  13. return '';
  14. return that(dom !== null && dom !== void 0 ? dom : that._root.children, null, undefined, options).toString();
  15. }
  16. /**
  17. * Checks if a passed object is an options object.
  18. *
  19. * @param dom - Object to check if it is an options object.
  20. * @returns Whether the object is an options object.
  21. */
  22. function isOptions(dom, options) {
  23. return (!options &&
  24. typeof dom === 'object' &&
  25. dom != null &&
  26. !('length' in dom) &&
  27. !('type' in dom));
  28. }
  29. export function html(dom, options) {
  30. /*
  31. * Be flexible about parameters, sometimes we call html(),
  32. * with options as only parameter
  33. * check dom argument for dom element specific properties
  34. * assume there is no 'length' or 'type' properties in the options object
  35. */
  36. const toRender = isOptions(dom) ? ((options = dom), undefined) : dom;
  37. /*
  38. * Sometimes `$.html()` is used without preloading html,
  39. * so fallback non-existing options to the default ones.
  40. */
  41. const opts = {
  42. ...defaultOptions,
  43. ...this === null || this === void 0 ? void 0 : this._options,
  44. ...flattenOptions(options !== null && options !== void 0 ? options : {}),
  45. };
  46. return render(this, toRender, opts);
  47. }
  48. /**
  49. * Render the document as XML.
  50. *
  51. * @param dom - Element to render.
  52. * @returns THe rendered document.
  53. */
  54. export function xml(dom) {
  55. const options = { ...this._options, xmlMode: true };
  56. return render(this, dom, options);
  57. }
  58. /**
  59. * Render the document as text.
  60. *
  61. * This returns the `textContent` of the passed elements. The result will
  62. * include the contents of `script` and `stype` elements. To avoid this, use
  63. * `.prop('innerText')` instead.
  64. *
  65. * @param elements - Elements to render.
  66. * @returns The rendered document.
  67. */
  68. export function text(elements) {
  69. const elems = elements ? elements : this ? this.root() : [];
  70. let ret = '';
  71. for (let i = 0; i < elems.length; i++) {
  72. ret += textContent(elems[i]);
  73. }
  74. return ret;
  75. }
  76. export function parseHTML(data, context, keepScripts = typeof context === 'boolean' ? context : false) {
  77. if (!data || typeof data !== 'string') {
  78. return null;
  79. }
  80. if (typeof context === 'boolean') {
  81. keepScripts = context;
  82. }
  83. const parsed = this.load(data, defaultOptions, false);
  84. if (!keepScripts) {
  85. parsed('script').remove();
  86. }
  87. /*
  88. * The `children` array is used by Cheerio internally to group elements that
  89. * share the same parents. When nodes created through `parseHTML` are
  90. * inserted into previously-existing DOM structures, they will be removed
  91. * from the `children` array. The results of `parseHTML` should remain
  92. * constant across these operations, so a shallow copy should be returned.
  93. */
  94. return parsed.root()[0].children.slice();
  95. }
  96. /**
  97. * Sometimes you need to work with the top-level root element. To query it, you
  98. * can use `$.root()`.
  99. *
  100. * @example
  101. *
  102. * ```js
  103. * $.root().append('<ul id="vegetables"></ul>').html();
  104. * //=> <ul id="fruits">...</ul><ul id="vegetables"></ul>
  105. * ```
  106. *
  107. * @returns Cheerio instance wrapping the root node.
  108. * @alias Cheerio.root
  109. */
  110. export function root() {
  111. return this(this._root);
  112. }
  113. /**
  114. * Checks to see if the `contained` DOM element is a descendant of the
  115. * `container` DOM element.
  116. *
  117. * @param container - Potential parent node.
  118. * @param contained - Potential child node.
  119. * @returns Indicates if the nodes contain one another.
  120. * @alias Cheerio.contains
  121. * @see {@link https://api.jquery.com/jQuery.contains/}
  122. */
  123. export function contains(container, contained) {
  124. // According to the jQuery API, an element does not "contain" itself
  125. if (contained === container) {
  126. return false;
  127. }
  128. /*
  129. * Step up the descendants, stopping when the root element is reached
  130. * (signaled by `.parent` returning a reference to the same object)
  131. */
  132. let next = contained;
  133. while (next && next !== next.parent) {
  134. next = next.parent;
  135. if (next === container) {
  136. return true;
  137. }
  138. }
  139. return false;
  140. }
  141. /**
  142. * $.merge().
  143. *
  144. * @param arr1 - First array.
  145. * @param arr2 - Second array.
  146. * @returns `arr1`, with elements of `arr2` inserted.
  147. * @alias Cheerio.merge
  148. * @see {@link https://api.jquery.com/jQuery.merge/}
  149. */
  150. export function merge(arr1, arr2) {
  151. if (!isArrayLike(arr1) || !isArrayLike(arr2)) {
  152. return;
  153. }
  154. let newLength = arr1.length;
  155. const len = +arr2.length;
  156. for (let i = 0; i < len; i++) {
  157. arr1[newLength++] = arr2[i];
  158. }
  159. arr1.length = newLength;
  160. return arr1;
  161. }
  162. /**
  163. * Checks if an object is array-like.
  164. *
  165. * @param item - Item to check.
  166. * @returns Indicates if the item is array-like.
  167. */
  168. function isArrayLike(item) {
  169. if (Array.isArray(item)) {
  170. return true;
  171. }
  172. if (typeof item !== 'object' ||
  173. !Object.prototype.hasOwnProperty.call(item, 'length') ||
  174. typeof item.length !== 'number' ||
  175. item.length < 0) {
  176. return false;
  177. }
  178. for (let i = 0; i < item.length; i++) {
  179. if (!(i in item)) {
  180. return false;
  181. }
  182. }
  183. return true;
  184. }
  185. //# sourceMappingURL=static.js.map