Handle IPC messages in webContents instead of BrowserWindow.

This commit is contained in:
Cheng Zhao 2014-04-25 16:13:16 +08:00
parent 1815f8b40d
commit c0875864dc
21 changed files with 138 additions and 421 deletions

View file

@ -48,7 +48,6 @@
'atom/browser/api/atom_api_app.h',
'atom/browser/api/atom_api_auto_updater.cc',
'atom/browser/api/atom_api_auto_updater.h',
'atom/browser/api/atom_api_browser_ipc.cc',
'atom/browser/api/atom_api_dialog.cc',
'atom/browser/api/atom_api_menu.cc',
'atom/browser/api/atom_api_menu.h',
@ -66,8 +65,6 @@
'atom/browser/api/atom_api_web_contents.h',
'atom/browser/api/atom_api_window.cc',
'atom/browser/api/atom_api_window.h',
'atom/browser/api/atom_browser_bindings.cc',
'atom/browser/api/atom_browser_bindings.h',
'atom/browser/api/event.cc',
'atom/browser/api/event.h',
'atom/browser/api/event_emitter.cc',
@ -95,8 +92,6 @@
'atom/browser/browser_observer.h',
'atom/browser/devtools_delegate.cc',
'atom/browser/devtools_delegate.h',
'atom/browser/devtools_web_contents_observer.cc',
'atom/browser/devtools_web_contents_observer.h',
'atom/browser/mac/atom_application.h',
'atom/browser/mac/atom_application.mm',
'atom/browser/mac/atom_application_delegate.h',

View file

@ -1,37 +0,0 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "atom/common/api/api_messages.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "content/public/browser/render_view_host.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using content::RenderViewHost;
namespace {
bool Send(const string16& channel, int process_id, int routing_id,
const base::ListValue& arguments) {
RenderViewHost* render_view_host(RenderViewHost::FromID(
process_id, routing_id));
if (!render_view_host) {
node::ThrowError("Invalid render view host");
return false;
}
return render_view_host->Send(new AtomViewMsg_Message(routing_id, channel,
arguments));
}
void Initialize(v8::Handle<v8::Object> exports) {
mate::Dictionary dict(v8::Isolate::GetCurrent(), exports);
dict.SetMethod("send", &Send);
}
} // namespace
NODE_MODULE(atom_browser_ipc, Initialize)

View file

@ -8,6 +8,7 @@
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@ -48,6 +49,18 @@ void WebContents::DidStopLoading(content::RenderViewHost* render_view_host) {
Emit("did-stop-loading");
}
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_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void WebContents::WebContentsDestroyed(content::WebContents*) {
// The RenderViewDeleted was not called when the WebContents is destroyed.
RenderViewDeleted(web_contents_->GetRenderViewHost());
@ -166,7 +179,20 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("getProcessId", &WebContents::GetProcessID)
.SetMethod("isCrashed", &WebContents::IsCrashed)
.SetMethod("executeJavaScript", &WebContents::ExecuteJavaScript)
.SetMethod("send", &WebContents::SendIPCMessage);
.SetMethod("_send", &WebContents::SendIPCMessage);
}
void WebContents::OnRendererMessage(const string16& channel,
const base::ListValue& args) {
// webContents.emit(channel, new Event(), args...);
Emit(UTF16ToUTF8(channel), args, web_contents(), NULL);
}
void WebContents::OnRendererMessageSync(const string16& channel,
const base::ListValue& args,
IPC::Message* message) {
// webContents.emit(channel, new Event(sender, message), args...);
Emit(UTF16ToUTF8(channel), args, web_contents(), message);
}
// static

View file

