Skip to content

Commit 1c8257b

Browse files
committed
Bump css-tree to 2.0.2, refactor validator and related changes
1 parent bc7c8d3 commit 1c8257b

File tree

6 files changed

+2635
-110
lines changed

6 files changed

+2635
-110
lines changed

docs/validator.html

Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -198,79 +198,80 @@ <h2 id="result-header"></h2>
198198
}
199199

200200
function validate() {
201-
var css = sourceInput.value.trim();
202-
var parseErrors = [];
203-
var ast;
201+
const css = sourceInput.value;
202+
const noContent = css.trim().length === 0;
203+
const parseErrors = [];
204+
let ast;
204205

205-
document.getElementById('intro').style.display = css ? 'none' : '';
206-
document.getElementById('result').style.display = css ? '' : 'none';
206+
document.getElementById('intro').style.display = noContent ? '' : 'none';
207+
document.getElementById('result').style.display = noContent ? 'none' : '';
207208
fillIssueBlock.style.display = 'none';
208209
wellDoneBlock.style.display = 'none';
209210

210-
if (!css) {
211+
if (noContent) {
211212
return;
212213
}
213214

214215
try {
215216
ast = csstree.parse(css, {
216217
positions: true,
217-
tolerant: true,
218-
onParseError: function(e, fallbackNode) {
218+
onParseError(e, fallbackNode) {
219219
parseErrors.push(e);
220220
}
221221
});
222222
} catch (e) {
223223
result.classList.add('error');
224224
resultHeader.innerHTML = 'Ooops, I can\'t parse your CSS:';
225225
resultBlock.innerHTML = escapeHtml(e.formattedMessage || e.message)
226-
.replace(/^(Parse error: )([^\r\n]*)/, function(m, prefix, message) {
227-
return prefix + createSourceLink(message, e.offset);
228-
});
226+
.replace(/^(Parse error: )([^\r\n]*)/, (m, prefix, message) =>
227+
prefix + createSourceLink(message, e.offset)
228+
);
229229
return;
230230
}
231231

232232
result.classList.remove('error');
233233
resultHeader.innerHTML = 'OK, that\'s what I know about your CSS:';
234234

235-
var declCount = 0;
236-
var uniqueDecls = {};
237-
var decls = [];
238-
var props = {};
239-
var errors = {};
240-
var fails = 0;
235+
const uniqueDecls = new Map();
236+
const decls = [];
237+
const props = new Set();
238+
const errors = Object.create(null);
239+
let declCount = 0;
241240

242241
csstree.walk(ast, function(node) {
243242
if (node.type === 'Declaration') {
243+
const id = csstree.generate(node);
244+
244245
declCount++;
245246

246-
var id = csstree.generate(node);
247-
if (id in uniqueDecls) {
248-
uniqueDecls[id]++;
247+
if (uniqueDecls.has(id)) {
248+
uniqueDecls.set(id, uniqueDecls.get(id) + 1);
249249
return;
250250
}
251251

252252
node.value.important = false;
253-
uniqueDecls[id] = 1;
253+
props.add(node.property);
254+
uniqueDecls.set(id, 1);
254255
decls.push({
255-
id: id,
256-
node: node,
256+
id,
257+
node,
257258
property: node.property,
258259
value: node.value
259260
});
260-
props[node.property] = true;
261261
}
262262
});
263263

264-
var syntax = csstree.lexer;
265-
var warns = [];
266-
decls.forEach(function(decl) {
267-
var node = decl.value;
268-
var match = syntax.matchProperty(decl.property, node);
269-
var error = match.error;
264+
const syntax = csstree.lexer;
265+
const warns = [];
266+
267+
for (const decl of decls) {
268+
const node = decl.value;
269+
const match = syntax.matchProperty(decl.property, node);
270+
const error = match.error;
270271

271272
if (error !== null) {
272-
var type = error.rawMessage || error.message;
273-
var message = error.message;
273+
let type = error.rawMessage || error.message;
274+
let message = error.message;
274275

275276
if (/^Unknown property/.test(message)) {
276277
type = 'Unknown property';
@@ -284,16 +285,15 @@ <h2 id="result-header"></h2>
284285

285286
errors[type] = (errors[type] || 0) + 1;
286287
warns.push({
287-
decl: decl,
288-
message: message
288+
decl,
289+
message
289290
});
290291
}
291-
});
292-
var fails = warns.length;
293-
var uniqueDeclCount = decls.length;
294-
var maxErrorCountLength = String(Math.max.apply(null, Object.keys(errors).map(function(k) {
295-
return errors[k];
296-
}))).length;
292+
}
293+
294+
const fails = warns.length;
295+
const uniqueDeclCount = decls.length;
296+
const maxErrorCountLength = String(Math.max(...Object.values(errors))).length;
297297

298298
// clean results
299299
resultBlock.innerHTML = '';
@@ -308,7 +308,7 @@ <h2 id="result-header"></h2>
308308
});
309309

310310
// warn summary
311-
var summaryBlock = document.createElement('div');
311+
const summaryBlock = document.createElement('div');
312312
summaryBlock.innerHTML = [
313313
'Unique properties: ' + Object.keys(props).length,
314314
'Unique declarations: ' + uniqueDeclCount + ' (total: ' + declCount + ')',
@@ -322,14 +322,16 @@ <h2 id="result-header"></h2>
322322

323323
// warn list
324324
warns.forEach(function(warn) {
325-
var warnBlock = document.createElement('div');
326-
var count = uniqueDecls[warn.decl.id];
325+
const warnBlock = document.createElement('div');
326+
const count = uniqueDecls.get(warn.decl.id);
327+
327328
warnBlock.innerHTML = escapeHtml(warn.message)
328329
.replace(/^[^\r\n]+/, '<span class="warn-type">$&</span>' + (count > 1 ? ' \u00d7 ' + count : ''))
329330
.replace(/ value(:[^\r\n]*)/, createSourceLink(warn.decl.property, warn.decl.node.loc.start.offset) + '$1')
330331
.replace(/(Unknown property: )\S+/, '$1' + createSourceLink(warn.decl.property, warn.decl.node.loc.start.offset))
331332
.replace('------^', repeat('-', warn.decl.property.length) + '^');
332333
warnBlock.className = 'warn';
334+
333335
resultBlock.appendChild(warnBlock);
334336
});
335337

@@ -340,26 +342,27 @@ <h2 id="result-header"></h2>
340342
}
341343
}
342344

343-
var sourceInput = document.getElementById('source');
344-
var resultBlock = document.getElementById('result-output');
345-
var resultHeader = document.getElementById('result-header');
346-
var fillIssueBlock = document.getElementById('fill-issue');
347-
var wellDoneBlock = document.getElementById('well-done');
345+
const sourceInput = document.getElementById('source');
346+
const resultBlock = document.getElementById('result-output');
347+
const resultHeader = document.getElementById('result-header');
348+
const fillIssueBlock = document.getElementById('fill-issue');
349+
const wellDoneBlock = document.getElementById('well-done');
348350

349351
sourceInput.addEventListener('input', validate, false);
350-
resultBlock.addEventListener('click', function(e) {
352+
resultBlock.addEventListener('click', (e) => {
351353
if (e.target.classList.contains('link-to-source')) {
352354
if (sourceInput.setSelectionRange) {
353355
sourceInput.setSelectionRange(e.target.dataset.offset, e.target.dataset.offset);
354356
}
355357
sourceInput.focus();
356358
}
357359
}, false);
360+
358361
validate();
359362

360363
if (window.FileReader && window.DataTransfer) {
361364
sourceInput.placeholder += ' or drop CSS file';
362-
document.addEventListener('dragover', function(e) {
365+
document.addEventListener('dragover', (e) => {
363366
if (e.dataTransfer.items && e.dataTransfer.items[0]) {
364367
if (e.dataTransfer.items[0].kind == 'file') {
365368
e.preventDefault();
@@ -371,14 +374,14 @@ <h2 id="result-header"></h2>
371374
if (e.dataTransfer.items[0].kind == 'file') {
372375
e.preventDefault();
373376

374-
var file = e.dataTransfer.items[0].getAsFile();
377+
const file = e.dataTransfer.items[0].getAsFile();
375378

376379
if (!/\.css$/.test(file.name)) {
377380
alert('Only CSS files may be loaded.');
378381
return;
379382
}
380383

381-
var reader = new FileReader();
384+
const reader = new FileReader();
382385

383386
reader.readAsText(file);
384387
reader.addEventListener('load', function() {
@@ -390,7 +393,7 @@ <h2 id="result-header"></h2>
390393
});
391394
document.addEventListener('dragend', function(e) {
392395
if (e.dataTransfer.items) {
393-
for (var i = 0; i < e.dataTransfer.items.length; i++) {
396+
for (let i = 0; i < e.dataTransfer.items.length; i++) {
394397
e.dataTransfer.items.remove(i);
395398
}
396399
} else {

0 commit comments

Comments
 (0)