chore: remove native_mate (Part 11) (#20719)
* refactor: convert Menu and globalShortcut to gin * refactor: convert api::Cookies to gin * refactor: convert View and WebContentsView to gin * refactor: convert WebContents related classes to gin * refactor: convert powerMonitor to gin * refactor: prepare for header change * refactor: remove last uses of mate::EventEmitter * refactor: remove mate::EventEmitter * refactor: move trackable_object to gin_helper * fix: custom converter should not use Handle * fix: no more need to check if icon is empty It was a bug that the Handle<NativeImage> can be non-empty when the image file does not exist. The bug was caused by the converter code writing out the image even when the convertion fails. The bug was work-arounded by adding an additional check, but since the original bug had been fixed, the additional check is no longer needed. * fix: should always set frameId even when callback is null * fix: do not mix gin/mate handles for NativeImage
This commit is contained in:
parent
0e0d4fe990
commit
0fe6767d6b
80 changed files with 823 additions and 1087 deletions
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "shell/browser/api/event.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
|
@ -62,6 +64,30 @@ v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags) {
|
|||
return obj.GetHandle();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> CreateNativeEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender,
|
||||
content::RenderFrameHost* frame,
|
||||
base::Optional<electron::mojom::ElectronBrowser::MessageSyncCallback>
|
||||
callback) {
|
||||
v8::Local<v8::Object> event;
|
||||
if (frame && callback) {
|
||||
mate::Handle<mate::Event> native_event = mate::Event::Create(isolate);
|
||||
native_event->SetCallback(std::move(callback));
|
||||
event = v8::Local<v8::Object>::Cast(native_event.ToV8());
|
||||
} else {
|
||||
// No need to create native event if we do not need to send reply.
|
||||
event = CreateEvent(isolate);
|
||||
}
|
||||
|
||||
Dictionary dict(isolate, event);
|
||||
dict.Set("sender", sender);
|
||||
// Should always set frameId even when callback is null.
|
||||
if (frame)
|
||||
dict.Set("frameId", frame->GetRoutingID());
|
||||
return event;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace gin_helper
|
||||
|
|
|
@ -9,9 +9,15 @@
|
|||
#include <vector>
|
||||
|
||||
#include "base/optional.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "electron/shell/common/api/api.mojom.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
|
||||
namespace content {
|
||||
class RenderFrameHost;
|
||||
}
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
namespace internal {
|
||||
|
@ -21,16 +27,21 @@ v8::Local<v8::Object> CreateEvent(
|
|||
v8::Local<v8::Object> sender = v8::Local<v8::Object>(),
|
||||
v8::Local<v8::Object> custom_event = v8::Local<v8::Object>());
|
||||
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
|
||||
v8::Local<v8::Object> CreateNativeEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender,
|
||||
content::RenderFrameHost* frame,
|
||||
base::Optional<electron::mojom::ElectronBrowser::MessageSyncCallback>
|
||||
callback);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Provide helperers to emit event in JavaScript.
|
||||
//
|
||||
// TODO(zcbenz): Inherit from Wrappable directly after removing native_mate.
|
||||
template <typename Base>
|
||||
class EventEmitter : public Base {
|
||||
template <typename T>
|
||||
class EventEmitter : public mate::Wrappable<T> {
|
||||
public:
|
||||
typedef std::vector<v8::Local<v8::Value>> ValueArray;
|
||||
using Base = mate::Wrappable<T>;
|
||||
using ValueArray = std::vector<v8::Local<v8::Value>>;
|
||||
|
||||
// Make the convinient methods visible:
|
||||
// https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
|
||||
|
@ -64,13 +75,30 @@ class EventEmitter : public Base {
|
|||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Object> wrapper = GetWrapper();
|
||||
if (wrapper.IsEmpty()) {
|
||||
if (wrapper.IsEmpty())
|
||||
return false;
|
||||
}
|
||||
v8::Local<v8::Object> event = internal::CreateEvent(isolate(), wrapper);
|
||||
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,
|
||||
base::Optional<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:
|
||||
EventEmitter() {}
|
||||
|
||||
|
|
71
shell/common/gin_helper/trackable_object.cc
Normal file
71
shell/common/gin_helper/trackable_object.cc
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/common/gin_helper/trackable_object.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/supports_user_data.h"
|
||||
#include "shell/browser/atom_browser_main_parts.h"
|
||||
#include "shell/common/api/locker.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kTrackedObjectKey = "TrackedObjectKey";
|
||||
|
||||
class IDUserData : public base::SupportsUserData::Data {
|
||||
public:
|
||||
explicit IDUserData(int32_t id) : id_(id) {}
|
||||
|
||||
operator int32_t() const { return id_; }
|
||||
|
||||
private:
|
||||
int32_t id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(IDUserData);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TrackableObjectBase::TrackableObjectBase() : weak_factory_(this) {
|
||||
// TODO(zcbenz): Make TrackedObject work in renderer process.
|
||||
DCHECK(mate::Locker::IsBrowserProcess())
|
||||
<< "This class only works for browser process";
|
||||
|
||||
electron::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||
GetDestroyClosure());
|
||||
}
|
||||
|
||||
TrackableObjectBase::~TrackableObjectBase() = default;
|
||||
|
||||
base::OnceClosure TrackableObjectBase::GetDestroyClosure() {
|
||||
return base::BindOnce(&TrackableObjectBase::Destroy,
|
||||
weak_factory_.GetWeakPtr());
|
||||
}
|
||||
|
||||
void TrackableObjectBase::Destroy() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
|
||||
wrapped->SetUserData(kTrackedObjectKey,
|
||||
std::make_unique<IDUserData>(weak_map_id_));
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(
|
||||
base::SupportsUserData* wrapped) {
|
||||
if (wrapped) {
|
||||
auto* id =
|
||||
static_cast<IDUserData*>(wrapped->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
135
shell/common/gin_helper/trackable_object.h
Normal file
135
shell/common/gin_helper/trackable_object.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_HELPER_TRACKABLE_OBJECT_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_TRACKABLE_OBJECT_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "shell/common/key_weak_map.h"
|
||||
|
||||
namespace base {
|
||||
class SupportsUserData;
|
||||
}
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
// Users should use TrackableObject instead.
|
||||
class TrackableObjectBase {
|
||||
public:
|
||||
TrackableObjectBase();
|
||||
|
||||
// The ID in weak map.
|
||||
int32_t weak_map_id() const { return weak_map_id_; }
|
||||
|
||||
// Wrap TrackableObject into a class that SupportsUserData.
|
||||
void AttachAsUserData(base::SupportsUserData* wrapped);
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
protected:
|
||||
virtual ~TrackableObjectBase();
|
||||
|
||||
// Returns a closure that can destroy the native class.
|
||||
base::OnceClosure GetDestroyClosure();
|
||||
|
||||
int32_t weak_map_id_ = 0;
|
||||
|
||||
private:
|
||||
void Destroy();
|
||||
|
||||
base::WeakPtrFactory<TrackableObjectBase> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrackableObjectBase);
|
||||
};
|
||||
|
||||
// All instances of TrackableObject will be kept in a weak map and can be got
|
||||
// from its ID.
|
||||
template <typename T>
|
||||
class TrackableObject : public TrackableObjectBase, public EventEmitter<T> {
|
||||
public:
|
||||
// Mark the JS object as destroyed.
|
||||
void MarkDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = mate::Wrappable<T>::GetWrapper();
|
||||
if (!wrapper.IsEmpty()) {
|
||||
wrapper->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = mate::Wrappable<T>::GetWrapper();
|
||||
return wrapper->InternalFieldCount() == 0 ||
|
||||
wrapper->GetAlignedPointerFromInternalField(0) == nullptr;
|
||||
}
|
||||
|
||||
// Finds out the TrackableObject from its ID in weak map.
|
||||
static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) {
|
||||
if (!weak_map_)
|
||||
return nullptr;
|
||||
|
||||
v8::MaybeLocal<v8::Object> object = weak_map_->Get(isolate, id);
|
||||
if (object.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
T* self = nullptr;
|
||||
gin::ConvertFromV8(isolate, object.ToLocalChecked(), &self);
|
||||
return self;
|
||||
}
|
||||
|
||||
// Finds out the TrackableObject from the class it wraps.
|
||||
static T* FromWrappedClass(v8::Isolate* isolate,
|
||||
base::SupportsUserData* wrapped) {
|
||||
int32_t id = GetIDFromWrappedClass(wrapped);
|
||||
if (!id)
|
||||
return nullptr;
|
||||
return FromWeakMapID(isolate, id);
|
||||
}
|
||||
|
||||
// Returns all objects in this class's weak map.
|
||||
static std::vector<v8::Local<v8::Object>> GetAll(v8::Isolate* isolate) {
|
||||
if (weak_map_)
|
||||
return weak_map_->Values(isolate);
|
||||
else
|
||||
return std::vector<v8::Local<v8::Object>>();
|
||||
}
|
||||
|
||||
// Removes this instance from the weak map.
|
||||
void RemoveFromWeakMap() {
|
||||
if (weak_map_ && weak_map_->Has(weak_map_id()))
|
||||
weak_map_->Remove(weak_map_id());
|
||||
}
|
||||
|
||||
protected:
|
||||
TrackableObject() { weak_map_id_ = ++next_id_; }
|
||||
|
||||
~TrackableObject() override { RemoveFromWeakMap(); }
|
||||
|
||||
void InitWith(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) override {
|
||||
mate::WrappableBase::InitWith(isolate, wrapper);
|
||||
if (!weak_map_) {
|
||||
weak_map_ = new electron::KeyWeakMap<int32_t>;
|
||||
}
|
||||
weak_map_->Set(isolate, weak_map_id_, wrapper);
|
||||
}
|
||||
|
||||
private:
|
||||
static int32_t next_id_;
|
||||
static electron::KeyWeakMap<int32_t>* weak_map_; // leaked on purpose
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrackableObject);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
int32_t TrackableObject<T>::next_id_ = 0;
|
||||
|
||||
template <typename T>
|
||||
electron::KeyWeakMap<int32_t>* TrackableObject<T>::weak_map_ = nullptr;
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_TRACKABLE_OBJECT_H_
|
Loading…
Add table
Add a link
Reference in a new issue