attributes.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.attributeRules = void 0;
  7. var boolbase_1 = __importDefault(require("boolbase"));
  8. /**
  9. * All reserved characters in a regex, used for escaping.
  10. *
  11. * Taken from XRegExp, (c) 2007-2020 Steven Levithan under the MIT license
  12. * https://github.com/slevithan/xregexp/blob/95eeebeb8fac8754d54eafe2b4743661ac1cf028/src/xregexp.js#L794
  13. */
  14. var reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
  15. function escapeRegex(value) {
  16. return value.replace(reChars, "\\$&");
  17. }
  18. /**
  19. * Attributes that are case-insensitive in HTML.
  20. *
  21. * @private
  22. * @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
  23. */
  24. var caseInsensitiveAttributes = new Set([
  25. "accept",
  26. "accept-charset",
  27. "align",
  28. "alink",
  29. "axis",
  30. "bgcolor",
  31. "charset",
  32. "checked",
  33. "clear",
  34. "codetype",
  35. "color",
  36. "compact",
  37. "declare",
  38. "defer",
  39. "dir",
  40. "direction",
  41. "disabled",
  42. "enctype",
  43. "face",
  44. "frame",
  45. "hreflang",
  46. "http-equiv",
  47. "lang",
  48. "language",
  49. "link",
  50. "media",
  51. "method",
  52. "multiple",
  53. "nohref",
  54. "noresize",
  55. "noshade",
  56. "nowrap",
  57. "readonly",
  58. "rel",
  59. "rev",
  60. "rules",
  61. "scope",
  62. "scrolling",
  63. "selected",
  64. "shape",
  65. "target",
  66. "text",
  67. "type",
  68. "valign",
  69. "valuetype",
  70. "vlink",
  71. ]);
  72. function shouldIgnoreCase(selector, options) {
  73. return typeof selector.ignoreCase === "boolean"
  74. ? selector.ignoreCase
  75. : selector.ignoreCase === "quirks"
  76. ? !!options.quirksMode
  77. : !options.xmlMode && caseInsensitiveAttributes.has(selector.name);
  78. }
  79. /**
  80. * Attribute selectors
  81. */
  82. exports.attributeRules = {
  83. equals: function (next, data, options) {
  84. var adapter = options.adapter;
  85. var name = data.name;
  86. var value = data.value;
  87. if (shouldIgnoreCase(data, options)) {
  88. value = value.toLowerCase();
  89. return function (elem) {
  90. var attr = adapter.getAttributeValue(elem, name);
  91. return (attr != null &&
  92. attr.length === value.length &&
  93. attr.toLowerCase() === value &&
  94. next(elem));
  95. };
  96. }
  97. return function (elem) {
  98. return adapter.getAttributeValue(elem, name) === value && next(elem);
  99. };
  100. },
  101. hyphen: function (next, data, options) {
  102. var adapter = options.adapter;
  103. var name = data.name;
  104. var value = data.value;
  105. var len = value.length;
  106. if (shouldIgnoreCase(data, options)) {
  107. value = value.toLowerCase();
  108. return function hyphenIC(elem) {
  109. var attr = adapter.getAttributeValue(elem, name);
  110. return (attr != null &&
  111. (attr.length === len || attr.charAt(len) === "-") &&
  112. attr.substr(0, len).toLowerCase() === value &&
  113. next(elem));
  114. };
  115. }
  116. return function hyphen(elem) {
  117. var attr = adapter.getAttributeValue(elem, name);
  118. return (attr != null &&
  119. (attr.length === len || attr.charAt(len) === "-") &&
  120. attr.substr(0, len) === value &&
  121. next(elem));
  122. };
  123. },
  124. element: function (next, data, options) {
  125. var adapter = options.adapter;
  126. var name = data.name, value = data.value;
  127. if (/\s/.test(value)) {
  128. return boolbase_1.default.falseFunc;
  129. }
  130. var regex = new RegExp("(?:^|\\s)".concat(escapeRegex(value), "(?:$|\\s)"), shouldIgnoreCase(data, options) ? "i" : "");
  131. return function element(elem) {
  132. var attr = adapter.getAttributeValue(elem, name);
  133. return (attr != null &&
  134. attr.length >= value.length &&
  135. regex.test(attr) &&
  136. next(elem));
  137. };
  138. },
  139. exists: function (next, _a, _b) {
  140. var name = _a.name;
  141. var adapter = _b.adapter;
  142. return function (elem) { return adapter.hasAttrib(elem, name) && next(elem); };
  143. },
  144. start: function (next, data, options) {
  145. var adapter = options.adapter;
  146. var name = data.name;
  147. var value = data.value;
  148. var len = value.length;
  149. if (len === 0) {
  150. return boolbase_1.default.falseFunc;
  151. }
  152. if (shouldIgnoreCase(data, options)) {
  153. value = value.toLowerCase();
  154. return function (elem) {
  155. var attr = adapter.getAttributeValue(elem, name);
  156. return (attr != null &&
  157. attr.length >= len &&
  158. attr.substr(0, len).toLowerCase() === value &&
  159. next(elem));
  160. };
  161. }
  162. return function (elem) {
  163. var _a;
  164. return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.startsWith(value)) &&
  165. next(elem);
  166. };
  167. },
  168. end: function (next, data, options) {
  169. var adapter = options.adapter;
  170. var name = data.name;
  171. var value = data.value;
  172. var len = -value.length;
  173. if (len === 0) {
  174. return boolbase_1.default.falseFunc;
  175. }
  176. if (shouldIgnoreCase(data, options)) {
  177. value = value.toLowerCase();
  178. return function (elem) {
  179. var _a;
  180. return ((_a = adapter
  181. .getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.substr(len).toLowerCase()) === value && next(elem);
  182. };
  183. }
  184. return function (elem) {
  185. var _a;
  186. return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.endsWith(value)) &&
  187. next(elem);
  188. };
  189. },
  190. any: function (next, data, options) {
  191. var adapter = options.adapter;
  192. var name = data.name, value = data.value;
  193. if (value === "") {
  194. return boolbase_1.default.falseFunc;
  195. }
  196. if (shouldIgnoreCase(data, options)) {
  197. var regex_1 = new RegExp(escapeRegex(value), "i");
  198. return function anyIC(elem) {
  199. var attr = adapter.getAttributeValue(elem, name);
  200. return (attr != null &&
  201. attr.length >= value.length &&
  202. regex_1.test(attr) &&
  203. next(elem));
  204. };
  205. }
  206. return function (elem) {
  207. var _a;
  208. return !!((_a = adapter.getAttributeValue(elem, name)) === null || _a === void 0 ? void 0 : _a.includes(value)) &&
  209. next(elem);
  210. };
  211. },
  212. not: function (next, data, options) {
  213. var adapter = options.adapter;
  214. var name = data.name;
  215. var value = data.value;
  216. if (value === "") {
  217. return function (elem) {
  218. return !!adapter.getAttributeValue(elem, name) && next(elem);
  219. };
  220. }
  221. else if (shouldIgnoreCase(data, options)) {
  222. value = value.toLowerCase();
  223. return function (elem) {
  224. var attr = adapter.getAttributeValue(elem, name);
  225. return ((attr == null ||
  226. attr.length !== value.length ||
  227. attr.toLowerCase() !== value) &&
  228. next(elem));
  229. };
  230. }
  231. return function (elem) {
  232. return adapter.getAttributeValue(elem, name) !== value && next(elem);
  233. };
  234. },
  235. };
  236. //# sourceMappingURL=attributes.js.map