Skip to content

feat(html): flesh out the browser environment (navigator, screen, performance, crypto, iframe) - #274

Closed
Sonic-Y3k wants to merge 1 commit into
gost-dom:mainfrom
Sonic-Y3k:feat/dom-environment
Closed

feat(html): flesh out the browser environment (navigator, screen, performance, crypto, iframe)#274
Sonic-Y3k wants to merge 1 commit into
gost-dom:mainfrom
Sonic-Y3k:feat/dom-environment

Conversation

@Sonic-Y3k

Copy link
Copy Markdown

Adds commonly-read parts of the browser environment that scripts feature-detect or branch on:

  • a populated navigator (userAgent, platform, languages, hardwareConcurrency, webdriver === false, userAgentData, …)
  • screen, performance (now/timeOrigin) and crypto (getRandomValues/randomUUID), implemented natively
  • window.top/frames/length for a top-level context (previously threw)
  • document.compatMode/characterSet/cookie/title/visibilityState/hidden/hasFocus, and a real document.readyState that is "loading" during parsing and "complete" afterwards
  • the legacy Document.createEvent factory plus initEvent/initMouseEvent/…
  • HTMLIFrameElement.contentWindow / contentDocument

Note: contentWindow resolves to the owning window's realm rather than a separate same-origin realm — the bundled gost-dom/v8go build doesn't expose security-token control, so a child context's globals aren't cross-realm accessible (V8 raises "no access"). Native built-ins on contentWindow are accessible and genuine; only object identity differs. Happy to revisit if a separate realm is preferred.

Testing: added TestEnvFidelity; the existing htmx integration suite and full test suite stay green. document.readyState is backed by the real load state specifically so script-timing-sensitive consumers (e.g. htmx) keep working.


AI disclosure: This change was developed with the help of an AI coding assistant. I've reviewed and tested it myself; it follows the existing conventions and the full test suite (main module, v8engine, sobekengine) passes locally.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Sonic-Y3k, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 9 minutes and 44 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e650945e-ab64-4681-b4d3-beab9ecd4b8e

📥 Commits

Reviewing files that changed from the base of the PR and between ac2cda7 and 2e74f2a.

📒 Files selected for processing (9)
  • html/html_document.go
  • html/html_iframe_element.go
  • html/window.go
  • internal/code-gen/scripting/configuration/dom_configuration.go
  • scripting/internal/dom/document_generated.go
  • scripting/internal/dom/event.go
  • scripting/internal/html/env_fidelity.go
  • scripting/internal/html/initializer.go
  • scripting/v8engine/env_fidelity_test.go

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…formance, crypto, iframe, ...)

Adds commonly-read parts of the browser environment that scripts feature-detect
or branch on:

- a populated navigator (userAgent, platform, languages, hardwareConcurrency,
  webdriver=false, userAgentData, ...)
- screen, performance (now/timeOrigin) and crypto (getRandomValues/randomUUID),
  implemented natively
- window.top/frames/length for a top-level context (previously threw)
- document.compatMode/characterSet/cookie/title/visibilityState/hidden/hasFocus,
  and a real document.readyState that is "loading" during parsing and
  "complete" afterwards
- the legacy Document.createEvent factory plus initEvent/initMouseEvent/...
- HTMLIFrameElement.contentWindow / contentDocument
@Sonic-Y3k
Sonic-Y3k force-pushed the feat/dom-environment branch from 965d963 to 2e74f2a Compare June 13, 2026 14:25
@stroiman

Copy link
Copy Markdown
Member

Hi.

There's a lot going on here, and as I mentioned in another PR, something in scope - but some things are out of scope. As I mentioned in another PR comment, I want to keep this repo as lean as possible.

However, there is a path to support the functionality that is out of scope.

I have only briefly skimmed the code, and description; so this may not be a full review, but I hope it can spawn a constructive discussion :)

iframe support

