pseudos.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // While filters are precompiled, pseudos get called when they are needed
  2. export const pseudos = {
  3. empty(elem, { adapter }) {
  4. return !adapter.getChildren(elem).some((elem) =>
  5. // FIXME: `getText` call is potentially expensive.
  6. adapter.isTag(elem) || adapter.getText(elem) !== "");
  7. },
  8. "first-child"(elem, { adapter, equals }) {
  9. if (adapter.prevElementSibling) {
  10. return adapter.prevElementSibling(elem) == null;
  11. }
  12. const firstChild = adapter
  13. .getSiblings(elem)
  14. .find((elem) => adapter.isTag(elem));
  15. return firstChild != null && equals(elem, firstChild);
  16. },
  17. "last-child"(elem, { adapter, equals }) {
  18. const siblings = adapter.getSiblings(elem);
  19. for (let i = siblings.length - 1; i >= 0; i--) {
  20. if (equals(elem, siblings[i]))
  21. return true;
  22. if (adapter.isTag(siblings[i]))
  23. break;
  24. }
  25. return false;
  26. },
  27. "first-of-type"(elem, { adapter, equals }) {
  28. const siblings = adapter.getSiblings(elem);
  29. const elemName = adapter.getName(elem);
  30. for (let i = 0; i < siblings.length; i++) {
  31. const currentSibling = siblings[i];
  32. if (equals(elem, currentSibling))
  33. return true;
  34. if (adapter.isTag(currentSibling) &&
  35. adapter.getName(currentSibling) === elemName) {
  36. break;
  37. }
  38. }
  39. return false;
  40. },
  41. "last-of-type"(elem, { adapter, equals }) {
  42. const siblings = adapter.getSiblings(elem);
  43. const elemName = adapter.getName(elem);
  44. for (let i = siblings.length - 1; i >= 0; i--) {
  45. const currentSibling = siblings[i];
  46. if (equals(elem, currentSibling))
  47. return true;
  48. if (adapter.isTag(currentSibling) &&
  49. adapter.getName(currentSibling) === elemName) {
  50. break;
  51. }
  52. }
  53. return false;
  54. },
  55. "only-of-type"(elem, { adapter, equals }) {
  56. const elemName = adapter.getName(elem);
  57. return adapter
  58. .getSiblings(elem)
  59. .every((sibling) => equals(elem, sibling) ||
  60. !adapter.isTag(sibling) ||
  61. adapter.getName(sibling) !== elemName);
  62. },
  63. "only-child"(elem, { adapter, equals }) {
  64. return adapter
  65. .getSiblings(elem)
  66. .every((sibling) => equals(elem, sibling) || !adapter.isTag(sibling));
  67. },
  68. };
  69. export function verifyPseudoArgs(func, name, subselect, argIndex) {
  70. if (subselect === null) {
  71. if (func.length > argIndex) {
  72. throw new Error(`Pseudo-class :${name} requires an argument`);
  73. }
  74. }
  75. else if (func.length === argIndex) {
  76. throw new Error(`Pseudo-class :${name} doesn't have any arguments`);
  77. }
  78. }
  79. //# sourceMappingURL=pseudos.js.map