* Custom rendering of image/png and image/jpeg to handle custom Jupyter metadata. * Behavior adopted from Jupyter lab. * For mimetype image/svg+xml, the data type will be string.
(mimeType: string, data: Blob | MediaSource, metadata: Record<string, unknown> = {})
| 67 | * For mimetype image/svg+xml, the data type will be string. |
| 68 | */ |
| 69 | private renderImage(mimeType: string, data: Blob | MediaSource, metadata: Record<string, unknown> = {}) { |
| 70 | if (this.props.ctx.postMessage) { |
| 71 | this.props.ctx.postMessage({ type: 'isDeepnoteExtensionInstalled' } as IsDeepnoteExtensionInstalled); |
| 72 | } |
| 73 | if (this.props.ctx.onDidReceiveMessage) { |
| 74 | const disposable = this.props.ctx.onDidReceiveMessage((response: Partial<IsDeepnoteExtensionInstalled>) => { |
| 75 | if (response?.type === 'isDeepnoteExtensionInstalled' && response.response) { |
| 76 | (globalThis as any).__isDeepnoteInstalled = response.response; |
| 77 | } |
| 78 | }); |
| 79 | this.disposables.push(disposable); |
| 80 | } |
| 81 | |
| 82 | const imgStyle: Record<string, string | number> = { maxWidth: '100%', height: 'auto' }; |
| 83 | const divStyle: Record<string, string | number> = { overflow: 'scroll', position: 'relative' }; // `overflow:scroll` is the default style used by Jupyter lab. |
| 84 | const imgSrc = |
| 85 | mimeType.toLowerCase().includes('svg') && typeof data === 'string' ? undefined : URL.createObjectURL(data); |
| 86 | const customMetadata = metadata.metadata as PartialJSONObject | undefined; |
| 87 | const showPlotViewer = metadata.__displayOpenPlotIcon === true; |
| 88 | const showCopyImage = mimeType === 'image/png'; |
| 89 | const copyButtonMargin = showPlotViewer ? '85px' : '45px'; |
| 90 | if (customMetadata && typeof customMetadata.needs_background === 'string') { |
| 91 | imgStyle.backgroundColor = customMetadata.needs_background === 'light' ? 'white' : 'black'; |
| 92 | } |
| 93 | const imgHeightWidth: { height?: number; width?: number } = {}; |
| 94 | const imageMetadata: Record<string, any> | undefined = customMetadata |
| 95 | ? (customMetadata[mimeType] as any) |
| 96 | : undefined; |
| 97 | if (imageMetadata?.height) { |
| 98 | imgHeightWidth.height = imageMetadata.height; |
| 99 | } |
| 100 | if (imageMetadata?.width) { |
| 101 | imgHeightWidth.width = imageMetadata.width; |
| 102 | } |
| 103 | if (imageMetadata?.unconfined === true) { |
| 104 | imgStyle.maxWidth = 'none'; |
| 105 | } |
| 106 | |
| 107 | // Hack, use same classes as used in VSCode for images (keep things as similar as possible). |
| 108 | // This is to maintain consistently in displaying images (if we hadn't used HTML). |
| 109 | // See src/vs/workbench/contrib/notebook/browser/view/output/transforms/richTransform.ts |
| 110 | const saveAs = () => { |
| 111 | if (this.props.ctx.postMessage) { |
| 112 | this.props.ctx.postMessage({ |
| 113 | type: 'saveImageAs', |
| 114 | outputId: this.props.outputId, |
| 115 | mimeType: this.props.mimeType |
| 116 | } as SaveImageAs); |
| 117 | } |
| 118 | }; |
| 119 | const openPlot = () => { |
| 120 | if (this.props.ctx.postMessage) { |
| 121 | this.props.ctx.postMessage({ |
| 122 | type: 'openImageInPlotViewer', |
| 123 | outputId: this.props.outputId, |
| 124 | mimeType: this.props.mimeType |
| 125 | } as OpenImageInPlotViewer); |
| 126 | } |
no test coverage detected