iframe support is definitely in scope; but this has enough complexity to a warrant dedicated PR by itself.

I haven't used iframes for 15-ish years, so my knowledge how a document and iframe documents can interact is very dated. I assume run scripts in a separate JavaScript realm, and there some message passing capabilities between the two - like workers.

As I have skeleton worker support with message passing capabilities and a shared clock, i.e., all workers run in with the same simulated clock. I haven't merged yet, at I'm not happy with the implementation; but maybe I should, so there's a foundation for message passing between different realms.

Having said that, I will be happy releasing preliminary iframe support without full script isolation and message passing. But I want to have a clear knowledge about what the level of compliance is, what works as it should, and what is lacking.

User-agent properties on the Navigator object

First of all, which problem is this solving? Is it solving a real problem; or was it mostly just a low-hanging fruit for making it more specs-compliant?

The intended use case is to provide a useful tool for testing modern web applications. Does you client code actually depend on what the navigator reports?

If yes, I'd go for a solution where client code can provide these options; e.g., as options to browser.New() - which also seem reasonable to me. We dictate the browser properties when creating it.

But it's something I'd like to avoid in the core browser module.

initEvent and friends.

These operations are deprecated, so they will not be part of the Gost-DOM browser module. However; there may be another solution for projects that would depend on these.

Solution for Navigator/initEvent

It has always been the goal that Gost-DOM's JavaScript scope is extensible. Gost-DOM provides essential browser functionality, like the DOM, HTTPDOM, fetch APIs, etc. Client code should be able to add "plug-ins" implementing other web APIs as needed. E.g., you could add a Geolocation implementation through a "plug-in".

Extending JS scope isn't restricted to adding new values in global scope; you can also extend existing IDL interfaces with new operations/attributes. So a "plug-in" could provide browser capabilities.

So both problems, reporting browser "capabilities" on the navigator object, as well as eventInit can be supported without adding this to core browser behaviour.

This "plugin" architecture currently exists in internal/ package scope. How client code can add a plug-in probably needs a wee review, maybe some refactoring; but the internal mechanisms seem to have stabilized enough to be ready for experimental "release".

@Sonic-Y3k

Copy link
Copy Markdown
Author

Thanks for the detailed feedback - agreed on all of it. Rather than reshape this
single PR, I have split it into focused PRs and will close this in favour of them:

  • iframe -> feat(html): implement HTMLIFrameElement contentWindow/contentDocument #278. Preliminary support: contentWindow / contentDocument resolve
    the nested browsing context. Compliance level is stated up front in the PR -
    one realm per script context for now, so the nested context resolves to the
    owning window's realm. Every native built-in on contentWindow stays genuine
    and accessible; only object identity differs from a real same-origin iframe.
    Your worker / shared-clock message-passing work looks like the right
    foundation for real per-realm isolation later, so I kept this deliberately
    minimal.

  • navigator -> feat(html): make the navigator profile configurable #279. Made configurable instead of hardcoded: client code supplies
    the profile via a browser.WithNavigator(...) option (user agent, platform,
    languages, hardware concurrency), with a default fallback. On "does client code
    depend on it?" - yes: apps and libraries branch on navigator (UA sniffing,
    languages for i18n, hardwareConcurrency for pool sizing), and a faithful test
    wants to control what they see. This keeps the values out of core as fixed
    constants, which was your main concern.

  • performance / crypto / document.readyState -> feat(html): add performance, crypto and live document.readyState #280. A separate "environment"
    PR for the functional bits.

  • initEvent / createEvent: dropped, since they are deprecated.

  • screen + window viewport metrics + document string constants: deferred. I will
    bring them back only if there is real demand, and screen would likely follow
    the same configurable approach as navigator rather than landing as fixed
    constants.

Closing this in favour of #278, #279 and #280.

@Sonic-Y3k Sonic-Y3k closed this Jun 27, 2026
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.

2 participants