feat: add webFrameMain.send() / webFrameMain.postMessage() (#26807)

This commit is contained in:
Milan Burda 2021-01-15 01:00:37 +01:00 committed by GitHub
parent 28b6579538
commit 2be3d03630
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 340 additions and 209 deletions

View file

@ -13,9 +13,12 @@
#include "base/logging.h"
#include "content/browser/renderer_host/frame_tree_node.h" // nogncheck
#include "content/public/browser/render_frame_host.h"
#include "electron/shell/common/api/api.mojom.h"
#include "gin/object_template_builder.h"
#include "shell/browser/api/message_port.h"
#include "shell/browser/browser.h"
#include "shell/browser/javascript_environment.h"
#include "shell/common/gin_converters/blink_converter.h"
#include "shell/common/gin_converters/frame_converter.h"
#include "shell/common/gin_converters/gurl_converter.h"
#include "shell/common/gin_converters/value_converter.h"
@ -24,6 +27,8 @@
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/gin_helper/promise.h"
#include "shell/common/node_includes.h"
#include "shell/common/v8_value_serializer.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
namespace electron {
@ -157,6 +162,63 @@ bool WebFrameMain::Reload(v8::Isolate* isolate) {
return render_frame_->Reload();
}
void WebFrameMain::Send(v8::Isolate* isolate,
bool internal,
const std::string& channel,
v8::Local<v8::Value> args) {
blink::CloneableMessage message;
if (!gin::ConvertFromV8(isolate, args, &message)) {
isolate->ThrowException(v8::Exception::Error(
gin::StringToV8(isolate, "Failed to serialize arguments")));
return;
}
if (!CheckRenderFrame())
return;
mojo::AssociatedRemote<mojom::ElectronRenderer> electron_renderer;
render_frame_->GetRemoteAssociatedInterfaces()->GetInterface(
&electron_renderer);
electron_renderer->Message(internal, channel, std::move(message),
0 /* sender_id */);
}
void WebFrameMain::PostMessage(v8::Isolate* isolate,
const std::string& channel,
v8::Local<v8::Value> message_value,
base::Optional<v8::Local<v8::Value>> transfer) {
blink::TransferableMessage transferable_message;
if (!electron::SerializeV8Value(isolate, message_value,
&transferable_message)) {
// SerializeV8Value sets an exception.
return;
}
std::vector<gin::Handle<MessagePort>> wrapped_ports;
if (transfer) {
if (!gin::ConvertFromV8(isolate, *transfer, &wrapped_ports)) {
isolate->ThrowException(v8::Exception::Error(
gin::StringToV8(isolate, "Invalid value for transfer")));
return;
}
}
bool threw_exception = false;
transferable_message.ports =
MessagePort::DisentanglePorts(isolate, wrapped_ports, &threw_exception);
if (threw_exception)
return;
if (!CheckRenderFrame())
return;
mojo::AssociatedRemote<mojom::ElectronRenderer> electron_renderer;
render_frame_->GetRemoteAssociatedInterfaces()->GetInterface(
&electron_renderer);
electron_renderer->ReceivePostMessage(channel,
std::move(transferable_message));
}
int WebFrameMain::FrameTreeNodeID(v8::Isolate* isolate) const {
if (!CheckRenderFrame())
return -1;
@ -234,6 +296,11 @@ std::vector<content::RenderFrameHost*> WebFrameMain::FramesInSubtree(
return frame_hosts;
}
// static
gin::Handle<WebFrameMain> WebFrameMain::New(v8::Isolate* isolate) {
return gin::Handle<WebFrameMain>();
}
// static
gin::Handle<WebFrameMain> WebFrameMain::From(v8::Isolate* isolate,
content::RenderFrameHost* rfh) {
@ -261,13 +328,17 @@ void WebFrameMain::RenderFrameDeleted(content::RenderFrameHost* rfh) {
web_frame->MarkRenderFrameDisposed();
}
gin::ObjectTemplateBuilder WebFrameMain::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<WebFrameMain>::GetObjectTemplateBuilder(isolate)
// static
v8::Local<v8::ObjectTemplate> WebFrameMain::FillObjectTemplate(
v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> templ) {
return gin_helper::ObjectTemplateBuilder(isolate, templ)
.SetMethod("executeJavaScript", &WebFrameMain::ExecuteJavaScript)
.SetMethod("executeJavaScriptInIsolatedWorld",
&WebFrameMain::ExecuteJavaScriptInIsolatedWorld)
.SetMethod("reload", &WebFrameMain::Reload)
.SetMethod("_send", &WebFrameMain::Send)
.SetMethod("_postMessage", &WebFrameMain::PostMessage)
.SetProperty("frameTreeNodeId", &WebFrameMain::FrameTreeNodeID)
.SetProperty("name", &WebFrameMain::Name)
.SetProperty("osProcessId", &WebFrameMain::OSProcessID)
@ -277,7 +348,8 @@ gin::ObjectTemplateBuilder WebFrameMain::GetObjectTemplateBuilder(
.SetProperty("top", &WebFrameMain::Top)
.SetProperty("parent", &WebFrameMain::Parent)
.SetProperty("frames", &WebFrameMain::Frames)
.SetProperty("framesInSubtree", &WebFrameMain::FramesInSubtree);
.SetProperty("framesInSubtree", &WebFrameMain::FramesInSubtree)
.Build();
}
const char* WebFrameMain::GetTypeName() {
@ -311,6 +383,7 @@ void Initialize(v8::Local<v8::Object> exports,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
gin_helper::Dictionary dict(isolate, exports);
dict.Set("WebFrameMain", WebFrameMain::GetConstructor(context));
dict.SetMethod("fromId", &FromID);
}