fix: avoid IPC for renderer webFrame.getZoom... APIs (#45499)

* fix: avoid IPC for renderer `webFrame.getZoom...` APIs

* Remove `DoGetZoomLevel` IPC

* Fix synchronous behavior & nullptr deref

* Use local root
This commit is contained in:
Calvin 2025-02-10 14:09:11 -07:00 committed by GitHub
parent e055ce7c39
commit f5025b6246
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 22 additions and 34 deletions

View file

@ -3693,12 +3693,6 @@ void WebContents::SetTemporaryZoomLevel(double level) {
zoom_controller_->SetTemporaryZoomLevel(level); zoom_controller_->SetTemporaryZoomLevel(level);
} }
void WebContents::DoGetZoomLevel(
electron::mojom::ElectronWebContentsUtility::DoGetZoomLevelCallback
callback) {
std::move(callback).Run(GetZoomLevel());
}
std::optional<PreloadScript> WebContents::GetPreloadScript() const { std::optional<PreloadScript> WebContents::GetPreloadScript() const {
if (auto* web_preferences = WebContentsPreferences::From(web_contents())) { if (auto* web_preferences = WebContentsPreferences::From(web_contents())) {
if (auto preload = web_preferences->GetPreloadPath()) { if (auto preload = web_preferences->GetPreloadPath()) {

View file

@ -470,9 +470,6 @@ class WebContents final : public ExclusiveAccessContext,
// mojom::ElectronWebContentsUtility // mojom::ElectronWebContentsUtility
void OnFirstNonEmptyLayout(content::RenderFrameHost* render_frame_host); void OnFirstNonEmptyLayout(content::RenderFrameHost* render_frame_host);
void SetTemporaryZoomLevel(double level); void SetTemporaryZoomLevel(double level);
void DoGetZoomLevel(
electron::mojom::ElectronWebContentsUtility::DoGetZoomLevelCallback
callback);
void SetImageAnimationPolicy(const std::string& new_policy); void SetImageAnimationPolicy(const std::string& new_policy);

View file

@ -58,14 +58,6 @@ void ElectronWebContentsUtilityHandlerImpl::SetTemporaryZoomLevel(
} }
} }
void ElectronWebContentsUtilityHandlerImpl::DoGetZoomLevel(
DoGetZoomLevelCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->DoGetZoomLevel(std::move(callback));
}
}
void ElectronWebContentsUtilityHandlerImpl::CanAccessClipboardDeprecated( void ElectronWebContentsUtilityHandlerImpl::CanAccessClipboardDeprecated(
mojom::PermissionName name, mojom::PermissionName name,
const blink::LocalFrameToken& frame_token, const blink::LocalFrameToken& frame_token,

View file

@ -42,7 +42,6 @@ class ElectronWebContentsUtilityHandlerImpl
// mojom::ElectronWebContentsUtility: // mojom::ElectronWebContentsUtility:
void OnFirstNonEmptyLayout() override; void OnFirstNonEmptyLayout() override;
void SetTemporaryZoomLevel(double level) override; void SetTemporaryZoomLevel(double level) override;
void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;
void CanAccessClipboardDeprecated( void CanAccessClipboardDeprecated(
mojom::PermissionName name, mojom::PermissionName name,
const blink::LocalFrameToken& frame_token, const blink::LocalFrameToken& frame_token,

View file

@ -15,9 +15,6 @@ interface ElectronWebContentsUtility {
SetTemporaryZoomLevel(double zoom_level); SetTemporaryZoomLevel(double zoom_level);
[Sync]
DoGetZoomLevel() => (double result);
[Sync] [Sync]
CanAccessClipboardDeprecated( CanAccessClipboardDeprecated(
PermissionName name, PermissionName name,

View file

@ -441,25 +441,34 @@ class WebFrameRenderer final : public gin::Wrappable<WebFrameRenderer>,
if (!MaybeGetRenderFrame(isolate, "setZoomLevel", &render_frame)) if (!MaybeGetRenderFrame(isolate, "setZoomLevel", &render_frame))
return; return;
// Update the zoom controller.
mojo::AssociatedRemote<mojom::ElectronWebContentsUtility> mojo::AssociatedRemote<mojom::ElectronWebContentsUtility>
web_contents_utility_remote; web_contents_utility_remote;
render_frame->GetRemoteAssociatedInterfaces()->GetInterface( render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
&web_contents_utility_remote); &web_contents_utility_remote);
web_contents_utility_remote->SetTemporaryZoomLevel(level); web_contents_utility_remote->SetTemporaryZoomLevel(level);
// Update the local web frame for coherence with synchronous calls to
// |GetZoomLevel|.
if (blink::WebFrameWidget* web_frame =
render_frame->GetWebFrame()->LocalRoot()->FrameWidget()) {
web_frame->SetZoomLevel(level);
}
} }
double GetZoomLevel(v8::Isolate* isolate) { double GetZoomLevel(v8::Isolate* isolate) {
double result = 0.0;
content::RenderFrame* render_frame; content::RenderFrame* render_frame;
if (!MaybeGetRenderFrame(isolate, "getZoomLevel", &render_frame)) if (!MaybeGetRenderFrame(isolate, "getZoomLevel", &render_frame)) {
return result; return 0.0f;
}
mojo::AssociatedRemote<mojom::ElectronWebContentsUtility> blink::WebFrameWidget* web_frame =
web_contents_utility_remote; render_frame->GetWebFrame()->LocalRoot()->FrameWidget();
render_frame->GetRemoteAssociatedInterfaces()->GetInterface( if (!web_frame) {
&web_contents_utility_remote); return 0.0f;
web_contents_utility_remote->DoGetZoomLevel(&result); }
return result;
return web_frame->GetZoomLevel();
} }
void SetZoomFactor(gin_helper::ErrorThrower thrower, double factor) { void SetZoomFactor(gin_helper::ErrorThrower thrower, double factor) {

View file

@ -176,15 +176,15 @@ describe('webFrame module', () => {
describe('setZoomFactor()', () => { describe('setZoomFactor()', () => {
it('works', async () => { it('works', async () => {
const equal = await w.executeJavaScript('childFrame.setZoomFactor(2.0); childFrame.getZoomFactor() === 2.0'); const zoom = await w.executeJavaScript('childFrame.setZoomFactor(2.0); childFrame.getZoomFactor()');
expect(equal).to.be.true(); expect(zoom).to.equal(2.0);
}); });
}); });
describe('setZoomLevel()', () => { describe('setZoomLevel()', () => {
it('works', async () => { it('works', async () => {
const equal = await w.executeJavaScript('childFrame.setZoomLevel(5); childFrame.getZoomLevel() === 5'); const zoom = await w.executeJavaScript('childFrame.setZoomLevel(5); childFrame.getZoomLevel()');
expect(equal).to.be.true(); expect(zoom).to.equal(5);
}); });
}); });