Chromium Code Reviews| Index: services/js/js_app.cc |
| diff --git a/services/js/js_app.cc b/services/js/js_app.cc |
| index 0e31bbf3af8ce1339d99604de8879ea4a2ccbfed..9c1816b5fc2d6e3d96784738a7afdec56e52b13d 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; |
| + DCHECK(common::BlockingCopyToString(response->body.Pass(), &source)); |
|
abarth-chromium
2014/11/24 23:47:24
s/DCHECK/CHECK/
If you use DCHECK, this call will
hansmuller
2014/11/25 00:31:55
Done.
|
| - 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::LoadModuleCallback on_app_loaded = |
| + base::Bind(&JSApp::OnAppLoaded, base::Unretained(this), url); |
|
abarth-chromium
2014/11/24 23:47:24
I'd just inline this into the one place its used.
hansmuller
2014/11/25 00:31:55
Done.
|
| + |
| + gin::ModuleRegistry* registry = |
| + gin::ModuleRegistry::From(shell_runner_->GetContextHolder()->context()); |
| + registry->LoadModule(isolate, kMainModuleName, on_app_loaded); |
| } |
| 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( |
| + 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); |
| + if (!app->Has(key)) // Method doesn't exist. |
| + return; |
| + v8::Handle<v8::Value> value = app->Get(key); |
|
abarth-chromium
2014/11/24 23:47:24
You shouldn't separate Has and Get. Instead, you
hansmuller
2014/11/25 00:31:55
Good point. I'm applying IsFunction() to the resul
|
| + v8::Handle<v8::Function> app_method; |
| + CHECK(gin::ConvertFromV8(isolate, value, &app_method)); |
|
abarth-chromium
2014/11/24 23:47:24
Do we really want to crash if someone stores a non
hansmuller
2014/11/25 00:31:55
Since I'm allowing the function to not be defined
|
| + 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 |
| + |