| Index: services/js/js_app.cc
|
| diff --git a/services/js/js_app.cc b/services/js/js_app.cc
|
| index 0e31bbf3af8ce1339d99604de8879ea4a2ccbfed..11a555bca5fc91c974aa91785f3079c860cdb171 100644
|
| --- a/services/js/js_app.cc
|
| +++ b/services/js/js_app.cc
|
| @@ -5,60 +5,112 @@
|
| #include "services/js/js_app.h"
|
|
|
| #include "base/bind.h"
|
| -#include "gin/array_buffer.h"
|
| +#include "base/message_loop/message_loop.h"
|
| #include "gin/converter.h"
|
| +#include "gin/modules/module_registry.h"
|
| +#include "gin/try_catch.h"
|
| #include "mojo/common/data_pipe_utils.h"
|
| +#include "mojo/edk/js/core.h"
|
| +#include "mojo/edk/js/handle.h"
|
| +#include "mojo/edk/js/support.h"
|
| +#include "mojo/public/cpp/bindings/interface_request.h"
|
| +#include "services/js/js_app_shell.h"
|
| #include "services/js/mojo_bridge_module.h"
|
|
|
| namespace mojo {
|
| namespace js {
|
|
|
| +const char JSApp::kMainModuleName[] = "main";
|
| +
|
| JSApp::JSApp(ShellPtr shell, URLResponsePtr response) : shell_(shell.Pass()) {
|
| - // TODO(hansmuller): handle load failure here and below.
|
| + isolate_holder_.AddRunMicrotasksObserver();
|
| +
|
| DCHECK(!response.is_null());
|
| - file_name_ = response->url;
|
| - bool result = common::BlockingCopyToString(response->body.Pass(), &source_);
|
| - DCHECK(result);
|
| + std::string url(response->url);
|
| + std::string source;
|
| + CHECK(common::BlockingCopyToString(response->body.Pass(), &source));
|
|
|
| - runner_delegate.AddBuiltinModule(MojoInternals::kModuleName,
|
| - base::Bind(MojoInternals::GetModule, this));
|
| - shell_.set_client(this);
|
| + v8::Isolate* isolate = isolate_holder_.isolate();
|
| + shell_runner_.reset(new gin::ShellRunner(&runner_delegate_, isolate));
|
| + gin::Runner::Scope scope(shell_runner_.get());
|
| + shell_runner_->Run(source.c_str(), kMainModuleName);
|
| +
|
| + gin::ModuleRegistry* registry =
|
| + gin::ModuleRegistry::From(shell_runner_->GetContextHolder()->context());
|
| + registry->LoadModule(
|
| + isolate,
|
| + kMainModuleName,
|
| + base::Bind(&JSApp::OnAppLoaded, base::Unretained(this), url));
|
| }
|
|
|
| JSApp::~JSApp() {
|
| + app_instance_.Reset();
|
| }
|
|
|
| -void JSApp::Quit() {
|
| - isolate_holder_.RemoveRunMicrotasksObserver();
|
| - base::MessageLoop::current()->PostTask(
|
| - FROM_HERE, base::Bind(&JSApp::QuitInternal, base::Unretained(this)));
|
| +
|
| +void JSApp::OnAppLoaded(std::string url, v8::Handle<v8::Value> main_module) {
|
| + gin::Runner::Scope scope(shell_runner_.get());
|
| + gin::TryCatch try_catch;
|
| + v8::Isolate* isolate = isolate_holder_.isolate();
|
| +
|
| + v8::Handle<v8::Value> argv[] = {
|
| + gin::ConvertToV8(isolate, JSAppShell::Create(isolate, this)),
|
| + gin::ConvertToV8(isolate, url)
|
| + };
|
| +
|
| + v8::Handle<v8::Function> app_class;
|
| + CHECK(gin::ConvertFromV8(isolate, main_module, &app_class));
|
| + app_instance_.Reset(isolate, app_class->NewInstance(arraysize(argv), argv));
|
| + if (try_catch.HasCaught())
|
| + runner_delegate_.UnhandledException(shell_runner_.get(), try_catch);
|
| +
|
| + shell_.set_client(this);
|
| }
|
|
|
| -MessagePipeHandle JSApp::ConnectToApplication(
|
| - const std::string& application_url) {
|
| - MessagePipe pipe;
|
| - InterfaceRequest<ServiceProvider> request =
|
| - MakeRequest<ServiceProvider>(pipe.handle1.Pass());
|
| - shell_->ConnectToApplication(application_url, request.Pass());
|
| - return pipe.handle0.Pass().release();
|
| +void JSApp::ConnectToApplication(const std::string& application_url,
|
| + ScopedMessagePipeHandle service_provider) {
|
| + shell_->ConnectToApplication(
|
| + application_url, MakeRequest<ServiceProvider>(service_provider.Pass()));
|
| }
|
|
|
| -MessagePipeHandle JSApp::RequestorMessagePipeHandle() {
|
| - return requestor_handle_.get();
|
| +void JSApp::CallAppInstanceMethod(
|
| + const std::string& name, int argc, v8::Handle<v8::Value> argv[]) {
|
| + v8::Isolate* isolate = isolate_holder_.isolate();
|
| + v8::Local<v8::Object> app =
|
| + v8::Local<v8::Object>::New(isolate, app_instance_);
|
| + v8::Handle<v8::Value> key = gin::StringToV8(isolate, name);
|
| + v8::Handle<v8::Value> value = app->Get(key);
|
| + if (!value->IsFunction())
|
| + return;
|
| + v8::Handle<v8::Function> app_method;
|
| + CHECK(gin::ConvertFromV8(isolate, value, &app_method));
|
| + shell_runner_->Call(app_method, app, argc, argv);
|
| +}
|
| +
|
| +void JSApp::Initialize(Array<String> app_args) {
|
| + gin::Runner::Scope scope(shell_runner_.get());
|
| + v8::Isolate* isolate = isolate_holder_.isolate();
|
| + v8::Handle<v8::Value> argv[] = {
|
| + gin::ConvertToV8(isolate, app_args.To<std::vector<std::string>>()),
|
| + };
|
| + CallAppInstanceMethod("initialize", 1, argv);
|
| }
|
|
|
| void JSApp::AcceptConnection(const String& requestor_url,
|
| ServiceProviderPtr provider) {
|
| - requestor_handle_ = provider.PassMessagePipe();
|
| -
|
| - isolate_holder_.AddRunMicrotasksObserver();
|
| - shell_runner_.reset(
|
| - new gin::ShellRunner(&runner_delegate, isolate_holder_.isolate()));
|
| gin::Runner::Scope scope(shell_runner_.get());
|
| - shell_runner_->Run(source_.c_str(), file_name_.c_str());
|
| + v8::Isolate* isolate = isolate_holder_.isolate();
|
| + v8::Handle<v8::Value> argv[] = {
|
| + gin::ConvertToV8(isolate, requestor_url.To<std::string>()),
|
| + gin::ConvertToV8(isolate, provider.PassMessagePipe().get()),
|
| + };
|
| + CallAppInstanceMethod("acceptConnection", arraysize(argv), argv);
|
| }
|
|
|
| -void JSApp::Initialize(Array<String> args) {
|
| +void JSApp::Quit() {
|
| + isolate_holder_.RemoveRunMicrotasksObserver();
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE, base::Bind(&JSApp::QuitInternal, base::Unretained(this)));
|
| }
|
|
|
| void JSApp::QuitInternal() {
|
| @@ -68,3 +120,4 @@ void JSApp::QuitInternal() {
|
|
|
| } // namespace js
|
| } // namespace mojo
|
| +
|
|
|