From 4ef84b2adc5402d8d26bf47afba2ec16bef5e8e8 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Mon, 20 Apr 2026 11:35:05 +0100 Subject: [PATCH] Enable "Capture screenshot" command for React Native targets Remove the `canDock` condition gate on the capture screenshot action so it is available for React Native targets. When the DeviceModeWrapper is not instantiated, capture the screenshot directly via the ScreenCaptureModel and trigger a download. --- .../panels/emulation/DeviceModeWrapper.ts | 24 ++++++++++++++++++- front_end/panels/emulation/emulation-meta.ts | 3 ++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/front_end/panels/emulation/DeviceModeWrapper.ts b/front_end/panels/emulation/DeviceModeWrapper.ts index a8377cd318c1..500972baecb4 100644 --- a/front_end/panels/emulation/DeviceModeWrapper.ts +++ b/front_end/panels/emulation/DeviceModeWrapper.ts @@ -110,7 +110,11 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate { handleAction(context: UI.Context.Context, actionId: string): boolean { switch (actionId) { case 'emulation.capture-screenshot': - return DeviceModeWrapper.instance().captureScreenshot(); + if (deviceModeWrapperInstance) { + return DeviceModeWrapper.instance().captureScreenshot(); + } + void captureScreenshotDirect(); + return true; case 'emulation.capture-node-screenshot': { const node = context.flavor(SDK.DOMModel.DOMNode); @@ -164,3 +168,21 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate { return false; } } + +async function captureScreenshotDirect(): Promise { + const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget(); + const screenCaptureModel = target?.model(SDK.ScreenCaptureModel.ScreenCaptureModel); + if (!screenCaptureModel) { + return; + } + const screenshot = await screenCaptureModel.captureScreenshot( + 'png' as Protocol.Page.CaptureScreenshotRequestFormat, 100, + SDK.ScreenCaptureModel.ScreenshotMode.FROM_VIEWPORT); + if (!screenshot) { + return; + } + const link = document.createElement('a'); + link.download = 'screenshot.png'; + link.href = 'data:image/png;base64,' + screenshot; + link.click(); +} diff --git a/front_end/panels/emulation/emulation-meta.ts b/front_end/panels/emulation/emulation-meta.ts index acca495b6f73..b1e87bc880e2 100644 --- a/front_end/panels/emulation/emulation-meta.ts +++ b/front_end/panels/emulation/emulation-meta.ts @@ -103,7 +103,8 @@ UI.ActionRegistration.registerActionExtension({ const Emulation = await loadEmulationModule(); return new Emulation.DeviceModeWrapper.ActionDelegate(); }, - condition: Root.Runtime.conditions.canDock, + // [RN] Available without docking for React Native targets. + // condition: Root.Runtime.conditions.canDock, title: i18nLazyString(UIStrings.captureScreenshot), });