refactor: ginify WebContents (#24651)

This commit is contained in:
Jeremy Rose 2020-07-30 09:17:57 -07:00 committed by GitHub
parent e7fc19c98e
commit b5cd9ce0b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 156 additions and 67 deletions

View file

@ -1,4 +1,4 @@
# KeyboardEvent Object extends `Event` # KeyboardEvent Object
* `ctrlKey` Boolean (optional) - whether the Control key was used in an accelerator to trigger the Event * `ctrlKey` Boolean (optional) - whether the Control key was used in an accelerator to trigger the Event
* `metaKey` Boolean (optional) - whether a meta key was used in an accelerator to trigger the Event * `metaKey` Boolean (optional) - whether a meta key was used in an accelerator to trigger the Event

View file

@ -9,7 +9,6 @@ import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils'; import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
import { parseFeatures } from '@electron/internal/common/parse-features-string'; import { parseFeatures } from '@electron/internal/common/parse-features-string';
import { MessagePortMain } from '@electron/internal/browser/message-port-main'; import { MessagePortMain } from '@electron/internal/browser/message-port-main';
import { EventEmitter } from 'events';
// session is not used here, the purpose is to make sure session is initalized // session is not used here, the purpose is to make sure session is initalized
// before the webContents module. // before the webContents module.
@ -124,8 +123,6 @@ const defaultPrintingSetting = {
const binding = process._linkedBinding('electron_browser_web_contents'); const binding = process._linkedBinding('electron_browser_web_contents');
const { WebContents } = binding as { WebContents: { prototype: Electron.WebContentsInternal } }; const { WebContents } = binding as { WebContents: { prototype: Electron.WebContentsInternal } };
Object.setPrototypeOf(WebContents.prototype, EventEmitter.prototype);
WebContents.prototype.send = function (channel, ...args) { WebContents.prototype.send = function (channel, ...args) {
if (typeof channel !== 'string') { if (typeof channel !== 'string') {
throw new Error('Missing required channel argument'); throw new Error('Missing required channel argument');

View file

@ -78,7 +78,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
Observe(api_web_contents_->web_contents()); Observe(api_web_contents_->web_contents());
// Keep a copy of the options for later use. // Keep a copy of the options for later use.
gin_helper::Dictionary(isolate, web_contents->GetWrapper()) gin_helper::Dictionary(isolate, web_contents.ToV8().As<v8::Object>())
.Set("browserWindowOptions", options); .Set("browserWindowOptions", options);
// Associate with BrowserWindow. // Associate with BrowserWindow.

View file

@ -12,6 +12,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "base/containers/id_map.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
@ -332,6 +333,11 @@ namespace api {
namespace { namespace {
base::IDMap<WebContents*>& GetAllWebContents() {
static base::NoDestructor<base::IDMap<WebContents*>> s_all_web_contents;
return *s_all_web_contents;
}
// Called when CapturePage is done. // Called when CapturePage is done.
void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise, void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise,
const SkBitmap& bitmap) { const SkBitmap& bitmap) {
@ -389,12 +395,21 @@ base::string16 GetDefaultPrinterAsync() {
} }
#endif #endif
struct UserDataLink : public base::SupportsUserData::Data {
explicit UserDataLink(base::WeakPtr<WebContents> contents)
: web_contents(contents) {}
base::WeakPtr<WebContents> web_contents;
};
const void* kElectronApiWebContentsKey = &kElectronApiWebContentsKey;
} // namespace } // namespace
WebContents::WebContents(v8::Isolate* isolate, WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents) content::WebContents* web_contents)
: content::WebContentsObserver(web_contents), : content::WebContentsObserver(web_contents),
type_(Type::REMOTE), type_(Type::REMOTE),
id_(GetAllWebContents().Add(this)),
weak_factory_(this) { weak_factory_(this) {
auto session = Session::CreateFrom(isolate, GetBrowserContext()); auto session = Session::CreateFrom(isolate, GetBrowserContext());
session_.Reset(isolate, session.ToV8()); session_.Reset(isolate, session.ToV8());
@ -402,8 +417,8 @@ WebContents::WebContents(v8::Isolate* isolate,
web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly( web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(
GetBrowserContext()->GetUserAgent()), GetBrowserContext()->GetUserAgent()),
false); false);
Init(isolate); web_contents->SetUserData(kElectronApiWebContentsKey,
AttachAsUserData(web_contents); std::make_unique<UserDataLink>(GetWeakPtr()));
InitZoomController(web_contents, gin::Dictionary::CreateEmpty(isolate)); InitZoomController(web_contents, gin::Dictionary::CreateEmpty(isolate));
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
extensions::ElectronExtensionWebContentsObserver::CreateForWebContents( extensions::ElectronExtensionWebContentsObserver::CreateForWebContents(
@ -421,6 +436,7 @@ WebContents::WebContents(v8::Isolate* isolate,
Type type) Type type)
: content::WebContentsObserver(web_contents.get()), : content::WebContentsObserver(web_contents.get()),
type_(type), type_(type),
id_(GetAllWebContents().Add(this)),
weak_factory_(this) { weak_factory_(this) {
DCHECK(type != Type::REMOTE) DCHECK(type != Type::REMOTE)
<< "Can't take ownership of a remote WebContents"; << "Can't take ownership of a remote WebContents";
@ -432,7 +448,7 @@ WebContents::WebContents(v8::Isolate* isolate,
WebContents::WebContents(v8::Isolate* isolate, WebContents::WebContents(v8::Isolate* isolate,
const gin_helper::Dictionary& options) const gin_helper::Dictionary& options)
: weak_factory_(this) { : id_(GetAllWebContents().Add(this)), weak_factory_(this) {
// Read options. // Read options.
options.Get("backgroundThrottling", &background_throttling_); options.Get("backgroundThrottling", &background_throttling_);
@ -610,11 +626,12 @@ void WebContents::InitWithSessionAndOptions(
SetOwnerWindow(owner_window); SetOwnerWindow(owner_window);
} }
Init(isolate); web_contents()->SetUserData(kElectronApiWebContentsKey,
AttachAsUserData(web_contents()); std::make_unique<UserDataLink>(GetWeakPtr()));
} }
WebContents::~WebContents() { WebContents::~WebContents() {
MarkDestroyed();
// The destroy() is called. // The destroy() is called.
if (managed_web_contents()) { if (managed_web_contents()) {
managed_web_contents()->GetView()->SetDelegate(nullptr); managed_web_contents()->GetView()->SetDelegate(nullptr);
@ -740,19 +757,19 @@ void WebContents::AddNewContents(
content::WebContents* WebContents::OpenURLFromTab( content::WebContents* WebContents::OpenURLFromTab(
content::WebContents* source, content::WebContents* source,
const content::OpenURLParams& params) { const content::OpenURLParams& params) {
auto weak_this = GetWeakPtr();
if (params.disposition != WindowOpenDisposition::CURRENT_TAB) { if (params.disposition != WindowOpenDisposition::CURRENT_TAB) {
Emit("-new-window", params.url, "", params.disposition, "", params.referrer, Emit("-new-window", params.url, "", params.disposition, "", params.referrer,
params.post_data); params.post_data);
return nullptr; return nullptr;
} }
if (!weak_this)
return nullptr;
// Give user a chance to cancel navigation. // Give user a chance to cancel navigation.
if (Emit("will-navigate", params.url)) if (Emit("will-navigate", params.url))
return nullptr; return nullptr;
if (!weak_this)
// Don't load the URL if the web contents was marked as destroyed from a
// will-navigate event listener
if (IsDestroyed())
return nullptr; return nullptr;
return CommonWebContentsDelegate::OpenURLFromTab(source, params); return CommonWebContentsDelegate::OpenURLFromTab(source, params);
@ -1217,9 +1234,7 @@ void WebContents::MessageTo(bool internal,
const std::string& channel, const std::string& channel,
blink::CloneableMessage arguments) { blink::CloneableMessage arguments) {
TRACE_EVENT1("electron", "WebContents::MessageTo", "channel", channel); TRACE_EVENT1("electron", "WebContents::MessageTo", "channel", channel);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); auto* web_contents = FromID(web_contents_id);
auto* web_contents = gin_helper::TrackableObject<WebContents>::FromWeakMapID(
isolate, web_contents_id);
if (web_contents) { if (web_contents) {
web_contents->SendIPCMessageWithSender(internal, send_to_all, channel, web_contents->SendIPCMessageWithSender(internal, send_to_all, channel,
@ -1398,6 +1413,17 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
return handled; return handled;
} }
void WebContents::MarkDestroyed() {
if (GetAllWebContents().Lookup(id_))
GetAllWebContents().Remove(id_);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
v8::Local<v8::Object> wrapper;
if (!GetWrapper(isolate).ToLocal(&wrapper))
return;
wrapper->SetAlignedPointerInInternalField(0, nullptr);
}
// There are three ways of destroying a webContents: // There are three ways of destroying a webContents:
// 1. call webContents.destroy(); // 1. call webContents.destroy();
// 2. garbage collection; // 2. garbage collection;
@ -1419,7 +1445,6 @@ void WebContents::WebContentsDestroyed() {
guest_delegate_->WillDestroy(); guest_delegate_->WillDestroy();
// Cleanup relationships with other parts. // Cleanup relationships with other parts.
RemoveFromWeakMap();
// We can not call Destroy here because we need to call Emit first, but we // We can not call Destroy here because we need to call Emit first, but we
// also do not want any method to be used, so just mark as destroyed here. // also do not want any method to be used, so just mark as destroyed here.
@ -1435,7 +1460,13 @@ void WebContents::WebContentsDestroyed() {
} }
// Destroy the native class in next tick. // Destroy the native class in next tick.
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, GetDestroyClosure()); base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(
[](base::WeakPtr<WebContents> wc) {
if (wc)
delete wc.get();
},
GetWeakPtr()));
} }
void WebContents::NavigationEntryCommitted( void WebContents::NavigationEntryCommitted(
@ -2632,10 +2663,6 @@ v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow(
return v8::Null(isolate); return v8::Null(isolate);
} }
int32_t WebContents::ID() const {
return weak_map_id();
}
v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) { v8::Local<v8::Value> WebContents::Session(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, session_); return v8::Local<v8::Value>::New(isolate, session_);
} }
@ -2754,11 +2781,28 @@ v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
} }
// static // static
void WebContents::BuildPrototype(v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> WebContents::FillObjectTemplate(
v8::Local<v8::FunctionTemplate> prototype) { v8::Isolate* isolate,
prototype->SetClassName(gin::StringToV8(isolate, "WebContents")); v8::Local<v8::ObjectTemplate> templ) {
gin_helper::Destroyable::MakeDestroyable(isolate, prototype); gin::InvokerOptions options;
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) options.holder_is_first_argument = true;
options.holder_type = "WebContents";
templ->Set(
gin::StringToSymbol(isolate, "isDestroyed"),
gin::CreateFunctionTemplate(
isolate, base::BindRepeating(&gin_helper::Destroyable::IsDestroyed),
options));
templ->Set(
gin::StringToSymbol(isolate, "destroy"),
gin::CreateFunctionTemplate(
isolate, base::BindRepeating([](gin::Handle<WebContents> handle) {
delete handle.get();
}),
options));
// We use gin_helper::ObjectTemplateBuilder instead of
// gin::ObjectTemplateBuilder here to handle the fact that WebContents is
// destroyable.
return gin_helper::ObjectTemplateBuilder(isolate, templ)
.SetMethod("getBackgroundThrottling", .SetMethod("getBackgroundThrottling",
&WebContents::GetBackgroundThrottling) &WebContents::GetBackgroundThrottling)
.SetMethod("setBackgroundThrottling", .SetMethod("setBackgroundThrottling",
@ -2870,7 +2914,12 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetProperty("session", &WebContents::Session) .SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("hostWebContents", &WebContents::HostWebContents)
.SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents)
.SetProperty("debugger", &WebContents::Debugger); .SetProperty("debugger", &WebContents::Debugger)
.Build();
}
const char* WebContents::GetTypeName() {
return "WebContents";
} }
ElectronBrowserContext* WebContents::GetBrowserContext() const { ElectronBrowserContext* WebContents::GetBrowserContext() const {
@ -2882,7 +2931,17 @@ ElectronBrowserContext* WebContents::GetBrowserContext() const {
gin::Handle<WebContents> WebContents::Create( gin::Handle<WebContents> WebContents::Create(
v8::Isolate* isolate, v8::Isolate* isolate,
const gin_helper::Dictionary& options) { const gin_helper::Dictionary& options) {
return gin::CreateHandle(isolate, new WebContents(isolate, options)); gin::Handle<WebContents> handle =
gin::CreateHandle(isolate, new WebContents(isolate, options));
gin_helper::CallMethod(isolate, handle.get(), "_init");
return handle;
}
// static
gin::Handle<WebContents> WebContents::New(
v8::Isolate* isolate,
const gin_helper::Dictionary& options) {
return Create(isolate, options);
} }
// static // static
@ -2890,15 +2949,19 @@ gin::Handle<WebContents> WebContents::CreateAndTake(
v8::Isolate* isolate, v8::Isolate* isolate,
std::unique_ptr<content::WebContents> web_contents, std::unique_ptr<content::WebContents> web_contents,
Type type) { Type type) {
return gin::CreateHandle( gin::Handle<WebContents> handle = gin::CreateHandle(
isolate, new WebContents(isolate, std::move(web_contents), type)); isolate, new WebContents(isolate, std::move(web_contents), type));
gin_helper::CallMethod(isolate, handle.get(), "_init");
return handle;
} }
// static // static
WebContents* WebContents::From(content::WebContents* web_contents) { WebContents* WebContents::From(content::WebContents* web_contents) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); if (!web_contents)
auto* existing = TrackableObject::FromWrappedClass(isolate, web_contents); return nullptr;
return static_cast<WebContents*>(existing); UserDataLink* data = static_cast<UserDataLink*>(
web_contents->GetUserData(kElectronApiWebContentsKey));
return data ? data->web_contents.get() : nullptr;
} }
// static // static
@ -2906,36 +2969,50 @@ gin::Handle<WebContents> WebContents::FromOrCreate(
v8::Isolate* isolate, v8::Isolate* isolate,
content::WebContents* web_contents) { content::WebContents* web_contents) {
WebContents* api_web_contents = From(web_contents); WebContents* api_web_contents = From(web_contents);
if (!api_web_contents) if (!api_web_contents) {
api_web_contents = new WebContents(isolate, web_contents); api_web_contents = new WebContents(isolate, web_contents);
gin_helper::CallMethod(isolate, api_web_contents, "_init");
}
return gin::CreateHandle(isolate, api_web_contents); return gin::CreateHandle(isolate, api_web_contents);
} }
// static // static
WebContents* WebContents::FromID(int32_t id) { WebContents* WebContents::FromID(int32_t id) {
return FromWeakMapID(JavascriptEnvironment::GetIsolate(), id); return GetAllWebContents().Lookup(id);
} }
// static
gin::WrapperInfo WebContents::kWrapperInfo = {gin::kEmbedderNativeGin};
} // namespace api } // namespace api
} // namespace electron } // namespace electron
namespace { namespace {
using electron::api::GetAllWebContents;
using electron::api::WebContents; using electron::api::WebContents;
std::vector<gin::Handle<WebContents>> GetAllWebContentsAsV8(
v8::Isolate* isolate) {
std::vector<gin::Handle<WebContents>> list;
for (auto iter = base::IDMap<WebContents*>::iterator(&GetAllWebContents());
!iter.IsAtEnd(); iter.Advance()) {
list.push_back(gin::CreateHandle(isolate, iter.GetCurrentValue()));
}
return list;
}
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) {
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
gin_helper::Dictionary dict(isolate, exports); gin_helper::Dictionary dict(isolate, exports);
dict.Set("WebContents", WebContents::GetConstructor(isolate) dict.Set("WebContents", WebContents::GetConstructor(context));
->GetFunction(context)
.ToLocalChecked());
dict.SetMethod("create", &WebContents::Create); dict.SetMethod("create", &WebContents::Create);
dict.SetMethod("fromId", &WebContents::FromWeakMapID); dict.SetMethod("fromId", &WebContents::FromID);
dict.SetMethod("getAllWebContents", &WebContents::GetAll); dict.SetMethod("getAllWebContents", &GetAllWebContentsAsV8);
} }
} // namespace } // namespace

View file

@ -8,6 +8,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/observer_list.h" #include "base/observer_list.h"
@ -22,14 +23,17 @@
#include "electron/buildflags/buildflags.h" #include "electron/buildflags/buildflags.h"
#include "electron/shell/common/api/api.mojom.h" #include "electron/shell/common/api/api.mojom.h"
#include "gin/handle.h" #include "gin/handle.h"
#include "gin/wrappable.h"
#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/receiver_set.h"
#include "printing/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "shell/browser/api/frame_subscriber.h" #include "shell/browser/api/frame_subscriber.h"
#include "shell/browser/api/save_page_handler.h" #include "shell/browser/api/save_page_handler.h"
#include "shell/browser/common_web_contents_delegate.h" #include "shell/browser/common_web_contents_delegate.h"
#include "shell/browser/event_emitter_mixin.h"
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
#include "shell/common/gin_helper/constructible.h"
#include "shell/common/gin_helper/error_thrower.h" #include "shell/common/gin_helper/error_thrower.h"
#include "shell/common/gin_helper/trackable_object.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#if BUILDFLAG(ENABLE_PRINTING) #if BUILDFLAG(ENABLE_PRINTING)
@ -131,7 +135,10 @@ class ExtendedWebContentsObserver : public base::CheckedObserver {
}; };
// Wrapper around the content::WebContents. // Wrapper around the content::WebContents.
class WebContents : public gin_helper::TrackableObject<WebContents>, class WebContents : public gin::Wrappable<WebContents>,
public gin_helper::EventEmitterMixin<WebContents>,
public gin_helper::Constructible<WebContents>,
public gin_helper::CleanedUpAtExit,
public CommonWebContentsDelegate, public CommonWebContentsDelegate,
public content::WebContentsObserver, public content::WebContentsObserver,
public mojom::ElectronBrowser { public mojom::ElectronBrowser {
@ -148,6 +155,8 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
// Create a new WebContents and return the V8 wrapper of it. // Create a new WebContents and return the V8 wrapper of it.
static gin::Handle<WebContents> Create(v8::Isolate* isolate, static gin::Handle<WebContents> Create(v8::Isolate* isolate,
const gin_helper::Dictionary& options); const gin_helper::Dictionary& options);
static gin::Handle<WebContents> New(v8::Isolate* isolate,
const gin_helper::Dictionary& options);
// Create a new V8 wrapper for an existing |web_content|. // Create a new V8 wrapper for an existing |web_content|.
// //
@ -170,8 +179,12 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
v8::Isolate* isolate, v8::Isolate* isolate,
content::WebContents* web_contents); content::WebContents* web_contents);
static void BuildPrototype(v8::Isolate* isolate, // gin::Wrappable
v8::Local<v8::FunctionTemplate> prototype); static gin::WrapperInfo kWrapperInfo;
static v8::Local<v8::ObjectTemplate> FillObjectTemplate(
v8::Isolate*,
v8::Local<v8::ObjectTemplate>);
const char* GetTypeName() override;
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
@ -375,7 +388,7 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
const base::FilePath& file_path); const base::FilePath& file_path);
// Properties. // Properties.
int32_t ID() const; int32_t ID() const { return id_; }
v8::Local<v8::Value> Session(v8::Isolate* isolate); v8::Local<v8::Value> Session(v8::Isolate* isolate);
content::WebContents* HostWebContents() const; content::WebContents* HostWebContents() const;
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate); v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
@ -395,6 +408,25 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
bool EmitNavigationEvent(const std::string& event, bool EmitNavigationEvent(const std::string& event,
content::NavigationHandle* navigation_handle); content::NavigationHandle* navigation_handle);
// this.emit(name, new Event(sender, message), args...);
template <typename... Args>
bool EmitWithSender(base::StringPiece name,
content::RenderFrameHost* sender,
electron::mojom::ElectronBrowser::InvokeCallback callback,
Args&&... args) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Object> wrapper;
if (!GetWrapper(isolate).ToLocal(&wrapper))
return false;
v8::Local<v8::Object> event = gin_helper::internal::CreateNativeEvent(
isolate, wrapper, sender, std::move(callback));
return EmitCustomEvent(name, event, std::forward<Args>(args)...);
}
void MarkDestroyed();
WebContents* embedder() { return embedder_; } WebContents* embedder() { return embedder_; }
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS) #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
@ -637,6 +669,8 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
// The type of current WebContents. // The type of current WebContents.
Type type_ = Type::BROWSER_WINDOW; Type type_ = Type::BROWSER_WINDOW;
int32_t id_;
// Request id used for findInPage request. // Request id used for findInPage request.
uint32_t request_id_ = 0; uint32_t request_id_ = 0;

View file

@ -44,9 +44,7 @@ class EventEmitterMixin {
v8::Local<v8::Object> wrapper; v8::Local<v8::Object> wrapper;
if (!static_cast<T*>(this)->GetWrapper(isolate).ToLocal(&wrapper)) if (!static_cast<T*>(this)->GetWrapper(isolate).ToLocal(&wrapper))
return false; return false;
v8::Local<v8::Object> event = return EmitWithEvent(isolate, wrapper, name, custom_event,
internal::CreateEvent(isolate, wrapper, custom_event);
return EmitWithEvent(isolate, wrapper, name, event,
std::forward<Args>(args)...); std::forward<Args>(args)...);
} }

View file

@ -157,7 +157,7 @@ v8::Local<v8::Function> CreateConstructor(
CHECK(!called) << "CreateConstructor can only be called for one type once"; CHECK(!called) << "CreateConstructor can only be called for one type once";
called = true; called = true;
#endif #endif
v8::Local<v8::FunctionTemplate> templ = CreateFunctionTemplate( v8::Local<v8::FunctionTemplate> templ = gin_helper::CreateFunctionTemplate(
isolate, base::BindRepeating(&internal::InvokeNew<Sig>, func)); isolate, base::BindRepeating(&internal::InvokeNew<Sig>, func));
templ->InstanceTemplate()->SetInternalFieldCount(1); templ->InstanceTemplate()->SetInternalFieldCount(1);
T::BuildPrototype(isolate, templ); T::BuildPrototype(isolate, templ);

View file

@ -70,23 +70,6 @@ class EventEmitter : public gin_helper::Wrappable<T> {
return EmitWithEvent(name, event, std::forward<Args>(args)...); return EmitWithEvent(name, event, std::forward<Args>(args)...);
} }
// this.emit(name, new Event(sender, message), args...);
template <typename... Args>
bool EmitWithSender(base::StringPiece name,
content::RenderFrameHost* sender,
electron::mojom::ElectronBrowser::InvokeCallback callback,
Args&&... args) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Object> wrapper = GetWrapper();
if (wrapper.IsEmpty())
return false;
v8::Local<v8::Object> event = internal::CreateNativeEvent(
isolate(), wrapper, sender, std::move(callback));
return EmitWithEvent(name, event, std::forward<Args>(args)...);
}
protected: protected:
EventEmitter() {} EventEmitter() {}