fix(editor): attach monaco's static widget CSS - #5830
Merged
norman-abramovitz merged 2 commits intoAug 19, 2026
Merged
Conversation
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
approved these changes
Aug 19, 2026
norman-abramovitz
left a comment
Contributor
There was a problem hiding this comment.
LGTM - Redid the live verify and saw no extra unexplained behaviors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
.cssfiles, but nothing attaches those for a plain dynamicimport(). 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'sime-text-arearelies 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).monaco(angular.json) — emitted as a stable, unhashedmonaco.css, so nothing pays for it at first paint.monaco-loaderlinks it (idempotent, resolved againstdocument.baseURI) when the editor loads. Same-origin, sostyle-src-elem 'self'covers it — no nonce required.Live-verified on a deployed foundation:
monaco.cssattached with 1138 rules; the IME textarea computesposition: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.csswhenever the feature list or the monaco version changes — the command is in the file header.