@ -60,9 +60,18 @@ class WebContents : public mate::EventEmitter,
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void DidStopLoading(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE;
private:
// Called when received a message from renderer.
void OnRendererMessage(const string16& channel, const base::ListValue& args);
// Called when received a synchronous message from renderer.
void OnRendererMessageSync(const string16& channel,
const base::ListValue& args,
IPC::Message* message);
content::WebContents* web_contents_; // Weak.
DISALLOW_COPY_AND_ASSIGN(WebContents);

View file

@ -1,93 +0,0 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_browser_bindings.h"
#include <vector>
#include "atom/browser/api/event.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/v8_value_converter.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "atom/common/node_includes.h"
namespace atom {
AtomBrowserBindings::AtomBrowserBindings() {
}
void AtomBrowserBindings::OnRendererMessage(int process_id,
int routing_id,
const string16& channel,
const base::ListValue& args) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);
// process.emit(channel, 'message', process_id, routing_id);
std::vector<v8::Handle<v8::Value>> arguments;
arguments.reserve(3 + args.GetSize());
arguments.push_back(mate::ConvertToV8(node_isolate, channel));
const base::Value* value;
if (args.Get(0, &value))
arguments.push_back(converter->ToV8Value(value, global_env->context()));
arguments.push_back(v8::Integer::New(process_id));
arguments.push_back(v8::Integer::New(routing_id));
for (size_t i = 1; i < args.GetSize(); i++) {
const base::Value* value;
if (args.Get(i, &value))
arguments.push_back(converter->ToV8Value(value, global_env->context()));
}
node::MakeCallback(global_env->process_object(),
"emit",
arguments.size(),
&arguments[0]);
}
void AtomBrowserBindings::OnRendererMessageSync(
int process_id,
int routing_id,
const string16& channel,
const base::ListValue& args,
content::WebContents* sender,
IPC::Message* message) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);
// Create the event object.
mate::Handle<mate::Event> event = mate::Event::Create(node_isolate);
event->SetSenderAndMessage(sender, message);
// process.emit(channel, 'sync-message', event, process_id, routing_id);
std::vector<v8::Handle<v8::Value>> arguments;
arguments.reserve(3 + args.GetSize());
arguments.push_back(mate::ConvertToV8(node_isolate, channel));
const base::Value* value;
if (args.Get(0, &value))
arguments.push_back(converter->ToV8Value(value, global_env->context()));
arguments.push_back(event.ToV8());
arguments.push_back(v8::Integer::New(process_id));
arguments.push_back(v8::Integer::New(routing_id));
for (size_t i = 1; i < args.GetSize(); i++) {
const base::Value* value;
if (args.Get(i, &value))
arguments.push_back(converter->ToV8Value(value, global_env->context()));
}
node::MakeCallback(global_env->process_object(),
"emit",
arguments.size(),
&arguments[0]);
}
} // namespace atom

View file

