@typedcss/eslint-plugin 22.0.8 → 22.0.10
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.
|
@@ -77,6 +77,8 @@ exports.noUnresolvedComposition = {
|
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
function meaningful(node) {
|
|
80
|
+
if (typeof node === 'string')
|
|
81
|
+
return node.trim().length > 0;
|
|
80
82
|
if (node.type === 'Literal' && typeof node.value === 'string') {
|
|
81
83
|
return node.value.trim().length > 0;
|
|
82
84
|
}
|
|
@@ -97,7 +99,178 @@ exports.noUnresolvedComposition = {
|
|
|
97
99
|
(0, coreImport_1.memberName)(node) === 'className' &&
|
|
98
100
|
isProps(node.object));
|
|
99
101
|
}
|
|
102
|
+
const markups = new WeakMap();
|
|
103
|
+
function markup(node) {
|
|
104
|
+
if (node.type !== 'TemplateLiteral')
|
|
105
|
+
return null;
|
|
106
|
+
if (markups.has(node))
|
|
107
|
+
return markups.get(node);
|
|
108
|
+
const values = [];
|
|
109
|
+
let state = 'text';
|
|
110
|
+
let tagged = false;
|
|
111
|
+
let name = '';
|
|
112
|
+
let quote = '';
|
|
113
|
+
let value = null;
|
|
114
|
+
let text = '';
|
|
115
|
+
let tail = '';
|
|
116
|
+
const begin = () => {
|
|
117
|
+
value = [];
|
|
118
|
+
text = '';
|
|
119
|
+
};
|
|
120
|
+
const end = () => {
|
|
121
|
+
if (value === null)
|
|
122
|
+
return;
|
|
123
|
+
if (text)
|
|
124
|
+
value.push(text);
|
|
125
|
+
const attribute = name.toLowerCase();
|
|
126
|
+
if (attribute === 'class' || attribute === 'classname')
|
|
127
|
+
values.push(value);
|
|
128
|
+
value = null;
|
|
129
|
+
};
|
|
130
|
+
node.quasis.forEach((quasi, index) => {
|
|
131
|
+
for (const char of quasi.value.cooked ?? quasi.value.raw) {
|
|
132
|
+
const space = /\s/.test(char);
|
|
133
|
+
switch (state) {
|
|
134
|
+
case 'text':
|
|
135
|
+
if (char === '<')
|
|
136
|
+
state = 'open';
|
|
137
|
+
break;
|
|
138
|
+
case 'open':
|
|
139
|
+
if (/[a-z]/i.test(char)) {
|
|
140
|
+
state = 'tagName';
|
|
141
|
+
tagged = true;
|
|
142
|
+
}
|
|
143
|
+
else if (char === '!') {
|
|
144
|
+
state = 'declaration';
|
|
145
|
+
tagged = true;
|
|
146
|
+
tail = '';
|
|
147
|
+
}
|
|
148
|
+
else if (char === '/') {
|
|
149
|
+
state = 'skip';
|
|
150
|
+
tagged = true;
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
state = 'text';
|
|
154
|
+
break;
|
|
155
|
+
case 'declaration':
|
|
156
|
+
tail += char;
|
|
157
|
+
if (tail === '--') {
|
|
158
|
+
state = 'comment';
|
|
159
|
+
tail = '';
|
|
160
|
+
}
|
|
161
|
+
else if (char === '>')
|
|
162
|
+
state = 'text';
|
|
163
|
+
else if (!'--'.startsWith(tail))
|
|
164
|
+
state = 'skip';
|
|
165
|
+
break;
|
|
166
|
+
case 'comment':
|
|
167
|
+
tail = (tail + char).slice(-3);
|
|
168
|
+
if (tail === '-->')
|
|
169
|
+
state = 'text';
|
|
170
|
+
break;
|
|
171
|
+
case 'skip':
|
|
172
|
+
if (char === '>')
|
|
173
|
+
state = 'text';
|
|
174
|
+
break;
|
|
175
|
+
case 'tagName':
|
|
176
|
+
if (char === '>')
|
|
177
|
+
state = 'text';
|
|
178
|
+
else if (space || char === '/')
|
|
179
|
+
state = 'tag';
|
|
180
|
+
break;
|
|
181
|
+
case 'tag':
|
|
182
|
+
if (char === '>')
|
|
183
|
+
state = 'text';
|
|
184
|
+
else if (!space && char !== '/') {
|
|
185
|
+
state = 'attribute';
|
|
186
|
+
name = char;
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
case 'attribute':
|
|
190
|
+
if (char === '=')
|
|
191
|
+
state = 'beforeValue';
|
|
192
|
+
else if (char === '>')
|
|
193
|
+
state = 'text';
|
|
194
|
+
else if (char === '/')
|
|
195
|
+
state = 'tag';
|
|
196
|
+
else if (space)
|
|
197
|
+
state = 'afterAttribute';
|
|
198
|
+
else
|
|
199
|
+
name += char;
|
|
200
|
+
break;
|
|
201
|
+
case 'afterAttribute':
|
|
202
|
+
if (char === '=')
|
|
203
|
+
state = 'beforeValue';
|
|
204
|
+
else if (char === '>')
|
|
205
|
+
state = 'text';
|
|
206
|
+
else if (char === '/')
|
|
207
|
+
state = 'tag';
|
|
208
|
+
else if (!space) {
|
|
209
|
+
state = 'attribute';
|
|
210
|
+
name = char;
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
case 'beforeValue':
|
|
214
|
+
if (char === '"' || char === "'") {
|
|
215
|
+
state = 'quoted';
|
|
216
|
+
quote = char;
|
|
217
|
+
begin();
|
|
218
|
+
}
|
|
219
|
+
else if (char === '>')
|
|
220
|
+
state = 'text';
|
|
221
|
+
else if (!space) {
|
|
222
|
+
state = 'unquoted';
|
|
223
|
+
begin();
|
|
224
|
+
text = char;
|
|
225
|
+
}
|
|
226
|
+
break;
|
|
227
|
+
case 'quoted':
|
|
228
|
+
if (char === quote) {
|
|
229
|
+
end();
|
|
230
|
+
state = 'tag';
|
|
231
|
+
}
|
|
232
|
+
else
|
|
233
|
+
text += char;
|
|
234
|
+
break;
|
|
235
|
+
case 'unquoted':
|
|
236
|
+
if (space || char === '>') {
|
|
237
|
+
end();
|
|
238
|
+
state = char === '>' ? 'text' : 'tag';
|
|
239
|
+
}
|
|
240
|
+
else
|
|
241
|
+
text += char;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const expression = node.expressions[index];
|
|
246
|
+
if (!expression)
|
|
247
|
+
return;
|
|
248
|
+
if (state === 'beforeValue') {
|
|
249
|
+
state = 'unquoted';
|
|
250
|
+
begin();
|
|
251
|
+
}
|
|
252
|
+
if (state === 'quoted' || state === 'unquoted') {
|
|
253
|
+
if (text)
|
|
254
|
+
value.push(text);
|
|
255
|
+
text = '';
|
|
256
|
+
value.push(expression);
|
|
257
|
+
}
|
|
258
|
+
else if (state === 'open') {
|
|
259
|
+
state = 'tagName';
|
|
260
|
+
tagged = true;
|
|
261
|
+
}
|
|
262
|
+
else if (state === 'attribute' || state === 'afterAttribute') {
|
|
263
|
+
name = '';
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
end();
|
|
267
|
+
const result = tagged ? values : null;
|
|
268
|
+
markups.set(node, result);
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
100
271
|
function uses(node, seen = new Set()) {
|
|
272
|
+
if (typeof node === 'string' || markup(node))
|
|
273
|
+
return [];
|
|
101
274
|
if (isResult(node))
|
|
102
275
|
return [node];
|
|
103
276
|
if ((node.type === 'Identifier' || node.type === 'MemberExpression') &&
|
|
@@ -146,7 +319,17 @@ exports.noUnresolvedComposition = {
|
|
|
146
319
|
context.report({ node, messageId: 'stringified' });
|
|
147
320
|
return;
|
|
148
321
|
}
|
|
149
|
-
const
|
|
322
|
+
const attributes = markup(node);
|
|
323
|
+
if (attributes) {
|
|
324
|
+
for (const pieces of attributes) {
|
|
325
|
+
compose(node, pieces.flatMap((piece) => typeof piece === 'string' ? [piece] : flatten(piece)));
|
|
326
|
+
}
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
compose(node, children.flatMap(flatten));
|
|
330
|
+
}
|
|
331
|
+
function compose(node, pieces) {
|
|
332
|
+
const values = pieces.filter(meaningful);
|
|
150
333
|
const calls = values.flatMap((value) => uses(value));
|
|
151
334
|
if (values.length < 2 || !calls.some((call) => !reported.has(call)))
|
|
152
335
|
return;
|
|
@@ -156,9 +339,11 @@ exports.noUnresolvedComposition = {
|
|
|
156
339
|
return;
|
|
157
340
|
}
|
|
158
341
|
const label = (value) => {
|
|
159
|
-
const text = value
|
|
160
|
-
? JSON.stringify(
|
|
161
|
-
:
|
|
342
|
+
const text = typeof value === 'string'
|
|
343
|
+
? JSON.stringify(value.trim())
|
|
344
|
+
: value.type === 'TemplateElement'
|
|
345
|
+
? JSON.stringify((value.value.cooked ?? value.value.raw).trim())
|
|
346
|
+
: context.sourceCode.getText(value);
|
|
162
347
|
return text.length > 40 ? `${text.slice(0, 39)}…` : text;
|
|
163
348
|
};
|
|
164
349
|
context.report({
|
|
@@ -59,6 +59,31 @@ const VALID_STATIC_PSEUDOS = new Set([
|
|
|
59
59
|
'::file-selector-button',
|
|
60
60
|
'::details-content',
|
|
61
61
|
'::target-text',
|
|
62
|
+
'::-webkit-scrollbar',
|
|
63
|
+
'::-webkit-scrollbar-button',
|
|
64
|
+
'::-webkit-scrollbar-thumb',
|
|
65
|
+
'::-webkit-scrollbar-track',
|
|
66
|
+
'::-webkit-scrollbar-track-piece',
|
|
67
|
+
'::-webkit-scrollbar-corner',
|
|
68
|
+
'::-webkit-resizer',
|
|
69
|
+
'::-webkit-inner-spin-button',
|
|
70
|
+
'::-webkit-outer-spin-button',
|
|
71
|
+
'::-webkit-search-cancel-button',
|
|
72
|
+
'::-webkit-search-decoration',
|
|
73
|
+
'::-webkit-slider-thumb',
|
|
74
|
+
'::-webkit-slider-runnable-track',
|
|
75
|
+
'::-webkit-progress-bar',
|
|
76
|
+
'::-webkit-progress-value',
|
|
77
|
+
'::-webkit-meter-bar',
|
|
78
|
+
'::-webkit-meter-optimum-value',
|
|
79
|
+
'::-webkit-meter-suboptimum-value',
|
|
80
|
+
'::-webkit-meter-even-less-good-value',
|
|
81
|
+
'::-webkit-calendar-picker-indicator',
|
|
82
|
+
'::-moz-range-thumb',
|
|
83
|
+
'::-moz-range-track',
|
|
84
|
+
'::-moz-range-progress',
|
|
85
|
+
'::-moz-progress-bar',
|
|
86
|
+
'::-moz-meter-bar',
|
|
62
87
|
':before',
|
|
63
88
|
':after',
|
|
64
89
|
':first-letter',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typedcss/eslint-plugin",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.10",
|
|
4
4
|
"description": "TypedCSS ESLint plugin",
|
|
5
5
|
"author": "Refirst 11",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"oxlint": "1.87.0",
|
|
57
57
|
"zss-engine": "3.1.2",
|
|
58
|
-
"@typedcss/oxide": "22.0.
|
|
58
|
+
"@typedcss/oxide": "22.0.10"
|
|
59
59
|
},
|
|
60
60
|
"publishConfig": {
|
|
61
61
|
"access": "public",
|