5079204f7e0b20d9e60fcc0915b19af727d3d86a5bddfa4948df80b61fee6bdce6d985caa0463344f2060a6e1411f58c493ab46813ed1efb36e1f8cbd9a080 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. 'use strict';
  2. const isTag = (node) => {
  3. return node.type === 'element';
  4. };
  5. const existsOne = (test, elems) => {
  6. return elems.some((elem) => {
  7. if (isTag(elem)) {
  8. return test(elem) || existsOne(test, getChildren(elem));
  9. } else {
  10. return false;
  11. }
  12. });
  13. };
  14. const getAttributeValue = (elem, name) => {
  15. return elem.attributes[name];
  16. };
  17. const getChildren = (node) => {
  18. return node.children || [];
  19. };
  20. const getName = (elemAst) => {
  21. return elemAst.name;
  22. };
  23. const getParent = (node) => {
  24. return node.parentNode || null;
  25. };
  26. const getSiblings = (elem) => {
  27. var parent = getParent(elem);
  28. return parent ? getChildren(parent) : [];
  29. };
  30. const getText = (node) => {
  31. if (node.children[0].type === 'text' && node.children[0].type === 'cdata') {
  32. return node.children[0].value;
  33. }
  34. return '';
  35. };
  36. const hasAttrib = (elem, name) => {
  37. return elem.attributes[name] !== undefined;
  38. };
  39. const removeSubsets = (nodes) => {
  40. let idx = nodes.length;
  41. let node;
  42. let ancestor;
  43. let replace;
  44. // Check if each node (or one of its ancestors) is already contained in the
  45. // array.
  46. while (--idx > -1) {
  47. node = ancestor = nodes[idx];
  48. // Temporarily remove the node under consideration
  49. nodes[idx] = null;
  50. replace = true;
  51. while (ancestor) {
  52. if (nodes.includes(ancestor)) {
  53. replace = false;
  54. nodes.splice(idx, 1);
  55. break;
  56. }
  57. ancestor = getParent(ancestor);
  58. }
  59. // If the node has been found to be unique, re-insert it.
  60. if (replace) {
  61. nodes[idx] = node;
  62. }
  63. }
  64. return nodes;
  65. };
  66. const findAll = (test, elems) => {
  67. const result = [];
  68. for (const elem of elems) {
  69. if (isTag(elem)) {
  70. if (test(elem)) {
  71. result.push(elem);
  72. }
  73. result.push(...findAll(test, getChildren(elem)));
  74. }
  75. }
  76. return result;
  77. };
  78. const findOne = (test, elems) => {
  79. for (const elem of elems) {
  80. if (isTag(elem)) {
  81. if (test(elem)) {
  82. return elem;
  83. }
  84. const result = findOne(test, getChildren(elem));
  85. if (result) {
  86. return result;
  87. }
  88. }
  89. }
  90. return null;
  91. };
  92. const svgoCssSelectAdapter = {
  93. isTag,
  94. existsOne,
  95. getAttributeValue,
  96. getChildren,
  97. getName,
  98. getParent,
  99. getSiblings,
  100. getText,
  101. hasAttrib,
  102. removeSubsets,
  103. findAll,
  104. findOne,
  105. };
  106. module.exports = svgoCssSelectAdapter;