Skip to content

Fix rendering of inline notebook content from ark#14150

Open
thomasp85 wants to merge 6 commits into
mainfrom
fix/html-widget-output-rendering
Open

Fix rendering of inline notebook content from ark#14150
thomasp85 wants to merge 6 commits into
mainfrom
fix/html-widget-output-rendering

Conversation

@thomasp85

@thomasp85 thomasp85 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #4219

This PR and the related ark PR (posit-dev/ark#1215) should fix htmlwidget rendering in all notebook types.

There is one positron-side blocker related to inline quarto output that seems to be a bug in quartoOutputViewZone._renderHtmlInWebview. It senst text/html through createNotebookOutputWebview, which only builds a webview when an extension renderer is registered for the MIME type. text/html resolves to the built-in renderer, which strips <head> and scripts, resulting in blank output.

The fix is to route the output through createRawHtmlOutputWebview(outputId, content), which injects the document verbatim with scripts enabled (same path the Positron notebook uses).

There shouldn't be any fallout from this change as this path is only ever reached for unsafe html without any mime renderer registered.

Testing

  • ark: crates/ark/tests/html_widgets.rs updated to assert literal inline <script> content (markers) rather than data: URIs; 4/4 pass.
  • Manual: leaflet + plotly now render in the VS Code .ipynb notebook (ark changes alone), and — with the two Positron fixes — in the Positron notebook and Quarto inline output.

Release Notes

New Features

  • N/A

Bug Fixes

  • Inline output is now supported for htmlwidgets in all 3 modes: VS Code notebook view, Positron notebook view, and inline quarto view.

Validation Steps

@:ark @:jupyter @:quarto @:notebooks @:positron-notebooks @:web

@thomasp85 thomasp85 self-assigned this Jun 10, 2026
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:ark @:jupyter @:quarto @:notebooks @:positron-notebooks @:web

readme  valid tags

@github-actions

Copy link
Copy Markdown

PETE's assessment 🧪

Verdict: 🔴 Insufficient -- a behavior-changing bug fix (Quarto inline HTML now routes through the raw-HTML webview path) ships with no regression test pinning the new path.

What changed

  • quartoOutputViewZone.ts: _renderHtmlInWebview now calls createRawHtmlOutputWebview(outputId, content) instead of building an ILanguageRuntimeMessageWebOutput and routing through createNotebookOutputWebview. This bypasses the MIME-renderer fallback that stripped <head>/scripts and left interactive widgets (plotly, leaflet) blank in Quarto inline output.
  • extensions/positron-r/ark: submodule commit bump carrying the AMD-guard / inline-deps / staticRender() fixes -- the logic lives in the ark repo, not testable from this checkout.

Tests in this PR

  • Unit (Vitest/Mocha) ❌ (no test added; quartoOutputViewZone has no test file)
  • Extension host ✅ (not applicable -- change is in src/vs/, not an extension feature)
  • E2E (Playwright) ❌ (no Quarto htmlwidget-rendering e2e added)

Existing coverage

  • src/vs/workbench/contrib/positronOutputWebview/browser/notebookOutputWebviewServiceImpl.vitest.ts tests createRawHtmlOutputWebview on the service (base-URI injection, captured HTML) -- but it does not exercise QuartoOutputViewZone's decision to call it, so it doesn't cover this change.
  • No test under src/vs/workbench/contrib/positronQuarto/test/ references QuartoOutputViewZone or _renderHtmlInWebview (verified -- the eight existing vitest files cover the parser, document model, kernel/output managers, and toolbar only).

Suggested additions

  • Add test/e2e/tests/<quarto-area>/quarto-html-widget.test.ts: an e2e that runs an R chunk emitting an htmlwidget (e.g. plotly/leaflet) and asserts the Quarto inline output webview renders non-blank with non-zero height. This is the one behavior that the whole fix stack targets and it can only be verified with the full app rendered (webview script execution + height message + view zone). If a Quarto e2e suite already exists, add the case there rather than a new file.
  • Optionally add to notebookOutputWebviewServiceImpl.vitest.ts (cheap unit guard): assert that for plain text/html content the raw path is the one chosen -- but note this only covers the service, not the view zone's routing decision, so it does not substitute for the e2e.

Deployment note (optional)

The underlying bug is webview script execution (UMD/AMD define conflict, async script reload). Web and desktop build webviews differently, so a Quarto-output e2e guarding this fix should be considered for @:web tagging -- a web-only regression in raw-HTML webview rendering would otherwise slip past PR CI. Confirm whether the e2e infra supports Quarto inline output on the web target before tagging.


PETE (Positron Extreme Test Experiment) - LLM-based test-coverage advisor, in pilot. Triggers on PR open and on /recheck-tests comments. Wrong verdict? Comment /recheck-tests (or /rePETE) on this PR to re-run. Please share feedback on how PETE performed here.

Comment on lines +2609 to +2621
// Render the self-contained HTML document directly in an overlay
// webview. We must NOT route this through `createNotebookOutputWebview`,
// which only builds a webview when an extension renderer is registered
// for the MIME type; plain `text/html` has none, so it falls back to
// the built-in renderer that strips `<head>` and scripts, leaving
// interactive widgets (plotly, leaflet) blank. The raw path injects the
// document verbatim with scripts enabled. This reaches us only for
// unsafe HTML (see `_renderHtml`/`_isSafeHtml`), i.e. exactly the
// script-bearing documents that need it.
const webview = await this._webviewService.createRawHtmlOutputWebview(
output.outputId,
content,
);

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.

Two notes:

  • There is a 3rd arg for baseUri that may be useful, but I am not sure
  • The comment here seems a bit overly verbose

Both of these may be addressed by looking at the solution from
main...fix/quarto-inline-output-self-contained-webview

@thomasp85 thomasp85 requested a review from DavisVaughan June 15, 2026 09:36
@thomasp85

Copy link
Copy Markdown
Contributor Author

The two failing tests appears to be unrelated to this PR. They fail on some Posit AI chat button that we don't touch

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.

Support R HTML Widgets in Jupyter notebooks

2 participants