@thejaredwilcurt/csslop 0.0.20 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -53,4 +53,85 @@ function findMatchingParenthesis (value, openParenIndex) {
53
53
  return -1;
54
54
  }
55
55
 
56
- export { findMatchingParenthesis };
56
+ /**
57
+ * Splits a CSS value into its top-level components, keeping parenthesized
58
+ * function arguments and quoted strings intact. Components are separated by
59
+ * whitespace, or by a `#`, which always starts a hash token and therefore ends
60
+ * any component already in progress.
61
+ *
62
+ * For example, `rgb(0 0 0) red` yields `["rgb(0 0 0)", "red"]`, and the
63
+ * minified `red#00f` yields `["red", "#00f"]`.
64
+ *
65
+ * @param {string} value The CSS value to split.
66
+ * @return {Array} The top-level components of the value.
67
+ */
68
+ function splitTopLevelComponents (value) {
69
+ const components = [];
70
+ let current = '';
71
+ let depth = 0;
72
+ let activeQuote = '';
73
+ let index = 0;
74
+
75
+ while (index < value.length) {
76
+ const character = value[index];
77
+
78
+ if (activeQuote) {
79
+ current += character;
80
+ if (character === '\\') {
81
+ current += value[index + 1] ?? '';
82
+ index += 2;
83
+ continue;
84
+ }
85
+ if (character === activeQuote) {
86
+ activeQuote = '';
87
+ }
88
+ index++;
89
+ continue;
90
+ }
91
+
92
+ if (character === '"' || character === '\'') {
93
+ activeQuote = character;
94
+ current += character;
95
+ index++;
96
+ continue;
97
+ }
98
+
99
+ if (character === '(') {
100
+ depth++;
101
+ }
102
+ if (character === ')' && depth > 0) {
103
+ depth--;
104
+ }
105
+
106
+ // Match any whitespace character, which separates components at depth zero
107
+ const isSeparator = depth === 0 && /\s/.test(character);
108
+ if (isSeparator) {
109
+ if (current) {
110
+ components.push(current);
111
+ current = '';
112
+ }
113
+ index++;
114
+ continue;
115
+ }
116
+
117
+ const startsHashToken = character === '#' && depth === 0 && current !== '';
118
+ if (startsHashToken) {
119
+ components.push(current);
120
+ current = '';
121
+ }
122
+
123
+ current += character;
124
+ index++;
125
+ }
126
+
127
+ if (current) {
128
+ components.push(current);
129
+ }
130
+
131
+ return components;
132
+ }
133
+
134
+ export {
135
+ findMatchingParenthesis,
136
+ splitTopLevelComponents
137
+ };