Skip to content

Fix quick fixes / known bugs from TODO section 1 - #9

Open
aaralh wants to merge 12 commits into
mainfrom
fix/todo-quick-fixes
Open

Fix quick fixes / known bugs from TODO section 1#9
aaralh wants to merge 12 commits into
mainfrom
fix/todo-quick-fixes

Conversation

@aaralh

@aaralh aaralh commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Fixes all 11 items in TODO.md section 1 (quick fixes / known bugs), one commit per bug, with unit tests for everything testable headlessly.

Engine (web/)

  • Percentage font-size with a parent resolved to nothing — the computation was misindented into the no-parent branch of computed_style, so the property was silently dropped for any element with a parent.
  • raise NotImplementedraise NotImplementedError in tag_is_special (the constant is not an exception, so it raised TypeError).
  • EventInit trailing commas made bubbles/cancelable default to the truthy tuple (False,) instead of False.
  • DomException now subclasses Exception (was BaseException), carries its message through super().__init__, and is actually raised: Node.removeChild/appendChildBeforeElement raise it with name NotFoundError per the DOM spec instead of leaking a bare ValueError.

Application (browser/)

  • rem/em width/height math — the width branches assigned a str to font_size and then multiplied it, string-repeating into self.width and crashing later int() calls; the height branches crashed on any non-px font-size. Both now use the already-resolved self.font_size. (rem still uses the element font size as its base, matching create_margin/create_padding; the proper root-based distinction is tracked in TODO §3.)
  • Keyword font sizesconvert_absolute_size_to_pixels returned 16 for everything; xx-smallxxx-large now map to the standard scale on a 16px medium base.
  • Scrolling used window width for heightscroll_down's max-scroll plus the scrollbar thumb updates in scroll_down/scroll_up/scrollbar_scroll all read get_window_size()[0], letting pages scroll past their end.
  • internal_padding clobbering — every create_border branch overwrote it (last write won), so e.g. a lone border-top-width horizontally indented text. It's now derived once from the left border width, matching its sole use as TextLayout's x inset.
  • DrawBorder.calculate_offset body was commented out (always (0, 0)); restored the corner-mitre logic so mixed-width borders meet at corners.
  • Debug artifactsraster() no longer writes rules.txt/document.html to the CWD on every load; removed stray prints in ImageLayout and transform_color.
  • Swallowed load errorscheck_key's bare except: pass now catches Exception and logs the failure.

Tests & typing

  • 29 new unit tests across 6 new files (test_computed_style, test_parser_utils, test_event, test_dom_exception, test_font_utils, test_layout_units); suite grows 47 → 76, all green via ./test.sh.
  • Zero new mypy errors; 66 pre-existing ones eliminated (mypy had been flagging three of these bugs — the missing return and the tuple defaults — all along).

Follow-ups (out of scope here)

  • internal_padding still ignores left padding; padding handling is separate.
  • Proper rem (root font size) vs em distinction — TODO §3.

🤖 Generated with Claude Code

aaralh added 12 commits July 11, 2026 13:24
The computation was misindented into the no-parent branch of
computed_style, so any element with a parent got None back and the
property was silently dropped by the cascade.
raise NotImplemented is a TypeError at runtime since NotImplemented is
not an exception class.
bubbles and cancelable defaulted to the truthy tuple (False,) instead
of False.
DomException subclassed BaseException and was never raised anywhere.
It now subclasses Exception, carries its message through
super().__init__, and Node.removeChild/appendChildBeforeElement raise
it with name NotFoundError (per the DOM spec) instead of leaking a
bare ValueError from the list operations.
convert_absolute_size_to_pixels was a stub that returned 16 for every
keyword; small/large/etc. now map to the standard scale on a 16px
medium base.
The width branches re-derived the font size from the raw style string
and assigned a str in the rem/em arms, so int * str string-repeated
into self.width and later int() calls raised ValueError. The height
branches crashed on any non-px font-size value. Both now use
self.font_size, which is already resolved to int pixels in __init__.
rem still uses the element font size as its base like create_margin/
create_padding do; the proper root-based rem distinction is tracked in
TODO section 3.
Every border branch in create_border wrote internal_padding, so the
value ended up as whichever side was processed last — e.g. a lone
border-top-width horizontally indented the first word of text. It is
now derived once from the parsed left border, matching its sole use
as TextLayout's x inset. The em branch of calclulate_border_width also
now uses the resolved self.font_size instead of re-parsing the raw
style string, which crashed on non-px font-size values.

Left padding is intentionally still not included; tracked as follow-up.
The body was commented out so the method always returned (0, 0),
leaving corner gaps whenever per-side borders had differing widths.
Each border line is again extended by half the width of its
perpendicular neighbours.
scroll_down's max-scroll and the scrollbar thumb updates in
scroll_down, scroll_up and scrollbar_scroll all read
get_window_size()[0] (width) where the viewport height belongs,
letting the page scroll past its end on landscape windows.
raster() no longer dumps rules.txt and document.html into the working
directory on every page load; drop leftover debug prints in
ImageLayout and transform_color.
check_key wrapped load_webpage in a bare except: pass, so any network,
parse or layout error on Enter produced no feedback at all. Catch
Exception, log it, and keep the 'break' binding behavior. Also annotate
the log helper so it passes strict mypy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant