Skip to content

Add a Playground page that formats Java in the browser - #10

Open
abashev wants to merge 3 commits into
mainfrom
abashev/playground
Open

abashev wants to merge 3 commits into
mainfrom
abashev/playground

Conversation

@abashev

@abashev abashev commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

What

A Playground page at /playground/, after "Get started" in the navigation. Code goes on the left, the formatted result shows on the right, and the formatting runs in the browser. The formatter is compiled to WebAssembly by openjavaformat/open-java-format#196. The code is not sent anywhere, and the result is what the command line writes for the same input. Part of openjavaformat/open-java-format#21.

  • Page: docs/playground/index.md. Every message is in the Markdown, links included, so the strict build checks them; the script only shows the one that applies.
  • Thanks at the end of the page, to Denis Pavlyuchenko, who suggested the playground, and to cobr123, whose WebAssembly build it started from.
  • Script and styles: docs/javascripts/playground.js and docs/stylesheets/playground.css, through extra_javascript and extra_css.
    • The script sets the page up through document$, because the site navigates without reloading. On other pages it does nothing.
    • It loads the module on this page only, once per visit. It starts it with GraalVM.run and learns from the promise whether loading failed.
    • Format runs on the button or Ctrl/⌘+Enter. Copy copies the result.
  • Header tab: Playground is white on the theme's blue, like the Format button, on every page and in both palettes.
  • Fetching the module: scripts/fetch-playground.sh takes the zip from the GitHub release that ojf_version names, checks it against that release's checksums_sha256.txt, and unpacks the two files next to the page. docs.yml runs it before the build, and so do mise run serve and mise run build. OJF_WASM_ZIP=<zip> takes a module built locally instead.

Before a release carries the module

21.0.1 has no zip. In that case the script writes a warning and the build carries on. The page then says that the playground comes with the next release and links to the command line. follow-releases.yml already redeploys the site when a new release is out, so the page starts working with no change here. A zip that is present but fails its checksum fails the build.

Tests

The tests ran with Playwright on a local build of the site, in Chromium 134, Firefox 135 and WebKit 18.4, against a module built from the formatter PR. All of these passed:

  • Loading:
    • Other pages do not request the module.
    • The playground works both when reached through the navigation and when opened directly.
    • After leaving and coming back, it works again without downloading the module a second time.
  • Formatting:
    • Format gives the same text as open-java-format-<version>-all.jar - for the starting example.
    • Pressing Format makes no request.
    • A warm format of the example takes 6 to 35 ms.
  • Errors:
    • class B { gives a line:column error.
    • The shortcut works.
    • Formatting works again after the error is fixed.
  • Layout:
    • Panes are side by side at 1400 px.
    • At 390 px in dark mode they are stacked, with no horizontal scroll.
  • Fallback states:
    • With WebAssembly.validate returning false, the page shows the unsupported-browser message.
    • Without the module, the page shows "comes with the next release" and Format stays disabled.

zensical build --clean --strict passes with the module and without it. The fetch script was tried on all three paths: the real 21.0.1 release without the zip (a warning), a local zip, and a wrong checksum (fails).

The page has the code on the left and the result on the right, and
formats with the formatter compiled to WebAssembly, so the code never
leaves the browser and the site still needs no server
(openjavaformat/open-java-format#21). The result is what the command
line writes for the same input.

The module is not in this repository. scripts/fetch-playground.sh
downloads open-java-format-wasm-<version>.zip from the GitHub release
that ojf_version names, checks it against the release's checksums and
unpacks it next to the page. docs.yml runs it before the build, and so
do mise run serve and build. A release without the zip is a warning,
not an error: the page then says that the playground comes with the
next release, and follow-releases.yml turns it on with the redeploy it
already runs for that release. A download that fails its checksum
fails the build.

The script comes through extra_javascript and sets the page up through
document$, since the site navigates without reloading. The module, 8 MB
over the wire, loads on this page only, once per visit. A browser
without WebAssembly GC gets a sentence and a link to the command line
instead of an empty pane.
The tab is white on the theme's blue, like the Format button and Get
started on Home, so the page is easy to find from any other. It turns
to the accent colour on hover and focus. The selector matches the end
of the link, since the tab links are relative to the page.
Denis Pavlyuchenko suggested a playground that runs in the browser, on
Telegram, and cobr123 built the first WebAssembly version of the
formatter, which the module the page runs grew from.

This branch has not been deployed

No deployments
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.

1 participant