subselects.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. "use strict";
  2. var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
  3. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  4. if (ar || !(i in from)) {
  5. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  6. ar[i] = from[i];
  7. }
  8. }
  9. return to.concat(ar || Array.prototype.slice.call(from));
  10. };
  11. var __importDefault = (this && this.__importDefault) || function (mod) {
  12. return (mod && mod.__esModule) ? mod : { "default": mod };
  13. };
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. exports.subselects = exports.getNextSiblings = exports.ensureIsTag = exports.PLACEHOLDER_ELEMENT = void 0;
  16. var boolbase_1 = __importDefault(require("boolbase"));
  17. var sort_js_1 = require("../sort.js");
  18. /** Used as a placeholder for :has. Will be replaced with the actual element. */
  19. exports.PLACEHOLDER_ELEMENT = {};
  20. function ensureIsTag(next, adapter) {
  21. if (next === boolbase_1.default.falseFunc)
  22. return boolbase_1.default.falseFunc;
  23. return function (elem) { return adapter.isTag(elem) && next(elem); };
  24. }
  25. exports.ensureIsTag = ensureIsTag;
  26. function getNextSiblings(elem, adapter) {
  27. var siblings = adapter.getSiblings(elem);
  28. if (siblings.length <= 1)
  29. return [];
  30. var elemIndex = siblings.indexOf(elem);
  31. if (elemIndex < 0 || elemIndex === siblings.length - 1)
  32. return [];
  33. return siblings.slice(elemIndex + 1).filter(adapter.isTag);
  34. }
  35. exports.getNextSiblings = getNextSiblings;
  36. function copyOptions(options) {
  37. // Not copied: context, rootFunc
  38. return {
  39. xmlMode: !!options.xmlMode,
  40. lowerCaseAttributeNames: !!options.lowerCaseAttributeNames,
  41. lowerCaseTags: !!options.lowerCaseTags,
  42. quirksMode: !!options.quirksMode,
  43. cacheResults: !!options.cacheResults,
  44. pseudos: options.pseudos,
  45. adapter: options.adapter,
  46. equals: options.equals,
  47. };
  48. }
  49. var is = function (next, token, options, context, compileToken) {
  50. var func = compileToken(token, copyOptions(options), context);
  51. return func === boolbase_1.default.trueFunc
  52. ? next
  53. : func === boolbase_1.default.falseFunc
  54. ? boolbase_1.default.falseFunc
  55. : function (elem) { return func(elem) && next(elem); };
  56. };
  57. /*
  58. * :not, :has, :is, :matches and :where have to compile selectors
  59. * doing this in src/pseudos.ts would lead to circular dependencies,
  60. * so we add them here
  61. */
  62. exports.subselects = {
  63. is: is,
  64. /**
  65. * `:matches` and `:where` are aliases for `:is`.
  66. */
  67. matches: is,
  68. where: is,
  69. not: function (next, token, options, context, compileToken) {
  70. var func = compileToken(token, copyOptions(options), context);
  71. return func === boolbase_1.default.falseFunc
  72. ? next
  73. : func === boolbase_1.default.trueFunc
  74. ? boolbase_1.default.falseFunc
  75. : function (elem) { return !func(elem) && next(elem); };
  76. },
  77. has: function (next, subselect, options, _context, compileToken) {
  78. var adapter = options.adapter;
  79. var opts = copyOptions(options);
  80. opts.relativeSelector = true;
  81. var context = subselect.some(function (s) { return s.some(sort_js_1.isTraversal); })
  82. ? // Used as a placeholder. Will be replaced with the actual element.
  83. [exports.PLACEHOLDER_ELEMENT]
  84. : undefined;
  85. var compiled = compileToken(subselect, opts, context);
  86. if (compiled === boolbase_1.default.falseFunc)
  87. return boolbase_1.default.falseFunc;
  88. var hasElement = ensureIsTag(compiled, adapter);
  89. // If `compiled` is `trueFunc`, we can skip this.
  90. if (context && compiled !== boolbase_1.default.trueFunc) {
  91. /*
  92. * `shouldTestNextSiblings` will only be true if the query starts with
  93. * a traversal (sibling or adjacent). That means we will always have a context.
  94. */
  95. var _a = compiled.shouldTestNextSiblings, shouldTestNextSiblings_1 = _a === void 0 ? false : _a;
  96. return function (elem) {
  97. if (!next(elem))
  98. return false;
  99. context[0] = elem;
  100. var childs = adapter.getChildren(elem);
  101. var nextElements = shouldTestNextSiblings_1
  102. ? __spreadArray(__spreadArray([], childs, true), getNextSiblings(elem, adapter), true) : childs;
  103. return adapter.existsOne(hasElement, nextElements);
  104. };
  105. }
  106. return function (elem) {
  107. return next(elem) &&
  108. adapter.existsOne(hasElement, adapter.getChildren(elem));
  109. };
  110. },
  111. };
  112. //# sourceMappingURL=subselects.js.map