Commit 13586b8
feat: comprehensive browser rendering improvements (#31)
* feat: major browser rendering improvements across 8 phases
Wire in 3 complete but dead-code layout modules (table, float,
positioning), fix text measurement, add border styles, overflow
clipping, collect <style> blocks and inline style="" attributes
from the DOM (previously silently ignored), support @media queries,
inherit/initial keywords, and optimize cascade with HashMap lookups.
Phase 1: Wire table.rs (1,217 LOC) into block layout
Phase 2: Wire float.rs (485 LOC) with FloatContext, clear, clearfix
Phase 3: Wire positioning.rs (833 LOC) - already partially connected
Phase 4: Fix text width from char-count to bitmap_measure_text()
Phase 5: Dashed/dotted/double borders, overflow:hidden clipping
Phase 6: inherit/initial keywords, @media query parsing (screen,
max-width, min-width)
Phase 7: Collect <style> blocks + inline style="" from DOM into
cascade (critical fix - these were completely ignored)
Phase 8: O(1) inline style lookup via HashMap in cascade
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add mouse scroll wheel support and visual scrollbars for browser and terminal
Add InputEvent::MouseWheel variant and SDL2 mouse wheel event mapping.
Browser and terminal now respond to scroll wheel input with smooth
scrolling and display prominent 6px scrollbar tracks with proportional
thumbs on the right edge of their content areas.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: browser phases 9-10 — pseudo-elements, hover/visited, clippy fixes
Add ::before/::after pseudo-element support (Phase 9) with CSS content
property parsing, pseudo-element selector matching, and inline text box
generation in the layout engine.
Add :hover, :visited, and :link pseudo-class support (Phase 10) via a
new CascadeContext that threads hover node and visited URL state through
the entire CSS cascade. BrowserWidget tracks visited URLs and responds
to CursorMove events for hover hit-testing against link regions.
Also fixes pre-existing clippy warnings (collapsible if blocks,
unnecessary cast) and updates all benchmarks for the new style_tree
signature.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: connect browser image rendering pipeline (decode, layout, paint)
Wire up the full <img> rendering path: decode images from VFS during
navigation, use intrinsic dimensions for layout, and upload GPU
textures during paint. Previously all pieces existed but were
disconnected — images always rendered as broken placeholders.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add image rendering tests (unit + screenshot)
9 unit tests verify the full image pipeline: VFS loading, BMP decoding,
intrinsic dimensions, HTML attribute overrides, broken image placeholders,
texture creation during paint, and navigation state cleanup. Screenshot
test confirms end-to-end rendering with the SDL backend.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve 8 browser layout/paint bugs for correct CSS rendering
- Fix parent padding double-counted in child positioning (depth >= 2)
- Fix <br> and \n not causing line breaks in inline layout
- Fix block centering without margin:auto (add margin_left/right_auto)
- Fix inline backgrounds using hardcoded padding instead of CSS values
- Fix white-space:nowrap not preventing line wrapping
- Apply letter-spacing and word-spacing in text measurement
- Add parent-child margin collapsing (top and bottom)
- Apply text-indent to first line of inline content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* perf: optimize browser with time-sliced images, selector index, incremental hover, O(1) LRU
Five-phase performance optimization for the browser engine:
1. Time-sliced image loading: replace synchronous fetch-all-images loop
with deferred per-frame batches (8ms budget), so page text renders
immediately and images stream in. Auto-downscale images exceeding 1M
pixels.
2. CSS selector index: bucket rules by rightmost selector (id/class/tag/
universal) for O(1) candidate lookup instead of testing every rule
against every element (~10x fewer match attempts).
3. Incremental hover restyle: cache parsed stylesheets, re-cascade only
ancestor chains of old/new hover nodes instead of entire DOM. Throttle
hover restyles to 20/sec.
4. Reduce allocations: cache image_info_map with dirty flag (no per-layout
rebuild). Derive PartialEq on ComputedStyle for change detection.
5. O(1) LRU cache: replace VecDeque O(N) retain() with arena-backed
doubly-linked list. Add decoded image eviction with 8MB memory budget.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: 13 browser rendering correctness improvements across 5 phases
Phase 1 — inline/text: fix emergency word-break letter-spacing, text
decoration positioning (underline/strikethrough), CSS width/height on
<img> elements with aspect ratio preservation, remove dead paint_line_box.
Phase 2 — dimensions: percentage height resolution via containing height,
min/max-height properties and clamping, min/max-width constraint
enforcement in block width calculation.
Phase 3 — CSS cascade: margin-top/bottom auto flags, currentcolor
resolution for border colors via resolve_color_or_current().
Phase 4 — UA defaults: add body { margin: 8px } per CSS 2.1 spec.
Phase 5 — paint: clamp negative letter-spacing widths to zero,
propagate overflow:hidden clip rect to nested children via PaintContext.
13 new tests added, 742 browser tests passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add CSS custom properties (var()) support for Wikipedia rendering
Wikipedia's Codex design system defines 352 custom properties in :root
and references them 385 times via var(). This adds full support:
- :root pseudo-class matching (matches <html> element)
- CssValue::Var variant for unresolved var(--name, fallback) references
- Custom property declarations (--*) stored as raw CSS text
- custom_properties HashMap on ComputedStyle with CSS inheritance
- Two-pass cascade: first builds property map, then resolves var() refs
- resolve_css_var() with chained variable and fallback support
- var() handling in border/background shorthand expansion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: browser rendering improvements for Google and Wikipedia pages
- Fix prefers-color-scheme:dark media query to not match (light mode default)
- Change unknown media features to reject instead of match (safer default)
- Add border-top/right/bottom/left shorthand expansion
- Fix border-style:none forcing border-width to 0 per CSS spec
- Add inline element horizontal margin support (links no longer run together)
- Add presentational HTML attributes (bgcolor, width, height, align, etc.)
- Add <input> element rendering (text inputs and submit buttons)
- Add <center> tag support and InlineBlock layout fixes
- Add Google and Wikipedia HTML test fixtures with screenshot tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: 8-phase browser rendering quality improvements
Add box-sizing: border-box, CSS-styled inputs/buttons, unicode tofu
fallback, percentage min/max dimensions, vertical-align, HR border
styling, and background-image support. Fixes text centering in submit
buttons via bitmap measurement and replaces unrenderable glyphs with ?.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: 3 critical browser rendering bugs — whitespace, tables, HR
- Preserve inter-element whitespace: collapse_whitespace() no longer
strips leading/trailing spaces from text nodes, fixing "a bold and
italic" rendering as "aboldanditalic"
- Fix table cell content positioning: offset all descendants after
build_table_box() repositions cells so content renders at correct
table position instead of (0,0)
- Fix block-level replaced elements: HR now participates in block
flow with full container width instead of getting zero-width inline
layout
- Add line-boundary whitespace trimming per CSS 2.1 §16.6.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: 7-phase browser rendering quality improvements (round 3)
Implements phases 1-10 of the comprehensive browser improvement plan:
- Phase 1: Bold/italic text via faux-bold double-strike and skew rendering
- Phase 2: Extended character set (Latin-1, Cyrillic, 50+ Unicode symbols)
- Phase 3: Sub-pixel font scaling with Bresenham interpolation
- Phase 4: Form element rendering (3D inset inputs, raised buttons, placeholders)
- Phase 5: CSS margin collapsing (parent-child, empty blocks, BFC inhibition)
- Phase 6: Linear gradients, text-shadow, background-image gradient rendering
- Phase 7: Table layout fixes (thead/tbody/tfoot display, cell borders, valign)
- Phase 8: text-overflow ellipsis, word-break, overflow-wrap CSS properties
- Phase 9: User-agent stylesheet with proper defaults for all HTML elements
- Phase 10: Full-page screenshot infrastructure with wiki/news test fixtures
Key fixes: thead/tbody/tfoot display changed from table-row to block
(was causing all table body content to be invisible), sub-pixel font
scaling for accurate text sizes, and proper margin collapsing per CSS 2.1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: 5-phase browser rendering improvements (round 4)
Fix button text content (<button>Search</button> now shows "Search"
instead of "Button"), add percentage padding/margin resolution against
containing block width, add <select> dropdown rendering with selected
option label, fix inline-block percentage widths resolving against real
available width instead of 10000px, and add Wikipedia real portal test
fixture exercising all fixes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address AI review feedback (iteration 1)
Automated fix by Claude in response to Gemini/Codex review.
Iteration: 1/5
Co-Authored-By: AI Review Agent <noreply@anthropic.com>
* fix: address AI review feedback (iteration 2)
Fix SelectorIndex mixed selector list bug where rules with both keyed
and non-keyed selectors (e.g. `*, .foo`) missed the universal bucket,
causing non-keyed elements to miss valid matches. Fix pseudo-element
content resolution to respect cascade ordering (specificity, !important,
source order) instead of naive last-wins iteration order.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve CI pipeline failures
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: 1/5
Co-Authored-By: AI Pipeline Agent <noreply@anthropic.com>
* fix: address AI review feedback (iteration 3)
- Fix expand_border_side assigning unknown keywords to style instead
of color (e.g. currentcolor was misclassified as border-style)
- Fix matches_selector_ignoring_pseudo dropping the combinator when
pseudo-element compound becomes empty (e.g. `div ::before` matched
div itself instead of descendants)
- Fix trim_line_boundary_spaces skipping trailing space trim on
single-fragment lines due to unnecessary len > 1 guard
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: AI Agent Bot <ai-agent@localhost>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: AI Review Agent <ai-review-agent@localhost>
Co-authored-by: AI Pipeline Agent <ai-pipeline-agent@localhost>1 parent 1e29489 commit 13586b8
44 files changed
Lines changed: 10574 additions & 507 deletions
File tree
- crates
- oasis-app/src
- oasis-backend-sdl/src
- oasis-browser
- benches
- src
- css
- html
- layout
- loader
- oasis-types/src
- docs
- screenshots/classic
- test-fixtures/html
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| 68 | + | |
68 | 69 | | |
69 | 70 | | |
70 | 71 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
430 | 430 | | |
431 | 431 | | |
432 | 432 | | |
| 433 | + | |
433 | 434 | | |
434 | 435 | | |
435 | 436 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
134 | 134 | | |
135 | 135 | | |
136 | 136 | | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
137 | 144 | | |
138 | 145 | | |
139 | 146 | | |
| |||
380 | 387 | | |
381 | 388 | | |
382 | 389 | | |
| 390 | + | |
383 | 391 | | |
384 | 392 | | |
385 | 393 | | |
| |||
413 | 421 | | |
414 | 422 | | |
415 | 423 | | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
416 | 442 | | |
417 | 443 | | |
418 | 444 | | |
| |||
554 | 580 | | |
555 | 581 | | |
556 | 582 | | |
| 583 | + | |
557 | 584 | | |
558 | 585 | | |
559 | 586 | | |
| |||
680 | 707 | | |
681 | 708 | | |
682 | 709 | | |
683 | | - | |
| 710 | + | |
684 | 711 | | |
685 | 712 | | |
686 | 713 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
170 | 170 | | |
171 | 171 | | |
172 | 172 | | |
| 173 | + | |
173 | 174 | | |
174 | 175 | | |
175 | 176 | | |
| |||
349 | 350 | | |
350 | 351 | | |
351 | 352 | | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
352 | 358 | | |
353 | 359 | | |
354 | 360 | | |
| |||
374 | 380 | | |
375 | 381 | | |
376 | 382 | | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
377 | 392 | | |
378 | 393 | | |
379 | 394 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| |||
0 commit comments