feat(browser): comprehensive engine improvements — rendering, JS, networking, SVG, canvas#89
Conversation
…on, layout, networking Paint pipeline: - CSS filter effects engine (grayscale, invert, sepia, brightness, contrast, saturate, hue-rotate, opacity) applied to backgrounds and text - Multi-stop gradient interpolation with banded rendering per stop pair - True diagonal gradient rendering (per-pixel for arbitrary angles) - Rounded box shadows (fill_rounded_rect when border_radius > 0) - Inset box shadow support (edge strips inside padding box) Animation & transitions: - Wire TransitionEngine.tick() and AnimationEngine.tick() into frame loop with Instant-based delta time tracking - Register @Keyframes animations from UA + author stylesheets on page load - Active animations/transitions trigger layout invalidation Layout: - margin: auto on flex items absorbs free space before justify-content - tab-size CSS property (parsed, default 8, tabs expanded in pre/pre-wrap) Networking & security: - Brotli decompression (Accept-Encoding: gzip, br) - RFC 6265 cookie path/domain validation with boundary checking - CSP: style-src, img-src, connect-src directives with default-src fallback Images: - WebP format detection (RIFF/WEBP magic bytes) - loading="lazy" defers image loading after eager images Developer experience: - BrowserError API (Network/Parse/Script errors, cleared per navigation) - Focus indicator (2px blue outline on focused form element) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…vent dispatch JavaScript DOM & timers: - removeChild / insertBefore bindings with JS-side Element.prototype wrappers - Wire setTimeout/setInterval via existing TimerQueue in oasis-js engine - Timer callbacks evaluated each tick(), layout marked dirty on fire Event dispatch: - mouseover/mouseout dispatched on hover node changes - keydown + input events dispatched on focused form elements - All events use bubbling dispatch with stopPropagation support HTTP connection pooling: - Thread-local ConnectionPool with per-host reuse (max 2/host, 8 total) - 30-second idle timeout with stale connection detection - Changed Connection header from close to keep-alive - Graceful fallback to fresh connection on pooled stream failure SVG basic shapes: - New svg.rs module: parser + renderer for rect, circle, ellipse, line, text - Color parsing: named colors (21), #RGB, #RRGGBB, rgb(r,g,b), none - ViewBox scaling for proper coordinate mapping - Integrated as ReplacedContent::Svg in layout pipeline - 13 unit tests for SVG parsing and color handling Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…n, getComputedStyle JavaScript APIs: - fetch() with synchronous HTTP GET, thenable response with .text()/.json() - getComputedStyle() returning ~30 CSS properties via ComputedStyle serialization - Inline event handlers (onclick, onchange, onsubmit, etc.) auto-registered - localStorage/sessionStorage backed by in-memory HashMap - Canvas 2D context: fillRect, strokeRect, clearRect, fillText, beginPath, moveTo, lineTo, arc, fill, stroke with fillStyle/strokeStyle/lineWidth CSS rendering: - radial-gradient() with circle/ellipse shape, multi-stop interpolation - repeating-linear-gradient() with tiled stop pattern - RadialGradient type + parser + pixel-by-pixel rendering Forms & images: - Form submission on Enter/submit button (GET query string + POST body) - srcset attribute parsing with width/density descriptor selection - WebP decoding via optional image crate (behind webp feature flag) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… with band-based Diagonal linear gradients were rendering pixel-by-pixel with O(w*h) individual fill_rect(1,1) calls, causing multi-second freezes on pages like Wikipedia. Replaced with axis-snapping approach using a single fill_rect_gradient call. Radial gradients similarly replaced: pixel-by-pixel O(w*h) rendering replaced with concentric rounded-rect bands (max 128 bands), reducing draw calls from ~130K to ~128 for a typical element. Fixes app freeze when navigating to https://www.wikipedia.com. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…test The Connection: keep-alive change caused read_response() to block for the full 15-second READ_TIMEOUT on every request. With keep-alive the server doesn't close the connection, so reading until EOF hangs. Fixed by making read_response() content-length-aware: once headers arrive, it parses Content-Length or detects chunked encoding and stops reading when the body is complete. Falls back to EOF/timeout only when neither is present. Also added an integration test that runs a complex page (with CSS gradients, tables, nested structure) through the full parse → cascade → layout pipeline and asserts completion within 500ms. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
go_back() and go_forward() previously called navigate_vfs() which always re-fetches from the network. For HTTPS pages like Wikipedia, this caused a second TLS handshake + full page download, freezing the UI. Added navigate_cached_or_fetch() which checks the in-memory ResourceCache first. On cache hit for HTML content, re-renders directly from cached body with zero network latency. Falls back to navigate_vfs() on cache miss. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Forward button was broken because navigate_cached_or_fetch() called load_html() which calls nav.navigate() — clearing the forward stack. Added skip_nav_push flag so cache-restored pages don't push new navigation entries. Also made srcset URL selection more defensive: filters out empty and data: URLs before preferring srcset over src, preventing cases where a bad srcset candidate would suppress the working src URL. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y mismatch Two bugs prevented most images from loading on Wikipedia: 1. Missing 303 (See Other) in redirect handling. Wikipedia's image CDN (upload.wikimedia.org) returns 303 redirects for thumbnails. The browser wasn't following them, receiving empty bodies that failed to decode. Added 303 to is_redirect(). 2. srcset/src URL key mismatch. collect_page_image_requests() stored decoded images under srcset-derived URLs, but ensure_image_textures() and assign_textures_recursive() only looked up by elem.src(). When both attributes were present (nearly all Wikipedia images), textures were never created. Extracted effective_img_src() helper used consistently across all three code paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gemini AI Code ReviewIssues (if any)
Previous Issues (for incremental reviews)(none) Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |
Review Response Agent (Iteration 1)Status: No changes needed
Fixed Issues
Ignored Issues
Deferred to Human
Notes
The agent reviewed feedback but no file modifications were detected. |
Failure Handler Agent (Iteration 1)Status: No changes needed The agent analyzed the failures but no automated fixes could be applied. Manual intervention may be required. |
Fixes all 5 bugs and 2 suggestions from the Gemini code review: 1. Chunked stream parsing false-positive (CRITICAL): Changed from find_subsequence scanning entire buffer to ends_with checks on buffer tail, preventing binary data mid-stream from triggering premature response truncation. 2. CSP bypass in fetch API (CRITICAL): __oasis_fetch now checks connect-src CSP directives before making HTTP requests. Added install_document_global_with_csp() that accepts the page CspPolicy. 3. Unsafe JS character escaping (BUG): dispatch_js_key_event now escapes backslash, single quote, newline, and carriage return to prevent JS syntax errors on special key presses. 4. Alpha over-accumulation in radial gradients (BUG): Force gradient band colors to alpha=255 since element-level opacity is handled separately by apply_opacity at the call site. 5. Stroked arcs silently ignored (BUG): Canvas Arc command now handles stroke case via stroke_rounded_rect. 6. SVG diagonal lines (SUGGESTION): Diagonal lines now use Bresenham-like plotting instead of bounding-box fill_rect. 7. Wire repeating-linear-gradient (SUGGESTION): Axis-aligned path now tiles stop bands when grad.repeating is true. Also fixes flaky CI test oasis-net::listener_max_connections_reached by adding retry loop with fresh ports on bind failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review Fixes Applied (commit 25c9153)Addressed all findings from the Gemini AI code review and the CI failure: Critical Fixes
Bug Fixes
Suggestions Implemented
CI Fix
|
Gemini AI Incremental ReviewThis is an incremental review focusing on changes since the last review. Issues (if any)
Previous Issues
Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |
Automated fix by Claude in response to Gemini/Codex review. Iteration: 2/5 Co-Authored-By: AI Review Agent <noreply@anthropic.com>
Review Response Agent (Iteration 2)Status: Changes committed, pushing... Commit: Fixed Issues
Ignored Issues
Deferred to Human
Notes
Automated summary of agent fixes. |
Gemini AI Incremental ReviewThis is an incremental review focusing on changes since the last review. Issues (if any)
Previous Issues (for incremental reviews)
Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |
Automated fix by Claude in response to Gemini/Codex review. Iteration: 3/5 Co-Authored-By: AI Review Agent <noreply@anthropic.com>
Review Response Agent (Iteration 3)Status: Changes committed, pushing... Commit: Fixed Issues
Ignored Issues
Deferred to Human
Notes
Automated summary of agent fixes. |
Gemini AI Incremental ReviewThis is an incremental review focusing on changes since the last review. Issues (if any)
Previous Issues (for incremental reviews)
Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |
Review Response Agent (Iteration 4)Status: No changes needed
Fixed Issues
Ignored Issues
Deferred to Human
Notes
The agent reviewed feedback but no file modifications were detected. |
Automated fix by Claude in response to pipeline failures. Failures addressed: - format - lint - test-suite Actions taken: - Ran autoformat (ruff format, cargo fmt) - Fixed remaining lint issues Iteration: 2/5 Co-Authored-By: AI Pipeline Agent <noreply@anthropic.com>
Failure Handler Agent (Iteration 2)Status: Changes committed, pushing... Commit: Failures addressed:
Automated fix in response to CI pipeline failures. |
Gemini AI Incremental ReviewThis is an incremental review focusing on changes since the last review. Issues (if any)
Previous Issues (for incremental reviews)
Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |
Automated fix by Claude in response to Gemini/Codex review. Iteration: 5/5 Co-Authored-By: AI Review Agent <noreply@anthropic.com>
Review Response Agent (Iteration 5)Status: Changes committed, pushing... Commit: Fixed Issues
Ignored Issues
Deferred to Human
Notes
Automated summary of agent fixes. |
Gemini AI Incremental ReviewThis is an incremental review focusing on changes since the last review. Issues (if any)
Previous Issues (for incremental reviews)
Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |
Automated fix by Claude in response to pipeline failures. Failures addressed: - format - lint - test-suite Actions taken: - Ran autoformat (ruff format, cargo fmt) - Fixed remaining lint issues Iteration: 3/5 Co-Authored-By: AI Pipeline Agent <noreply@anthropic.com>
Failure Handler Agent (Iteration 3)Status: Changes committed, pushing... Commit: Failures addressed:
Automated fix in response to CI pipeline failures. |
Gemini AI Incremental ReviewThis is an incremental review focusing on changes since the last review. Issues (if any)
Previous Issues (for incremental reviews)
Suggestions (if any)
Notes
Generated by Gemini AI (gemini-3.1-pro-preview). Supplementary to human reviews. |

Summary
Comprehensive browser engine improvements across 8 commits, 40 files changed, +3,647 lines.
Rendering Pipeline
repeating-linear-gradient()supportJavaScript Interactivity
fetch()API (synchronous HTTP GET, thenable response)getComputedStyle()returning ~30 CSS propertiessetTimeout/setIntervalvia TimerQueuelocalStorage/sessionStorage(in-memory)removeChild/insertBeforeDOM manipulationonclick,onchange,onsubmit, etc.)<canvas>2D context (fillRect, strokeRect, clearRect, fillText, path ops)Layout & CSS
margin: autoon flex itemstab-sizeCSS property for preformatted textradial-gradient()CSS parsing + renderingNetworking
Accept-Encoding: gzip, br)style-src,img-src,connect-srcdirectivesImages & Media
srcsetattribute parsing with width/density descriptor selectionwebpfeature)loading="lazy"defers image loadingNavigation & UX
BrowserErrorwith Network/Parse/Script categories)Performance
Test plan
-D warningsGenerated with Claude Code