diff --git a/crates/browser/src/form_submission.rs b/crates/browser/src/form_submission.rs index 753204e..43cff49 100644 --- a/crates/browser/src/form_submission.rs +++ b/crates/browser/src/form_submission.rs @@ -149,20 +149,18 @@ pub fn construct_entry_list( } } } - "button" => { - // Only the submitter button is included. - if Some(control) == submitter { - let btn_type = doc - .get_attribute(control, "type") - .unwrap_or("submit") - .to_ascii_lowercase(); - if btn_type == "submit" { - let value = doc - .get_attribute(control, "value") - .unwrap_or("") - .to_string(); - entries.push(FormEntry { name, value }); - } + // Only the submitter button is included. + "button" if Some(control) == submitter => { + let btn_type = doc + .get_attribute(control, "type") + .unwrap_or("submit") + .to_ascii_lowercase(); + if btn_type == "submit" { + let value = doc + .get_attribute(control, "value") + .unwrap_or("") + .to_string(); + entries.push(FormEntry { name, value }); } } _ => {} diff --git a/crates/dom/src/canvas.rs b/crates/dom/src/canvas.rs index bb197ec..3ac4102 100644 --- a/crates/dom/src/canvas.rs +++ b/crates/dom/src/canvas.rs @@ -624,27 +624,15 @@ impl Canvas2dContext { pub fn stroke(&self, buf: &mut [u8], canvas_w: u32, canvas_h: u32) { let color = apply_global_alpha(self.state.stroke_style, self.state.global_alpha); let subpaths = flatten_path(&self.path.segments, &self.state.transform); - stroke_subpaths( - buf, - canvas_w, - canvas_h, - &subpaths, - color, - self.state.line_width, - ); + let style = StrokeStyle::from_state(&self.state, color); + stroke_subpaths(buf, canvas_w, canvas_h, &subpaths, &style); } pub fn stroke_with_path2d(&self, buf: &mut [u8], canvas_w: u32, canvas_h: u32, path: &Path2D) { let color = apply_global_alpha(self.state.stroke_style, self.state.global_alpha); let subpaths = flatten_path(&path.inner.segments, &self.state.transform); - stroke_subpaths( - buf, - canvas_w, - canvas_h, - &subpaths, - color, - self.state.line_width, - ); + let style = StrokeStyle::from_state(&self.state, color); + stroke_subpaths(buf, canvas_w, canvas_h, &subpaths, &style); } pub fn is_point_in_path(&self, x: f64, y: f64, rule: FillRule) -> bool { @@ -1343,38 +1331,162 @@ fn fill_span( // ── Stroke rasterization ────────────────────────────────────────── +struct StrokeStyle<'a> { + color: [u8; 4], + line_width: f64, + /// 0 = butt, 1 = round, 2 = square + line_cap: u8, + /// 0 = miter, 1 = round, 2 = bevel + line_join: u8, + miter_limit: f64, + line_dash: &'a [f64], + line_dash_offset: f64, +} + +impl<'a> StrokeStyle<'a> { + fn from_state(state: &'a Canvas2dState, color: [u8; 4]) -> Self { + StrokeStyle { + color, + line_width: state.line_width, + line_cap: state.line_cap, + line_join: state.line_join, + miter_limit: state.miter_limit, + line_dash: &state.line_dash, + line_dash_offset: state.line_dash_offset, + } + } +} + fn stroke_subpaths( buf: &mut [u8], canvas_w: u32, canvas_h: u32, subpaths: &[Vec<(f64, f64)>], - color: [u8; 4], - line_width: f64, + style: &StrokeStyle, ) { - if color[3] == 0 || line_width <= 0.0 { + if style.color[3] == 0 || style.line_width <= 0.0 { return; } - let half = line_width / 2.0; + let half = style.line_width / 2.0; for sp in subpaths { if sp.len() < 2 { continue; } let n = sp.len(); - // Draw each segment as a filled quad - for i in 0..n - 1 { - let (x0, y0) = sp[i]; - let (x1, y1) = sp[i + 1]; - stroke_segment(buf, canvas_w, canvas_h, x0, y0, x1, y1, half, color); - } - // Draw a small circle at each joint to fill gaps between segment quads - for &(px, py) in &sp[1..n - 1] { - rasterize_filled_circle(buf, canvas_w, canvas_h, px, py, half, color); + // A closed subpath has its first and last points equal (added by flatten_path on Close). + let is_closed = n >= 3 + && (sp[0].0 - sp[n - 1].0).abs() < 1e-10 + && (sp[0].1 - sp[n - 1].1).abs() < 1e-10; + + if style.line_dash.is_empty() { + stroke_open_or_closed(buf, canvas_w, canvas_h, sp, is_closed, half, style); + } else { + // Apply dash pattern — each dash segment is always rendered open. + let dashes = apply_dash(sp, style.line_dash, style.line_dash_offset); + for dash_pts in &dashes { + if dash_pts.len() >= 2 { + stroke_open_or_closed(buf, canvas_w, canvas_h, dash_pts, false, half, style); + } + } } } } +fn stroke_open_or_closed( + buf: &mut [u8], + canvas_w: u32, + canvas_h: u32, + points: &[(f64, f64)], + is_closed: bool, + half: f64, + style: &StrokeStyle, +) { + let n = points.len(); + if n < 2 { + return; + } + + // Number of distinct points for a closed path (last == first). + let m = if is_closed { n - 1 } else { n }; + if m < 2 { + return; + } + + let seg_count = if is_closed { m } else { m - 1 }; + + // 1. Draw segment body rectangles. + for i in 0..seg_count { + let (x0, y0) = points[i]; + let (x1, y1) = points[(i + 1) % m]; + stroke_segment_rect(buf, canvas_w, canvas_h, x0, y0, x1, y1, half, style.color); + } + + // 2. Caps at open endpoints. + if !is_closed { + let (sx, sy) = points[0]; + let (sx1, sy1) = points[1]; + // Start cap: extend backward from the first point. + draw_cap_directional( + buf, + canvas_w, + canvas_h, + sx, + sy, + sx1, + sy1, + half, + style.line_cap, + style.color, + -1.0, + ); + + let (ex, ey) = points[m - 1]; + let (epx, epy) = points[m - 2]; + // End cap: extend forward from the last point. + draw_cap_directional( + buf, + canvas_w, + canvas_h, + epx, + epy, + ex, + ey, + half, + style.line_cap, + style.color, + 1.0, + ); + } + + // 3. Joins at each interior (or all, if closed) point. + let join_range = if is_closed { 0..m } else { 1..m - 1 }; + for i in join_range { + let prev = if i == 0 { m - 1 } else { i - 1 }; + let next = (i + 1) % m; + let (x0, y0) = points[prev]; + let (x1, y1) = points[i]; + let (x2, y2) = points[next]; + draw_join( + buf, + canvas_w, + canvas_h, + x0, + y0, + x1, + y1, + x2, + y2, + half, + style.line_join, + style.miter_limit, + style.color, + ); + } +} + +/// Draw the rectangular body of a stroke segment (flat butt ends). #[allow(clippy::too_many_arguments)] -fn stroke_segment( +fn stroke_segment_rect( buf: &mut [u8], canvas_w: u32, canvas_h: u32, @@ -1392,10 +1504,8 @@ fn stroke_segment( rasterize_filled_circle(buf, canvas_w, canvas_h, x0, y0, half_width, color); return; } - // Perpendicular unit vector let nx = -dy / len; let ny = dx / len; - // Quad corners let quad = [ (x0 + nx * half_width, y0 + ny * half_width), (x0 - nx * half_width, y0 - ny * half_width), @@ -1405,6 +1515,267 @@ fn stroke_segment( rasterize_polygon(buf, canvas_w, canvas_h, &quad, color); } +#[allow(clippy::too_many_arguments)] +fn draw_cap_directional( + buf: &mut [u8], + canvas_w: u32, + canvas_h: u32, + // Segment body direction (from prev to endpoint). + px: f64, + py: f64, + ex: f64, + ey: f64, + half: f64, + cap: u8, + color: [u8; 4], + outward_sign: f64, // +1.0 = extend in segment direction, -1.0 = extend backward +) { + let dx = ex - px; + let dy = ey - py; + let len = (dx * dx + dy * dy).sqrt(); + if len < 1e-10 { + return; + } + let tx = (dx / len) * outward_sign; + let ty = (dy / len) * outward_sign; + let nx = -ty; + let ny = tx; + let (cx, cy) = if outward_sign > 0.0 { + (ex, ey) + } else { + (px, py) + }; + match cap { + 0 => {} + 1 => { + rasterize_filled_circle(buf, canvas_w, canvas_h, cx, cy, half, color); + } + _ => { + let quad = [ + (cx + nx * half, cy + ny * half), + (cx - nx * half, cy - ny * half), + (cx - nx * half + tx * half, cy - ny * half + ty * half), + (cx + nx * half + tx * half, cy + ny * half + ty * half), + ]; + rasterize_polygon(buf, canvas_w, canvas_h, &quad, color); + } + } +} + +/// Draw a line join at joint point (jx, jy). +/// Incoming segment: ... → (jx, jy), outgoing: (jx, jy) → ... +#[allow(clippy::too_many_arguments)] +fn draw_join( + buf: &mut [u8], + canvas_w: u32, + canvas_h: u32, + x0: f64, + y0: f64, // previous point + jx: f64, + jy: f64, // joint point + x2: f64, + y2: f64, // next point + half: f64, + join: u8, + miter_limit: f64, + color: [u8; 4], +) { + let d1x = jx - x0; + let d1y = jy - y0; + let len1 = (d1x * d1x + d1y * d1y).sqrt(); + + let d2x = x2 - jx; + let d2y = y2 - jy; + let len2 = (d2x * d2x + d2y * d2y).sqrt(); + + if len1 < 1e-10 || len2 < 1e-10 { + return; + } + + let t1x = d1x / len1; + let t1y = d1y / len1; + let t2x = d2x / len2; + let t2y = d2y / len2; + + // 2D cross product: positive = left turn, negative = right turn. + let cross = t1x * t2y - t1y * t2x; + if cross.abs() < 1e-10 { + // Collinear — no gap to fill. + return; + } + + // Left normals (90° CCW from direction). + let n1x = -t1y; + let n1y = t1x; + let n2x = -t2y; + let n2y = t2x; + + // Gap is on the convex side: + // left turn (cross > 0) → gap on right side (negative normal) + // right turn (cross < 0) → gap on left side (positive normal) + let sign = if cross > 0.0 { -1.0_f64 } else { 1.0_f64 }; + let gn1x = n1x * sign; + let gn1y = n1y * sign; + let gn2x = n2x * sign; + let gn2y = n2y * sign; + + // The two gap-side corners at the joint. + let c1x = jx + gn1x * half; + let c1y = jy + gn1y * half; + let c2x = jx + gn2x * half; + let c2y = jy + gn2y * half; + + match join { + 0 => { + // Miter join: extend outer edges to intersection. + // Check miter ratio = 1 / sin(alpha/2) where alpha = interior angle. + // cos(alpha) = -dot(t1, t2) (interior angle uses reversed incoming direction). + let cos_alpha = -(t1x * t2x + t1y * t2y).clamp(-1.0, 1.0); + let sin_half_sq = (1.0 + cos_alpha) / 2.0; + let miter_ok = if sin_half_sq < 1e-10 { + false + } else { + let miter_ratio = 1.0 / sin_half_sq.sqrt(); + miter_ratio <= miter_limit + }; + + if miter_ok { + // Compute miter point via line intersection. + let delta_x = c2x - c1x; + let delta_y = c2y - c1y; + let denom = t1x * t2y - t1y * t2x; + if denom.abs() > 1e-10 { + let num = delta_x * t2y - delta_y * t2x; + let s = num / denom; + let mx = c1x + s * t1x; + let my = c1y + s * t1y; + // Fill the miter quad: joint, c1, miter_tip, c2. + let quad = [(jx, jy), (c1x, c1y), (mx, my), (c2x, c2y)]; + rasterize_polygon(buf, canvas_w, canvas_h, &quad, color); + return; + } + } + // Fall through to bevel if miter exceeds limit or denom ≈ 0. + let tri = [(jx, jy), (c1x, c1y), (c2x, c2y)]; + rasterize_polygon(buf, canvas_w, canvas_h, &tri, color); + } + 1 => { + // Round join: full circle covers the gap. + rasterize_filled_circle(buf, canvas_w, canvas_h, jx, jy, half, color); + } + _ => { + // Bevel join: triangle. + let tri = [(jx, jy), (c1x, c1y), (c2x, c2y)]; + rasterize_polygon(buf, canvas_w, canvas_h, &tri, color); + } + } +} + +/// Split a polyline subpath into dash segments according to the dash pattern. +/// +/// Returns a list of point sequences, each representing one visible dash. +/// Each returned segment is open (caps will be applied at its endpoints). +fn apply_dash(points: &[(f64, f64)], dash: &[f64], offset: f64) -> Vec> { + if dash.is_empty() || points.len() < 2 { + return vec![points.to_vec()]; + } + + // Per spec: if odd length, double the array. + let norm: Vec = if dash.len() % 2 == 1 { + let mut d = dash.to_vec(); + d.extend_from_slice(dash); + d + } else { + dash.to_vec() + }; + + let total: f64 = norm.iter().sum(); + if total <= 0.0 { + return vec![points.to_vec()]; + } + + // Find the starting phase and remaining length within it. + let mut pos = offset.rem_euclid(total); + let mut phase = 0usize; + while phase < norm.len() && pos >= norm[phase] { + pos -= norm[phase]; + phase += 1; + } + if phase >= norm.len() { + phase = 0; + pos = 0.0; + } + let mut remaining = norm[phase] - pos; + let mut is_drawing = phase.is_multiple_of(2); + + let mut result: Vec> = Vec::new(); + let mut current: Vec<(f64, f64)> = Vec::new(); + + if is_drawing { + current.push(points[0]); + } + + for i in 0..points.len() - 1 { + let (x0, y0) = points[i]; + let (x1, y1) = points[i + 1]; + let dx = x1 - x0; + let dy = y1 - y0; + let seg_len = (dx * dx + dy * dy).sqrt(); + + if seg_len < 1e-10 { + if is_drawing { + current.push((x1, y1)); + } + continue; + } + + let mut traveled = 0.0; + + loop { + let step = remaining.min(seg_len - traveled); + traveled += step; + remaining -= step; + + let t = traveled / seg_len; + let px = x0 + dx * t; + let py = y0 + dy * t; + + if is_drawing { + current.push((px, py)); + } + + if remaining < 1e-10 { + // Phase transition. + is_drawing = !is_drawing; + phase = (phase + 1) % norm.len(); + remaining = norm[phase]; + + if is_drawing { + // Start a new dash at this point. + current.push((px, py)); + } else { + // End the current dash. + if current.len() >= 2 { + result.push(std::mem::take(&mut current)); + } else { + current.clear(); + } + } + } + + if traveled >= seg_len - 1e-10 { + break; + } + } + } + + if is_drawing && current.len() >= 2 { + result.push(current); + } + + result +} + /// Fill an arbitrary convex/concave polygon using even-odd scanline. fn rasterize_polygon( buf: &mut [u8], @@ -2669,4 +3040,208 @@ mod tests { // Path should still have both segments after restore assert_eq!(ctx.path.segments.len(), 2); } + + // ── Line style tests ────────────────────────────────────────────── + + #[test] + fn apply_dash_solid_line() { + let pts = vec![(0.0, 0.0), (10.0, 0.0)]; + let result = apply_dash(&pts, &[], 0.0); + assert_eq!(result.len(), 1); + assert_eq!(result[0], pts); + } + + #[test] + fn apply_dash_simple_pattern() { + // Dash [5, 5] on a 20-unit horizontal line: dashes at [0,5] and [10,15]. + let pts = vec![(0.0, 0.0), (20.0, 0.0)]; + let result = apply_dash(&pts, &[5.0, 5.0], 0.0); + assert_eq!(result.len(), 2); + // First dash: (0,0) to (5,0) + assert!((result[0][0].0 - 0.0).abs() < 1e-9); + assert!((result[0].last().unwrap().0 - 5.0).abs() < 1e-9); + // Second dash: (10,0) to (15,0) + assert!((result[1][0].0 - 10.0).abs() < 1e-9); + assert!((result[1].last().unwrap().0 - 15.0).abs() < 1e-9); + } + + #[test] + fn apply_dash_odd_length_doubled() { + // Odd-length [5]: treated as [5,5]. 20-unit line → same as above. + let pts = vec![(0.0, 0.0), (20.0, 0.0)]; + let result_odd = apply_dash(&pts, &[5.0], 0.0); + let result_even = apply_dash(&pts, &[5.0, 5.0], 0.0); + assert_eq!(result_odd.len(), result_even.len()); + } + + #[test] + fn apply_dash_with_offset() { + // [5, 5] with offset 2.5: draw starts 2.5 into the pattern. + // At offset 2.5 we're mid-dash, 2.5 left → first dash ends at 2.5. + // Then gap [2.5,7.5], dash [7.5,12.5], etc. + let pts = vec![(0.0, 0.0), (20.0, 0.0)]; + let result = apply_dash(&pts, &[5.0, 5.0], 2.5); + assert!(!result.is_empty()); + // First dash is shorter than 5 (only 2.5 of it is visible from offset). + assert!((result[0].last().unwrap().0 - 2.5).abs() < 1e-9); + } + + #[test] + fn apply_dash_zero_total_returns_solid() { + let pts = vec![(0.0, 0.0), (10.0, 0.0)]; + let result = apply_dash(&pts, &[0.0, 0.0], 0.0); + assert_eq!(result.len(), 1); + } + + #[test] + fn line_styles_saved_and_restored() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_cap = 1; + ctx.state.line_join = 2; + ctx.state.miter_limit = 5.0; + ctx.state.line_dash = vec![4.0, 2.0]; + ctx.state.line_dash_offset = 1.0; + ctx.save(); + + ctx.state.line_cap = 0; + ctx.state.line_join = 0; + ctx.state.miter_limit = 10.0; + ctx.state.line_dash = vec![]; + ctx.state.line_dash_offset = 0.0; + ctx.restore(); + + assert_eq!(ctx.state.line_cap, 1); + assert_eq!(ctx.state.line_join, 2); + assert!((ctx.state.miter_limit - 5.0).abs() < 1e-9); + assert_eq!(ctx.state.line_dash, vec![4.0, 2.0]); + assert!((ctx.state.line_dash_offset - 1.0).abs() < 1e-9); + } + + #[test] + fn stroke_butt_cap_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_cap = 0; // butt + ctx.state.line_width = 4.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(90.0, 50.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); // should not panic + } + + #[test] + fn stroke_round_cap_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_cap = 1; // round + ctx.state.line_width = 4.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(90.0, 50.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); + } + + #[test] + fn stroke_square_cap_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_cap = 2; // square + ctx.state.line_width = 4.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(90.0, 50.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); + } + + #[test] + fn stroke_miter_join_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_join = 0; // miter + ctx.state.miter_limit = 10.0; + ctx.state.line_width = 4.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(50.0, 50.0); + ctx.line_to(50.0, 90.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); + } + + #[test] + fn stroke_round_join_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_join = 1; // round + ctx.state.line_width = 4.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(50.0, 50.0); + ctx.line_to(50.0, 90.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); + } + + #[test] + fn stroke_bevel_join_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_join = 2; // bevel + ctx.state.line_width = 4.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(50.0, 50.0); + ctx.line_to(50.0, 90.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); + } + + #[test] + fn stroke_dashed_line_does_not_panic() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_dash = vec![5.0, 3.0]; + ctx.state.line_dash_offset = 0.0; + ctx.state.line_width = 2.0; + ctx.move_to(10.0, 50.0); + ctx.line_to(90.0, 50.0); + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); + } + + #[test] + fn stroke_dashed_line_paints_pixels() { + let mut ctx = Canvas2dContext::new(); + ctx.state.line_dash = vec![10.0, 5.0]; + ctx.state.line_width = 4.0; + ctx.state.stroke_style = [255, 0, 0, 255]; + ctx.move_to(0.0, 50.0); + ctx.line_to(100.0, 50.0); + let mut buf = vec![0u8; 200 * 100 * 4]; + ctx.stroke(&mut buf, 200, 100); + // Pixel at x=5, y=50 should be red (inside first dash [0,10]). + let idx = (50 * 200 + 5) * 4; + assert_eq!(buf[idx], 255, "expected red at x=5"); + // Pixel at x=12, y=50 should be transparent (gap [10,15]). + let idx_gap = (50 * 200 + 12) * 4; + assert_eq!(buf[idx_gap + 3], 0, "expected transparent at x=12 (gap)"); + } + + #[test] + fn stroke_closed_path_no_caps() { + // A closed path gets joins at every vertex, not caps. + // Just verify it doesn't panic. + let mut ctx = Canvas2dContext::new(); + ctx.state.line_cap = 1; // round (would cause extra circle for caps) + ctx.state.line_join = 0; // miter + ctx.state.line_width = 2.0; + ctx.rect_path(10.0, 10.0, 50.0, 50.0); + let mut buf = vec![0u8; 200 * 200 * 4]; + ctx.stroke(&mut buf, 200, 200); + } + + #[test] + fn stroke_miter_exceeds_limit_falls_back_to_bevel() { + // Very sharp angle: miter ratio will exceed the limit → bevel fallback. + let mut ctx = Canvas2dContext::new(); + ctx.state.line_join = 0; // miter + ctx.state.miter_limit = 1.5; // low limit forces bevel on sharp angles + ctx.state.line_width = 4.0; + // Nearly 180° turn (very sharp angle). + ctx.move_to(10.0, 50.0); + ctx.line_to(50.0, 50.0); + ctx.line_to(10.0, 51.0); // nearly 180° turn + let mut buf = vec![0u8; 100 * 100 * 4]; + ctx.stroke(&mut buf, 100, 100); // should not panic + } } diff --git a/crates/js/src/compiler.rs b/crates/js/src/compiler.rs index 23a3a36..4beca7f 100644 --- a/crates/js/src/compiler.rs +++ b/crates/js/src/compiler.rs @@ -422,10 +422,8 @@ fn collect_stmt_refs(stmt: &Stmt, declared: &HashSet, refs: &mut HashSet /// inner function/arrow bodies (those form their own scope). fn collect_expr_refs(expr: &Expr, declared: &HashSet, refs: &mut HashSet) { match &expr.kind { - ExprKind::Identifier(name) => { - if !declared.contains(name) { - refs.insert(name.clone()); - } + ExprKind::Identifier(name) if !declared.contains(name) => { + refs.insert(name.clone()); } ExprKind::Binary { left, right, .. } | ExprKind::Logical { left, right, .. } diff --git a/crates/js/src/parser.rs b/crates/js/src/parser.rs index fc89ae7..552c5a6 100644 --- a/crates/js/src/parser.rs +++ b/crates/js/src/parser.rs @@ -1478,10 +1478,7 @@ impl Parser { let start = self.start_span(); let mut left = self.parse_unary_expression()?; - loop { - let Some((op, left_bp, right_bp)) = self.peek_binary_op() else { - break; - }; + while let Some((op, left_bp, right_bp)) = self.peek_binary_op() { if left_bp < min_bp { break; } diff --git a/crates/net/src/tls/handshake.rs b/crates/net/src/tls/handshake.rs index 5909caa..53f33a4 100644 --- a/crates/net/src/tls/handshake.rs +++ b/crates/net/src/tls/handshake.rs @@ -410,10 +410,10 @@ fn parse_server_hello(data: &[u8]) -> Result { key.copy_from_slice(key_data); server_key = Some(key); } - EXT_SUPPORTED_VERSIONS => { - if ext_data.len() >= 2 && ext_data[0] == 0x03 && ext_data[1] == 0x04 { - has_supported_versions = true; - } + EXT_SUPPORTED_VERSIONS + if ext_data.len() >= 2 && ext_data[0] == 0x03 && ext_data[1] == 0x04 => + { + has_supported_versions = true; } _ => {} // Ignore unknown extensions } diff --git a/crates/style/src/computed.rs b/crates/style/src/computed.rs index c5ca496..6a10933 100644 --- a/crates/style/src/computed.rs +++ b/crates/style/src/computed.rs @@ -1898,10 +1898,8 @@ fn parse_grid_track_list( ComponentValue::Percentage(n) => { tracks.push(GridTrackSize::Percentage(*n as f32)); } - ComponentValue::Number(n, _) => { - if *n == 0.0 { - tracks.push(GridTrackSize::Length(0.0)); - } + ComponentValue::Number(n, _) if *n == 0.0 => { + tracks.push(GridTrackSize::Length(0.0)); } ComponentValue::Ident(s) => match s.to_ascii_lowercase().as_str() { "auto" => tracks.push(GridTrackSize::Auto),