Previously, every operation would run synchronously, and resolve the value
on the next drain (schedule task run on the next tick).
With 1 connection per DB, this doesn't work with SQLite: you cannot have nested
transactions. Imagine:
add
begin
insert into
JS callback (success)
add
begin <-- nested
insert
This approach captures the requested operation and does all necessary validation
(since most validation errors are returned synchronously), but only executes
operations on drain. Hence, rather than IDBTransaction._requests being a
queue of result values to emit on drain, it is now a queue of operations to
execute and then emit.
This will also potentially make it easier to address serious memory
issues by better scoping the lifetime of things (particularly requests).
Initial WIP on IndexedDB WebAPI. Uses sqlite and a new `--indexdb_dir` config.
Defaults to :memory:.
The main things missing are the IDBCursor, IDBIndex and IDBKeyRange, along with
a bunch of smaller apis.
Also, every object is currently tied to the Page arena / factory. It's possible
that's how it will have to be, but, once more of the API lands, I will check
if we can scope these better.
actions.setChecked set the input state and then dispatched a trusted
click, but the click's activation behavior (EventManager's
ActivationState) toggles a checkbox on every click dispatch — undoing
the state just set — and its commit path fires input/change, which
setChecked then fired a second time. Checkboxes always landed in the
opposite of the requested state with doubled events; radios only
appeared to work because radio activation always checks. It survived
because existing tests asserted the tool's report string, never the
resulting DOM state.
setChecked is now a no-op when the state already matches, otherwise it
performs the click (reusing actions.click) and verifies the state
landed — erroring before the click for radio+false (a click can never
uncheck a radio, and the click has observable page side effects) and
after it when a listener preventDefault()ed the toggle.
Caught by the checked.js golden in the demo agent regression suite.
The Runtime test now asserts DOM state and idempotency instead of
trusting the report string.
The main addition in this commit is that we hook into the Isolate's
AddNearHeapLimitCallback callback and try to force the isolate to shutdown
rather than letting v8 hit an OOM which would take down the entire process.
In support of this, we now support a `--v8-max-heap-mb` command line option to
set an explicit heap limit. As a simple way to test this feature, load a
relatively heavy JS page with `--v8-max-heap-mb 1`.
There's also a `--v8-flags-unsafe` which is a mechanism to pass arbitrary
flags to v8 via its `SetFlagsFromString`. The parameter is called `unsafe`
because some [of the many] configurable flags could conflict with how the
snapshot is built and result in crashes. The snapshot creator also gains a
`--v8-flags-unsafe` flag, so advance users COULD create their snapshot and
run lightpanda with the same set of flags.
When an iframe has "loading=lazy" it no longer delays the parent's "load" event.
It's still loaded (subject to `--disable-subframes` parameter).
Many sites use loading=lazy for non-critical content (e.g. ads). On Chrome/
Firefox, these are only loaded when they're in the viewport, so sites usually
can't depend/rely on them being loaded.
Per spec, nested timers eventually (5-level deeps) enforce a minimum timeout
(4ms).
This commit also fixes 2 UAFs in module loading where a map entry would become
invalid through nested mutations.
All issues were encountered on https://111skin.com/.
Window.event, screen, visualViewport and crypto are all [Replaceble]. This
should be all the one's we're missing.
Also, apply the repleceable on the correct v8 global's context in the case where
a caller reaches into an iframe to replace a property on the iframe's window.
Fixes endless loop on https://100500dobavok.ua/ which replaces window.event.
When CSSStyleDeclaration.getPropertyValue is called for width or height, and the
inline style isn't found, return the elements actual width/height. Without this
we return "" which is wrong and can cause script error/hangs.
This change touches a lot of files, but it's pretty minor. Most files simply
have .dom_exception = true removed from their WebAPI binding.
The only reason NOT to have this on is in the case where a Zig function returns
an error that incorrectly gets mapped to a DOMException. But this hasn't
happened yet, none of the base errors (e.g. OutOfMemory) map to a DOMException,
but the opposite DOES happen: we don't flag an API as dom_exception = true that
we should.
Module loaders (Vite legacy plugin, Shopify themes) feature-detect
HTMLScriptElement.supports("module") and
link.relList.supports("modulepreload"). Both were missing, so themes
fell back to fetch()-based legacy chunk loading: on allbirds.com that
meant 676 requests instead of 305 for two page loads, the same module
fetched 9x per page by page JS, and a ~4% CDP driver flake from the
legacy path replacing the document mid-query (0/50 repro with this
change, vs failing within 3 iterations without).
HTMLScriptElement.supports returns true for the types this engine
loads (classic, module, importmap). DOMTokenList.supports implements
the rel supported-tokens set and throws TypeError for attributes that
define none, per spec.
startGoto runs under the browser's isolate; its error path rejected the
script-isolate resolver via a `return` inside that block, i.e. before
the deferred isolate exit — v8::Exception::Error on the wrong isolate,
SIGSEGV. Reached by any goto that fails to start: page.goto(null) (an
extract miss flowing into goto), malformed arguments.
Yield null from the isolate block and settle the resolver after it.
There was a `TODO` comment about this; nicer to actually have it. There's still stdlib's certificate bundle scanner for platforms we can't do this (like macOS).
Places the options in alphabetic order and applies the same indentation for
all commands (agent was formatted quite differently than the others).
While I would also like "more common" commands to be listed first, since they
can only be sorted one way, I find alphabetic to be the most generally useful
and the easier for us to maintain.
Feel free to reject this if you disagree.
Removes lying dead code here and simplifies `curl_easy_setopt` type checking. Also marks passed callbacks as with C calling convention in order to get away from additional function wrapping.