@ -1,49 +0,0 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_H_
#define ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_H_
#include "atom/common/api/atom_bindings.h"
#include "base/strings/string16.h"
namespace base {
class ListValue;
}
namespace content {
class WebContents;
}
namespace IPC {
class Message;
}
namespace atom {
class AtomBrowserBindings : public AtomBindings {
public:
AtomBrowserBindings();
// Called when received a message from renderer.
void OnRendererMessage(int process_id,
int routing_id,
const string16& channel,
const base::ListValue& args);
// Called when received a synchronous message from renderer.
void OnRendererMessageSync(int process_id,
int routing_id,
const string16& channel,
const base::ListValue& args,
content::WebContents* sender,
IPC::Message* message);
private:
DISALLOW_COPY_AND_ASSIGN(AtomBrowserBindings);
};
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_H_

View file

@ -24,6 +24,13 @@ bool EventEmitter::Emit(const base::StringPiece& name) {
bool EventEmitter::Emit(const base::StringPiece& name,
const base::ListValue& args) {
return Emit(name, args, NULL, NULL);
}
bool EventEmitter::Emit(const base::StringPiece& name,
const base::ListValue& args,
content::WebContents* sender,
IPC::Message* message) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
@ -31,6 +38,8 @@ bool EventEmitter::Emit(const base::StringPiece& name,
scoped_ptr<atom::V8ValueConverter> converter(new atom::V8ValueConverter);
mate::Handle<mate::Event> event = mate::Event::Create(node_isolate);
if (sender && message)
event->SetSenderAndMessage(sender, message);
// v8_args = [name, event, args...];
std::vector<v8::Handle<v8::Value>> v8_args;

View file

@ -11,6 +11,14 @@ namespace base {
class ListValue;
}
namespace content {
class WebContents;
}
namespace IPC {
class Message;
}
namespace mate {
// Provide helperers to emit event in JavaScript.
@ -18,12 +26,16 @@ class EventEmitter : public Wrappable {
protected:
EventEmitter();
// this.emit(name);
// this.emit(name, new Event());
bool Emit(const base::StringPiece& name);
// this.emit(name, args...);
// this.emit(name, new Event(), args...);
bool Emit(const base::StringPiece& name, const base::ListValue& args);
// this.emit(name, new Event(sender, message), args...);
bool Emit(const base::StringPiece& name, const base::ListValue& args,
content::WebContents* sender, IPC::Message* message);
private:
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
};

View file

@ -1,10 +1,32 @@
EventEmitter = require('events').EventEmitter
IDWeakMap = require 'id-weak-map'
app = require 'app'
ipc = require 'ipc'
BrowserWindow = process.atomBinding('window').BrowserWindow
BrowserWindow::__proto__ = EventEmitter.prototype
wrapWebContents = (webContents) ->
return null unless webContents.isAlive()
# webContents is an EventEmitter.
webContents.__proto__ = EventEmitter.prototype
# Wrap around the send method.
webContents.send = (args...) ->
@_send 'ATOM_INTERNAL_MESSAGE', [args...]
# Dispatch the ipc messages.
webContents.on 'ipc-message', (event, channel, args...) =>
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents.on 'ipc-message-sync', (event, channel, args...) =>
set = (value) -> event.sendReply JSON.stringify(value)
Object.defineProperty event, 'returnValue', {set}
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents
# Store all created windows in the weak map.
BrowserWindow.windows = new IDWeakMap
@ -45,15 +67,10 @@ BrowserWindow::toggleDevTools = ->
if @isDevToolsOpened() then @closeDevTools() else @openDevTools()
BrowserWindow::getWebContents = ->
webContents = @_getWebContents()
webContents.__proto__ = EventEmitter.prototype
webContents
wrapWebContents @_getWebContents()
BrowserWindow::getDevToolsWebContents = ->
webContents = @_getDevToolsWebContents()
webContents.__proto__ = EventEmitter.prototype
webContents = null unless webContents.isAlive()
webContents
wrapWebContents @_getDevToolsWebContents()
BrowserWindow::restart = ->
@loadUrl(@getUrl())

View file

@ -1,32 +1,3 @@
EventEmitter = require('events').EventEmitter
send = process.atomBinding('ipc').send
sendWrap = (channel, processId, routingId, args...) ->
BrowserWindow = require 'browser-window'
if processId?.constructor is BrowserWindow
window = processId
args = [routingId, args...]
processId = window.getProcessId()
routingId = window.getRoutingId()
send channel, processId, routingId, [args...]
class Ipc extends EventEmitter
constructor: ->
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
@emit(args...)
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (channel, event, args...) =>
set = (value) -> event.sendReply JSON.stringify(value)
Object.defineProperty event, 'returnValue', {set}
Object.defineProperty event, 'result', {set}
@emit(channel, event, args...)
send: (processId, routingId, args...) ->
@sendChannel(processId, routingId, 'message', args...)
sendChannel: (args...) ->
sendWrap('ATOM_INTERNAL_MESSAGE', args...)
module.exports = new Ipc
module.exports = new EventEmitter

View file

@ -4,10 +4,10 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/api/atom_browser_bindings.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/browser.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/node_bindings.h"
#include "net/proxy/proxy_resolver_v8.h"
@ -23,7 +23,7 @@ namespace atom {
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
AtomBrowserMainParts::AtomBrowserMainParts()
: atom_bindings_(new AtomBrowserBindings),
: atom_bindings_(new AtomBindings),
browser_(new Browser),
node_bindings_(NodeBindings::Create(true)) {
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";

View file

@ -9,7 +9,7 @@
namespace atom {
class AtomBrowserBindings;
class AtomBindings;
class Browser;
class NodeBindings;
@ -20,7 +20,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
static AtomBrowserMainParts* Get();
AtomBrowserBindings* atom_bindings() { return atom_bindings_.get(); }
Browser* browser() { return browser_.get(); }
protected:
@ -37,7 +36,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
#endif
private:
scoped_ptr<AtomBrowserBindings> atom_bindings_;
scoped_ptr<AtomBindings> atom_bindings_;
scoped_ptr<Browser> browser_;
scoped_ptr<NodeBindings> node_bindings_;

View file

@ -1,64 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "atom/browser/devtools_web_contents_observer.h"
#include "atom/browser/api/atom_browser_bindings.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/native_window.h"
#include "atom/common/api/api_messages.h"
#include "base/logging.h"
#include "content/public/browser/render_process_host.h"
#include "ipc/ipc_message_macros.h"
namespace atom {
DevToolsWebContentsObserver::DevToolsWebContentsObserver(
NativeWindow* native_window,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
inspected_window_(native_window) {
DCHECK(native_window);
}
DevToolsWebContentsObserver::~DevToolsWebContentsObserver() {
}
bool DevToolsWebContentsObserver::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(DevToolsWebContentsObserver, message)
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
OnRendererMessageSync)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void DevToolsWebContentsObserver::OnRendererMessage(
const string16& channel,
const base::ListValue& args) {
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessage(
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetRoutingID(),
channel,
args);
}
void DevToolsWebContentsObserver::OnRendererMessageSync(
const string16& channel,
const base::ListValue& args,
IPC::Message* reply_msg) {
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessageSync(
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetRoutingID(),
channel,
args,
web_contents(),
reply_msg);
}
} // namespace atom

View file

@ -1,41 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_DEVTOOLS_WEB_CONTENTS_OBSERVER_H_
#define ATOM_BROWSER_DEVTOOLS_WEB_CONTENTS_OBSERVER_H_
#include "content/public/browser/web_contents_observer.h"
namespace base {
class ListValue;
}
namespace atom {
class NativeWindow;
class DevToolsWebContentsObserver : public content::WebContentsObserver {
public:
DevToolsWebContentsObserver(NativeWindow* native_window,
content::WebContents* web_contents);
virtual ~DevToolsWebContentsObserver();
protected:
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void OnRendererMessage(const string16& channel,
const base::ListValue& args);
void OnRendererMessageSync(const string16& channel,
const base::ListValue& args,
IPC::Message* reply_msg);
private:
NativeWindow* inspected_window_;
DISALLOW_COPY_AND_ASSIGN(DevToolsWebContentsObserver);
};
} // namespace atom
#endif // ATOM_BROWSER_DEVTOOLS_WEB_CONTENTS_OBSERVER_H_

View file

@ -4,7 +4,7 @@ objectsRegistry = require './objects-registry.js'
v8Util = process.atomBinding 'v8_util'
# Convert a real value into meta data.
valueToMeta = (processId, routingId, value) ->
valueToMeta = (sender, value) ->
meta = type: typeof value
meta.type = 'value' if value is null
@ -15,13 +15,15 @@ valueToMeta = (processId, routingId, value) ->
if meta.type is 'array'
meta.members = []
meta.members.push valueToMeta(processId, routingId, el) for el in value
meta.members.push valueToMeta(sender, el) for el in value
else if meta.type is 'object' or meta.type is 'function'
meta.name = value.constructor.name
# Reference the original value if it's an object, because when it's
# passed to renderer we would assume the renderer keeps a reference of
# it.
processId = sender.getProcessId()
routingId = sender.getRoutingId()
[meta.id, meta.storeId] = objectsRegistry.add processId, routingId, value
meta.members = []
@ -37,12 +39,14 @@ errorToMeta = (error) ->
type: 'error', message: error.message, stack: (error.stack || error)
# Convert array of meta data from renderer into array of real values.
unwrapArgs = (processId, routingId, args) ->
unwrapArgs = (sender, args) ->
processId = sender.getProcessId()
routingId = sender.getRoutingId()
metaToValue = (meta) ->
switch meta.type
when 'value' then meta.value
when 'remote-object' then objectsRegistry.get meta.id
when 'array' then unwrapArgs processId, routingId, meta.value
when 'array' then unwrapArgs sender, meta.value
when 'object'
ret = v8Util.createObjectWithName meta.name
for member in meta.members
@ -58,10 +62,10 @@ unwrapArgs = (processId, routingId, args) ->
ret = ->
throw new Error('Calling a callback of released renderer view') if rendererReleased
ipc.sendChannel processId, routingId, 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(processId, routingId, arguments)
sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments)
v8Util.setDestructor ret, ->
return if rendererReleased
ipc.sendChannel processId, routingId, 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id
sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id
ret
else throw new TypeError("Unknown type: #{meta.type}")
@ -69,78 +73,80 @@ unwrapArgs = (processId, routingId, args) ->
# Call a function and send reply asynchronously if it's a an asynchronous
# style function and the caller didn't pass a callback.
callFunction = (event, processId, routingId, func, caller, args) ->
callFunction = (event, func, caller, args) ->
if v8Util.getHiddenValue(func, 'asynchronous') and typeof args[args.length - 1] isnt 'function'
args.push (ret) ->
event.returnValue = valueToMeta processId, routingId, ret
event.returnValue = valueToMeta event.sender, ret
func.apply caller, args
else
ret = func.apply caller, args
event.returnValue = valueToMeta processId, routingId, ret
event.returnValue = valueToMeta event.sender, ret
# Send by BrowserWindow when its render view is deleted.
process.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (processId, routingId) ->
objectsRegistry.clear processId, routingId
ipc.on 'ATOM_BROWSER_REQUIRE', (event, processId, routingId, module) ->
ipc.on 'ATOM_BROWSER_REQUIRE', (event, module) ->
try
event.returnValue = valueToMeta processId, routingId, require(module)
event.returnValue = valueToMeta event.sender, require(module)
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_GLOBAL', (event, processId, routingId, name) ->
ipc.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
try
event.returnValue = valueToMeta processId, routingId, global[name]
event.returnValue = valueToMeta event.sender, global[name]
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, processId, routingId) ->
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
try
BrowserWindow = require 'browser-window'
processId = event.sender.getProcessId()
routingId = event.sender.getRoutingId()
window = BrowserWindow.fromProcessIdAndRoutingId processId, routingId
window = BrowserWindow.fromDevTools processId, routingId unless window?
event.returnValue = valueToMeta processId, routingId, window
event.returnValue = valueToMeta event.sender, window
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
try
args = unwrapArgs processId, routingId, args
args = unwrapArgs event.sender, args
constructor = objectsRegistry.get id
# Call new with array of arguments.
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
obj = new (Function::bind.apply(constructor, [null].concat(args)))
event.returnValue = valueToMeta processId, routingId, obj
event.returnValue = valueToMeta event.sender, obj
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, processId, routingId, id, args) ->
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
try
args = unwrapArgs processId, routingId, args
args = unwrapArgs event.sender, args
func = objectsRegistry.get id
callFunction event, processId, routingId, func, global, args
callFunction event, func, global, args
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, processId, routingId, id, method, args) ->
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
try
args = unwrapArgs processId, routingId, args
args = unwrapArgs event.sender, args
constructor = objectsRegistry.get(id)[method]
# Call new with array of arguments.
obj = new (Function::bind.apply(constructor, [null].concat(args)))
event.returnValue = valueToMeta processId, routingId, obj
event.returnValue = valueToMeta event.sender, obj
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, processId, routingId, id, method, args) ->
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
try
args = unwrapArgs processId, routingId, args
args = unwrapArgs event.sender, args
obj = objectsRegistry.get id
callFunction event, processId, routingId, obj[method], obj, args
callFunction event, obj[method], obj, args
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, processId, routingId, id, name, value) ->
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
try
obj = objectsRegistry.get id
obj[name] = value
@ -148,12 +154,14 @@ ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, processId, routingId, id, name, value)
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, processId, routingId, id, name) ->
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
try
obj = objectsRegistry.get id
event.returnValue = valueToMeta processId, routingId, obj[name]
event.returnValue = valueToMeta event.sender, obj[name]
catch e
event.returnValue = errorToMeta e
ipc.on 'ATOM_BROWSER_DEREFERENCE', (processId, routingId, storeId) ->
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, storeId) ->
processId = event.sender.getProcessId()
routingId = event.sender.getRoutingId()
objectsRegistry.remove processId, routingId, storeId

