index.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. "use strict";
  2. module.exports = CSSselect;
  3. var DomUtils = require("domutils");
  4. var falseFunc = require("boolbase").falseFunc;
  5. var compileRaw = require("./lib/compile.js");
  6. function wrapCompile(func) {
  7. return function addAdapter(selector, options, context) {
  8. options = options || {};
  9. options.adapter = options.adapter || DomUtils;
  10. return func(selector, options, context);
  11. };
  12. }
  13. var compile = wrapCompile(compileRaw);
  14. var compileUnsafe = wrapCompile(compileRaw.compileUnsafe);
  15. function getSelectorFunc(searchFunc) {
  16. return function select(query, elems, options) {
  17. options = options || {};
  18. options.adapter = options.adapter || DomUtils;
  19. if (typeof query !== "function") {
  20. query = compileUnsafe(query, options, elems);
  21. }
  22. if (query.shouldTestNextSiblings) {
  23. elems = appendNextSiblings((options && options.context) || elems, options.adapter);
  24. }
  25. if (!Array.isArray(elems)) elems = options.adapter.getChildren(elems);
  26. else elems = options.adapter.removeSubsets(elems);
  27. return searchFunc(query, elems, options);
  28. };
  29. }
  30. function getNextSiblings(elem, adapter) {
  31. var siblings = adapter.getSiblings(elem);
  32. if (!Array.isArray(siblings)) return [];
  33. siblings = siblings.slice(0);
  34. while (siblings.shift() !== elem);
  35. return siblings;
  36. }
  37. function appendNextSiblings(elems, adapter) {
  38. // Order matters because jQuery seems to check the children before the siblings
  39. if (!Array.isArray(elems)) elems = [elems];
  40. var newElems = elems.slice(0);
  41. for (var i = 0, len = elems.length; i < len; i++) {
  42. var nextSiblings = getNextSiblings(newElems[i], adapter);
  43. newElems.push.apply(newElems, nextSiblings);
  44. }
  45. return newElems;
  46. }
  47. var selectAll = getSelectorFunc(function selectAll(query, elems, options) {
  48. return query === falseFunc || !elems || elems.length === 0 ? [] : options.adapter.findAll(query, elems);
  49. });
  50. var selectOne = getSelectorFunc(function selectOne(query, elems, options) {
  51. return query === falseFunc || !elems || elems.length === 0 ? null : options.adapter.findOne(query, elems);
  52. });
  53. function is(elem, query, options) {
  54. options = options || {};
  55. options.adapter = options.adapter || DomUtils;
  56. return (typeof query === "function" ? query : compile(query, options))(elem);
  57. }
  58. /*
  59. the exported interface
  60. */
  61. function CSSselect(query, elems, options) {
  62. return selectAll(query, elems, options);
  63. }
  64. CSSselect.compile = compile;
  65. CSSselect.filters = compileRaw.Pseudos.filters;
  66. CSSselect.pseudos = compileRaw.Pseudos.pseudos;
  67. CSSselect.selectAll = selectAll;
  68. CSSselect.selectOne = selectOne;
  69. CSSselect.is = is;
  70. //legacy methods (might be removed)
  71. CSSselect.parse = compile;
  72. CSSselect.iterate = selectAll;
  73. //hooks
  74. CSSselect._compileUnsafe = compileUnsafe;
  75. CSSselect._compileToken = compileRaw.compileToken;