Index: mojo/apps/js/main.cc |
diff --git a/mojo/apps/js/main.cc b/mojo/apps/js/main.cc |
index b5d4486736d60b2666b176880310c3922d8e8146..b4512884dd86b872a75734542dc27053d32006b5 100644 |
--- a/mojo/apps/js/main.cc |
+++ b/mojo/apps/js/main.cc |
@@ -1,41 +1,149 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <stdio.h> |
+ |
+#include "base/at_exit.h" |
+#include "base/bind.h" |
+#include "base/file_util.h" |
+#include "base/i18n/icu_util.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/path_service.h" |
+#include "gin/converter.h" |
+#include "gin/modules/console.h" |
+#include "gin/modules/module_registry.h" |
+#include "gin/modules/module_runner_delegate.h" |
#include "gin/public/isolate_holder.h" |
-#include "mojo/apps/js/mojo_runner_delegate.h" |
-#include "mojo/public/cpp/system/core.h" |
-#include "mojo/public/cpp/system/macros.h" |
- |
-#if defined(WIN32) |
-#if !defined(CDECL) |
-#define CDECL __cdecl |
-#endif |
-#define MOJO_APPS_JS_EXPORT __declspec(dllexport) |
-#else |
-#define CDECL |
-#define MOJO_APPS_JS_EXPORT __attribute__((visibility("default"))) |
-#endif |
+#include "gin/test/file_runner.h" |
+#include "gin/try_catch.h" |
+#include "mojo/apps/js/bindings/gl/module.h" |
+#include "mojo/apps/js/bindings/threading.h" |
+#include "mojo/bindings/js/core.h" |
+#include "mojo/bindings/js/handle.h" |
+#include "mojo/bindings/js/support.h" |
+#include "mojo/common/data_pipe_utils.h" |
+#include "mojo/public/c/system/main.h" |
+#include "mojo/public/cpp/application/application_delegate.h" |
+#include "mojo/public/cpp/application/application_impl.h" |
+#include "mojo/public/cpp/application/application_runner_chromium.h" |
+#include "mojo/public/cpp/application/interface_factory_impl.h" |
+#include "mojo/services/public/interfaces/content_handler/content_handler.mojom.h" |
namespace mojo { |
namespace apps { |
+namespace { |
+ |
+std::vector<base::FilePath> GetModuleSearchPaths() { |
+ std::vector<base::FilePath> module_base(1); |
+ CHECK(base::GetCurrentDirectory(&module_base[0])); |
+ return module_base; |
+} |
+ |
+void Run( |
+ base::WeakPtr<gin::Runner> runner, |
+ const std::string& code, |
+ const std::string& path) { |
+ if (!runner) |
+ return; |
+ gin::Runner::Scope scope(runner.get()); |
+ runner->Run(code.c_str(), path.c_str()); |
+} |
+ |
+class MojoRunnerDelegate : public gin::ModuleRunnerDelegate { |
+ public: |
+ MojoRunnerDelegate() : gin::ModuleRunnerDelegate(GetModuleSearchPaths()) { |
+ AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule); |
+ } |
+ |
+ virtual void UnhandledException(gin::ShellRunner* runner, |
+ gin::TryCatch& try_catch) OVERRIDE { |
+ gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch); |
+ LOG(ERROR) << try_catch.GetStackTrace(); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(MojoRunnerDelegate); |
+}; |
+ |
+} // namespace |
+ |
-void Start(MojoHandle pipe, const std::string& module) { |
- base::MessageLoop loop; |
+class ContentHandlerApp; |
- gin::IsolateHolder instance(gin::IsolateHolder::kStrictMode); |
- MojoRunnerDelegate delegate; |
- gin::ShellRunner runner(&delegate, instance.isolate()); |
- delegate.Start(&runner, pipe, module); |
+class ContentHandlerImpl : public InterfaceImpl<ContentHandler> { |
+ public: |
+ explicit ContentHandlerImpl(ContentHandlerApp* content_handler_app) |
+ : content_handler_app_(content_handler_app) { |
+ } |
+ virtual ~ContentHandlerImpl() {} |
- base::MessageLoop::current()->Run(); |
+ private: |
+ virtual void OnConnect(const mojo::String& url, |
+ URLResponsePtr content, |
+ ServiceProviderPtr service_provider) MOJO_OVERRIDE; |
+ |
+ ContentHandlerApp* content_handler_app_; |
+}; |
+ |
+// TODO(hansmuller); does this class define the right lifetime |
+// for its gin members? |
+class ContentHandlerApp : public ApplicationDelegate { |
Aaron Boodman
2014/08/25 17:25:37
Nit: the naming of this kind of confused me... I t
hansmuller
2014/08/26 23:39:12
I've renamed the class JSApp. It bugs me that the
|
+ public: |
+ ContentHandlerApp() |
+ : isolate_holder_(gin::IsolateHolder::kStrictMode), |
+ content_handler_factory_(this) { |
+ base::i18n::InitializeICU(); |
+ shell_runner_.reset( |
+ new gin::ShellRunner(&runner_delegate_, isolate_holder_.isolate())); |
+ } |
+ |
+ virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) |
+ MOJO_OVERRIDE { |
+ connection->AddService(&content_handler_factory_); |
+ return true; |
+ } |
+ |
+ void LoadMainJSModule(const std::string& module, const std::string& path) { |
+ // TODO(hansmuller): is this the right place to put the stack |
+ // frame capturer? |
+ { |
+ gin::Runner::Scope scope(shell_runner_.get()); |
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); |
+ } |
+ |
+ base::MessageLoop::current()->PostTask(FROM_HERE, |
darin (slow to review)
2014/08/26 05:23:22
why do you need to use PostTask here?
hansmuller
2014/08/26 23:39:12
It's not necessary to use PostTask. I've removed i
|
+ base::Bind(apps::Run, shell_runner_->GetWeakPtr(), module, path)); |
+ } |
+ |
+ private: |
+ gin::IsolateHolder isolate_holder_; |
+ scoped_ptr<gin::ShellRunner> shell_runner_; |
+ apps::MojoRunnerDelegate runner_delegate_; |
+ InterfaceFactoryImplWithContext< |
+ ContentHandlerImpl, ContentHandlerApp> content_handler_factory_; |
+}; |
+ |
+void ContentHandlerImpl::OnConnect( |
+ const mojo::String& url, |
+ URLResponsePtr content, |
+ ServiceProviderPtr service_provider) { |
+ |
+ std::string path(url.To<std::string>()); |
+ std::string module; |
+ // TODO(hansmuller): is this the right place to block and load the |
Aaron Boodman
2014/08/25 17:25:37
I agree with your comment that it would be better
hansmuller
2014/08/26 23:39:12
OK, I'll add async loading of JS modules in a subs
|
+ // initial JS module? |
+ // TODO(hansmuller): check the return value and fail gracefully. |
+ common::BlockingCopyToString(content->body.Pass(), &module); |
+ |
+ content_handler_app_->LoadMainJSModule(module, path); |
Aaron Boodman
2014/08/25 17:25:37
Remember that OnConnect() can get called multiple
hansmuller
2014/08/26 23:39:12
It looks like I should to wait for your CL (https:
Aaron Boodman
2014/08/27 05:55:53
I think that you could structure the code to have
|
} |
} // namespace apps |
} // namespace mojo |
-extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) { |
- mojo::apps::Start(pipe, "mojo/apps/js/main"); |
- return MOJO_RESULT_OK; |
+MojoResult MojoMain(MojoHandle shell_handle) { |
+ mojo::ApplicationRunnerChromium runner(new mojo::apps::ContentHandlerApp()); |
+ return runner.Run(shell_handle); |
} |
+ |