From c7dd9133889ca0801834cf111106da3bcdacc31b Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Wed, 10 Jun 2026 08:10:36 +0200 Subject: [PATCH 1/4] Fix rendering of inline notebook content from ark --- extensions/positron-r/ark | 2 +- .../browser/quartoOutputViewZone.ts | 35 ++++++++----------- .../browser/notebookOutputUtils.ts | 12 ++++--- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/extensions/positron-r/ark b/extensions/positron-r/ark index a412f78ea09e..8406043e41d2 160000 --- a/extensions/positron-r/ark +++ b/extensions/positron-r/ark @@ -1 +1 @@ -Subproject commit a412f78ea09eb383ccaf97174669845567ab59f8 +Subproject commit 8406043e41d23cbf4418b36a7e3321b6eebf5fa5 diff --git a/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts b/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts index 2ee14ca7bec2..2cb5c35c13fa 100644 --- a/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts +++ b/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts @@ -2606,29 +2606,22 @@ export class QuartoOutputViewZone extends Disposable implements IViewZone { container.appendChild(loadingIndicator); try { - // Create a runtime message for the HTML content - const runtimeMessage: ILanguageRuntimeMessageWebOutput = { - id: output.outputId, - parent_id: '', - when: new Date().toISOString(), - type: LanguageRuntimeMessageType.Output, - event_clock: 0, - kind: RuntimeOutputKind.ViewerWidget, - data: { 'text/html': content }, - output_location: PositronOutputLocation.Console, - resource_roots: undefined, - }; - - // Create the webview - const webview = await this._webviewService.createNotebookOutputWebview({ - id: output.outputId, - runtime: this._session, - output: runtimeMessage, - viewType: 'jupyter-notebook', - }); + // 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 `` 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, + ); if (!webview) { - // No renderer available - show the HTML escaped + // No webview available - show the HTML escaped container.removeChild(loadingIndicator); const pre = document.createElement('pre'); pre.className = 'quarto-output-html-escaped'; diff --git a/src/vs/workbench/contrib/positronWebviewPreloads/browser/notebookOutputUtils.ts b/src/vs/workbench/contrib/positronWebviewPreloads/browser/notebookOutputUtils.ts index bcc0fc53cf75..16f25b65743d 100644 --- a/src/vs/workbench/contrib/positronWebviewPreloads/browser/notebookOutputUtils.ts +++ b/src/vs/workbench/contrib/positronWebviewPreloads/browser/notebookOutputUtils.ts @@ -66,10 +66,14 @@ export function isWheelForwardMessage(message: unknown): message is WheelForward && typeof m.deltaY === 'number'; } -// Helper function for TypeScript typing -function acquireVsCodeApi(): { postMessage: (message: HTMLOutputWebviewMessage) => void } { - throw new Error('Function not implemented.'); -} +// Ambient declaration for the webview-provided global. This MUST be `declare` +// (no runtime body): a real local function gets renamed by the bundler (e.g. to +// `acquireVsCodeApi2`) along with its reference inside `webviewMessageCode`. +// Since `webviewMessageCode` is injected into the webview via `.toString()`, +// the renamed identifier doesn't exist there and the injected script throws +// `acquireVsCodeApi2 is not defined`, so the output never reports its size and +// renders blank. See also the matching declaration in `downloadUtils.ts`. +declare function acquireVsCodeApi(): { postMessage: (message: HTMLOutputWebviewMessage) => void }; function webviewMessageCode() { const vscode = acquireVsCodeApi(); From ec06c81dee79c70d2643c0ec32d8458f0cbbd59a Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Thu, 11 Jun 2026 15:25:06 +0200 Subject: [PATCH 2/4] Apply upstream fix to tests --- .../test/browser/positronList.vitest.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/positronList/test/browser/positronList.vitest.tsx b/src/vs/workbench/browser/positronList/test/browser/positronList.vitest.tsx index 7fecc476c5d3..71647f765f4e 100644 --- a/src/vs/workbench/browser/positronList/test/browser/positronList.vitest.tsx +++ b/src/vs/workbench/browser/positronList/test/browser/positronList.vitest.tsx @@ -113,8 +113,8 @@ describe('PositronListInstance', () => { const instance = new PositronListInstance({ itemRenderer: item =>
{item}
, sectionRenderer: section =>
{section}
, - defaultItemHeight: ITEM_HEIGHT, - defaultSectionHeight: SECTION_HEIGHT, + itemHeight: ITEM_HEIGHT, + sectionHeight: SECTION_HEIGHT, }); store.add(instance); return instance; @@ -203,8 +203,8 @@ describe('PositronList keyboard navigation', () => { const common = { itemRenderer: (item: string) =>
{item}
, sectionRenderer: (section: string) =>
{section}
, - defaultItemHeight: ITEM_HEIGHT, - defaultSectionHeight: SECTION_HEIGHT, + itemHeight: ITEM_HEIGHT, + sectionHeight: SECTION_HEIGHT, }; const instance = selectionFollowsCursor ? new PositronListInstance({ ...common, selectionFollowsCursor: true }) @@ -339,8 +339,8 @@ describe('PositronList rendering', () => { const instance = new PositronListInstance({ itemRenderer: item =>
{item}
, sectionRenderer: section =>
{section}
, - defaultItemHeight: ITEM_HEIGHT, - defaultSectionHeight: SECTION_HEIGHT, + itemHeight: ITEM_HEIGHT, + sectionHeight: SECTION_HEIGHT, }); store.add(instance); return instance; From b226592e22a6e9f2388635a6f1ce1d29f3f9ebf3 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Fri, 12 Jun 2026 12:36:10 +0200 Subject: [PATCH 3/4] Apply Davis' approach to Quarto --- .../browser/quartoOutputViewZone.ts | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts b/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts index bfd588787873..2fed1d4db1a4 100644 --- a/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts +++ b/src/vs/workbench/contrib/positronQuarto/browser/quartoOutputViewZone.ts @@ -17,6 +17,8 @@ import { formatCellDuration, getRelativeTime } from '../../positronNotebook/brow import { ThemeIcon } from '../../../../base/common/themables.js'; import { Event as VSEvent, Emitter } from '../../../../base/common/event.js'; import { URI } from '../../../../base/common/uri.js'; +import { dirname } from '../../../../base/common/resources.js'; +import { Schemas } from '../../../../base/common/network.js'; import { INotebookOutputWebview, IPositronNotebookOutputWebviewService } from '../../positronOutputWebview/browser/notebookOutputWebviewService.js'; import { isHTMLOutputWebviewMessage } from '../../positronWebviewPreloads/browser/notebookOutputUtils.js'; import { ILanguageRuntimeSession } from '../../../services/runtimeSession/common/runtimeSessionService.js'; @@ -2606,30 +2608,22 @@ export class QuartoOutputViewZone extends Disposable implements IViewZone { container.appendChild(loadingIndicator); try { - // 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 `` 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. + // Resolve relative assets against the document's directory when it + // lives on disk (untitled documents have no meaningful base). + const baseUri = this._documentUri && this._documentUri.scheme !== Schemas.untitled + ? dirname(this._documentUri) + : undefined; + + // Render raw HTML content as a self-contained document (i.e. an R + // leaflet map). Using `createNotebookOutputWebview()` would find the + // built-in renderer for `text/html` and flatten the self-contained + // document, dropping `` and scripts. const webview = await this._webviewService.createRawHtmlOutputWebview( output.outputId, content, + baseUri, ); - if (!webview) { - // No webview available - show the HTML escaped - container.removeChild(loadingIndicator); - const pre = document.createElement('pre'); - pre.className = 'quarto-output-html-escaped'; - pre.textContent = content.substring(0, 1000) + (content.length > 1000 ? '...' : ''); - container.appendChild(pre); - return; - } - // Store the webview and container for later cleanup and scroll updates this._webviewsByOutputId.set(output.outputId, webview); this._webviewContainersByOutputId.set(output.outputId, container); From 23276f9ee05290de3bc6584e892c8da22b200be1 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 15 Jun 2026 09:15:51 +0200 Subject: [PATCH 4/4] Bump ark to 512d2b --- extensions/positron-r/ark | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/positron-r/ark b/extensions/positron-r/ark index 8406043e41d2..512d2bf5a465 160000 --- a/extensions/positron-r/ark +++ b/extensions/positron-r/ark @@ -1 +1 @@ -Subproject commit 8406043e41d23cbf4418b36a7e3321b6eebf5fa5 +Subproject commit 512d2bf5a465193798727aced7095c3c89922da4