chore: make rpc-server reply to sender frame instead of the main frame (#15973)
* chore: make rpc-server reply to frame * fix: check IsRenderFrameLive
This commit is contained in:
parent
eb8fcf833c
commit
db2fda1b6f
5 changed files with 51 additions and 10 deletions
|
@ -1674,6 +1674,23 @@ bool WebContents::SendIPCMessageWithSender(bool internal,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebContents::SendIPCMessageToFrame(bool internal,
|
||||||
|
bool send_to_all,
|
||||||
|
int32_t frame_id,
|
||||||
|
const std::string& channel,
|
||||||
|
const base::ListValue& args) {
|
||||||
|
auto frames = web_contents()->GetAllFrames();
|
||||||
|
auto iter = std::find_if(frames.begin(), frames.end(), [frame_id](auto* f) {
|
||||||
|
return f->GetRoutingID() == frame_id;
|
||||||
|
});
|
||||||
|
if (iter == frames.end())
|
||||||
|
return false;
|
||||||
|
if (!(*iter)->IsRenderFrameLive())
|
||||||
|
return false;
|
||||||
|
return (*iter)->Send(new AtomFrameMsg_Message(
|
||||||
|
frame_id, internal, send_to_all, channel, args, 0 /* sender_id */));
|
||||||
|
}
|
||||||
|
|
||||||
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Value> input_event) {
|
v8::Local<v8::Value> input_event) {
|
||||||
content::RenderWidgetHostView* view =
|
content::RenderWidgetHostView* view =
|
||||||
|
@ -2119,6 +2136,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("isFocused", &WebContents::IsFocused)
|
.SetMethod("isFocused", &WebContents::IsFocused)
|
||||||
.SetMethod("tabTraverse", &WebContents::TabTraverse)
|
.SetMethod("tabTraverse", &WebContents::TabTraverse)
|
||||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||||
|
.SetMethod("_sendToFrame", &WebContents::SendIPCMessageToFrame)
|
||||||
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
|
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
|
||||||
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
|
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
|
||||||
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
||||||
|
@ -2183,7 +2201,7 @@ void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
// webContents.emit(channel, new Event(), args...);
|
// webContents.emit(channel, new Event(), args...);
|
||||||
Emit(channel, args);
|
EmitWithSender(channel, frame_host, nullptr, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
||||||
|
|
|
@ -218,6 +218,12 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
int32_t sender_id = 0);
|
int32_t sender_id = 0);
|
||||||
|
|
||||||
|
bool SendIPCMessageToFrame(bool internal,
|
||||||
|
bool send_to_all,
|
||||||
|
int32_t frame_id,
|
||||||
|
const std::string& channel,
|
||||||
|
const base::ListValue& args);
|
||||||
|
|
||||||
// Send WebInputEvent to the page.
|
// Send WebInputEvent to the page.
|
||||||
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
|
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/event_emitter.h"
|
||||||
|
|
||||||
#include "atom/browser/api/event.h"
|
#include "atom/browser/api/event.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
#include "native_mate/arguments.h"
|
#include "native_mate/arguments.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
|
@ -56,6 +57,8 @@ v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||||
event = CreateEventObject(isolate);
|
event = CreateEventObject(isolate);
|
||||||
}
|
}
|
||||||
mate::Dictionary(isolate, event).Set("sender", object);
|
mate::Dictionary(isolate, event).Set("sender", object);
|
||||||
|
if (sender)
|
||||||
|
mate::Dictionary(isolate, event).Set("frameId", sender->GetRoutingID());
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,18 @@ WebContents.prototype._sendInternalToAll = function (channel, ...args) {
|
||||||
|
|
||||||
return this._send(internal, sendToAll, channel, args)
|
return this._send(internal, sendToAll, channel, args)
|
||||||
}
|
}
|
||||||
|
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
|
||||||
|
if (typeof channel !== 'string') {
|
||||||
|
throw new Error('Missing required channel argument')
|
||||||
|
} else if (typeof frameId !== 'number') {
|
||||||
|
throw new Error('Missing required frameId argument')
|
||||||
|
}
|
||||||
|
|
||||||
|
const internal = true
|
||||||
|
const sendToAll = false
|
||||||
|
|
||||||
|
return this._sendToFrame(internal, sendToAll, frameId, channel, args)
|
||||||
|
}
|
||||||
|
|
||||||
// Following methods are mapped to webFrame.
|
// Following methods are mapped to webFrame.
|
||||||
const webFrameMethods = [
|
const webFrameMethods = [
|
||||||
|
|
|
@ -174,7 +174,7 @@ const removeRemoteListenersAndLogWarning = (sender, callIntoRenderer) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert array of meta data from renderer into array of real values.
|
// Convert array of meta data from renderer into array of real values.
|
||||||
const unwrapArgs = function (sender, contextId, args) {
|
const unwrapArgs = function (sender, frameId, contextId, args) {
|
||||||
const metaToValue = function (meta) {
|
const metaToValue = function (meta) {
|
||||||
switch (meta.type) {
|
switch (meta.type) {
|
||||||
case 'value':
|
case 'value':
|
||||||
|
@ -182,7 +182,7 @@ const unwrapArgs = function (sender, contextId, args) {
|
||||||
case 'remote-object':
|
case 'remote-object':
|
||||||
return objectsRegistry.get(meta.id)
|
return objectsRegistry.get(meta.id)
|
||||||
case 'array':
|
case 'array':
|
||||||
return unwrapArgs(sender, contextId, meta.value)
|
return unwrapArgs(sender, frameId, contextId, meta.value)
|
||||||
case 'buffer':
|
case 'buffer':
|
||||||
return bufferUtils.metaToBuffer(meta.value)
|
return bufferUtils.metaToBuffer(meta.value)
|
||||||
case 'date':
|
case 'date':
|
||||||
|
@ -216,9 +216,11 @@ const unwrapArgs = function (sender, contextId, args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const callIntoRenderer = function (...args) {
|
const callIntoRenderer = function (...args) {
|
||||||
|
let succeed = false
|
||||||
if (!sender.isDestroyed()) {
|
if (!sender.isDestroyed()) {
|
||||||
sender._sendInternal('ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args))
|
succeed = sender._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args))
|
||||||
} else {
|
}
|
||||||
|
if (!succeed) {
|
||||||
removeRemoteListenersAndLogWarning(this, callIntoRenderer)
|
removeRemoteListenersAndLogWarning(this, callIntoRenderer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,7 +336,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, co
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
|
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
|
||||||
args = unwrapArgs(event.sender, contextId, args)
|
args = unwrapArgs(event.sender, event.frameId, contextId, args)
|
||||||
const constructor = objectsRegistry.get(id)
|
const constructor = objectsRegistry.get(id)
|
||||||
|
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
|
@ -345,7 +347,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId,
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
|
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
|
||||||
args = unwrapArgs(event.sender, contextId, args)
|
args = unwrapArgs(event.sender, event.frameId, contextId, args)
|
||||||
const func = objectsRegistry.get(id)
|
const func = objectsRegistry.get(id)
|
||||||
|
|
||||||
if (func == null) {
|
if (func == null) {
|
||||||
|
@ -356,7 +358,7 @@ handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
|
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
|
||||||
args = unwrapArgs(event.sender, contextId, args)
|
args = unwrapArgs(event.sender, event.frameId, contextId, args)
|
||||||
const object = objectsRegistry.get(id)
|
const object = objectsRegistry.get(id)
|
||||||
|
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
|
@ -367,7 +369,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, cont
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
|
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
|
||||||
args = unwrapArgs(event.sender, contextId, args)
|
args = unwrapArgs(event.sender, event.frameId, contextId, args)
|
||||||
const obj = objectsRegistry.get(id)
|
const obj = objectsRegistry.get(id)
|
||||||
|
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
|
@ -378,7 +380,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId,
|
||||||
})
|
})
|
||||||
|
|
||||||
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
|
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
|
||||||
args = unwrapArgs(event.sender, contextId, args)
|
args = unwrapArgs(event.sender, event.frameId, contextId, args)
|
||||||
const obj = objectsRegistry.get(id)
|
const obj = objectsRegistry.get(id)
|
||||||
|
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
|
|
Loading…
Reference in a new issue