//! Un `margin-right` NEGATIVO saca la caja de borde del contenedor a //! propósito: la que tiene que entrar es la caja de MARGEN. //! //! Es el botón de idiomas de Wikipedia («97 languages»), que lleva //! `margin-right: -12px` para que su padding interno no meta sangría en el //! borde derecho del encabezado. Medido en el árbol real: fila de 880, botón de //! 147 en x=745 → el borde llega a 892 y parece un desborde de 12px, pero la //! caja de margen mide 135 y cierra EXACTO en 880. Taffy reparte bien; el que //! medía mal era el harness `salud_web`, que comparaba bordes. //! //! Este test fija las dos mitades del contrato, porque de la primera sola se //! saca la conclusión equivocada: (a) sin el margen negativo el item entra //! justo, y (b) con él el borde asoma exactamente lo que se pidió, ni más. use llimphi_layout::taffy::{self, prelude::*, AvailableSpace}; /// Fila de 880 con una columna elástica y un item inflexible de 147 (una hoja /// medida, como el texto real) que lleva `margin-right: margen`. Devuelve /// `(x, ancho)` del item. fn fila_con_item(margen: f32) -> (f32, f32) { let mut t: TaffyTree = TaffyTree::new(); let item = t .new_leaf_with_context( Style { flex_grow: 0.0, flex_shrink: 0.0, margin: Rect { left: zero(), right: length(margen), top: zero(), bottom: zero(), }, ..Default::default() }, 147.0, ) .unwrap(); let columna = t .new_leaf(Style { flex_grow: 1.0, flex_basis: length(0.0_f32), min_size: Size { width: length(0.0_f32), height: auto() }, ..Default::default() }) .unwrap(); let fila = t .new_with_children( Style { display: Display::Flex, flex_direction: FlexDirection::Row, flex_wrap: FlexWrap::Wrap, align_items: Some(AlignItems::START), size: Size { width: length(880.0_f32), height: auto() }, ..Default::default() }, &[columna, item], ) .unwrap(); t.compute_layout_with_measure( fila, taffy::Size { width: AvailableSpace::Definite(880.0), height: AvailableSpace::MaxContent }, |known, avail, _n, ctx, _st| { let Some(&mut mx) = ctx else { return taffy::Size::ZERO }; let w = known.width.unwrap_or(match avail.width { AvailableSpace::Definite(w) => w.min(mx), AvailableSpace::MaxContent => mx, AvailableSpace::MinContent => mx, }); taffy::Size { width: w, height: 18.0 } }, ) .unwrap(); let l = t.layout(item).unwrap(); (l.location.x, l.size.width) } #[test] fn sin_margen_negativo_el_item_cierra_justo_en_el_contenedor() { let (x, w) = fila_con_item(0.0); assert_eq!(w, 147.0, "el item mide su max-content"); assert!((x + w - 880.0).abs() < 0.5, "cierra en el borde: {x}+{w}"); } #[test] fn con_margen_negativo_el_borde_asoma_justo_lo_pedido() { let (x, w) = fila_con_item(-12.0); // La caja de MARGEN cierra exacto en 880… assert!((x + w - 12.0 - 880.0).abs() < 0.5, "la caja de margen no cierra: {x}+{w}-12"); // …y por eso la de BORDE asoma 12, ni uno más. Un harness que mida bordes // ve acá un «desborde» de 12px que ningún browser reporta. assert!((x + w - 892.0).abs() < 0.5, "el borde asoma otra cosa: {x}+{w}"); }