mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-15 07:36:50 +03:00
Fix stripe-child edge and token matching
AI-assisted changes requested by pbakaus. Preserve winning auto inset longhands and require complete Tailwind cue tokens. Added regressions that fail before the fixes; focused tests, cargo test --workspace, release build, and the full rebuilt-engine Bun/Node suite pass.
This commit is contained in:
@@ -942,7 +942,10 @@ pub static REGEX_MATCHERS: Lazy<Vec<Matcher>> = Lazy::new(|| {
|
||||
let scope = containing_markup_tag(line)(m.index);
|
||||
find_solid_chromatic_bg(&scope).is_some()
|
||||
&& stripe_child_markup_empty(line, m.index)
|
||||
&& STRIPE_CHILD_CUE_RE.is_match(&scope)
|
||||
&& STRIPE_CHILD_CUE_RE.find_iter(&scope).any(|cue| {
|
||||
hyphen_safe_prefix(&scope, cue.start())
|
||||
&& hyphen_safe_suffix(&scope, cue.end())
|
||||
})
|
||||
&& !scope_has_fixed_height(&scope)
|
||||
&& !STRIPE_CHILD_ROUNDED_FULL_RE.is_match(&scope)
|
||||
&& !STRIPE_CHILD_ARIA_RE.is_match(&scope)
|
||||
@@ -1522,6 +1525,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stripe_child_cues_require_complete_class_tokens() {
|
||||
for cue in ["left-0.5", "right-0.5", "inset-y-0.5", "-left-0", "left-0/2", "shrink-0.5"] {
|
||||
let source = format!(r#"<div className="w-1 {cue} bg-amber-500" />"#);
|
||||
assert!(run("side-tab", &source).is_empty(), "{cue}");
|
||||
}
|
||||
for cue in ["left-0", "right-0", "inset-y-0", "shrink-0", "rounded-l-lg"] {
|
||||
let source = format!(r#"<div className="w-1 {cue} bg-amber-500" />"#);
|
||||
assert_eq!(run("side-tab", &source).len(), 1, "{cue}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stripe_child_tailwind() {
|
||||
let s = |line: &str| run("side-tab", line);
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::background::{
|
||||
a_ge, a_gt, read_own_background_color, resolve_background, resolve_background_info,
|
||||
resolve_border_radius_px, resolve_gradient_stops, sv, sv_opt, CustomPropMap,
|
||||
};
|
||||
use crate::cascade::{expand_static_box_values, split_css_tokens, StyleValues};
|
||||
use crate::cascade::StyleValues;
|
||||
use crate::dom::{StaticDocument, StaticElement};
|
||||
use crate::quality::{collapse_ws, pf0, resolve_font_size_px};
|
||||
use impeccable_core::checks::css_scan::css_length_to_px;
|
||||
@@ -469,25 +469,6 @@ fn static_edge_hugs(value: &str) -> bool {
|
||||
n.is_finite() && n.abs() <= 2.0
|
||||
}
|
||||
|
||||
fn static_resolved_inset(style: &StyleValues) -> [String; 4] {
|
||||
let mut out = [
|
||||
sv(style, "top").to_string(),
|
||||
sv(style, "right").to_string(),
|
||||
sv(style, "bottom").to_string(),
|
||||
sv(style, "left").to_string(),
|
||||
];
|
||||
let inset = sv(style, "inset");
|
||||
if !inset.is_empty() {
|
||||
let expanded = expand_static_box_values(&split_css_tokens(inset));
|
||||
for (i, val) in expanded.into_iter().enumerate() {
|
||||
if out[i].is_empty() || out[i] == "auto" {
|
||||
out[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// JS: checks.mjs#checkElementStripeChild(el, style)
|
||||
pub fn check_element_stripe_child(el: &StaticElement<'_>, style: &StyleValues) -> Vec<RuleHit> {
|
||||
let tag = el.tag_lower();
|
||||
@@ -518,7 +499,9 @@ pub fn check_element_stripe_child(el: &StaticElement<'_>, style: &StyleValues) -
|
||||
let host_style = host.style();
|
||||
let edge = if position == "absolute" || position == "fixed" {
|
||||
let height_raw = sv(style, "height");
|
||||
let inset = static_resolved_inset(style);
|
||||
// The cascade already expands inset; a winning `auto` longhand
|
||||
// must not be overwritten by the earlier shorthand.
|
||||
let inset = ["top", "right", "bottom", "left"].map(|prop| sv(style, prop));
|
||||
let height_stretches =
|
||||
height_raw == "100%" || (static_edge_hugs(&inset[0]) && static_edge_hugs(&inset[2]));
|
||||
if !height_stretches {
|
||||
|
||||
@@ -13,6 +13,17 @@ fn side_tab_snippets(html: &str) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn winning_auto_longhand_is_not_replaced_by_inset() {
|
||||
let html = r#"<html><body><div style="position:relative;width:320px;height:100px">
|
||||
<div class="stripe" style="position:absolute;inset:0;left:auto;width:4px;background:#3b82f6"></div>
|
||||
</div></body></html>"#;
|
||||
let hits = side_tab_snippets(html);
|
||||
assert_eq!(hits.len(), 1);
|
||||
assert!(hits[0].contains("stripe child (right)"), "{hits:?}");
|
||||
assert!(side_tab_snippets(&html.replace("left:auto", "left:auto;right:auto")).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flex_row_first_child_flags() {
|
||||
let html = r#"<!DOCTYPE html><html><head><style>
|
||||
|
||||
Reference in New Issue
Block a user