mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
Notebook Cells re-render upon changes to metadata (#156917)
* dataflow support for updated metadata * update cellAttachmentRenderer.ts to reflect metadata being a getter() inside MarkupCell * update condition to re-render cells, now includes metadata changes * notebook cells now re-render upon metadata changes * fix missing metadata update Co-authored-by: Peng Lyu <penn.lv@gmail.com>
This commit is contained in:
parent
57599a9ecd
commit
61e8687fa3
|
@ -22,7 +22,7 @@ export async function activate(ctx: RendererContext<void>) {
|
|||
md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => {
|
||||
const token = tokens[idx];
|
||||
const src = token.attrGet('src');
|
||||
const attachments: Record<string, Record<string, string>> = env.outputItem.metadata?.custom?.attachments; // this stores attachment entries for every image in the cell
|
||||
const attachments: Record<string, Record<string, string>> = env.outputItem.metadata().custom?.attachments;
|
||||
if (attachments && src) {
|
||||
const imageAttachment = attachments[src.replace('attachment:', '')];
|
||||
if (imageAttachment) {
|
||||
|
|
|
@ -44,7 +44,7 @@ export interface CellOutputMetadata {
|
|||
|
||||
/**
|
||||
* Metadata we store in VS Code cells.
|
||||
* This contains the original metadata from the Jupyuter cells.
|
||||
* This contains the original metadata from the Jupyter cells.
|
||||
*/
|
||||
export interface CellMetadata {
|
||||
/**
|
||||
|
|
|
@ -1025,31 +1025,33 @@ var requirejs = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
async showMarkupPreview(initialization: IMarkupCellInitialization) {
|
||||
async showMarkupPreview(newContent: IMarkupCellInitialization) {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entry = this.markupPreviewMapping.get(initialization.cellId);
|
||||
const entry = this.markupPreviewMapping.get(newContent.cellId);
|
||||
if (!entry) {
|
||||
return this.createMarkupPreview(initialization);
|
||||
return this.createMarkupPreview(newContent);
|
||||
}
|
||||
|
||||
const sameContent = initialization.content === entry.content;
|
||||
if (!sameContent || !entry.visible) {
|
||||
const sameContent = newContent.content === entry.content;
|
||||
const sameMetadata = newContent.metadata === entry.metadata;
|
||||
if (!sameContent || !sameMetadata || !entry.visible) {
|
||||
this._sendMessageToWebview({
|
||||
type: 'showMarkupCell',
|
||||
id: initialization.cellId,
|
||||
handle: initialization.cellHandle,
|
||||
id: newContent.cellId,
|
||||
handle: newContent.cellHandle,
|
||||
// If the content has not changed, we still want to make sure the
|
||||
// preview is visible but don't need to send anything over
|
||||
content: sameContent ? undefined : initialization.content,
|
||||
top: initialization.offset
|
||||
content: sameContent ? undefined : newContent.content,
|
||||
top: newContent.offset,
|
||||
metadata: sameMetadata ? undefined : newContent.metadata
|
||||
});
|
||||
}
|
||||
|
||||
entry.content = initialization.content;
|
||||
entry.offset = initialization.offset;
|
||||
entry.metadata = newContent.metadata;
|
||||
entry.content = newContent.content;
|
||||
entry.offset = newContent.offset;
|
||||
entry.visible = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,6 +316,7 @@ export interface IShowMarkupCellMessage {
|
|||
readonly handle: number;
|
||||
readonly content: string | undefined;
|
||||
readonly top: number;
|
||||
readonly metadata: NotebookCellMetadata | undefined;
|
||||
}
|
||||
|
||||
export interface IUpdateSelectedMarkupCellsMessage {
|
||||
|
|
|
@ -1035,7 +1035,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
break;
|
||||
|
||||
case 'showMarkupCell':
|
||||
viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content);
|
||||
viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content, event.data.metadata);
|
||||
break;
|
||||
|
||||
case 'hideMarkupCells':
|
||||
|
@ -1448,7 +1448,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
let cell = this._markupCells.get(info.cellId);
|
||||
if (cell) {
|
||||
cell.element.style.visibility = info.visible ? 'visible' : 'hidden';
|
||||
await cell.updateContentAndRender(info.content);
|
||||
await cell.updateContentAndRender(info.content, info.metadata);
|
||||
} else {
|
||||
cell = await this.createMarkupCell(info, info.offset, info.visible);
|
||||
}
|
||||
|
@ -1462,14 +1462,14 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
}
|
||||
}
|
||||
|
||||
public async updateMarkupContent(id: string, newContent: string): Promise<void> {
|
||||
public async updateMarkupContent(id: string, newContent: string, metadata: NotebookCellMetadata): Promise<void> {
|
||||
const cell = this.getExpectedMarkupCell(id);
|
||||
await cell?.updateContentAndRender(newContent);
|
||||
await cell?.updateContentAndRender(newContent, metadata);
|
||||
}
|
||||
|
||||
public showMarkupCell(id: string, top: number, newContent: string | undefined): void {
|
||||
public showMarkupCell(id: string, top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void {
|
||||
const cell = this.getExpectedMarkupCell(id);
|
||||
cell?.show(top, newContent);
|
||||
cell?.show(top, newContent, metadata);
|
||||
}
|
||||
|
||||
public hideMarkupCell(id: string): void {
|
||||
|
@ -1633,11 +1633,11 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
private readonly outputItem: rendererApi.OutputItem;
|
||||
|
||||
/// Internal field that holds text content
|
||||
private _content: { readonly value: string; readonly version: number };
|
||||
private _content: { readonly value: string; readonly version: number; readonly metadata: NotebookCellMetadata };
|
||||
|
||||
constructor(id: string, mime: string, content: string, top: number, metadata: NotebookCellMetadata) {
|
||||
this.id = id;
|
||||
this._content = { value: content, version: 0 };
|
||||
this._content = { value: content, version: 0, metadata: metadata };
|
||||
|
||||
let resolveReady: () => void;
|
||||
this.ready = new Promise<void>(r => resolveReady = r);
|
||||
|
@ -1646,7 +1646,10 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
this.outputItem = Object.freeze(<rendererApi.OutputItem>{
|
||||
id,
|
||||
mime,
|
||||
metadata,
|
||||
|
||||
metadata: (): NotebookCellMetadata => {
|
||||
return this._content.metadata;
|
||||
},
|
||||
|
||||
text: (): string => {
|
||||
return this._content.value;
|
||||
|
@ -1688,7 +1691,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
|
||||
this.addEventListeners();
|
||||
|
||||
this.updateContentAndRender(this._content.value).then(() => {
|
||||
this.updateContentAndRender(this._content.value, this._content.metadata).then(() => {
|
||||
resizeObserver.observe(this.element, this.id, false, this.id);
|
||||
resolveReady();
|
||||
});
|
||||
|
@ -1738,8 +1741,8 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
});
|
||||
}
|
||||
|
||||
public async updateContentAndRender(newContent: string): Promise<void> {
|
||||
this._content = { value: newContent, version: this._content.version + 1 };
|
||||
public async updateContentAndRender(newContent: string, metadata: NotebookCellMetadata): Promise<void> {
|
||||
this._content = { value: newContent, version: this._content.version + 1, metadata };
|
||||
|
||||
await renderers.render(this.outputItem, this.element);
|
||||
|
||||
|
@ -1772,11 +1775,11 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
});
|
||||
}
|
||||
|
||||
public show(top: number, newContent: string | undefined): void {
|
||||
public show(top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void {
|
||||
this.element.style.visibility = 'visible';
|
||||
this.element.style.top = `${top}px`;
|
||||
if (typeof newContent === 'string') {
|
||||
this.updateContentAndRender(newContent);
|
||||
if (typeof newContent === 'string' || metadata) {
|
||||
this.updateContentAndRender(newContent ?? this._content.value, metadata ?? this._content.metadata);
|
||||
} else {
|
||||
this.updateMarkupDimensions();
|
||||
}
|
||||
|
@ -1792,7 +1795,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
}
|
||||
|
||||
public rerender() {
|
||||
this.updateContentAndRender(this._content.value);
|
||||
this.updateContentAndRender(this._content.value, this._content.metadata);
|
||||
}
|
||||
|
||||
public remove() {
|
||||
|
|
|
@ -29,8 +29,10 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
|||
|
||||
public get renderedHtml(): string | undefined { return this._renderedHtml; }
|
||||
public set renderedHtml(value: string | undefined) {
|
||||
this._renderedHtml = value;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
if (this._renderedHtml !== value) {
|
||||
this._renderedHtml = value;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
}
|
||||
}
|
||||
|
||||
get layoutInfo() {
|
||||
|
|
Loading…
Reference in a new issue