columns.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _postcss = require('postcss');
  6. var _postcssValueParser = require('postcss-value-parser');
  7. var _stylehacks = require('stylehacks');
  8. var _canMerge = require('../canMerge');
  9. var _canMerge2 = _interopRequireDefault(_canMerge);
  10. var _getDecls = require('../getDecls');
  11. var _getDecls2 = _interopRequireDefault(_getDecls);
  12. var _getValue = require('../getValue');
  13. var _getValue2 = _interopRequireDefault(_getValue);
  14. var _mergeRules = require('../mergeRules');
  15. var _mergeRules2 = _interopRequireDefault(_mergeRules);
  16. var _insertCloned = require('../insertCloned');
  17. var _insertCloned2 = _interopRequireDefault(_insertCloned);
  18. var _remove = require('../remove');
  19. var _remove2 = _interopRequireDefault(_remove);
  20. var _isCustomProp = require('../isCustomProp');
  21. var _isCustomProp2 = _interopRequireDefault(_isCustomProp);
  22. var _canExplode = require('../canExplode');
  23. var _canExplode2 = _interopRequireDefault(_canExplode);
  24. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  25. const properties = ['column-width', 'column-count'];
  26. const auto = 'auto';
  27. const inherit = 'inherit';
  28. /**
  29. * Normalize a columns shorthand definition. Both of the longhand
  30. * properties' initial values are 'auto', and as per the spec,
  31. * omitted values are set to their initial values. Thus, we can
  32. * remove any 'auto' definition when there are two values.
  33. *
  34. * Specification link: https://www.w3.org/TR/css3-multicol/
  35. */
  36. function normalize(values) {
  37. if (values[0].toLowerCase() === auto) {
  38. return values[1];
  39. }
  40. if (values[1].toLowerCase() === auto) {
  41. return values[0];
  42. }
  43. if (values[0].toLowerCase() === inherit && values[1].toLowerCase() === inherit) {
  44. return inherit;
  45. }
  46. return values.join(' ');
  47. }
  48. function explode(rule) {
  49. rule.walkDecls(/^columns$/i, decl => {
  50. if (!(0, _canExplode2.default)(decl)) {
  51. return;
  52. }
  53. if ((0, _stylehacks.detect)(decl)) {
  54. return;
  55. }
  56. let values = _postcss.list.space(decl.value);
  57. if (values.length === 1) {
  58. values.push(auto);
  59. }
  60. values.forEach((value, i) => {
  61. let prop = properties[1];
  62. if (value.toLowerCase() === auto) {
  63. prop = properties[i];
  64. } else if ((0, _postcssValueParser.unit)(value).unit) {
  65. prop = properties[0];
  66. }
  67. (0, _insertCloned2.default)(decl.parent, decl, {
  68. prop,
  69. value
  70. });
  71. });
  72. decl.remove();
  73. });
  74. }
  75. function cleanup(rule) {
  76. let decls = (0, _getDecls2.default)(rule, ['columns'].concat(properties));
  77. while (decls.length) {
  78. const lastNode = decls[decls.length - 1];
  79. // remove properties of lower precedence
  80. const lesser = decls.filter(node => !(0, _stylehacks.detect)(lastNode) && !(0, _stylehacks.detect)(node) && node !== lastNode && node.important === lastNode.important && lastNode.prop === 'columns' && node.prop !== lastNode.prop);
  81. lesser.forEach(_remove2.default);
  82. decls = decls.filter(node => !~lesser.indexOf(node));
  83. // get duplicate properties
  84. let duplicates = decls.filter(node => !(0, _stylehacks.detect)(lastNode) && !(0, _stylehacks.detect)(node) && node !== lastNode && node.important === lastNode.important && node.prop === lastNode.prop && !(!(0, _isCustomProp2.default)(node) && (0, _isCustomProp2.default)(lastNode)));
  85. duplicates.forEach(_remove2.default);
  86. decls = decls.filter(node => node !== lastNode && !~duplicates.indexOf(node));
  87. }
  88. }
  89. function merge(rule) {
  90. (0, _mergeRules2.default)(rule, properties, (rules, lastNode) => {
  91. if ((0, _canMerge2.default)(rules) && !rules.some(_stylehacks.detect)) {
  92. (0, _insertCloned2.default)(lastNode.parent, lastNode, {
  93. prop: 'columns',
  94. value: normalize(rules.map(_getValue2.default))
  95. });
  96. rules.forEach(_remove2.default);
  97. return true;
  98. }
  99. });
  100. cleanup(rule);
  101. }
  102. exports.default = {
  103. explode,
  104. merge
  105. };
  106. module.exports = exports['default'];