Skip to content

fix(editor): attach monaco's static widget CSS - #5830

Merged
norman-abramovitz merged 2 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/monaco-static-css
Aug 19, 2026
Merged

fix(editor): attach monaco's static widget CSS#5830
norman-abramovitz merged 2 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/monaco-static-css

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Stacked on #5829 (branched from it — merge that first). Found while answering "what is that extra window?" on a deployed editor.

The defect — older than the recent monaco work: the application builder bundles the CSS that monaco imports from JS into per-chunk .css files, but nothing attaches those for a plain dynamic import(). Confirmed empirically: no built JS and no index.html reference the chunk css names, and the shipped v5.2.0 zip carries the same orphaned css chunks — so since the ESM switch (#5561) every deployed editor has rendered on monaco's runtime-injected styles plus browser defaults. monaco 0.52 masked the worst of it by positioning its input textarea from JS; 0.56's ime-text-area relies on the stylesheet, so an unstyled white textarea with a browser resize grip floated into view inside the editor, and the find widget renders with no chrome (transparent background, live-confirmed).

The fix:

  • monaco-styles.css — generated aggregate of the 98 css files in the curated subset's import graph (via the esbuild metafile; regeneration command in the header; relative paths because monaco's exports map rewrites every package subpath to *.js, blocking css specifiers).
  • Built as a non-injected styles bundle named monaco (angular.json) — emitted as a stable, unhashed monaco.css, so nothing pays for it at first paint.
  • monaco-loader links it (idempotent, resolved against document.baseURI) when the editor loads. Same-origin, so style-src-elem 'self' covers it — no nonce required.

Live-verified on a deployed foundation: monaco.css attached with 1138 rules; the IME textarea computes position:absolute, transparent, resize:none, z-index:-10 (the phantom window is gone); the find widget has its themed chrome back.

Maintenance note: regenerate monaco-styles.css whenever the feature list or the monaco version changes — the command is in the file header.

monaco 0.56's per-feature registry omits the suggest controller and
the go-to commands: features/suggest/register.js and register.all.js
import only suggestInlineCompletions, and features/gotoSymbol only
the mouse link path. Upstream's editor.main.js imports both contribs
directly, so only registry-composed builds lose them — our curated
subset shipped without Ctrl+Space, found by live-driving the deployed
editor (editor.action.triggerSuggest did not exist). Import both
contribs directly until the upstream registry is fixed.

Live-verified on the lab console: suggest action, controller and
widget all present after the fix. The goToCommands actions could not
be observed there — no surface with a definition provider exists on
that foundation — so that half rides along unverified.
The application builder bundles the CSS monaco imports from JS into
per-chunk .css files, but nothing attaches those to the page for a
plain dynamic import() — confirmed empirically: no built JS or the
index references the chunk css names. Since the ESM switch (cloudfoundry#5561)
every deployed editor has rendered on monaco's runtime-injected
styles and browser defaults; the v5.2.0 zip carries the same orphaned
chunk css. monaco 0.52 masked the worst symptom by positioning its
input textarea from JS — 0.56's ime-text-area relies on the
stylesheet, so an unstyled white textarea with a browser resize grip
floated into the editor, and the find widget has no chrome.

Fix: the subset's static CSS is generated into monaco-styles.css
(from the monaco-features import graph via the esbuild metafile;
regeneration command in its header; relative paths because the
package exports map rewrites every subpath to *.js) and built as a
non-injected styles bundle named "monaco" — stable, unhashed URL —
which the loader links once when the editor loads. Same-origin, so
style-src-elem 'self' covers it without a nonce.

Live-verified on the lab console: monaco.css attached (1138 rules),
the IME textarea computes absolute/transparent/no-resize, and the
find widget has its chrome back.

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Redid the live verify and saw no extra unexplained behaviors.

@norman-abramovitz
norman-abramovitz merged commit 17d4143 into cloudfoundry:develop Aug 19, 2026
23 checks passed
@nabramovitz
nabramovitz deleted the norm/fix/monaco-static-css branch August 19, 2026 18:05
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