refactor: mojofy MessageTo and MessageHost (#17613)

This commit is contained in:
Jeremy Apthorp 2019-04-03 14:22:23 -07:00 committed by GitHub
parent 5d45b59f7f
commit 127b87c713
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 95 deletions

View file

@ -275,6 +275,8 @@ WebContents::WebContents(v8::Isolate* isolate,
InitZoomController(web_contents, mate::Dictionary::CreateEmpty(isolate)); InitZoomController(web_contents, mate::Dictionary::CreateEmpty(isolate));
registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser, registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser,
base::Unretained(this))); base::Unretained(this)));
bindings_.set_connection_error_handler(base::BindRepeating(
&WebContents::OnElectronBrowserConnectionError, base::Unretained(this)));
} }
WebContents::WebContents(v8::Isolate* isolate, WebContents::WebContents(v8::Isolate* isolate,
@ -424,6 +426,8 @@ void WebContents::InitWithSessionAndOptions(
registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser, registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser,
base::Unretained(this))); base::Unretained(this)));
bindings_.set_connection_error_handler(base::BindRepeating(
&WebContents::OnElectronBrowserConnectionError, base::Unretained(this)));
web_contents()->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(), web_contents()->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(),
false); false);
@ -900,6 +904,12 @@ void WebContents::BindElectronBrowser(
frame_to_bindings_map_[render_frame_host].push_back(id); frame_to_bindings_map_[render_frame_host].push_back(id);
} }
void WebContents::OnElectronBrowserConnectionError() {
auto binding_id = bindings_.dispatch_binding();
auto* frame_host = bindings_.dispatch_context();
base::Erase(frame_to_bindings_map_[frame_host], binding_id);
}
void WebContents::Message(bool internal, void WebContents::Message(bool internal,
const std::string& channel, const std::string& channel,
base::Value arguments) { base::Value arguments) {
@ -919,6 +929,28 @@ void WebContents::MessageSync(bool internal,
std::move(callback), internal, channel, std::move(arguments)); std::move(callback), internal, channel, std::move(arguments));
} }
void WebContents::MessageTo(bool internal,
bool send_to_all,
int32_t web_contents_id,
const std::string& channel,
base::Value arguments) {
auto* web_contents = mate::TrackableObject<WebContents>::FromWeakMapID(
isolate(), web_contents_id);
if (web_contents) {
web_contents->SendIPCMessageWithSender(internal, send_to_all, channel,
base::ListValue(arguments.GetList()),
ID());
}
}
void WebContents::MessageHost(const std::string& channel,
base::Value arguments) {
// webContents.emit('ipc-message-host', new Event(), channel, args);
EmitWithSender("ipc-message-host", bindings_.dispatch_context(),
base::nullopt, channel, std::move(arguments));
}
void WebContents::RenderFrameDeleted( void WebContents::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) { content::RenderFrameHost* render_frame_host) {
// A RenderFrameHost can be destroyed before the related Mojo binding is // A RenderFrameHost can be destroyed before the related Mojo binding is
@ -1097,8 +1129,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
bool handled = true; bool handled = true;
FrameDispatchHelper helper = {this, frame_host}; FrameDispatchHelper helper = {this, frame_host};
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host) IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message_To, OnRendererMessageTo)
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message_Host, OnRendererMessageHost)
IPC_MESSAGE_FORWARD_DELAY_REPLY( IPC_MESSAGE_FORWARD_DELAY_REPLY(
AtomFrameHostMsg_SetTemporaryZoomLevel, &helper, AtomFrameHostMsg_SetTemporaryZoomLevel, &helper,
FrameDispatchHelper::OnSetTemporaryZoomLevel) FrameDispatchHelper::OnSetTemporaryZoomLevel)
@ -2258,28 +2288,6 @@ AtomBrowserContext* WebContents::GetBrowserContext() const {
return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext()); return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
} }
void WebContents::OnRendererMessageTo(content::RenderFrameHost* frame_host,
bool internal,
bool send_to_all,
int32_t web_contents_id,
const std::string& channel,
const base::ListValue& args) {
auto* web_contents = mate::TrackableObject<WebContents>::FromWeakMapID(
isolate(), web_contents_id);
if (web_contents) {
web_contents->SendIPCMessageWithSender(internal, send_to_all, channel, args,
ID());
}
}
void WebContents::OnRendererMessageHost(content::RenderFrameHost* frame_host,
const std::string& channel,
const base::ListValue& args) {
// webContents.emit('ipc-message-host', new Event(), channel, args);
EmitWithSender("ipc-message-host", frame_host, base::nullopt, channel, args);
}
// static // static
mate::Handle<WebContents> WebContents::Create(v8::Isolate* isolate, mate::Handle<WebContents> WebContents::Create(v8::Isolate* isolate,
const mate::Dictionary& options) { const mate::Dictionary& options) {

View file

@ -479,6 +479,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
// RenderFrameHost is destroyed, all related bindings will be removed. // RenderFrameHost is destroyed, all related bindings will be removed.
void BindElectronBrowser(mojom::ElectronBrowserRequest request, void BindElectronBrowser(mojom::ElectronBrowserRequest request,
content::RenderFrameHost* render_frame_host); content::RenderFrameHost* render_frame_host);
void OnElectronBrowserConnectionError();
uint32_t GetNextRequestId() { return ++request_id_; } uint32_t GetNextRequestId() { return ++request_id_; }
@ -495,23 +496,16 @@ class WebContents : public mate::TrackableObject<WebContents>,
const std::string& channel, const std::string& channel,
base::Value arguments, base::Value arguments,
MessageSyncCallback callback) override; MessageSyncCallback callback) override;
void MessageTo(bool internal,
bool send_to_all,
int32_t web_contents_id,
const std::string& channel,
base::Value arguments) override;
void MessageHost(const std::string& channel, base::Value arguments) override;
// Called when we receive a CursorChange message from chromium. // Called when we receive a CursorChange message from chromium.
void OnCursorChange(const content::WebCursor& cursor); void OnCursorChange(const content::WebCursor& cursor);
// Called when received a message from renderer to be forwarded.
void OnRendererMessageTo(content::RenderFrameHost* frame_host,
bool internal,
bool send_to_all,
int32_t web_contents_id,
const std::string& channel,
const base::ListValue& args);
// Called when received a message from renderer to host.
void OnRendererMessageHost(content::RenderFrameHost* frame_host,
const std::string& channel,
const base::ListValue& args);
// Called when received a synchronous message from renderer to // Called when received a synchronous message from renderer to
// set temporary zoom level. // set temporary zoom level.
void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host, void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host,

