look for re-used output id containing the image

This commit is contained in:
Aaron Munger
2023-08-30 14:34:42 -07:00
parent fe0237c038
commit e5851bc5f5
6 changed files with 17 additions and 11 deletions
@@ -55,7 +55,7 @@ registerAction2(class CopyCellOutputAction extends Action2 {
const mimeType = outputViewModel.pickedMimeType?.mimeType;
if (mimeType?.startsWith('image/')) {
const focusOptions = { skipReveal: true, outputId: outputViewModel.model.outputId };
const focusOptions = { skipReveal: true, outputId: outputViewModel.model.outputId, altOutputId: outputViewModel.model.alternativeOutputId };
await notebookEditor.focusNotebookCell(outputViewModel.cellViewModel as ICellViewModel, 'output', focusOptions);
notebookEditor.copyOutputImage(outputViewModel);
} else {
@@ -152,6 +152,7 @@ export interface IFocusNotebookCellOptions {
readonly focusEditorLine?: number;
readonly minimalScrolling?: boolean;
readonly outputId?: string;
readonly altOutputId?: string;
}
//#endregion
@@ -2350,7 +2350,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
}
const focusElementId = options?.outputId ?? cell.id;
this._webview.focusOutput(focusElementId, this._webviewFocused);
this._webview.focusOutput(focusElementId, options?.altOutputId, this._webviewFocused);
cell.updateEditState(CellEditState.Preview, 'focusNotebookCell');
cell.focusMode = CellFocusMode.Output;
@@ -1548,7 +1548,8 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
async copyImage(output: ICellOutputViewModel): Promise<void> {
this._sendMessageToWebview({
type: 'copyImage',
outputId: output.model.outputId
outputId: output.model.outputId,
altOutputId: output.model.alternativeOutputId
});
}
@@ -1608,7 +1609,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
this.webview?.focus();
}
focusOutput(cellOrOutputId: string, viewFocused: boolean) {
focusOutput(cellOrOutputId: string, backupId: string | undefined, viewFocused: boolean) {
if (this._disposed) {
return;
}
@@ -1620,6 +1621,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
this._sendMessageToWebview({
type: 'focus-output',
cellOrOutputId: cellOrOutputId,
backupId: backupId
});
}
@@ -269,11 +269,13 @@ export interface IShowOutputMessage {
export interface ICopyImageMessage {
readonly type: 'copyImage';
readonly outputId: string;
readonly altOutputId: string;
}
export interface IFocusOutputMessage {
readonly type: 'focus-output';
readonly cellOrOutputId: string;
readonly backupId?: string;
}
export interface IAckOutputHeight {
@@ -474,8 +474,9 @@ async function webviewPreloads(ctx: PreloadContext) {
});
};
function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string) {
const cellOutputContainer = document.getElementById(cellOrOutputId);
function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string, backupId?: string) {
const cellOutputContainer = document.getElementById(cellOrOutputId) ??
backupId ? document.getElementById(backupId!) : undefined;
if (cellOutputContainer) {
if (cellOutputContainer.contains(document.activeElement)) {
return;
@@ -1362,17 +1363,17 @@ async function webviewPreloads(ctx: PreloadContext) {
});
};
const copyOutputImage = async (outputId: string, retries = 5) => {
const copyOutputImage = async (outputId: string, altOutputId: string, retries = 5) => {
if (!document.hasFocus() && retries > 0) {
// copyImage can be called from outside of the webview, which means this function may be running whilst the webview is gaining focus.
// Since navigator.clipboard.write requires the document to be focused, we need to wait for focus.
// We cannot use a listener, as there is a high chance the focus is gained during the setup of the listener resulting in us missing it.
setTimeout(() => { copyOutputImage(outputId, retries - 1); }, 20);
setTimeout(() => { copyOutputImage(outputId, altOutputId, retries - 1); }, 20);
return;
}
try {
const image = document.getElementById(outputId)?.querySelector('img');
const image = document.getElementById(outputId)?.querySelector('img') || document.getElementById(altOutputId)?.querySelector('img');
if (image) {
await navigator.clipboard.write([new ClipboardItem({
'image/png': new Promise((resolve) => {
@@ -1501,7 +1502,7 @@ async function webviewPreloads(ctx: PreloadContext) {
}
case 'copyImage': {
await copyOutputImage(event.data.outputId);
await copyOutputImage(event.data.outputId, event.data.altOutputId);
break;
}
@@ -1524,7 +1525,7 @@ async function webviewPreloads(ctx: PreloadContext) {
break;
}
case 'focus-output':
focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId);
focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId, event.data.backupId);
break;
case 'decorations': {
let outputContainer = document.getElementById(event.data.cellId);