mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
Fix: blank preprocessor line comments inside component style blocks
Standalone SCSS/Sass/Less files already ignored // comments, but <style lang="scss"> in Astro/Vue/Svelte still scanned them as live CSS. Prepared with AI assistance. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -261,17 +261,34 @@ function blankHtmlComments(text) {
|
||||
return text.replace(/<!--[\s\S]*?-->/g, comment => comment.replace(/[^\n]/g, ' '));
|
||||
}
|
||||
|
||||
function blankCssLineCommentsInStyleBlocks(text) {
|
||||
const re = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
|
||||
let output = '';
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
while ((match = re.exec(text)) !== null) {
|
||||
const inner = match[1];
|
||||
const openLength = match[0].length - inner.length - '</style>'.length;
|
||||
output += text.slice(lastIndex, match.index);
|
||||
output += match[0].slice(0, openLength);
|
||||
output += blankCssLineComments(inner);
|
||||
output += match[0].slice(openLength + inner.length);
|
||||
lastIndex = re.lastIndex;
|
||||
}
|
||||
return output + text.slice(lastIndex);
|
||||
}
|
||||
|
||||
function blankHtmlAndCssCommentsOutsideScripts(text) {
|
||||
const re = /<script\b[^>]*>[\s\S]*?<\/script>/gi;
|
||||
let output = '';
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
while ((match = re.exec(text)) !== null) {
|
||||
output += stripCssComments(blankHtmlComments(text.slice(lastIndex, match.index)));
|
||||
output += blankCssLineCommentsInStyleBlocks(stripCssComments(blankHtmlComments(text.slice(lastIndex, match.index))));
|
||||
output += match[0];
|
||||
lastIndex = re.lastIndex;
|
||||
}
|
||||
return output + stripCssComments(blankHtmlComments(text.slice(lastIndex)));
|
||||
return output + blankCssLineCommentsInStyleBlocks(stripCssComments(blankHtmlComments(text.slice(lastIndex))));
|
||||
}
|
||||
|
||||
function blankCssLineComments(text) {
|
||||
@@ -1194,7 +1211,7 @@ function detectText(content, filePath, options = {}) {
|
||||
}, () => extractStyleBlocks(content, ext))
|
||||
: extractStyleBlocks(content, ext);
|
||||
for (const block of styleBlocks) {
|
||||
const blockContent = stripCssComments(block.content);
|
||||
const blockContent = blankCssLineComments(stripCssComments(block.content));
|
||||
const blockLines = blockContent.split('\n');
|
||||
findings.push(...runRegexMatchers(blockLines, filePath, block.startLine - 1, true, {
|
||||
profile,
|
||||
|
||||
@@ -551,6 +551,32 @@ describe('detectText — broken images in source comments', () => {
|
||||
|
||||
expect(detectText(source, 'hero.astro').filter(r => r.antipattern === 'broken-image')).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('ignores preprocessor line comments in component style blocks', () => {
|
||||
const source = [
|
||||
'<style lang="scss">',
|
||||
'// font-family: Inter',
|
||||
'.hero { color: red; }',
|
||||
'</style>',
|
||||
].join('\n');
|
||||
|
||||
for (const filePath of ['hero.astro', 'hero.vue', 'hero.svelte']) {
|
||||
expect(detectText(source, filePath).filter(r => r.antipattern === 'overused-font')).toHaveLength(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('still detects live font-family after a style-block line comment', () => {
|
||||
const source = [
|
||||
'<style lang="scss">',
|
||||
'// skip this',
|
||||
'.hero { font-family: Inter; }',
|
||||
'</style>',
|
||||
].join('\n');
|
||||
|
||||
const findings = detectText(source, 'hero.vue').filter(r => r.antipattern === 'overused-font');
|
||||
expect(findings).toHaveLength(1);
|
||||
expect(findings[0].line).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('detectText — CSS borders', () => {
|
||||
|
||||
Reference in New Issue
Block a user