View file

@ -8,13 +8,10 @@
#include <utility>
#include <vector>
#include "atom/browser/api/atom_browser_bindings.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_javascript_dialog_manager.h"
#include "atom/browser/browser.h"
#include "atom/browser/devtools_delegate.h"
#include "atom/browser/devtools_web_contents_observer.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h"
@ -195,12 +192,8 @@ bool NativeWindow::HasModalDialog() {
void NativeWindow::OpenDevTools() {
if (devtools_window_) {
devtools_window_->Focus(true);
devtools_web_contents_observer_.reset(new DevToolsWebContentsObserver(
this, devtools_window_->GetWebContents()));
} else {
inspectable_web_contents()->ShowDevTools();
devtools_web_contents_observer_.reset(new DevToolsWebContentsObserver(
this, GetDevToolsWebContents()));
#if defined(OS_MACOSX)
// Temporary fix for flashing devtools, try removing this after upgraded to
// Chrome 32.
@ -470,9 +463,6 @@ void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
OnRendererMessageSync)
IPC_MESSAGE_HANDLER(AtomViewHostMsg_UpdateDraggableRegions,
UpdateDraggableRegions)
IPC_MESSAGE_UNHANDLED(handled = false)
@ -602,25 +592,4 @@ void NativeWindow::CallDevToolsFunction(const std::string& function_name,
string16(), base::UTF8ToUTF16(function_name + "(" + params + ");"));
}
void NativeWindow::OnRendererMessage(const string16& channel,
const base::ListValue& args) {
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessage(
GetWebContents()->GetRenderProcessHost()->GetID(),
GetWebContents()->GetRoutingID(),
channel,
args);
}
void NativeWindow::OnRendererMessageSync(const string16& channel,
const base::ListValue& args,
IPC::Message* reply_msg) {
AtomBrowserMainParts::Get()->atom_bindings()->OnRendererMessageSync(
GetWebContents()->GetRenderProcessHost()->GetID(),
GetWebContents()->GetRoutingID(),
channel,
args,
GetWebContents(),
reply_msg);
}
} // namespace atom

