You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
8.4 KiB

  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. /**
  4. * Cache to store generated match functions
  5. * @type {Object}
  6. */
  7. var pMatchFunctionCache = {};
  8. function compare_tagname(tag1, tag2) {
  9. if (!tag1) {
  10. return !tag2;
  11. }
  12. if (!tag2) {
  13. return !tag1;
  14. }
  15. return tag1.toLowerCase() === tag2.toLowerCase();
  16. }
  17. /**
  18. * Function cache
  19. */
  20. var functionCache = {
  21. f145: function (el, tagName, classes) {
  22. 'use strict';
  23. tagName = tagName || '';
  24. classes = classes || [];
  25. if (el.id !== tagName.substr(1)) {
  26. return false;
  27. }
  28. for (var cls = classes, i = 0; i < cls.length; i++) {
  29. if (el.classNames.indexOf(cls[i]) === -1) {
  30. return false;
  31. }
  32. }
  33. return true;
  34. },
  35. f45: function (el, tagName, classes) {
  36. 'use strict';
  37. tagName = tagName || '';
  38. classes = classes || [];
  39. for (var cls = classes, i = 0; i < cls.length; i++) {
  40. if (el.classNames.indexOf(cls[i]) === -1) {
  41. return false;
  42. }
  43. }
  44. return true;
  45. },
  46. f15: function (el, tagName) {
  47. 'use strict';
  48. tagName = tagName || '';
  49. if (el.id !== tagName.substr(1)) {
  50. return false;
  51. }
  52. return true;
  53. },
  54. f1: function (el, tagName) {
  55. 'use strict';
  56. tagName = tagName || '';
  57. if (el.id !== tagName.substr(1)) {
  58. return false;
  59. }
  60. },
  61. f5: function () {
  62. 'use strict';
  63. return true;
  64. },
  65. f55: function (el, tagName, classes, attr_key) {
  66. 'use strict';
  67. tagName = tagName || '';
  68. classes = classes || [];
  69. attr_key = attr_key || '';
  70. var attrs = el.attributes;
  71. return attrs.hasOwnProperty(attr_key);
  72. },
  73. f245: function (el, tagName, classes, attr_key, value) {
  74. 'use strict';
  75. tagName = tagName || '';
  76. classes = classes || [];
  77. attr_key = attr_key || '';
  78. value = value || '';
  79. var attrs = el.attributes;
  80. return Object.keys(attrs).some(function (key) {
  81. var val = attrs[key];
  82. return key === attr_key && val === value;
  83. });
  84. // for (let cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}}
  85. // return true;
  86. },
  87. f25: function (el, tagName, classes, attr_key, value) {
  88. 'use strict';
  89. tagName = tagName || '';
  90. classes = classes || [];
  91. attr_key = attr_key || '';
  92. value = value || '';
  93. var attrs = el.attributes;
  94. return Object.keys(attrs).some(function (key) {
  95. var val = attrs[key];
  96. return key === attr_key && val === value;
  97. });
  98. // return true;
  99. },
  100. f2: function (el, tagName, classes, attr_key, value) {
  101. 'use strict';
  102. tagName = tagName || '';
  103. classes = classes || [];
  104. attr_key = attr_key || '';
  105. value = value || '';
  106. var attrs = el.attributes;
  107. return Object.keys(attrs).some(function (key) {
  108. var val = attrs[key];
  109. return key === attr_key && val === value;
  110. });
  111. },
  112. f345: function (el, tagName, classes) {
  113. 'use strict';
  114. tagName = tagName || '';
  115. classes = classes || [];
  116. if (!compare_tagname(el.tagName, tagName)) {
  117. return false;
  118. }
  119. for (var cls = classes, i = 0; i < cls.length; i++) {
  120. if (el.classNames.indexOf(cls[i]) === -1) {
  121. return false;
  122. }
  123. }
  124. return true;
  125. },
  126. f35: function (el, tagName) {
  127. 'use strict';
  128. tagName = tagName || '';
  129. return compare_tagname(el.tagName, tagName);
  130. },
  131. f3: function (el, tagName) {
  132. 'use strict';
  133. tagName = tagName || '';
  134. // if (el.tagName !== tagName) {
  135. // return false;
  136. // }
  137. return compare_tagname(el.tagName, tagName);
  138. }
  139. };
  140. /**
  141. * Matcher class to make CSS match
  142. *
  143. * @class Matcher
  144. */
  145. var Matcher = /** @class */ (function () {
  146. /**
  147. * Creates an instance of Matcher.
  148. * @param {string} selector
  149. *
  150. * @memberof Matcher
  151. */
  152. function Matcher(selector) {
  153. this.nextMatch = 0;
  154. this.matchers = selector.split(' ').map(function (matcher) {
  155. if (pMatchFunctionCache[matcher]) {
  156. return pMatchFunctionCache[matcher];
  157. }
  158. var parts = matcher.split('.');
  159. var tagName = parts[0];
  160. var classes = parts.slice(1).sort();
  161. // let source = '"use strict";';
  162. var function_name = 'f';
  163. var attr_key = '';
  164. var value = '';
  165. if (tagName && tagName !== '*') {
  166. var reg = void 0;
  167. if (tagName.startsWith('#')) {
  168. // source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';// 1
  169. function_name += '1';
  170. }
  171. else {
  172. reg = /^\[\s*(\S+)\s*(=|!=)\s*((((["'])([^\6]*)\6))|(\S*?))\]\s*/.exec(tagName);
  173. if (reg) {
  174. attr_key = reg[1];
  175. var method = reg[2];
  176. if (method !== '=' && method !== '!=') {
  177. // eslint-disable-next-line no-template-curly-in-string
  178. throw new Error('Selector not supported, Expect [key${op}value].op must be =,!=');
  179. }
  180. if (method === '=') {
  181. method = '==';
  182. }
  183. value = reg[7] || reg[8];
  184. // source += `let attrs = el.attributes;for (let key in attrs){const val = attrs[key]; if (key == "${attr_key}" && val == "${value}"){return true;}} return false;`;// 2
  185. function_name += '2';
  186. }
  187. else if ((reg = /^\[(.*?)\]/.exec(tagName))) {
  188. attr_key = reg[1];
  189. function_name += '5';
  190. }
  191. else {
  192. // source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';// 3
  193. function_name += '3';
  194. }
  195. }
  196. }
  197. if (classes.length > 0) {
  198. // source += 'for (let cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;';// 4
  199. function_name += '4';
  200. }
  201. // source += 'return true;';// 5
  202. function_name += '5';
  203. var obj = {
  204. func: functionCache[function_name],
  205. tagName: tagName || '',
  206. classes: classes || '',
  207. attr_key: attr_key || '',
  208. value: value || ''
  209. };
  210. // source = source || '';
  211. return (pMatchFunctionCache[matcher] = obj);
  212. });
  213. }
  214. /**
  215. * Trying to advance match pointer
  216. * @param {HTMLElement} el element to make the match
  217. * @return {bool} true when pointer advanced.
  218. */
  219. Matcher.prototype.advance = function (el) {
  220. if (this.nextMatch < this.matchers.length &&
  221. this.matchers[this.nextMatch].func(el, this.matchers[this.nextMatch].tagName, this.matchers[this.nextMatch].classes, this.matchers[this.nextMatch].attr_key, this.matchers[this.nextMatch].value)) {
  222. this.nextMatch++;
  223. return true;
  224. }
  225. return false;
  226. };
  227. /**
  228. * Rewind the match pointer
  229. */
  230. Matcher.prototype.rewind = function () {
  231. this.nextMatch--;
  232. };
  233. Object.defineProperty(Matcher.prototype, "matched", {
  234. /**
  235. * Trying to determine if match made.
  236. * @return {bool} true when the match is made
  237. */
  238. get: function () {
  239. return this.nextMatch === this.matchers.length;
  240. },
  241. enumerable: false,
  242. configurable: true
  243. });
  244. /**
  245. * Rest match pointer.
  246. * @return {[type]} [description]
  247. */
  248. Matcher.prototype.reset = function () {
  249. this.nextMatch = 0;
  250. };
  251. /**
  252. * flush cache to free memory
  253. */
  254. Matcher.prototype.flushCache = function () {
  255. pMatchFunctionCache = {};
  256. };
  257. return Matcher;
  258. }());
  259. exports.default = Matcher;