View file

@ -222,7 +222,6 @@ bool PdfViewerUI::OnMessageReceived(
content::RenderFrameHost* render_frame_host) { content::RenderFrameHost* render_frame_host) {
bool handled = true; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PdfViewerUI, message) IPC_BEGIN_MESSAGE_MAP(PdfViewerUI, message)
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_PDFSaveURLAs, OnSaveURLAs)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
return handled; return handled;

View file

@ -14,11 +14,16 @@ interface ElectronRenderer {
}; };
interface ElectronBrowser { interface ElectronBrowser {
// Emits an event on |channel| from the ipcMain JavaScript object in the main
// process.
Message( Message(
bool internal, bool internal,
string channel, string channel,
mojo_base.mojom.ListValue arguments); mojo_base.mojom.ListValue arguments);
// Emits an event on |channel| from the ipcMain JavaScript object in the main
// process, and waits synchronously for a response.
//
// NB. this is not marked [Sync] because mojo synchronous methods can be // NB. this is not marked [Sync] because mojo synchronous methods can be
// reordered with respect to asynchronous methods on the same channel. // reordered with respect to asynchronous methods on the same channel.
// Instead, callers can manually block on the response to this method. // Instead, callers can manually block on the response to this method.
@ -26,4 +31,17 @@ interface ElectronBrowser {
bool internal, bool internal,
string channel, string channel,
mojo_base.mojom.ListValue arguments) => (mojo_base.mojom.Value result); mojo_base.mojom.ListValue arguments) => (mojo_base.mojom.Value result);
// Emits an event from the |ipcRenderer| JavaScript object in the target
// WebContents's main frame, specified by |web_contents_id|.
MessageTo(
bool internal,
bool send_to_all,
int32 web_contents_id,
string channel,
mojo_base.mojom.ListValue arguments);
MessageHost(
string channel,
mojo_base.mojom.ListValue arguments);
}; };

View file

@ -25,17 +25,6 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion)
IPC_STRUCT_TRAITS_MEMBER(bounds) IPC_STRUCT_TRAITS_MEMBER(bounds)
IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_END()
IPC_MESSAGE_ROUTED5(AtomFrameHostMsg_Message_To,
bool /* internal */,
bool /* send_to_all */,
int32_t /* web_contents_id */,
std::string /* channel */,
base::ListValue /* arguments */)
IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_Message_Host,
std::string /* channel */,
base::ListValue /* arguments */)
IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen) IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen)
IPC_MESSAGE_ROUTED3(AtomAutofillFrameHostMsg_ShowPopup, IPC_MESSAGE_ROUTED3(AtomAutofillFrameHostMsg_ShowPopup,
@ -62,8 +51,3 @@ IPC_SYNC_MESSAGE_ROUTED1_1(AtomFrameHostMsg_SetTemporaryZoomLevel,
// Sent by renderer to get the zoom level. // Sent by renderer to get the zoom level.
IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */) IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */)
// Brings up SaveAs... dialog to save specified URL.
IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_PDFSaveURLAs,
GURL /* url */,
content::Referrer /* referrer */)

View file

