feat: add 'dom-ready' event to WebFrameMain (#29290)

This commit is contained in:
Samuel Maddock 2021-09-01 18:21:15 -04:00 committed by GitHub
parent 49e62f1261
commit 4d89174b41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 261 additions and 11 deletions

View file

@ -5,10 +5,18 @@
#include "shell/common/gin_converters/frame_converter.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "shell/browser/api/electron_api_web_frame_main.h"
#include "shell/common/gin_helper/accessor.h"
namespace gin {
namespace {
v8::Persistent<v8::ObjectTemplate> rfh_templ;
} // namespace
// static
v8::Local<v8::Value> Converter<content::RenderFrameHost*>::ToV8(
v8::Isolate* isolate,
@ -18,4 +26,64 @@ v8::Local<v8::Value> Converter<content::RenderFrameHost*>::ToV8(
return electron::api::WebFrameMain::From(isolate, val).ToV8();
}
// static
v8::Local<v8::Value>
Converter<gin_helper::AccessorValue<content::RenderFrameHost*>>::ToV8(
v8::Isolate* isolate,
gin_helper::AccessorValue<content::RenderFrameHost*> val) {
content::RenderFrameHost* rfh = val.Value;
if (!rfh)
return v8::Null(isolate);
const int process_id = rfh->GetProcess()->GetID();
const int routing_id = rfh->GetRoutingID();
if (rfh_templ.IsEmpty()) {
v8::EscapableHandleScope inner(isolate);
v8::Local<v8::ObjectTemplate> local = v8::ObjectTemplate::New(isolate);
local->SetInternalFieldCount(2);
rfh_templ.Reset(isolate, inner.Escape(local));
}
v8::Local<v8::Object> rfh_obj =
v8::Local<v8::ObjectTemplate>::New(isolate, rfh_templ)
->NewInstance(isolate->GetCurrentContext())
.ToLocalChecked();
rfh_obj->SetInternalField(0, v8::Number::New(isolate, process_id));
rfh_obj->SetInternalField(1, v8::Number::New(isolate, routing_id));
return rfh_obj;
}
// static
bool Converter<gin_helper::AccessorValue<content::RenderFrameHost*>>::FromV8(
v8::Isolate* isolate,
v8::Local<v8::Value> val,
gin_helper::AccessorValue<content::RenderFrameHost*>* out) {
v8::Local<v8::Object> rfh_obj;
if (!ConvertFromV8(isolate, val, &rfh_obj))
return false;
if (rfh_obj->InternalFieldCount() != 2)
return false;
v8::Local<v8::Value> process_id_wrapper = rfh_obj->GetInternalField(0);
v8::Local<v8::Value> routing_id_wrapper = rfh_obj->GetInternalField(1);
if (process_id_wrapper.IsEmpty() || !process_id_wrapper->IsNumber() ||
routing_id_wrapper.IsEmpty() || !routing_id_wrapper->IsNumber())
return false;
const int process_id = process_id_wrapper.As<v8::Number>()->Value();
const int routing_id = routing_id_wrapper.As<v8::Number>()->Value();
auto* rfh = content::RenderFrameHost::FromID(process_id, routing_id);
if (!rfh)
return false;
out->Value = rfh;
return true;
}
} // namespace gin

View file

@ -6,6 +6,7 @@
#define SHELL_COMMON_GIN_CONVERTERS_FRAME_CONVERTER_H_
#include "gin/converter.h"
#include "shell/common/gin_helper/accessor.h"
namespace content {
class RenderFrameHost;
@ -19,6 +20,16 @@ struct Converter<content::RenderFrameHost*> {
content::RenderFrameHost* val);
};
template <>
struct Converter<gin_helper::AccessorValue<content::RenderFrameHost*>> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
gin_helper::AccessorValue<content::RenderFrameHost*> val);
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
gin_helper::AccessorValue<content::RenderFrameHost*>* out);
};
} // namespace gin
#endif // SHELL_COMMON_GIN_CONVERTERS_FRAME_CONVERTER_H_

View file

@ -0,0 +1,27 @@
// Copyright (c) 2021 Samuel Maddock <sam@samuelmaddock.com>.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_COMMON_GIN_HELPER_ACCESSOR_H_
#define SHELL_COMMON_GIN_HELPER_ACCESSOR_H_
namespace gin_helper {
// Wrapper for a generic value to be used as an accessor in a
// gin_helper::Dictionary.
template <typename T>
struct AccessorValue {
T Value;
};
template <typename T>
struct AccessorValue<const T&> {
T Value;
};
template <typename T>
struct AccessorValue<const T*> {
T* Value;
};
} // namespace gin_helper
#endif // SHELL_COMMON_GIN_HELPER_ACCESSOR_H_

View file

@ -10,6 +10,7 @@
#include "gin/dictionary.h"
#include "shell/common/gin_converters/std_converter.h"
#include "shell/common/gin_helper/accessor.h"
#include "shell/common/gin_helper/function_template.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@ -109,6 +110,36 @@ class Dictionary : public gin::Dictionary {
.ToChecked();
}
template <typename K, typename V>
bool SetGetter(const K& key, const V& val) {
AccessorValue<V> acc_value;
acc_value.Value = val;
v8::Local<v8::Value> v8_value_accessor;
if (!gin::TryConvertToV8(isolate(), acc_value, &v8_value_accessor))
return false;
auto context = isolate()->GetCurrentContext();
return GetHandle()
->SetAccessor(
context, gin::StringToV8(isolate(), key),
[](v8::Local<v8::Name> property_name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
AccessorValue<V> acc_value;
if (!gin::ConvertFromV8(info.GetIsolate(), info.Data(),
&acc_value))
return;
V val = acc_value.Value;
v8::Local<v8::Value> v8_value;
if (gin::TryConvertToV8(info.GetIsolate(), val, &v8_value))
info.GetReturnValue().Set(v8_value);
},
NULL, v8_value_accessor)
.ToChecked();
}
template <typename T>
bool SetReadOnly(base::StringPiece key, const T& val) {
v8::Local<v8::Value> v8_value;