Merge pull request #12190 from electron/fix-double-preload-master

Ensure that a document has been created before sending IPC messages
This commit is contained in:
Samuel Attard 2018-03-14 10:34:05 +09:00 committed by GitHub
commit 8664dd2139
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 318 additions and 276 deletions

View file

@ -282,6 +282,27 @@ void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
} // namespace
struct WebContents::FrameDispatchHelper {
WebContents* api_web_contents;
content::RenderFrameHost* rfh;
bool Send(IPC::Message* msg) { return rfh->Send(msg); }
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg) {
api_web_contents->OnSetTemporaryZoomLevel(rfh, level, reply_msg);
}
void OnGetZoomLevel(IPC::Message* reply_msg) {
api_web_contents->OnGetZoomLevel(rfh, reply_msg);
}
void OnRendererMessageSync(const base::string16& channel,
const base::ListValue& args,
IPC::Message* message) {
api_web_contents->OnRendererMessageSync(rfh, channel, args, message);
}
};
WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents,
Type type)
@ -942,13 +963,6 @@ void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
bool WebContents::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
OnRendererMessageSync)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_SetTemporaryZoomLevel,
OnSetTemporaryZoomLevel)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel,
OnGetZoomLevel)
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
handled = false)
IPC_MESSAGE_UNHANDLED(handled = false)
@ -958,17 +972,28 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
}
bool WebContents::OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* frame_host) {
content::RenderFrameHost* frame_host) {
bool handled = true;
FrameDispatchHelper helper = {this, frame_host};
auto relay = NativeWindowRelay::FromWebContents(web_contents());
if (!relay)
return false;
if (relay) {
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
relay->window.get(), NativeWindow::HideAutofillPopup)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
}
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message, OnRendererMessage)
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper,
FrameDispatchHelper::OnRendererMessageSync)
IPC_MESSAGE_FORWARD_DELAY_REPLY(
AtomFrameHostMsg_SetTemporaryZoomLevel, &helper,
FrameDispatchHelper::OnSetTemporaryZoomLevel)
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper,
FrameDispatchHelper::OnGetZoomLevel)
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
IPC_END_MESSAGE_MAP()
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
relay->window.get(), NativeWindow::HideAutofillPopup)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@ -1487,7 +1512,12 @@ void WebContents::TabTraverse(bool reverse) {
bool WebContents::SendIPCMessage(bool all_frames,
const base::string16& channel,
const base::ListValue& args) {
return Send(new AtomViewMsg_Message(routing_id(), all_frames, channel, args));
auto frame_host = web_contents()->GetMainFrame();
if (frame_host) {
return frame_host->Send(new AtomFrameMsg_Message(
frame_host->GetRoutingID(), all_frames, channel, args));
}
return false;
}
void WebContents::SendInputEvent(v8::Isolate* isolate,
@ -1771,17 +1801,20 @@ double WebContents::GetZoomFactor() {
return content::ZoomLevelToZoomFactor(level);
}
void WebContents::OnSetTemporaryZoomLevel(double level,
void WebContents::OnSetTemporaryZoomLevel(content::RenderFrameHost* rfh,
double level,
IPC::Message* reply_msg) {
zoom_controller_->SetTemporaryZoomLevel(level);
double new_level = zoom_controller_->GetZoomLevel();
AtomViewHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg, new_level);
Send(reply_msg);
AtomFrameHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg,
new_level);
rfh->Send(reply_msg);
}
void WebContents::OnGetZoomLevel(IPC::Message* reply_msg) {
AtomViewHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
Send(reply_msg);
void WebContents::OnGetZoomLevel(content::RenderFrameHost* rfh,
IPC::Message* reply_msg) {
AtomFrameHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
rfh->Send(reply_msg);
}
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
@ -1974,17 +2007,19 @@ AtomBrowserContext* WebContents::GetBrowserContext() const {
return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
}
void WebContents::OnRendererMessage(const base::string16& channel,
void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host,
const base::string16& channel,
const base::ListValue& args) {
// webContents.emit(channel, new Event(), args...);
Emit(base::UTF16ToUTF8(channel), args);
}
void WebContents::OnRendererMessageSync(const base::string16& channel,
void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,
const base::string16& channel,
const base::ListValue& args,
IPC::Message* message) {
// webContents.emit(channel, new Event(sender, message), args...);
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
EmitWithSender(base::UTF16ToUTF8(channel), frame_host, message, args);
}
// static

View file

@ -383,6 +383,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
const std::vector<base::string16>& labels);
private:
struct FrameDispatchHelper;
AtomBrowserContext* GetBrowserContext() const;
uint32_t GetNextRequestId() {
@ -393,21 +394,26 @@ class WebContents : public mate::TrackableObject<WebContents>,
void OnCursorChange(const content::WebCursor& cursor);
// Called when received a message from renderer.
void OnRendererMessage(const base::string16& channel,
void OnRendererMessage(content::RenderFrameHost* frame_host,
const base::string16& channel,
const base::ListValue& args);
// Called when received a synchronous message from renderer.
void OnRendererMessageSync(const base::string16& channel,
void OnRendererMessageSync(content::RenderFrameHost* frame_host,
const base::string16& channel,
const base::ListValue& args,
IPC::Message* message);
// Called when received a synchronous message from renderer to
// set temporary zoom level.
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg);
void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host,
double level,
IPC::Message* reply_msg);
// Called when received a synchronous message from renderer to
// get the zoom level.
void OnGetZoomLevel(IPC::Message* reply_msg);
void OnGetZoomLevel(content::RenderFrameHost* frame_host,
IPC::Message* reply_msg);
void InitZoomController(content::WebContents* web_contents,
const mate::Dictionary& options);

View file

@ -6,6 +6,7 @@
#include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/object_template_builder.h"
@ -20,17 +21,32 @@ Event::Event(v8::Isolate* isolate)
Event::~Event() {
}
void Event::SetSenderAndMessage(content::WebContents* sender,
void Event::SetSenderAndMessage(content::RenderFrameHost* sender,
IPC::Message* message) {
DCHECK(!sender_);
DCHECK(!message_);
sender_ = sender;
message_ = message;
Observe(sender);
Observe(content::WebContents::FromRenderFrameHost(sender));
}
void Event::WebContentsDestroyed() {
void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) {
if (sender_ != rfh)
return;
sender_ = nullptr;
message_ = nullptr;
}
void Event::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
content::RenderFrameHost* new_rfh) {
if (sender_ && sender_ == old_rfh)
sender_ = new_rfh;
}
void Event::FrameDeleted(content::RenderFrameHost* rfh) {
if (sender_ != rfh)
return;
sender_ = nullptr;
message_ = nullptr;
}
@ -44,7 +60,7 @@ bool Event::SendReply(const base::string16& json) {
if (message_ == nullptr || sender_ == nullptr)
return false;
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, json);
bool success = sender_->Send(message_);
message_ = nullptr;
sender_ = nullptr;

View file

@ -24,7 +24,8 @@ class Event : public Wrappable<Event>,
v8::Local<v8::FunctionTemplate> prototype);
// Pass the sender and message to be replied.
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
void SetSenderAndMessage(content::RenderFrameHost* sender,
IPC::Message* message);
// event.PreventDefault().
void PreventDefault(v8::Isolate* isolate);
@ -37,11 +38,14 @@ class Event : public Wrappable<Event>,
~Event() override;
// content::WebContentsObserver implementations:
void WebContentsDestroyed() override;
void RenderFrameDeleted(content::RenderFrameHost* rfh) override;
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
content::RenderFrameHost* new_rfh) override;
void FrameDeleted(content::RenderFrameHost* rfh) override;
private:
// Replyer for the synchronous messages.
content::WebContents* sender_;
content::RenderFrameHost* sender_;
IPC::Message* message_;
DISALLOW_COPY_AND_ASSIGN(Event);

View file

@ -39,11 +39,10 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
namespace internal {
v8::Local<v8::Object> CreateJSEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::WebContents* sender,
IPC::Message* message) {
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::RenderFrameHost* sender,
IPC::Message* message) {
v8::Local<v8::Object> event;
bool use_native_event = sender && message;

View file

@ -11,7 +11,7 @@
#include "native_mate/wrappable.h"
namespace content {
class WebContents;
class RenderFrameHost;
}
namespace IPC {
@ -24,7 +24,7 @@ namespace internal {
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::WebContents* sender,
content::RenderFrameHost* sender,
IPC::Message* message);
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate,
@ -74,9 +74,9 @@ class EventEmitter : public Wrappable<T> {
}
// this.emit(name, new Event(sender, message), args...);
template<typename... Args>
template <typename... Args>
bool EmitWithSender(const base::StringPiece& name,
content::WebContents* sender,
content::RenderFrameHost* sender,
IPC::Message* message,
const Args&... args) {
v8::Locker locker(isolate());