selector.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. "use strict";
  2. function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
  3. function _createForOfIteratorHelperLoose(o) { var i = 0; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } i = o[Symbol.iterator](); return i.next.bind(i); }
  4. function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  5. function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  6. function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
  7. function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
  8. function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
  9. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
  10. function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
  11. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _defaults(subClass, superClass); }
  12. var _require = require('postcss'),
  13. list = _require.list;
  14. var OldSelector = require('./old-selector');
  15. var Prefixer = require('./prefixer');
  16. var Browsers = require('./browsers');
  17. var utils = require('./utils');
  18. var Selector = /*#__PURE__*/function (_Prefixer) {
  19. _inheritsLoose(Selector, _Prefixer);
  20. var _super = _createSuper(Selector);
  21. function Selector(name, prefixes, all) {
  22. var _this;
  23. _this = _Prefixer.call(this, name, prefixes, all) || this;
  24. _this.regexpCache = {};
  25. return _this;
  26. }
  27. /**
  28. * Is rule selectors need to be prefixed
  29. */
  30. var _proto = Selector.prototype;
  31. _proto.check = function check(rule) {
  32. if (rule.selector.includes(this.name)) {
  33. return !!rule.selector.match(this.regexp());
  34. }
  35. return false;
  36. }
  37. /**
  38. * Return prefixed version of selector
  39. */
  40. ;
  41. _proto.prefixed = function prefixed(prefix) {
  42. return this.name.replace(/^(\W*)/, "$1" + prefix);
  43. }
  44. /**
  45. * Lazy loadRegExp for name
  46. */
  47. ;
  48. _proto.regexp = function regexp(prefix) {
  49. if (this.regexpCache[prefix]) {
  50. return this.regexpCache[prefix];
  51. }
  52. var name = prefix ? this.prefixed(prefix) : this.name;
  53. this.regexpCache[prefix] = new RegExp("(^|[^:\"'=])" + utils.escapeRegexp(name), 'gi');
  54. return this.regexpCache[prefix];
  55. }
  56. /**
  57. * All possible prefixes
  58. */
  59. ;
  60. _proto.possible = function possible() {
  61. return Browsers.prefixes();
  62. }
  63. /**
  64. * Return all possible selector prefixes
  65. */
  66. ;
  67. _proto.prefixeds = function prefixeds(rule) {
  68. var _this2 = this;
  69. if (rule._autoprefixerPrefixeds) {
  70. if (rule._autoprefixerPrefixeds[this.name]) {
  71. return rule._autoprefixerPrefixeds;
  72. }
  73. } else {
  74. rule._autoprefixerPrefixeds = {};
  75. }
  76. var prefixeds = {};
  77. if (rule.selector.includes(',')) {
  78. var ruleParts = list.comma(rule.selector);
  79. var toProcess = ruleParts.filter(function (el) {
  80. return el.includes(_this2.name);
  81. });
  82. var _loop = function _loop() {
  83. var prefix = _step.value;
  84. prefixeds[prefix] = toProcess.map(function (el) {
  85. return _this2.replace(el, prefix);
  86. }).join(', ');
  87. };
  88. for (var _iterator = _createForOfIteratorHelperLoose(this.possible()), _step; !(_step = _iterator()).done;) {
  89. _loop();
  90. }
  91. } else {
  92. for (var _iterator2 = _createForOfIteratorHelperLoose(this.possible()), _step2; !(_step2 = _iterator2()).done;) {
  93. var prefix = _step2.value;
  94. prefixeds[prefix] = this.replace(rule.selector, prefix);
  95. }
  96. }
  97. rule._autoprefixerPrefixeds[this.name] = prefixeds;
  98. return rule._autoprefixerPrefixeds;
  99. }
  100. /**
  101. * Is rule already prefixed before
  102. */
  103. ;
  104. _proto.already = function already(rule, prefixeds, prefix) {
  105. var index = rule.parent.index(rule) - 1;
  106. while (index >= 0) {
  107. var before = rule.parent.nodes[index];
  108. if (before.type !== 'rule') {
  109. return false;
  110. }
  111. var some = false;
  112. for (var key in prefixeds[this.name]) {
  113. var prefixed = prefixeds[this.name][key];
  114. if (before.selector === prefixed) {
  115. if (prefix === key) {
  116. return true;
  117. } else {
  118. some = true;
  119. break;
  120. }
  121. }
  122. }
  123. if (!some) {
  124. return false;
  125. }
  126. index -= 1;
  127. }
  128. return false;
  129. }
  130. /**
  131. * Replace selectors by prefixed one
  132. */
  133. ;
  134. _proto.replace = function replace(selector, prefix) {
  135. return selector.replace(this.regexp(), "$1" + this.prefixed(prefix));
  136. }
  137. /**
  138. * Clone and add prefixes for at-rule
  139. */
  140. ;
  141. _proto.add = function add(rule, prefix) {
  142. var prefixeds = this.prefixeds(rule);
  143. if (this.already(rule, prefixeds, prefix)) {
  144. return;
  145. }
  146. var cloned = this.clone(rule, {
  147. selector: prefixeds[this.name][prefix]
  148. });
  149. rule.parent.insertBefore(rule, cloned);
  150. }
  151. /**
  152. * Return function to fast find prefixed selector
  153. */
  154. ;
  155. _proto.old = function old(prefix) {
  156. return new OldSelector(this, prefix);
  157. };
  158. return Selector;
  159. }(Prefixer);
  160. module.exports = Selector;