github lightpanda-io/browser 1.0.4

46 minutes ago

Behavior changes

  • Requests to the Fetch "bad ports" (ssh, smtp, pop3, imap, …) are now refused for every request, not only WebSocket.
  • window.postMessage now honors targetOrigin.
  • A cross-site response can no longer set a SameSite cookie other than None.
  • Proxy and server credentials are tracked separately, so proxy credentials are no longer sent to the server after a redirect.
  • An about:blank (or src-less) iframe now gets its contentWindow and contentDocument even without --load-resources iframe. Its HTTP and WebSocket requests are blocked while iframe loading is off.
  • An HTTP status from 600 to 999 (e.g. LinkedIn's 999) is now reported as-is instead of 0.
  • Trusted mousedown, mouseup, click and dblclick now stop at the first disabled form control, as in Chrome.
  • Element clicks and hovers from tools now hit the element's center instead of (0, 0).
  • document.readyState is now interactive when deferred scripts run.
  • Network.setUserAgentOverride now logs a warning when a restricted user agent is ignored.
  • The HTTP server parses requests more strictly and its routes are guarded against DNS rebinding.

CDP

  • Several page targets in one browser context. Console, exception and network events are routed to the right target, and a frame id from another target is rejected
  • Accessibility: ignoredReasons now match Chrome (ariaHiddenElement, ariaHiddenSubtree, inertElement, notRendered, notVisible)
  • Lone surrogate escapes in JSON ("\udc00") are accepted instead of closing the connection
  • LP.waitUntil and a settled lifecycle event
  • beacon added to LP.configureLoading
  • A closed browser context no longer leaves its viewport override for the next one
  • LP commands described in /json/protocol

Serve / CLI

  • --wait-until settled (experimental): waits for load, then for the work that can still change the page. Interval timers, long timers and intersection observers don't hold it
  • --v8-gc-hint-floor-mb replaces the fixed 1 MiB GC hint floor. Off in fetch
  • --experimental-features animation: fire animationstart, animationend and animationcancel for CSS animations
  • Bash 3.2 (macOS) filename completion

New Web APIs

  • AnimationEvent and CSS animation events (behind --experimental-features animation)
  • ClipboardEvent
  • InputEvent.getTargetRanges()
  • execCommand('insertParagraph')
  • getComputedStyle().content resolved from the cascade

Web API behavior / fixes

  • Text editors: CKEditor works, and clicks, focus and Tab place the caret in a contenteditable (Slate, Draft.js)
  • contenteditable: Backspace and Delete merge blocks (nested ones too), side-by-side lists merge, Enter in an empty list item outdents it
  • execCommand: runs of spaces and spaces at line edges become  , so they stay visible
  • innerText keeps spaces when CSS white-space preserves them, and puts a newline between rows of thead, tbody and tfoot
  • :defined follows the custom element state; customized built-ins (<button is=...>) now upgrade
  • [CEReactions] for createElement/createElementNS; the reactions queue is no longer drained when a constructor returns
  • a.hash and a.search (and <area>) return "" for a lone # or ?
  • history.pushState(undefined) no longer breaks history.state; state that JSON can't encode throws DataCloneError
  • import() of an already available module settles in a later task, as in Chrome
  • window.<id> on an iframe's window looks up the iframe's document
  • Functions called from a realm whose frame is gone no longer crash (import(), import.meta, postMessage, location)
  • WebSocket: fragmented messages are reassembled; the server's Sec-WebSocket-Protocol is checked against the offered list
  • CORS responses filter their headers
  • Response.clone() on a stream; pipeTo/pipeThrough fixes
  • Input stepUp/stepDown with fractional steps (0.1 + 0.2 gives 0.3)
  • matchMedia("") always matches
  • SVG getCTM()/getScreenCTM() return an identity matrix on a detached element
  • frame and basefont are serialized as void elements
  • document.createEvent('inputevent') is rejected; PromiseRejectionEvent requires its options
  • new CSSStyleSheet() sheets are the only ones replace() accepts
  • IntersectionObserver: the first check runs on the next tick

Tools / MCP

  • tree delta: true: returns only the lines that changed since the last call
  • The page's WebMCP tools are reported in a tool result whenever they change
  • Actions that open a window late (after a fetch or a timer) now follow it; new popups tool lists and switches windows
  • click says when the element is disabled or not rendered
  • Tool arguments are type-checked, and every error names the argument and the problem
  • tree and markdown keep content that is rendered despite hidden or aria-hidden
  • Markdown: <ol start>, multi-paragraph blockquotes, a blank line before ---
  • MCP over HTTP: tool output streamed over SSE (the run tool streams console lines), logging/setLevel, and notifications/cancelled now stops the call in flight
  • The run tool description explains how to load pages in parallel

Performance / stability

  • Style caches are invalidated per property group, and a geometry change no longer resets the whole geometry cache
  • Smaller CSS declarations (~500 KB saved on a style-heavy site); property names are ids, and style matching compares ids (7%+ faster rebuilds on most frameworks)
  • XHR takes the response body instead of copying it
  • XPath parsing allocates less
  • Crash fixes: abort during a gated transfer, a UAF in custom element upgrade
  • The crash reporter exits non-zero when it can't start curl

Release

  • macOS builds run on macOS 15; the Intel build targets baseline x86_64, fixing "Illegal instruction" on older CPUs
  • Release candidates (1.0.4-rc1) are now published

Don't miss a new browser release

NewReleases is sending notifications on new releases.