mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
Flag inset stripes written with the two-length box-shadow form
box-shadow takes <length>{2,4}: only the two offsets are required, so
`inset 4px 0 red` is valid and paints the same single-edge stripe as
`inset 4px 0 0 red`. The scan demanded a third length, so the short form was
silently missed.
Blur and spread now default to 0 when omitted, which is exactly the stripe shape
the rule looks for. The neutral-color and blur/spread exclusions still hold:
`inset 4px 0 #000` and `inset 4px 0 5px var(--brand-accent)` both pass. Fixture
covers both orders of the short form plus those two exclusions, and fails against
the previous regex.
Third false negative found in this rule (after trailing `inset` and literal
neutral colors), all from the same cause: the scan was written against one
spelling of the syntax rather than the grammar.
Prepared with AI assistance under maintainer direction.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -425,11 +425,15 @@ function scanInsetStripeCss(rawContent, filePath, lineOffset = 0) {
|
||||
// an unchanged layer had no inset keyword and is not our shape.
|
||||
const body = layer.replace(/(^|\s)inset(?=\s|$)/i, '$1').trim();
|
||||
if (body === layer) continue;
|
||||
const shadow = body.match(/^(-?\d*\.?\d+)(px)?\s+(-?\d*\.?\d+)(px)?\s+(-?\d*\.?\d+)(px)?(?:\s+(-?\d*\.?\d+)(px)?)?\s+(.+)$/i);
|
||||
// box-shadow takes <length>{2,4}: only the two offsets are required, so
|
||||
// `inset 4px 0 red` is valid and paints the same stripe as
|
||||
// `inset 4px 0 0 red`. Demanding a third length missed the short form.
|
||||
const shadow = body.match(/^(-?\d*\.?\d+)(px)?\s+(-?\d*\.?\d+)(px)?(?:\s+(-?\d*\.?\d+)(px)?)?(?:\s+(-?\d*\.?\d+)(px)?)?\s+(.+)$/i);
|
||||
if (!shadow) continue;
|
||||
const x = Number(shadow[1]);
|
||||
const y = Number(shadow[3]);
|
||||
const blur = Number(shadow[5]);
|
||||
// Omitted blur and spread default to 0, which is exactly the stripe shape.
|
||||
const blur = shadow[5] == null ? 0 : Number(shadow[5]);
|
||||
const spread = shadow[7] == null ? 0 : Number(shadow[7]);
|
||||
if ((x !== 0 && !shadow[2]) || (y !== 0 && !shadow[4]) || blur !== 0 || spread !== 0) continue;
|
||||
const ax = Math.abs(x);
|
||||
|
||||
@@ -33,6 +33,9 @@ describe('detectText - Astro structural CSS fixtures', () => {
|
||||
'Trailing Inset Edge',
|
||||
'Trailing Inset Token Edge',
|
||||
'Inset Named Token Edge',
|
||||
// Only the two offsets are required; blur/spread default to 0.
|
||||
'Two Length Edge',
|
||||
'Two Length Trailing Inset Edge',
|
||||
];
|
||||
const SHOULD_PASS = [
|
||||
'Neutral Shadow Token',
|
||||
@@ -56,6 +59,9 @@ describe('detectText - Astro structural CSS fixtures', () => {
|
||||
'Commented Out Edge',
|
||||
// Trailing `inset` still respects the neutral-color exemption.
|
||||
'Trailing Inset Neutral Edge',
|
||||
// The short form still respects the neutral and blur exclusions.
|
||||
'Two Length Neutral Edge',
|
||||
'Two Length Blurred Edge',
|
||||
];
|
||||
|
||||
it('Astro style blocks flag unresolved chromatic inset stripes only', () => {
|
||||
|
||||
@@ -17,6 +17,8 @@ const title = 'Astro inset shadow stripe regression';
|
||||
<article data-case="Trailing Inset Edge"><h3>Trailing Inset Edge</h3></article>
|
||||
<article data-case="Trailing Inset Token Edge"><h3>Trailing Inset Token Edge</h3></article>
|
||||
<article data-case="Inset Named Token Edge"><h3>Inset Named Token Edge</h3></article>
|
||||
<article data-case="Two Length Edge"><h3>Two Length Edge</h3></article>
|
||||
<article data-case="Two Length Trailing Inset Edge"><h3>Two Length Trailing Inset Edge</h3></article>
|
||||
</section>
|
||||
<section aria-labelledby="should-pass">
|
||||
<h2 id="should-pass">Should pass</h2>
|
||||
@@ -35,6 +37,8 @@ const title = 'Astro inset shadow stripe regression';
|
||||
<article data-case="Shorthand Neutral Hex Edge"><h3>Shorthand Neutral Hex Edge</h3></article>
|
||||
<article data-case="Commented Out Edge"><h3>Commented Out Edge</h3></article>
|
||||
<article data-case="Trailing Inset Neutral Edge"><h3>Trailing Inset Neutral Edge</h3></article>
|
||||
<article data-case="Two Length Neutral Edge"><h3>Two Length Neutral Edge</h3></article>
|
||||
<article data-case="Two Length Blurred Edge"><h3>Two Length Blurred Edge</h3></article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
@@ -71,6 +75,13 @@ const title = 'Astro inset shadow stripe regression';
|
||||
[data-case="Inset Named Token Edge"] { box-shadow: inset 4px 0 0 var(--inset-accent); }
|
||||
[data-case="Trailing Inset Neutral Edge"] { box-shadow: 4px 0 0 #000 inset; }
|
||||
|
||||
/* box-shadow takes <length>{2,4}: blur and spread are optional and default to
|
||||
0, so these paint the same stripe as the four-length forms above. */
|
||||
[data-case="Two Length Edge"] { box-shadow: inset 4px 0 var(--brand-accent); }
|
||||
[data-case="Two Length Trailing Inset Edge"] { box-shadow: 0 5px #6366f1 inset; }
|
||||
[data-case="Two Length Neutral Edge"] { box-shadow: inset 4px 0 #000; }
|
||||
[data-case="Two Length Blurred Edge"] { box-shadow: inset 4px 0 5px var(--brand-accent); }
|
||||
|
||||
/* Commented-out rules are not live CSS.
|
||||
[data-case="Commented Out Edge"] { box-shadow: inset 4px 0 0 var(--brand-accent); }
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user