August brings HtmlUnit 5.4.0 with Firefox 153 support and a release heavily focused on HTML form validation, HTML parsing improvements, and JavaScript standards compliance.

🚀 Version 5.4.0 - August 7, 2026

Input Validation & Form Controls Overhaul

This release includes comprehensive improvements to form validation that bring HtmlUnit much closer to real browser behavior.

Number Input Handling: I’ve implemented a new HTML spec-conformant number parser (HtmlNumberParser) that all number validation now uses. The improvements include:

  • Proper validation method implementation for number inputs
  • Fixed value property getter to avoid locale-based formatting
  • Value sanitization now happens in the setter (not the getter), matching browser behavior
  • Relaxed parsing for validation while maintaining strict output format

Form Validation Methods: Implemented proper checkValidity() and reportValidity() methods that:

  • Correctly fire cancelable invalid events on every failing control
  • Have reportValidity() focus the first invalid control
  • Now work correctly for HtmlButton, HtmlTextArea, HtmlInput, HtmlObject, HtmlOutput, and HtmlSelect
  • Aggregate checks properly iterate through all form controls

Validation Properties: Added the validationMessage property to all form control elements, enabling better error reporting in JavaScript.

FieldSet Improvements:

  • Added type and elements properties to HTMLFieldSetElement
  • Fixed disabled state handling so that disabled fieldsets no longer disable descendants of their first legend element (matching the spec’s exemption)

File Input Fixes:

  • reset() now properly clears selected files without trying to reconstruct fake Files from the value attribute
  • Fixed validation to not incorrectly report disabled required file inputs as invalid when empty

TextArea Refactoring: Major refactoring of value handling—instead of manipulating the DOM, textarea now maintains a separate value and dirty flag (in sync with the spec and the input element). This also fixes cursor/selection issues when resetting or setting values.

Selection & Cursor Handling:

  • Setting a value to its current value no longer moves the text entry cursor
  • Form reset now only moves the cursor when the value actually changes
  • Selection state is properly maintained throughout operations

HTML Parser (Neko) Enhancements

The parser received several important updates:

Select Element Flexibility: The <select> element now allows arbitrary tags inside it (per WHATWG HTML PR #10557). This is a significant spec update that enables more flexible form structures.

Element Closing Behavior:

  • <section> no longer incorrectly closes <select> elements
  • New <nobr> start tags now correctly close open <nobr> elements, even across intervening block elements
  • New <a> start tags now correctly close open <a> elements, even across intervening block elements
  • <input> elements now correctly close <select> elements

Obsolete Elements Removed: Cleaned up support for obsolete HTML tags: <SOUND>, <ILAYER>, <LAYER>, <NOLAYER>, <NEXTID>, <MULTICOL>, <BLINK>, <SPACER>, and <XML>.

Textarea & Title Serialization: Fixed HTMLWriterFilter to properly serialize <textarea> and <title> element content with entity encoding.

Performance: Various optimizations and code cleanup throughout the parser.

JavaScript Engine Progress

WeakRef and FinalizationRegistry: The Rhino team has added full ES2021 standard-compliant implementations of WeakRef and FinalizationRegistry, enabling proper garbage collection callbacks and weak reference patterns.

Reflect.construct() for Subclassing: Added support for the common workaround for subclassing built-in objects (such as Set) without using ES6 class/extends syntax, by using Reflect.construct() with a newTarget argument. Thanks to Lai Quang Duong for this contribution.

Eval and Strict Mode: The Rhino team improved strict mode handling for direct eval() calls.

Hostname Setter Fixes: Several fixes to the URL/anchor hostname setter improve compliance with URL parsing specifications.

Web Standards & Networking

Navigator.sendBeacon(): Implemented the sendBeacon() method for reliable data transmission.

Sec-Fetch-* Headers: Major update to WebRequest to improve support for these critical security headers that communicate request context to servers.

XHR & Preflight Improvements:

  • Improved headers for XHR preflight requests
  • Frame/iframe requests now send the Accept header
  • Anchor ping requests now send Accept-Encoding and Cache-Control headers

Crossorigin Attribute: Script and anchor web requests now respect the crossorigin attribute.

Area Element Improvements: Unified area link handling with anchor handling through a new HyperlinkElementSupport class and HyperlinkElement interface. This adds support for ping and download attributes, among others.

Range & Selection Refinements

Whitespace Handling: Range.getClientRects() and Range.getBoundingClientRect() now properly ignore whitespace-only text nodes and block-level siblings when calculating the horizontal offset of a text node.

Bounding Box Calculations:

  • getBoundingClientRect() now uses shrink-wrap width calculation for block elements, returning a tight bounding box around actual content
  • Correctly handles character offset determination when range boundaries are set on parent elements
  • Properly handles DomText nodes throughout

Browser Compatibility Updates

  • Firefox 153: Area element now supports the type property
  • Firefox 153: Error.stackTraceLimit is now available
  • Updated innerText() for select elements to match real browser output

Infrastructure & Code Quality

  • WebSocket client (Jetty) updated to 12.1.12
  • Fixed resource leak in ImageIOImageData by properly closing base streams
  • Migrated from finalize() to Cleaner in DownloadedContent.OnFile and ImageIOImageData
  • java.net.http module is now required
  • CSP Multi-Policy Support: Thanks to Rick Mitchell, added multi-policy AND query APIs for Content Security Policy

Incompatible Changes

  • org.htmlunit.html.ValidatableElement renamed to ValidatableHtmlElement for consistency
  • DisabledElement now implements Element and provides a default isDisabled() implementation
  • Removed isReadonly() method from HtmlButton (no readonly support for buttons)
  • Removed isReadonly() method from HtmlSelect (no readonly support for select)

Version 5.4.0 is available on Maven Central. Check out the full changes report for the complete list of changes.

Special thanks to Lai Quang Duong for the Reflect.construct() work, Rick Mitchell for CSP multi-policy support, and the Rhino team for WeakRef/FinalizationRegistry implementation and strict mode improvements.

Happy testing!

— RBRi


Resources: