Move all sources under atom/.

This commit is contained in:
Cheng Zhao 2014-03-16 08:30:26 +08:00
parent 26ddbbb0ee
commit 516d46444d
217 changed files with 519 additions and 519 deletions

View file

@ -0,0 +1,98 @@
// 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/renderer/api/atom_api_renderer_ipc.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/v8/native_type_conversions.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "atom/common/v8/node_common.h"
using content::RenderView;
using WebKit::WebFrame;
using WebKit::WebView;
namespace atom {
namespace api {
namespace {
RenderView* GetCurrentRenderView() {
WebFrame* frame = WebFrame::frameForCurrentContext();
if (!frame)
return NULL;
WebView* view = frame->view();
if (!view)
return NULL; // can happen during closing.
return RenderView::FromWebView(view);
}
} // namespace
// static
void RendererIPC::Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
string16 channel;
scoped_ptr<base::Value> arguments;
if (!FromV8Arguments(args, &channel, &arguments))
return node::ThrowTypeError("Bad argument");
RenderView* render_view = GetCurrentRenderView();
if (render_view == NULL)
return;
bool success = render_view->Send(new AtomViewHostMsg_Message(
render_view->GetRoutingID(),
channel,
*static_cast<base::ListValue*>(arguments.get())));
if (!success)
return node::ThrowError("Unable to send AtomViewHostMsg_Message");
}
// static
void RendererIPC::SendSync(const v8::FunctionCallbackInfo<v8::Value>& args) {
string16 channel;
scoped_ptr<base::Value> arguments;
if (!FromV8Arguments(args, &channel, &arguments))
return node::ThrowTypeError("Bad argument");
RenderView* render_view = GetCurrentRenderView();
if (render_view == NULL)
return;
string16 json;
IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync(
render_view->GetRoutingID(),
channel,
*static_cast<base::ListValue*>(arguments.get()),
&json);
// Enable the UI thread in browser to receive messages.
message->EnableMessagePumping();
bool success = render_view->Send(message);
if (!success)
return node::ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
args.GetReturnValue().Set(ToV8Value(json));
}
// static
void RendererIPC::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope handle_scope(node_isolate);
NODE_SET_METHOD(target, "send", Send);
NODE_SET_METHOD(target, "sendSync", SendSync);
}
} // namespace api
} // namespace atom
NODE_MODULE(atom_renderer_ipc, atom::api::RendererIPC::Initialize)

View file

@ -0,0 +1,30 @@
// 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_RENDERER_API_ATOM_API_RENDERER_IPC_H_
#define ATOM_RENDERER_API_ATOM_API_RENDERER_IPC_H_
#include "base/basictypes.h"
#include "v8/include/v8.h"
namespace atom {
namespace api {
class RendererIPC {
public:
static void Initialize(v8::Handle<v8::Object> target);
private:
static void Send(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SendSync(const v8::FunctionCallbackInfo<v8::Value>& args);
DISALLOW_IMPLICIT_CONSTRUCTORS(RendererIPC);
};
} // namespace api
} // namespace atom
#endif // ATOM_RENDERER_API_ATOM_API_RENDERER_IPC_H_

View file

@ -0,0 +1,76 @@
// 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/renderer/api/atom_renderer_bindings.h"
#include "atom/common/v8/native_type_conversions.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "atom/common/v8/node_common.h"
namespace atom {
namespace {
v8::Handle<v8::Object> GetProcessObject(v8::Handle<v8::Context> context) {
v8::Handle<v8::Object> process =
context->Global()->Get(v8::String::New("process"))->ToObject();
DCHECK(!process.IsEmpty());
return process;
}
} // namespace
AtomRendererBindings::AtomRendererBindings() {
}
AtomRendererBindings::~AtomRendererBindings() {
}
void AtomRendererBindings::BindToFrame(WebKit::WebFrame* frame) {
v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope scope(context);
AtomBindings::BindTo(GetProcessObject(context));
}
void AtomRendererBindings::OnBrowserMessage(content::RenderView* render_view,
const string16& channel,
const base::ListValue& args) {
if (!render_view->GetWebView())
return;
v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::Context> context =
render_view->GetWebView()->mainFrame()->mainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
v8::Handle<v8::Object> process = GetProcessObject(context);
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);
std::vector<v8::Handle<v8::Value>> arguments;
arguments.reserve(1 + args.GetSize());
arguments.push_back(ToV8Value(channel));
for (size_t i = 0; i < args.GetSize(); i++) {
const base::Value* value;
if (args.Get(i, &value))
arguments.push_back(converter->ToV8Value(value, context));
}
node::MakeCallback(process, "emit", arguments.size(), &arguments[0]);
}
} // namespace atom

View file

@ -0,0 +1,45 @@
// 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_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
#define ATOM_RENDERER_API_ATOM_RENDERER_BINDINGS_H_
#include "atom/common/api/atom_bindings.h"
#include "base/strings/string16.h"
namespace base {
class ListValue;
}
namespace content {
class RenderView;
}
namespace WebKit {
class WebFrame;
}
namespace atom {
class AtomRendererBindings : public AtomBindings {
public:
AtomRendererBindings();
virtual ~AtomRendererBindings();
// Call BindTo for process object of the frame.
void BindToFrame(WebKit::WebFrame* frame);
// Dispatch messages from browser.
void OnBrowserMessage(content::RenderView* render_view,
const string16& channel,
const base::ListValue& args);
private:
DISALLOW_COPY_AND_ASSIGN(AtomRendererBindings);
};
} // namespace atom
#endif // ATOM_RENDERER_API_ATOM_BINDINGS_H_

View file

@ -0,0 +1,24 @@
EventEmitter = require('events').EventEmitter
ipc = process.atomBinding('ipc')
class Ipc extends EventEmitter
constructor: ->
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
@emit args...
window.addEventListener 'unload', (event) ->
process.removeAllListeners 'ATOM_INTERNAL_MESSAGE'
send: (args...) ->
@sendChannel 'message', args...
sendChannel: (args...) ->
ipc.send 'ATOM_INTERNAL_MESSAGE', [args...]
sendSync: (args...) ->
@sendSync 'sync-message', args...
sendChannelSync: (args...) ->
JSON.parse ipc.sendSync('ATOM_INTERNAL_MESSAGE_SYNC', [args...])
module.exports = new Ipc

View file

@ -0,0 +1,131 @@
ipc = require 'ipc'
CallbacksRegistry = require 'callbacks-registry'
v8Util = process.atomBinding 'v8_util'
callbacksRegistry = new CallbacksRegistry
# Convert the arguments object into an array of meta data.
wrapArgs = (args) ->
valueToMeta = (value) ->
if Array.isArray value
type: 'array', value: wrapArgs(value)
else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId'
type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId'
else if value? and typeof value is 'object'
ret = type: 'object', name: value.constructor.name, members: []
ret.members.push(name: prop, value: valueToMeta(field)) for prop, field of value
ret
else if typeof value is 'function' and v8Util.getHiddenValue value, 'returnValue'
type: 'function-with-return-value', value: valueToMeta(value())
else if typeof value is 'function'
type: 'function', id: callbacksRegistry.add(value)
else
type: 'value', value: value
Array::slice.call(args).map valueToMeta
# Convert meta data from browser into real value.
metaToValue = (meta) ->
switch meta.type
when 'value' then meta.value
when 'array' then (metaToValue(el) for el in meta.members)
when 'error'
throw new Error("#{meta.message}\n#{meta.stack}")
else
if meta.type is 'function'
# A shadow class to represent the remote function object.
ret =
class RemoteFunction
constructor: ->
if @constructor == RemoteFunction
# Constructor call.
obj = ipc.sendChannelSync 'ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)
# Returning object in constructor will replace constructed object
# with the returned object.
# http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this
return metaToValue obj
else
# Function call.
ret = ipc.sendChannelSync 'ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)
return metaToValue ret
else
ret = v8Util.createObjectWithName meta.name
# Polulate delegate members.
for member in meta.members
do (member) ->
if member.type is 'function'
ret[member.name] =
class RemoteMemberFunction
constructor: ->
if @constructor is RemoteMemberFunction
# Constructor call.
obj = ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', meta.id, member.name, wrapArgs(arguments)
return metaToValue obj
else
# Call member function.
ret = ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_CALL', meta.id, member.name, wrapArgs(arguments)
return metaToValue ret
else
ret.__defineSetter__ member.name, (value) ->
# Set member data.
ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_SET', meta.id, member.name, value
value
ret.__defineGetter__ member.name, ->
# Get member data.
ret = ipc.sendChannelSync 'ATOM_BROWSER_MEMBER_GET', meta.id, member.name
metaToValue ret
# Track delegate object's life time, and tell the browser to clean up
# when the object is GCed.
v8Util.setDestructor ret, ->
ipc.sendChannel 'ATOM_BROWSER_DEREFERENCE', meta.storeId
# Remember object's id.
v8Util.setHiddenValue ret, 'atomId', meta.id
ret
# Browser calls a callback in renderer.
ipc.on 'ATOM_RENDERER_CALLBACK', (id, args) ->
callbacksRegistry.apply id, metaToValue(args)
# A callback in browser is released.
ipc.on 'ATOM_RENDERER_RELEASE_CALLBACK', (id) ->
callbacksRegistry.remove id
# Get remote module.
# (Just like node's require, the modules are cached permanently, note that this
# is safe leak since the object is not expected to get freed in browser)
moduleCache = {}
exports.require = (module) ->
return moduleCache[module] if moduleCache[module]?
meta = ipc.sendChannelSync 'ATOM_BROWSER_REQUIRE', module
moduleCache[module] = metaToValue meta
# Get current window object.
windowCache = null
exports.getCurrentWindow = ->
return windowCache if windowCache?
meta = ipc.sendChannelSync 'ATOM_BROWSER_CURRENT_WINDOW'
windowCache = metaToValue meta
# Get a global object in browser.
exports.getGlobal = (name) ->
meta = ipc.sendChannelSync 'ATOM_BROWSER_GLOBAL', name
metaToValue meta
# Get the process object in browser.
processCache = null
exports.__defineGetter__ 'process', ->
processCache = exports.getGlobal('process') unless processCache?
processCache
# Create a funtion that will return the specifed value when called in browser.
exports.createFunctionWithReturnValue = (returnValue) ->
func = -> returnValue
v8Util.setHiddenValue func, 'returnValue', true
func