UNPKG

1.73 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const rangeOperators = ['>=', '<=', '>', '<', '='];
6const styleSearch = require('style-search');
7
8function getRangeContextOperators(node) {
9 const operators = [];
10
11 styleSearch({ source: node.value, target: rangeOperators }, (match) => {
12 const before = node[match.startIndex - 1];
13
14 if (before === '>' || before === '<') {
15 return;
16 }
17
18 operators.push(match.target);
19 });
20
21 // Sorting helps when using the operators to split
22 // E.g. for "(10em < width <= 50em)" this returns ["<=", "<"]
23 return operators.sort((a, b) => b.length - a.length);
24}
25
26function getRangeContextName(parsedNode) {
27 // When the node is like "(10em < width < 50em)"
28 // The parsedNode is ["10em", "width", "50em"] - the name is always in the second position
29 if (parsedNode.length === 3) {
30 return parsedNode[1];
31 }
32
33 // When the node is like "(width > 10em)" or "(10em < width)"
34 // Regex is needed because the name can either be in the first or second position
35 return parsedNode.find((value) => value.match(/^(?!--)\D+/) || value.match(/^(--).+/));
36}
37
38module.exports = function (node) {
39 const nodeValue = node.value;
40
41 const operators = getRangeContextOperators(node);
42
43 // Remove spaces and parentheses and split by the operators
44 const parsedMedia = nodeValue.replace(/[()\s]/g, '').split(new RegExp(operators.join('|')));
45
46 const name = getRangeContextName(parsedMedia);
47 const nameObj = {
48 value: name,
49 sourceIndex: node.sourceIndex + nodeValue.indexOf(name),
50 };
51
52 const values = parsedMedia
53 .filter((parsedValue) => parsedValue !== name)
54 .map((value) => {
55 return {
56 value,
57 sourceIndex: node.sourceIndex + nodeValue.indexOf(value),
58 };
59 });
60
61 return {
62 name: nameObj,
63 values,
64 };
65};