source: trip-planner-front/node_modules/postcss-merge-longhand/dist/lib/decl/borders.js@ 188ee53

Last change on this file since 188ee53 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 19.0 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8var _postcss = require("postcss");
9
10var _stylehacks = require("stylehacks");
11
12var _insertCloned = _interopRequireDefault(require("../insertCloned"));
13
14var _parseTrbl = _interopRequireDefault(require("../parseTrbl"));
15
16var _hasAllProps = _interopRequireDefault(require("../hasAllProps"));
17
18var _getDecls = _interopRequireDefault(require("../getDecls"));
19
20var _getRules = _interopRequireDefault(require("../getRules"));
21
22var _getValue = _interopRequireDefault(require("../getValue"));
23
24var _mergeRules = _interopRequireDefault(require("../mergeRules"));
25
26var _minifyTrbl = _interopRequireDefault(require("../minifyTrbl"));
27
28var _minifyWsc = _interopRequireDefault(require("../minifyWsc"));
29
30var _canMerge = _interopRequireDefault(require("../canMerge"));
31
32var _remove = _interopRequireDefault(require("../remove"));
33
34var _trbl = _interopRequireDefault(require("../trbl"));
35
36var _isCustomProp = _interopRequireDefault(require("../isCustomProp"));
37
38var _canExplode = _interopRequireDefault(require("../canExplode"));
39
40var _getLastNode = _interopRequireDefault(require("../getLastNode"));
41
42var _parseWsc = _interopRequireDefault(require("../parseWsc"));
43
44var _validateWsc = require("../validateWsc");
45
46function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
47
48const wsc = ['width', 'style', 'color'];
49const defaults = ['medium', 'none', 'currentcolor'];
50
51function borderProperty(...parts) {
52 return `border-${parts.join('-')}`;
53}
54
55function mapBorderProperty(value) {
56 return borderProperty(value);
57}
58
59const directions = _trbl.default.map(mapBorderProperty);
60
61const properties = wsc.map(mapBorderProperty);
62const directionalProperties = directions.reduce((prev, curr) => prev.concat(wsc.map(prop => `${curr}-${prop}`)), []);
63const precedence = [['border'], directions.concat(properties), directionalProperties];
64const allProperties = precedence.reduce((a, b) => a.concat(b));
65
66function getLevel(prop) {
67 for (let i = 0; i < precedence.length; i++) {
68 if (~precedence[i].indexOf(prop.toLowerCase())) {
69 return i;
70 }
71 }
72}
73
74const isValueCustomProp = value => value && !!~value.search(/var\s*\(\s*--/i);
75
76function canMergeValues(values) {
77 return !values.some(isValueCustomProp);
78}
79
80function getColorValue(decl) {
81 if (decl.prop.substr(-5) === 'color') {
82 return decl.value;
83 }
84
85 return (0, _parseWsc.default)(decl.value)[2] || defaults[2];
86}
87
88function diffingProps(values, nextValues) {
89 return wsc.reduce((prev, curr, i) => {
90 if (values[i] === nextValues[i]) {
91 return prev;
92 }
93
94 return [...prev, curr];
95 }, []);
96}
97
98function mergeRedundant({
99 values,
100 nextValues,
101 decl,
102 nextDecl,
103 index
104}) {
105 if (!(0, _canMerge.default)([decl, nextDecl])) {
106 return;
107 }
108
109 if ((0, _stylehacks.detect)(decl) || (0, _stylehacks.detect)(nextDecl)) {
110 return;
111 }
112
113 const diff = diffingProps(values, nextValues);
114
115 if (diff.length > 1) {
116 return;
117 }
118
119 const prop = diff.pop();
120 const position = wsc.indexOf(prop);
121 const prop1 = `${nextDecl.prop}-${prop}`;
122 const prop2 = `border-${prop}`;
123 let props = (0, _parseTrbl.default)(values[position]);
124 props[index] = nextValues[position];
125 const borderValue2 = values.filter((e, i) => i !== position).join(' ');
126 const propValue2 = (0, _minifyTrbl.default)(props);
127 const origLength = ((0, _minifyWsc.default)(decl.value) + nextDecl.prop + nextDecl.value).length;
128 const newLength1 = decl.value.length + prop1.length + (0, _minifyWsc.default)(nextValues[position]).length;
129 const newLength2 = borderValue2.length + prop2.length + propValue2.length;
130
131 if (newLength1 < newLength2 && newLength1 < origLength) {
132 nextDecl.prop = prop1;
133 nextDecl.value = nextValues[position];
134 }
135
136 if (newLength2 < newLength1 && newLength2 < origLength) {
137 decl.value = borderValue2;
138 nextDecl.prop = prop2;
139 nextDecl.value = propValue2;
140 }
141}
142
143function isCloseEnough(mapped) {
144 return mapped[0] === mapped[1] && mapped[1] === mapped[2] || mapped[1] === mapped[2] && mapped[2] === mapped[3] || mapped[2] === mapped[3] && mapped[3] === mapped[0] || mapped[3] === mapped[0] && mapped[0] === mapped[1];
145}
146
147function getDistinctShorthands(mapped) {
148 return mapped.reduce((a, b) => {
149 a = Array.isArray(a) ? a : [a];
150
151 if (!~a.indexOf(b)) {
152 a.push(b);
153 }
154
155 return a;
156 });
157}
158
159function explode(rule) {
160 rule.walkDecls(/^border/i, decl => {
161 if (!(0, _canExplode.default)(decl, false)) {
162 return;
163 }
164
165 if ((0, _stylehacks.detect)(decl)) {
166 return;
167 }
168
169 const prop = decl.prop.toLowerCase(); // border -> border-trbl
170
171 if (prop === 'border') {
172 if ((0, _validateWsc.isValidWsc)((0, _parseWsc.default)(decl.value))) {
173 directions.forEach(direction => {
174 (0, _insertCloned.default)(decl.parent, decl, {
175 prop: direction
176 });
177 });
178 return decl.remove();
179 }
180 } // border-trbl -> border-trbl-wsc
181
182
183 if (directions.some(direction => prop === direction)) {
184 let values = (0, _parseWsc.default)(decl.value);
185
186 if ((0, _validateWsc.isValidWsc)(values)) {
187 wsc.forEach((d, i) => {
188 (0, _insertCloned.default)(decl.parent, decl, {
189 prop: `${prop}-${d}`,
190 value: values[i] || defaults[i]
191 });
192 });
193 return decl.remove();
194 }
195 } // border-wsc -> border-trbl-wsc
196
197
198 wsc.some(style => {
199 if (prop !== borderProperty(style)) {
200 return false;
201 }
202
203 (0, _parseTrbl.default)(decl.value).forEach((value, i) => {
204 (0, _insertCloned.default)(decl.parent, decl, {
205 prop: borderProperty(_trbl.default[i], style),
206 value
207 });
208 });
209 return decl.remove();
210 });
211 });
212}
213
214function merge(rule) {
215 // border-trbl-wsc -> border-trbl
216 _trbl.default.forEach(direction => {
217 const prop = borderProperty(direction);
218 (0, _mergeRules.default)(rule, wsc.map(style => borderProperty(direction, style)), (rules, lastNode) => {
219 if ((0, _canMerge.default)(rules, false) && !rules.some(_stylehacks.detect)) {
220 (0, _insertCloned.default)(lastNode.parent, lastNode, {
221 prop,
222 value: rules.map(_getValue.default).join(' ')
223 });
224 rules.forEach(_remove.default);
225 return true;
226 }
227 });
228 }); // border-trbl-wsc -> border-wsc
229
230
231 wsc.forEach(style => {
232 const prop = borderProperty(style);
233 (0, _mergeRules.default)(rule, _trbl.default.map(direction => borderProperty(direction, style)), (rules, lastNode) => {
234 if ((0, _canMerge.default)(rules) && !rules.some(_stylehacks.detect)) {
235 (0, _insertCloned.default)(lastNode.parent, lastNode, {
236 prop,
237 value: (0, _minifyTrbl.default)(rules.map(_getValue.default).join(' '))
238 });
239 rules.forEach(_remove.default);
240 return true;
241 }
242 });
243 }); // border-trbl -> border-wsc
244
245 (0, _mergeRules.default)(rule, directions, (rules, lastNode) => {
246 if (rules.some(_stylehacks.detect)) {
247 return;
248 }
249
250 const values = rules.map(({
251 value
252 }) => value);
253
254 if (!canMergeValues(values)) {
255 return;
256 }
257
258 const parsed = values.map(value => (0, _parseWsc.default)(value));
259
260 if (!parsed.every(_validateWsc.isValidWsc)) {
261 return;
262 }
263
264 wsc.forEach((d, i) => {
265 const value = parsed.map(v => v[i] || defaults[i]);
266
267 if (canMergeValues(value)) {
268 (0, _insertCloned.default)(lastNode.parent, lastNode, {
269 prop: borderProperty(d),
270 value: (0, _minifyTrbl.default)(value)
271 });
272 } else {
273 (0, _insertCloned.default)(lastNode.parent, lastNode);
274 }
275 });
276 rules.forEach(_remove.default);
277 return true;
278 }); // border-wsc -> border
279 // border-wsc -> border + border-color
280 // border-wsc -> border + border-dir
281
282 (0, _mergeRules.default)(rule, properties, (rules, lastNode) => {
283 if (rules.some(_stylehacks.detect)) {
284 return;
285 }
286
287 const values = rules.map(node => (0, _parseTrbl.default)(node.value));
288 const mapped = [0, 1, 2, 3].map(i => [values[0][i], values[1][i], values[2][i]].join(' '));
289
290 if (!canMergeValues(mapped)) {
291 return;
292 }
293
294 const [width, style, color] = rules;
295 const reduced = getDistinctShorthands(mapped);
296
297 if (isCloseEnough(mapped) && (0, _canMerge.default)(rules, false)) {
298 const first = mapped.indexOf(reduced[0]) !== mapped.lastIndexOf(reduced[0]);
299 const border = (0, _insertCloned.default)(lastNode.parent, lastNode, {
300 prop: 'border',
301 value: first ? reduced[0] : reduced[1]
302 });
303
304 if (reduced[1]) {
305 const value = first ? reduced[1] : reduced[0];
306 const prop = borderProperty(_trbl.default[mapped.indexOf(value)]);
307 rule.insertAfter(border, Object.assign(lastNode.clone(), {
308 prop,
309 value
310 }));
311 }
312
313 rules.forEach(_remove.default);
314 return true;
315 } else if (reduced.length === 1) {
316 rule.insertBefore(color, Object.assign(lastNode.clone(), {
317 prop: 'border',
318 value: [width, style].map(_getValue.default).join(' ')
319 }));
320 rules.filter(node => node.prop.toLowerCase() !== properties[2]).forEach(_remove.default);
321 return true;
322 }
323 }); // border-wsc -> border + border-trbl
324
325 (0, _mergeRules.default)(rule, properties, (rules, lastNode) => {
326 if (rules.some(_stylehacks.detect)) {
327 return;
328 }
329
330 const values = rules.map(node => (0, _parseTrbl.default)(node.value));
331 const mapped = [0, 1, 2, 3].map(i => [values[0][i], values[1][i], values[2][i]].join(' '));
332 const reduced = getDistinctShorthands(mapped);
333 const none = 'medium none currentcolor';
334
335 if (reduced.length > 1 && reduced.length < 4 && reduced.includes(none)) {
336 const filtered = mapped.filter(p => p !== none);
337 const mostCommon = reduced.sort((a, b) => mapped.filter(v => v === b).length - mapped.filter(v => v === a).length)[0];
338 const borderValue = reduced.length === 2 ? filtered[0] : mostCommon;
339 rule.insertBefore(lastNode, Object.assign(lastNode.clone(), {
340 prop: 'border',
341 value: borderValue
342 }));
343 directions.forEach((dir, i) => {
344 if (mapped[i] !== borderValue) {
345 rule.insertBefore(lastNode, Object.assign(lastNode.clone(), {
346 prop: dir,
347 value: mapped[i]
348 }));
349 }
350 });
351 rules.forEach(_remove.default);
352 return true;
353 }
354 }); // border-trbl -> border
355 // border-trbl -> border + border-trbl
356
357 (0, _mergeRules.default)(rule, directions, (rules, lastNode) => {
358 if (rules.some(_stylehacks.detect)) {
359 return;
360 }
361
362 const values = rules.map(node => {
363 const wscValue = (0, _parseWsc.default)(node.value);
364
365 if (!(0, _validateWsc.isValidWsc)(wscValue)) {
366 return node.value;
367 }
368
369 return wscValue.map((value, i) => value || defaults[i]).join(' ');
370 });
371 const reduced = getDistinctShorthands(values);
372
373 if (isCloseEnough(values)) {
374 const first = values.indexOf(reduced[0]) !== values.lastIndexOf(reduced[0]);
375 rule.insertBefore(lastNode, Object.assign(lastNode.clone(), {
376 prop: 'border',
377 value: (0, _minifyWsc.default)(first ? values[0] : values[1])
378 }));
379
380 if (reduced[1]) {
381 const value = first ? reduced[1] : reduced[0];
382 const prop = directions[values.indexOf(value)];
383 rule.insertBefore(lastNode, Object.assign(lastNode.clone(), {
384 prop: prop,
385 value: (0, _minifyWsc.default)(value)
386 }));
387 }
388
389 rules.forEach(_remove.default);
390 return true;
391 }
392 }); // border-trbl-wsc + border-trbl (custom prop) -> border-trbl + border-trbl-wsc (custom prop)
393
394 directions.forEach(direction => {
395 wsc.forEach((style, i) => {
396 const prop = `${direction}-${style}`;
397 (0, _mergeRules.default)(rule, [direction, prop], (rules, lastNode) => {
398 if (lastNode.prop !== direction) {
399 return;
400 }
401
402 const values = (0, _parseWsc.default)(lastNode.value);
403
404 if (!(0, _validateWsc.isValidWsc)(values)) {
405 return;
406 }
407
408 const wscProp = rules.filter(r => r !== lastNode)[0];
409
410 if (!isValueCustomProp(values[i]) || (0, _isCustomProp.default)(wscProp)) {
411 return;
412 }
413
414 const wscValue = values[i];
415 values[i] = wscProp.value;
416
417 if ((0, _canMerge.default)(rules, false) && !rules.some(_stylehacks.detect)) {
418 (0, _insertCloned.default)(lastNode.parent, lastNode, {
419 prop,
420 value: wscValue
421 });
422 lastNode.value = (0, _minifyWsc.default)(values);
423 wscProp.remove();
424 return true;
425 }
426 });
427 });
428 }); // border-wsc + border (custom prop) -> border + border-wsc (custom prop)
429
430 wsc.forEach((style, i) => {
431 const prop = borderProperty(style);
432 (0, _mergeRules.default)(rule, ['border', prop], (rules, lastNode) => {
433 if (lastNode.prop !== 'border') {
434 return;
435 }
436
437 const values = (0, _parseWsc.default)(lastNode.value);
438
439 if (!(0, _validateWsc.isValidWsc)(values)) {
440 return;
441 }
442
443 const wscProp = rules.filter(r => r !== lastNode)[0];
444
445 if (!isValueCustomProp(values[i]) || (0, _isCustomProp.default)(wscProp)) {
446 return;
447 }
448
449 const wscValue = values[i];
450 values[i] = wscProp.value;
451
452 if ((0, _canMerge.default)(rules, false) && !rules.some(_stylehacks.detect)) {
453 (0, _insertCloned.default)(lastNode.parent, lastNode, {
454 prop,
455 value: wscValue
456 });
457 lastNode.value = (0, _minifyWsc.default)(values);
458 wscProp.remove();
459 return true;
460 }
461 });
462 }); // optimize border-trbl
463
464 let decls = (0, _getDecls.default)(rule, directions);
465
466 while (decls.length) {
467 const lastNode = decls[decls.length - 1];
468 wsc.forEach((d, i) => {
469 const names = directions.filter(name => name !== lastNode.prop).map(name => `${name}-${d}`);
470 let nodes = rule.nodes.slice(0, rule.nodes.indexOf(lastNode));
471 const border = (0, _getLastNode.default)(nodes, 'border');
472
473 if (border) {
474 nodes = nodes.slice(nodes.indexOf(border));
475 }
476
477 const props = nodes.filter(node => node.prop && ~names.indexOf(node.prop) && node.important === lastNode.important);
478 const rules = (0, _getRules.default)(props, names);
479
480 if ((0, _hasAllProps.default)(rules, ...names) && !rules.some(_stylehacks.detect)) {
481 const values = rules.map(node => node ? node.value : null);
482 const filteredValues = values.filter(Boolean);
483
484 const lastNodeValue = _postcss.list.space(lastNode.value)[i];
485
486 values[directions.indexOf(lastNode.prop)] = lastNodeValue;
487 let value = (0, _minifyTrbl.default)(values.join(' '));
488
489 if (filteredValues[0] === filteredValues[1] && filteredValues[1] === filteredValues[2]) {
490 value = filteredValues[0];
491 }
492
493 let refNode = props[props.length - 1];
494
495 if (value === lastNodeValue) {
496 refNode = lastNode;
497
498 let valueArray = _postcss.list.space(lastNode.value);
499
500 valueArray.splice(i, 1);
501 lastNode.value = valueArray.join(' ');
502 }
503
504 (0, _insertCloned.default)(refNode.parent, refNode, {
505 prop: borderProperty(d),
506 value
507 });
508 decls = decls.filter(node => !~rules.indexOf(node));
509 rules.forEach(_remove.default);
510 }
511 });
512 decls = decls.filter(node => node !== lastNode);
513 }
514
515 rule.walkDecls('border', decl => {
516 const nextDecl = decl.next();
517
518 if (!nextDecl || nextDecl.type !== 'decl') {
519 return;
520 }
521
522 const index = directions.indexOf(nextDecl.prop);
523
524 if (!~index) {
525 return;
526 }
527
528 const values = (0, _parseWsc.default)(decl.value);
529 const nextValues = (0, _parseWsc.default)(nextDecl.value);
530
531 if (!(0, _validateWsc.isValidWsc)(values) || !(0, _validateWsc.isValidWsc)(nextValues)) {
532 return;
533 }
534
535 const config = {
536 values,
537 nextValues,
538 decl,
539 nextDecl,
540 index
541 };
542 return mergeRedundant(config);
543 });
544 rule.walkDecls(/^border($|-(top|right|bottom|left)$)/i, decl => {
545 let values = (0, _parseWsc.default)(decl.value);
546
547 if (!(0, _validateWsc.isValidWsc)(values)) {
548 return;
549 }
550
551 const position = directions.indexOf(decl.prop);
552 let dirs = [...directions];
553 dirs.splice(position, 1);
554 wsc.forEach((d, i) => {
555 const props = dirs.map(dir => `${dir}-${d}`);
556 (0, _mergeRules.default)(rule, [decl.prop, ...props], rules => {
557 if (!rules.includes(decl)) {
558 return;
559 }
560
561 const longhands = rules.filter(p => p !== decl);
562
563 if (longhands[0].value.toLowerCase() === longhands[1].value.toLowerCase() && longhands[1].value.toLowerCase() === longhands[2].value.toLowerCase() && values[i] !== undefined && longhands[0].value.toLowerCase() === values[i].toLowerCase()) {
564 longhands.forEach(_remove.default);
565 (0, _insertCloned.default)(decl.parent, decl, {
566 prop: borderProperty(d),
567 value: values[i]
568 });
569 values[i] = null;
570 }
571 });
572 const newValue = values.join(' ');
573
574 if (newValue) {
575 decl.value = newValue;
576 } else {
577 decl.remove();
578 }
579 });
580 }); // clean-up values
581
582 rule.walkDecls(/^border($|-(top|right|bottom|left)$)/i, decl => {
583 decl.value = (0, _minifyWsc.default)(decl.value);
584 }); // border-spacing-hv -> border-spacing
585
586 rule.walkDecls(/^border-spacing$/i, decl => {
587 const value = _postcss.list.space(decl.value); // merge vertical and horizontal dups
588
589
590 if (value.length > 1 && value[0] === value[1]) {
591 decl.value = value.slice(1).join(' ');
592 }
593 }); // clean-up rules
594
595 decls = (0, _getDecls.default)(rule, allProperties);
596
597 while (decls.length) {
598 const lastNode = decls[decls.length - 1];
599 const lastPart = lastNode.prop.split('-').pop(); // remove properties of lower precedence
600
601 const lesser = decls.filter(node => !(0, _stylehacks.detect)(lastNode) && !(0, _stylehacks.detect)(node) && !(0, _isCustomProp.default)(lastNode) && node !== lastNode && node.important === lastNode.important && getLevel(node.prop) > getLevel(lastNode.prop) && (!!~node.prop.toLowerCase().indexOf(lastNode.prop) || node.prop.toLowerCase().endsWith(lastPart)));
602 lesser.forEach(_remove.default);
603 decls = decls.filter(node => !~lesser.indexOf(node)); // get duplicate properties
604
605 let duplicates = decls.filter(node => !(0, _stylehacks.detect)(lastNode) && !(0, _stylehacks.detect)(node) && node !== lastNode && node.important === lastNode.important && node.prop === lastNode.prop && !(!(0, _isCustomProp.default)(node) && (0, _isCustomProp.default)(lastNode)));
606
607 if (duplicates.length) {
608 if (/hsla\(|rgba\(/i.test(getColorValue(lastNode))) {
609 const preserve = duplicates.filter(node => !/hsla\(|rgba\(/i.test(getColorValue(node))).pop();
610 duplicates = duplicates.filter(node => node !== preserve);
611 }
612
613 duplicates.forEach(_remove.default);
614 }
615
616 decls = decls.filter(node => node !== lastNode && !~duplicates.indexOf(node));
617 }
618}
619
620var _default = {
621 explode,
622 merge
623};
624exports.default = _default;
625module.exports = exports.default;
Note: See TracBrowser for help on using the repository browser.