dom/query.js

  1. /**
  2. * @module DOM
  3. * @memberOf dom
  4. */
  5. const {isEl, isEls, isStr, isVal} = require("../core/types");
  6. const L = require("../core/logging");
  7. const {cls} = require("../dom/classes");
  8. //
  9. // import {isEl, isEls, isStr, isVal} from "../core/types";
  10. // import {error} from "../core/logging";
  11. // import {cls} from "../dom/classes";
  12. //
  13. /**
  14. * jQuery-like select "all" by query accepts element, nodes or query
  15. * @param {String|HTMLElement|Element|Node|HTMLCollection|NodeList} q - query string
  16. * @param {HTMLElement|Element|Node} [root] - root which query is issued from
  17. * @return {Array}
  18. */
  19. function $(q, root = document) {
  20. if (isEl(q)) return Array.of(q);
  21. if (isEls(q)) return Array.from(q);
  22. if (!isStr(q)) {
  23. L.error(`Query is not string nor element X.$(${q})`);
  24. return null;
  25. }
  26. if (!isEl(root)) {
  27. L.error(`Query root is not a node!\t[X.$(${q}, ${root})]`);
  28. return null;
  29. }
  30. return Array.from(root.querySelectorAll(q));
  31. }
  32. /**
  33. * jQuery-like select "one" by query accepts element, node or query
  34. * @param {String|HTMLElement|Element|Node} q - query string
  35. * @param {HTMLElement|Element|Node} [root] - root which query is issued from
  36. * @return {Array} - returns array of length=1
  37. */
  38. function $$(q, root = document) {
  39. if (isEl(q)) return Array.of(q);
  40. if (!isStr(q)) {
  41. L.error(`Query is not string nor element X.$$(${q})`);
  42. return null;
  43. }
  44. if (!isEl(root)) {
  45. L.error(`Query root is not a node!\t[X.$(${q}, ${root})]`);
  46. return null;
  47. }
  48. return Array.of(root.querySelector(q));
  49. }
  50. /**
  51. * Generate relative query of given element/node
  52. * @param {HTMLElement|Element|Node} e - element/node
  53. * @param {HTMLElement|Element|Node} maxParent - parent where the query relates to
  54. * @return {String} - query relative to maxParent
  55. */
  56. function queryOf(e, maxParent, q) {
  57. if ((!isVal(e) || !isEl(e))) {
  58. L.error(`\nQuery generator's first parameter must be Element/Node! CAUSE: X.queryOf(${e}, ${maxParent})`);
  59. return null;
  60. }
  61. maxParent = maxParent || document.body;
  62. let gen = e.tagName;
  63. q = q || "";
  64. if (e.id) {
  65. gen += e.id ? ('#' + e.id) : "";
  66. return gen + (!(q === "") ? ' ' + q : "");
  67. }
  68. cls(e).items.forEach(function (value) {
  69. gen = gen + (value !== '' ? '.' + value : '')
  70. });
  71. if (gen) {
  72. let sibs = $(gen, e.parentElement);
  73. if (sibs.length>1) {
  74. let idx = Array.from(e.parentElement.children).findIndex(function (i) {
  75. return e === i;
  76. });
  77. if (idx > 0) {
  78. gen = gen + ":nth-child("+(idx+1)+")";
  79. }
  80. }
  81. }
  82. if (e.parentElement && (e.parentElement !== maxParent) && e.parentElement !== document) {
  83. return (queryOf(e.parentElement, maxParent) + " > " + gen) + (!(q === "") ? ' ' + q : "");
  84. } else {
  85. return gen + (!(q === "") ? ' ' + q : "");
  86. }
  87. }
  88. module.exports = {$, $$, queryOf};