@ -47,7 +47,9 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
prototype->SetClassName(mate::StringToV8(isolate, "IPCRenderer")); prototype->SetClassName(mate::StringToV8(isolate, "IPCRenderer"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("send", &IPCRenderer::Send) .SetMethod("send", &IPCRenderer::Send)
.SetMethod("sendSync", &IPCRenderer::SendSync); .SetMethod("sendSync", &IPCRenderer::SendSync)
.SetMethod("sendTo", &IPCRenderer::SendTo)
.SetMethod("sendToHost", &IPCRenderer::SendToHost);
} }
static mate::Handle<IPCRenderer> Create(v8::Isolate* isolate) { static mate::Handle<IPCRenderer> Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new IPCRenderer(isolate)); return mate::CreateHandle(isolate, new IPCRenderer(isolate));
@ -60,6 +62,22 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
electron_browser_ptr_->Message(internal, channel, arguments.Clone()); electron_browser_ptr_->Message(internal, channel, arguments.Clone());
} }
void SendTo(mate::Arguments* args,
bool internal,
bool send_to_all,
int32_t web_contents_id,
const std::string& channel,
const base::ListValue& arguments) {
electron_browser_ptr_->MessageTo(internal, send_to_all, web_contents_id,
channel, arguments.Clone());
}
void SendToHost(mate::Arguments* args,
const std::string& channel,
const base::ListValue& arguments) {
electron_browser_ptr_->MessageHost(channel, arguments.Clone());
}
base::Value SendSync(mate::Arguments* args, base::Value SendSync(mate::Arguments* args,
bool internal, bool internal,
const std::string& channel, const std::string& channel,
@ -119,46 +137,12 @@ class IPCRenderer : public mate::Wrappable<IPCRenderer> {
atom::mojom::ElectronBrowserPtr electron_browser_ptr_; atom::mojom::ElectronBrowserPtr electron_browser_ptr_;
}; };
void SendTo(mate::Arguments* args,
bool internal,
bool send_to_all,
int32_t web_contents_id,
const std::string& channel,
const base::ListValue& arguments) {
RenderFrame* render_frame = GetCurrentRenderFrame();
if (render_frame == nullptr)
return;
bool success = render_frame->Send(new AtomFrameHostMsg_Message_To(
render_frame->GetRoutingID(), internal, send_to_all, web_contents_id,
channel, arguments));
if (!success)
args->ThrowError("Unable to send AtomFrameHostMsg_Message_To");
}
void SendToHost(mate::Arguments* args,
const std::string& channel,
const base::ListValue& arguments) {
RenderFrame* render_frame = GetCurrentRenderFrame();
if (render_frame == nullptr)
return;
bool success = render_frame->Send(new AtomFrameHostMsg_Message_Host(
render_frame->GetRoutingID(), channel, arguments));
if (!success)
args->ThrowError("Unable to send AtomFrameHostMsg_Message_Host");
}
void Initialize(v8::Local<v8::Object> exports, void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, v8::Local<v8::Context> context,
void* priv) { void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports); mate::Dictionary dict(context->GetIsolate(), exports);
dict.Set("ipc", IPCRenderer::Create(context->GetIsolate())); dict.Set("ipc", IPCRenderer::Create(context->GetIsolate()));
dict.SetMethod("sendTo", &SendTo);
dict.SetMethod("sendToHost", &SendToHost);
} }
} // namespace } // namespace

View file

@ -1,6 +1,6 @@
'use strict' 'use strict'
const binding = process.electronBinding('ipc') const { ipc } = process.electronBinding('ipc')
const v8Util = process.electronBinding('v8_util') const v8Util = process.electronBinding('v8_util')
// Created by init.js. // Created by init.js.
@ -8,23 +8,23 @@ const ipcRenderer = v8Util.getHiddenValue(global, 'ipc')
const internal = false const internal = false
ipcRenderer.send = function (channel, ...args) { ipcRenderer.send = function (channel, ...args) {
return binding.ipc.send(internal, channel, args) return ipc.send(internal, channel, args)
} }
ipcRenderer.sendSync = function (channel, ...args) { ipcRenderer.sendSync = function (channel, ...args) {
return binding.ipc.sendSync(internal, channel, args)[0] return ipc.sendSync(internal, channel, args)[0]
} }
ipcRenderer.sendToHost = function (channel, ...args) { ipcRenderer.sendToHost = function (channel, ...args) {
return binding.sendToHost(channel, args) return ipc.sendToHost(channel, args)
} }
ipcRenderer.sendTo = function (webContentsId, channel, ...args) { ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
return binding.sendTo(internal, false, webContentsId, channel, args) return ipc.sendTo(internal, false, webContentsId, channel, args)
} }
ipcRenderer.sendToAll = function (webContentsId, channel, ...args) { ipcRenderer.sendToAll = function (webContentsId, channel, ...args) {
return binding.sendTo(internal, true, webContentsId, channel, args) return ipc.sendTo(internal, true, webContentsId, channel, args)
} }
module.exports = ipcRenderer module.exports = ipcRenderer