View file

@ -46,7 +46,6 @@ namespace atom {
class AtomJavaScriptDialogManager;
class DevToolsDelegate;
class DevToolsWebContentsObserver;
struct DraggableRegion;
class NativeWindow : public brightray::DefaultWebContentsDelegate,
@ -270,13 +269,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
bool succeed,
const SkBitmap& bitmap);
void OnRendererMessage(const string16& channel,
const base::ListValue& args);
void OnRendererMessageSync(const string16& channel,
const base::ListValue& args,
IPC::Message* reply_msg);
// Notification manager.
content::NotificationRegistrar registrar_;
@ -301,9 +293,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
base::WeakPtr<NativeWindow> devtools_window_;
scoped_ptr<DevToolsDelegate> devtools_delegate_;
// WebContentsObserver for the WebContents of devtools.
scoped_ptr<DevToolsWebContentsObserver> devtools_web_contents_observer_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
// Notice that inspectable_web_contents_ must be placed after dialog_manager_,

View file

@ -12,7 +12,6 @@ NODE_EXT_LIST_START
NODE_EXT_LIST_ITEM(atom_browser_app)
NODE_EXT_LIST_ITEM(atom_browser_auto_updater)
NODE_EXT_LIST_ITEM(atom_browser_dialog)
NODE_EXT_LIST_ITEM(atom_browser_ipc)
NODE_EXT_LIST_ITEM(atom_browser_menu)
NODE_EXT_LIST_ITEM(atom_browser_power_monitor)
NODE_EXT_LIST_ITEM(atom_browser_protocol)

