JsDom.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. "use strict";
  2. import { JSDOM } from "jsdom";
  3. export const jsDomParse = function (string) {
  4. // JSDOM does not properly handle :scope CSS selector (https://github.com/jsdom/jsdom/issues/3067)
  5. // It does not handle innerText property either : https://github.com/jsdom/jsdom/issues/1245
  6. // This code is used to patch it (inspiration from : https://github.com/asamuzaK/domSelector#monkey-patch-jsdom)
  7. return function () {
  8. const jsdom = new JSDOM(string, {
  9. beforeParse: (window) => {
  10. const querySelectorAllFunc = window.Element.prototype.querySelectorAll;
  11. window.Element.prototype.querySelectorAll = function (...args) {
  12. if (!args.length) {
  13. throw new window.TypeError(
  14. "1 argument required, but only 0 present."
  15. );
  16. }
  17. const [selector] = args;
  18. if (selector.startsWith(":scope")) {
  19. const old_id = this.id;
  20. this.id = "scope";
  21. const ret = this.parentElement.querySelectorAll(
  22. selector.replace(":scope", "#scope")
  23. );
  24. this.id = old_id;
  25. return ret;
  26. } else {
  27. return querySelectorAllFunc.apply(this, args);
  28. }
  29. };
  30. const querySelectorFunc = window.Element.prototype.querySelector;
  31. window.Element.prototype.querySelector = function (...args) {
  32. if (!args.length) {
  33. throw new window.TypeError(
  34. "1 argument required, but only 0 present."
  35. );
  36. }
  37. const [selector] = args;
  38. if (selector.startsWith(":scope")) {
  39. const old_id = this.id;
  40. this.id = "scope";
  41. const ret = this.parentElement.querySelector(
  42. selector.replace(":scope", "#scope")
  43. );
  44. this.id = old_id;
  45. return ret;
  46. } else {
  47. return querySelectorFunc.apply(this, args);
  48. }
  49. };
  50. Object.defineProperty(window.Element.prototype, "innerText", {
  51. get() {
  52. return this.textContent;
  53. },
  54. });
  55. },
  56. });
  57. return jsdom.window.document;
  58. };
  59. };