--strip-mode was silently ignored for --dump markdown, and fetch had no
way to scope a dump to one element or cap its size although the markdown
and html tools have both.
--selector dumps the first matching element in any dump mode, --max-bytes
caps html and markdown with the tools' truncation marker, and markdown
now honors strip ui (images; scripts, styles and hidden elements are
never rendered, so the other groups don't apply).
Review feedback: navigation writes cookies and storage and a wait lets page
scripts mutate state, so neither can be auto-approved as read-only.
consoleLogs drains its buffer, so repeated calls differ.
Since all children of an invisible element are skipped, the visibility cache
serves no purpose AND we can assume that any element we do visit has a visible
parent and thus just need to check the element's own visibility.
interactiveElements and findElement returned elements under display:none
or [hidden], so agents were offered controls no user could reach and the
list disagreed with tree, which already filters on visibility. Reuse the
same cached check and skip the hidden subtree.
StyleManager ultimately ends up calling el.getOrCreateStyle() which either
returns the element's CSSStyleProperties OR (creates it AND stores it in the
Frame._element_styles for future lookups).
The goal behind this caching is twofold:
1 - Performance of not having to reparse the "style" attribute
2 - Identity: two calls from JS to get the properties should return the same
value
(2) is non-negotiable, so the 'getOrCreate' _has_ to exist for JS-facing APIs.
But (1) is CPU vs memory optimization that we've decided should always favor the
CPU. But, in any case where we dump an entire tree, that memory cost can be
significant (# of elements with a style attribute) and the CPU gains are
questionable (it isn't like a JS loop re-checking an element's properties, it's
a one-time dump). So, the StyleManager now takes a comptime `InlineAccess` which
is either `.scan` or `.materialize`. When it's `.materialize` it behaves as
before. When it's `.scan` is will use an existing `_element_styles` if available
else it will re-parse but not store the value.
The renderer's only visibility test was the tag (metadata/svg), so
display:none, [hidden], aria-hidden="true", closed <details> content and
closed <dialog>s all ended up in the output.
Check each element's own computed display:none through StyleManager plus
aria-hidden="true"; the dump root is exempt so a scoped dump of a hidden
subtree still renders it. analyzeContent/isStandaloneAnchor use the same
predicate so an anchor whose only content is hidden falls back to its label.
Also adds the missing dialog:not([open]) { display: none } UA rule.
Apply same conditions than CDP for MCP HTTP conns:
* refuse requests including Origin header
* accept only ip as host
* ensure content-type is json for POST
So we're trying to limit glibc to 2.43.0 do to an issue in Zig's self-hosted
compiler. I'm on 2.44.0 and I hard-coded 2.43.0. But for anyone on a version
prior to 2.43.0, that causes issues. So this takes the host version but limits
it to 2.43.0
The explicit version only exists to force Zig's bundled CRT (zig#31272),
but it also selects symbol versions. PR #3231 added tiny-skia, which
calls acosf, and glibc 2.43 re-versioned that symbol, so the binary now
fails to load on hosts with an older glibc:
libm.so.6: version `GLIBC_2.43' not found
Use the detected host glibc instead: still an explicit version, so the
bundled CRT is still used, but never newer than what the binary runs on.
An unscoped html call returned the whole document, inline scripts and
stylesheets included, with no way to cap it; markdown already had
maxBytes. The byte-capping writer moves out of markdown.zig into a shared
LimitedWriter so both tools use it, and strip reuses dump.Opts.Strip.
Every tool already had a short summary and a natural read-only /
destructive classification, but tools/list exposed neither, so clients
had to prompt for every call, including pure reads like getUrl.
ARIA `role` is a space-separated fallback list (`role="switch checkbox"`),
but interactive.zig and AXNode compared the raw attribute whole, so a
fallback list or padded value was neither interactive nor findable by
role, and the semantic tree reported the raw string as the role.
One explicitRole helper takes the first token; a blank attribute now
falls through to the implicit role.
initialize always answered 2024-11-05 regardless of what the client asked
for. Per the spec, echo the requested version when we support it and
otherwise reply with the newest we do (2025-11-25).
- Stop re-exporting command-line variables via MAKEFLAGS: tikv-jemalloc-sys's
build script appends its jobserver flags after the inherited "-- F=..."
separator, so a cold cargo cache failed with "No rule to make target '-j'"
whenever any VAR=value was passed to make.
- `TEST_FILTER=... make test` was silently clobbered by the empty F and ran
the full suite; fall back to the environment value when F is unset.
CI build, for e2e-test and nightly now build with:
-Dorderfile/lightpanda.ld
This file informs the build on how to organize the code in the binary, grouping
hot code together so that we have to load less of the binary into memory.
lightpanda.ld will drift: we'll refactor our code, add new features, update
dependencies, update Zig, ... So it has to be re-generated. But we can do that
automatically in the CI (say, before the nightly build). That's for a follow up
PR.
This does not currently cover V8. V8 is being build with
`-no-unique-section-names`, so we don't get names that we can correctly
organize. The real win comes from doing this in V8, since a lot of V8 is cold.
This PR can land as-is, a zig-v8-fork PR will remove that flag, and then we can
have a follow up PR with an lightpanda.ld that includes the v8 symbols.
This is opt-in (via the -Dorderfile flag) because it adds ~20 seconds of
linking time.
CSS keywords are ASCII case-insensitive, but StyleManager matched
display:none / visibility:hidden|collapse / opacity:0 / pointer-events:none
with exact String.eql, so `style="DISPLAY: NONE"` or a `.x { Visibility:
Hidden }` rule left the element visible to checkVisibility,
getComputedStyle, the semantic tree and interactiveElements.
Compare at the check sites via a new String.eqlSliceIgnoreCase rather than
lowercasing declared values, which would corrupt content, url() and custom
property values that el.style must reflect verbatim.