View file

@ -10,15 +10,13 @@ class Ipc extends EventEmitter
process.removeAllListeners 'ATOM_INTERNAL_MESSAGE'
send: (args...) ->
@sendChannel 'message', args...
sendChannel: (args...) ->
ipc.send 'ATOM_INTERNAL_MESSAGE', [args...]
ipc.send 'ipc-message', [args...]
sendSync: (args...) ->
@sendSync 'sync-message', args...
JSON.parse ipc.sendSync('ipc-message-sync', [args...])
sendChannelSync: (args...) ->
JSON.parse ipc.sendSync('ATOM_INTERNAL_MESSAGE_SYNC', [args...])
# Discarded
sendChannel: -> @send.apply this, arguments
sendChannelSync: -> @sendSync.apply this, arguments
module.exports = new Ipc

View file

@ -48,13 +48,13 @@ describe 'ipc module', ->
print_name = remote.require path.join(fixtures, 'module', 'print_name.js')
assert.equal print_name.print(buf), 'Buffer'
describe 'ipc.send', ->
describe 'ipc.sender.send', ->
it 'should work when sending an object containing id property', (done) ->
obj = id: 1, name: 'ly'
ipc.once 'message', (message) ->
assert.deepEqual message, obj
done()
ipc.send obj
ipc.send 'message', obj
describe 'ipc.sendSync', ->
it 'can be replied by setting event.returnValue', ->

View file

@ -8,8 +8,8 @@ var window = null;
app.commandLine.appendSwitch('js-flags', '--expose_gc');
ipc.on('message', function() {
ipc.send.apply(this, arguments);
ipc.on('message', function(event, arg) {
event.sender.send('message', arg);
});
ipc.on('console.log', function(pid, rid, args) {
@ -24,11 +24,11 @@ ipc.on('process.exit', function(pid, rid, code) {
process.exit(code);
});
ipc.on('eval', function(ev, pid, rid, script) {
ipc.on('eval', function(ev, script) {
ev.returnValue = eval(script);
});
ipc.on('echo', function(ev, pid, rid, msg) {
ipc.on('echo', function(ev, msg) {
ev.returnValue = msg;
});