UNPKG

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