Merge remote-tracking branch 'refs/remotes/electron/master'

This commit is contained in:
Plusb Preco 2016-05-02 10:18:25 +09:00
commit a60bb9031a
207 changed files with 3518 additions and 983 deletions

View file

@ -56,6 +56,7 @@ npm install electron-prebuilt --save-dev
- [스페인어](https://github.com/electron/electron/tree/master/docs-translations/es) - [스페인어](https://github.com/electron/electron/tree/master/docs-translations/es)
- [중국어 간체](https://github.com/electron/electron/tree/master/docs-translations/zh-CN) - [중국어 간체](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
- [중국어 번체](https://github.com/electron/electron/tree/master/docs-translations/zh-TW) - [중국어 번체](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
- [터키의](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
- [우크라이나어](https://github.com/electron/electron/tree/master/docs-translations/uk-UA) - [우크라이나어](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
- [러시아어](https://github.com/electron/electron/tree/master/docs-translations/ru-RU) - [러시아어](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
- [프랑스어](https://github.com/electron/electron/tree/master/docs-translations/fr-FR) - [프랑스어](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)

View file

@ -53,6 +53,7 @@ contains documents describing how to build and contribute to Electron.
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es) - [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN) - [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW) - [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA) - [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU) - [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR) - [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)

View file

@ -15,15 +15,17 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/login_handler.h" #include "atom/browser/login_handler.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/environment.h" #include "base/environment.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "brightray/browser/brightray_paths.h" #include "brightray/browser/brightray_paths.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
@ -39,7 +41,6 @@
#if defined(OS_WIN) #if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "ui/base/win/shell.h"
#endif #endif
using atom::Browser; using atom::Browser;
@ -157,12 +158,46 @@ void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
login_handler->CancelAuth(); login_handler->CancelAuth();
} }
#if defined(USE_NSS_CERTS)
int ImportIntoCertStore(
CertificateManagerModel* model,
const base::DictionaryValue& options) {
std::string file_data, cert_path;
base::string16 password;
net::CertificateList imported_certs;
int rv = -1;
options.GetString("certificate", &cert_path);
options.GetString("password", &password);
if (!cert_path.empty()) {
if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) {
auto module = model->cert_db()->GetPublicModule();
rv = model->ImportFromPKCS12(module,
file_data,
password,
true,
&imported_certs);
if (imported_certs.size() > 1) {
auto it = imported_certs.begin();
++it; // skip first which would be the client certificate.
for (; it != imported_certs.end(); ++it)
rv &= model->SetCertTrust(it->get(),
net::CA_CERT,
net::NSSCertDatabase::TRUSTED_SSL);
}
}
}
return rv;
}
#endif
} // namespace } // namespace
App::App() { App::App(v8::Isolate* isolate) {
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this); static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this);
Browser::Get()->AddObserver(this); Browser::Get()->AddObserver(this);
content::GpuDataManager::GetInstance()->AddObserver(this); content::GpuDataManager::GetInstance()->AddObserver(this);
Init(isolate);
} }
App::~App() { App::~App() {
@ -296,12 +331,6 @@ void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
Emit("gpu-process-crashed"); Emit("gpu-process-crashed");
} }
#if defined(OS_MACOSX)
void App::OnPlatformThemeChanged() {
Emit("platform-theme-changed");
}
#endif
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
bool succeed = false; bool succeed = false;
base::FilePath path; base::FilePath path;
@ -316,10 +345,15 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
void App::SetPath(mate::Arguments* args, void App::SetPath(mate::Arguments* args,
const std::string& name, const std::string& name,
const base::FilePath& path) { const base::FilePath& path) {
if (!path.IsAbsolute()) {
args->ThrowError("path must be absolute");
return;
}
bool succeed = false; bool succeed = false;
int key = GetPathConstant(name); int key = GetPathConstant(name);
if (key >= 0) if (key >= 0)
succeed = PathService::Override(key, path); succeed = PathService::OverrideAndCreateIfNeeded(key, path, true, false);
if (!succeed) if (!succeed)
args->ThrowError("Failed to set path"); args->ThrowError("Failed to set path");
} }
@ -341,12 +375,6 @@ std::string App::GetLocale() {
return l10n_util::GetApplicationLocale(""); return l10n_util::GetApplicationLocale("");
} }
#if defined(OS_WIN)
bool App::IsAeroGlassEnabled() {
return ui::win::IsAeroGlassEnabled();
}
#endif
bool App::MakeSingleInstance( bool App::MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback) { const ProcessSingleton::NotificationCallback& callback) {
if (process_singleton_.get()) if (process_singleton_.get())
@ -369,10 +397,46 @@ bool App::MakeSingleInstance(
} }
} }
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( #if defined(USE_NSS_CERTS)
v8::Isolate* isolate) { void App::ImportCertificate(
const base::DictionaryValue& options,
const net::CompletionCallback& callback) {
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
if (!certificate_manager_model_) {
scoped_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
CertificateManagerModel::Create(browser_context,
base::Bind(&App::OnCertificateManagerModelCreated,
base::Unretained(this),
base::Passed(&copy),
callback));
return;
}
int rv = ImportIntoCertStore(certificate_manager_model_.get(), options);
callback.Run(rv);
}
void App::OnCertificateManagerModelCreated(
scoped_ptr<base::DictionaryValue> options,
const net::CompletionCallback& callback,
scoped_ptr<CertificateManagerModel> model) {
certificate_manager_model_ = std::move(model);
int rv = ImportIntoCertStore(certificate_manager_model_.get(),
*(options.get()));
callback.Run(rv);
}
#endif
// static
mate::Handle<App> App::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new App(isolate));
}
// static
void App::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
auto browser = base::Unretained(Browser::Get()); auto browser = base::Unretained(Browser::Get());
return mate::ObjectTemplateBuilder(isolate) mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("quit", base::Bind(&Browser::Quit, browser)) .SetMethod("quit", base::Bind(&Browser::Quit, browser))
.SetMethod("exit", base::Bind(&Browser::Exit, browser)) .SetMethod("exit", base::Bind(&Browser::Exit, browser))
.SetMethod("focus", base::Bind(&Browser::Focus, browser)) .SetMethod("focus", base::Bind(&Browser::Focus, browser))
@ -387,6 +451,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
base::Bind(&Browser::ClearRecentDocuments, browser)) base::Bind(&Browser::ClearRecentDocuments, browser))
.SetMethod("setAppUserModelId", .SetMethod("setAppUserModelId",
base::Bind(&Browser::SetAppUserModelID, browser)) base::Bind(&Browser::SetAppUserModelID, browser))
.SetMethod("isDefaultProtocolClient",
base::Bind(&Browser::IsDefaultProtocolClient, browser))
.SetMethod("setAsDefaultProtocolClient", .SetMethod("setAsDefaultProtocolClient",
base::Bind(&Browser::SetAsDefaultProtocolClient, browser)) base::Bind(&Browser::SetAsDefaultProtocolClient, browser))
.SetMethod("removeAsDefaultProtocolClient", .SetMethod("removeAsDefaultProtocolClient",
@ -394,13 +460,10 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
.SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("hide", base::Bind(&Browser::Hide, browser))
.SetMethod("show", base::Bind(&Browser::Show, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser))
.SetMethod("isDarkMode",
base::Bind(&Browser::IsDarkMode, browser))
#endif #endif
#if defined(OS_WIN) #if defined(OS_WIN)
.SetMethod("setUserTasks", .SetMethod("setUserTasks",
base::Bind(&Browser::SetUserTasks, browser)) base::Bind(&Browser::SetUserTasks, browser))
.SetMethod("isAeroGlassEnabled", &App::IsAeroGlassEnabled)
#endif #endif
.SetMethod("setPath", &App::SetPath) .SetMethod("setPath", &App::SetPath)
.SetMethod("getPath", &App::GetPath) .SetMethod("getPath", &App::GetPath)
@ -408,14 +471,12 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
.SetMethod("allowNTLMCredentialsForAllDomains", .SetMethod("allowNTLMCredentialsForAllDomains",
&App::AllowNTLMCredentialsForAllDomains) &App::AllowNTLMCredentialsForAllDomains)
.SetMethod("getLocale", &App::GetLocale) .SetMethod("getLocale", &App::GetLocale)
#if defined(USE_NSS_CERTS)
.SetMethod("importCertificate", &App::ImportCertificate)
#endif
.SetMethod("makeSingleInstance", &App::MakeSingleInstance); .SetMethod("makeSingleInstance", &App::MakeSingleInstance);
} }
// static
mate::Handle<App> App::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new App);
}
} // namespace api } // namespace api
} // namespace atom } // namespace atom
@ -427,7 +488,6 @@ void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
auto command_line = base::CommandLine::ForCurrentProcess(); auto command_line = base::CommandLine::ForCurrentProcess();
if (switch_string == atom::switches::kPpapiFlashPath || if (switch_string == atom::switches::kPpapiFlashPath ||
switch_string == atom::switches::kClientCertificate ||
switch_string == switches::kLogNetLog) { switch_string == switches::kLogNetLog) {
base::FilePath path; base::FilePath path;
args->GetNext(&path); args->GetNext(&path);

View file

@ -14,6 +14,11 @@
#include "chrome/browser/process_singleton.h" #include "chrome/browser/process_singleton.h"
#include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/browser/gpu_data_manager_observer.h"
#include "native_mate/handle.h" #include "native_mate/handle.h"
#include "net/base/completion_callback.h"
#if defined(USE_NSS_CERTS)
#include "chrome/browser/certificate_manager_model.h"
#endif
namespace base { namespace base {
class FilePath; class FilePath;
@ -28,12 +33,15 @@ namespace atom {
namespace api { namespace api {
class App : public AtomBrowserClient::Delegate, class App : public AtomBrowserClient::Delegate,
public mate::EventEmitter, public mate::EventEmitter<App>,
public BrowserObserver, public BrowserObserver,
public content::GpuDataManagerObserver { public content::GpuDataManagerObserver {
public: public:
static mate::Handle<App> Create(v8::Isolate* isolate); static mate::Handle<App> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
// Called when window with disposition needs to be created. // Called when window with disposition needs to be created.
void OnCreateWindow(const GURL& target_url, void OnCreateWindow(const GURL& target_url,
const std::string& frame_name, const std::string& frame_name,
@ -41,9 +49,16 @@ class App : public AtomBrowserClient::Delegate,
int render_process_id, int render_process_id,
int render_frame_id); int render_frame_id);
#if defined(USE_NSS_CERTS)
void OnCertificateManagerModelCreated(
scoped_ptr<base::DictionaryValue> options,
const net::CompletionCallback& callback,
scoped_ptr<CertificateManagerModel> model);
#endif
protected: protected:
App(); explicit App(v8::Isolate* isolate);
virtual ~App(); ~App() override;
// BrowserObserver: // BrowserObserver:
void OnBeforeQuit(bool* prevent_default) override; void OnBeforeQuit(bool* prevent_default) override;
@ -77,14 +92,6 @@ class App : public AtomBrowserClient::Delegate,
// content::GpuDataManagerObserver: // content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
#if defined(OS_MACOSX)
void OnPlatformThemeChanged() override;
#endif
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private: private:
// Get/Set the pre-defined path in PathService. // Get/Set the pre-defined path in PathService.
base::FilePath GetPath(mate::Arguments* args, const std::string& name); base::FilePath GetPath(mate::Arguments* args, const std::string& name);
@ -98,12 +105,17 @@ class App : public AtomBrowserClient::Delegate,
const ProcessSingleton::NotificationCallback& callback); const ProcessSingleton::NotificationCallback& callback);
std::string GetLocale(); std::string GetLocale();
#if defined(OS_WIN) #if defined(USE_NSS_CERTS)
bool IsAeroGlassEnabled(); void ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback);
#endif #endif
scoped_ptr<ProcessSingleton> process_singleton_; scoped_ptr<ProcessSingleton> process_singleton_;
#if defined(USE_NSS_CERTS)
scoped_ptr<CertificateManagerModel> certificate_manager_model_;
#endif
DISALLOW_COPY_AND_ASSIGN(App); DISALLOW_COPY_AND_ASSIGN(App);
}; };

View file

@ -34,8 +34,9 @@ namespace atom {
namespace api { namespace api {
AutoUpdater::AutoUpdater() { AutoUpdater::AutoUpdater(v8::Isolate* isolate) {
auto_updater::AutoUpdater::SetDelegate(this); auto_updater::AutoUpdater::SetDelegate(this);
Init(isolate);
} }
AutoUpdater::~AutoUpdater() { AutoUpdater::~AutoUpdater() {
@ -78,14 +79,6 @@ void AutoUpdater::OnWindowAllClosed() {
QuitAndInstall(); QuitAndInstall();
} }
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
}
void AutoUpdater::QuitAndInstall() { void AutoUpdater::QuitAndInstall() {
// If we don't have any window then quitAndInstall immediately. // If we don't have any window then quitAndInstall immediately.
WindowList* window_list = WindowList::GetInstance(); WindowList* window_list = WindowList::GetInstance();
@ -102,7 +95,16 @@ void AutoUpdater::QuitAndInstall() {
// static // static
mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) { mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new AutoUpdater); return mate::CreateHandle(isolate, new AutoUpdater(isolate));
}
// static
void AutoUpdater::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
} }
} // namespace api } // namespace api

View file

@ -16,15 +16,18 @@ namespace atom {
namespace api { namespace api {
class AutoUpdater : public mate::EventEmitter, class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
public auto_updater::Delegate, public auto_updater::Delegate,
public WindowListObserver { public WindowListObserver {
public: public:
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate); static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
AutoUpdater(); explicit AutoUpdater(v8::Isolate* isolate);
virtual ~AutoUpdater(); ~AutoUpdater() override;
// Delegate implementations. // Delegate implementations.
void OnError(const std::string& error) override; void OnError(const std::string& error) override;
@ -39,10 +42,6 @@ class AutoUpdater : public mate::EventEmitter,
// WindowListObserver: // WindowListObserver:
void OnWindowAllClosed() override; void OnWindowAllClosed() override;
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private: private:
void QuitAndInstall(); void QuitAndInstall();

View file

@ -186,8 +186,10 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
} // namespace } // namespace
Cookies::Cookies(content::BrowserContext* browser_context) Cookies::Cookies(v8::Isolate* isolate,
: request_context_getter_(browser_context->GetRequestContext()) { content::BrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()) {
Init(isolate);
} }
Cookies::~Cookies() { Cookies::~Cookies() {
@ -223,7 +225,7 @@ void Cookies::Set(const base::DictionaryValue& details,
mate::Handle<Cookies> Cookies::Create( mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate, v8::Isolate* isolate,
content::BrowserContext* browser_context) { content::BrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(browser_context)); return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
} }
// static // static

View file

@ -46,8 +46,8 @@ class Cookies : public mate::TrackableObject<Cookies> {
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Cookies(content::BrowserContext* browser_context); Cookies(v8::Isolate* isolate, content::BrowserContext* browser_context);
~Cookies(); ~Cookies() override;
void Get(const base::DictionaryValue& filter, const GetCallback& callback); void Get(const base::DictionaryValue& filter, const GetCallback& callback);
void Remove(const GURL& url, const std::string& name, void Remove(const GURL& url, const std::string& name,

View file

@ -31,9 +31,10 @@ WrapDebuggerCallback g_wrap_debugger;
} // namespace } // namespace
Debugger::Debugger(content::WebContents* web_contents) Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
: web_contents_(web_contents), : web_contents_(web_contents),
previous_request_id_(0) { previous_request_id_(0) {
Init(isolate);
} }
Debugger::~Debugger() { Debugger::~Debugger() {
@ -150,7 +151,8 @@ void Debugger::SendCommand(mate::Arguments* args) {
mate::Handle<Debugger> Debugger::Create( mate::Handle<Debugger> Debugger::Create(
v8::Isolate* isolate, v8::Isolate* isolate,
content::WebContents* web_contents) { content::WebContents* web_contents) {
auto handle = mate::CreateHandle(isolate, new Debugger(web_contents)); auto handle = mate::CreateHandle(
isolate, new Debugger(isolate, web_contents));
g_wrap_debugger.Run(handle.ToV8()); g_wrap_debugger.Run(handle.ToV8());
return handle; return handle;
} }
@ -165,16 +167,8 @@ void Debugger::BuildPrototype(v8::Isolate* isolate,
.SetMethod("sendCommand", &Debugger::SendCommand); .SetMethod("sendCommand", &Debugger::SendCommand);
} }
void ClearWrapDebugger() {
g_wrap_debugger.Reset();
}
void SetWrapDebugger(const WrapDebuggerCallback& callback) { void SetWrapDebugger(const WrapDebuggerCallback& callback) {
g_wrap_debugger = callback; g_wrap_debugger = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapDebugger));
} }
} // namespace api } // namespace api

View file

@ -42,8 +42,8 @@ class Debugger: public mate::TrackableObject<Debugger>,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Debugger(content::WebContents* web_contents); Debugger(v8::Isolate* isolate, content::WebContents* web_contents);
~Debugger(); ~Debugger() override;
// content::DevToolsAgentHostClient: // content::DevToolsAgentHostClient:
void AgentHostClosed(content::DevToolsAgentHost* agent_host, void AgentHostClosed(content::DevToolsAgentHost* agent_host,

View file

@ -38,7 +38,8 @@ namespace atom {
namespace api { namespace api {
DesktopCapturer::DesktopCapturer() { DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
Init(isolate);
} }
DesktopCapturer::~DesktopCapturer() { DesktopCapturer::~DesktopCapturer() {
@ -88,19 +89,19 @@ void DesktopCapturer::OnSourceThumbnailChanged(int index) {
bool DesktopCapturer::OnRefreshFinished() { bool DesktopCapturer::OnRefreshFinished() {
Emit("finished", media_list_->GetSources()); Emit("finished", media_list_->GetSources());
media_list_.reset();
return false; return false;
} }
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
}
// static // static
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) { mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new DesktopCapturer); return mate::CreateHandle(isolate, new DesktopCapturer(isolate));
}
// static
void DesktopCapturer::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
} }
} // namespace api } // namespace api

View file

@ -14,18 +14,21 @@ namespace atom {
namespace api { namespace api {
class DesktopCapturer: public mate::EventEmitter, class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
public DesktopMediaListObserver { public DesktopMediaListObserver {
public: public:
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate); static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
void StartHandling(bool capture_window, void StartHandling(bool capture_window,
bool capture_screen, bool capture_screen,
const gfx::Size& thumbnail_size); const gfx::Size& thumbnail_size);
protected: protected:
DesktopCapturer(); explicit DesktopCapturer(v8::Isolate* isolate);
~DesktopCapturer(); ~DesktopCapturer() override;
// DesktopMediaListObserver overrides. // DesktopMediaListObserver overrides.
void OnSourceAdded(int index) override; void OnSourceAdded(int index) override;
@ -36,10 +39,6 @@ class DesktopCapturer: public mate::EventEmitter,
bool OnRefreshFinished() override; bool OnRefreshFinished() override;
private: private:
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
scoped_ptr<DesktopMediaList> media_list_; scoped_ptr<DesktopMediaList> media_list_;
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer); DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);

View file

@ -57,9 +57,11 @@ std::map<uint32_t, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
} // namespace } // namespace
DownloadItem::DownloadItem(content::DownloadItem* download_item) DownloadItem::DownloadItem(v8::Isolate* isolate,
content::DownloadItem* download_item)
: download_item_(download_item) { : download_item_(download_item) {
download_item_->AddObserver(this); download_item_->AddObserver(this);
Init(isolate);
AttachAsUserData(download_item); AttachAsUserData(download_item);
} }
@ -173,7 +175,7 @@ mate::Handle<DownloadItem> DownloadItem::Create(
if (existing) if (existing)
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing)); return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
auto handle = mate::CreateHandle(isolate, new DownloadItem(item)); auto handle = mate::CreateHandle(isolate, new DownloadItem(isolate, item));
g_wrap_download_item.Run(handle.ToV8()); g_wrap_download_item.Run(handle.ToV8());
// Reference this object in case it got garbage collected. // Reference this object in case it got garbage collected.
@ -182,16 +184,8 @@ mate::Handle<DownloadItem> DownloadItem::Create(
return handle; return handle;
} }
void ClearWrapDownloadItem() {
g_wrap_download_item.Reset();
}
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) { void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
g_wrap_download_item = callback; g_wrap_download_item = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapDownloadItem));
} }
} // namespace api } // namespace api

View file

@ -23,7 +23,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate, static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
content::DownloadItem* item); content::DownloadItem* item);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
@ -41,7 +40,7 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
base::FilePath GetSavePath() const; base::FilePath GetSavePath() const;
protected: protected:
explicit DownloadItem(content::DownloadItem* download_item); DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item);
~DownloadItem(); ~DownloadItem();
// Override content::DownloadItem::Observer methods // Override content::DownloadItem::Observer methods

View file

@ -19,7 +19,8 @@ namespace atom {
namespace api { namespace api {
GlobalShortcut::GlobalShortcut() { GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) {
Init(isolate);
} }
GlobalShortcut::~GlobalShortcut() { GlobalShortcut::~GlobalShortcut() {
@ -66,20 +67,21 @@ void GlobalShortcut::UnregisterAll() {
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this); GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
} }
mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder( // static
v8::Isolate* isolate) { mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate) return mate::CreateHandle(isolate, new GlobalShortcut(isolate));
}
// static
void GlobalShortcut::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("register", &GlobalShortcut::Register) .SetMethod("register", &GlobalShortcut::Register)
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered) .SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
.SetMethod("unregister", &GlobalShortcut::Unregister) .SetMethod("unregister", &GlobalShortcut::Unregister)
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll); .SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
} }
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new GlobalShortcut);
}
} // namespace api } // namespace api
} // namespace atom } // namespace atom

View file

@ -23,13 +23,12 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
public: public:
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate); static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
protected: static void BuildPrototype(v8::Isolate* isolate,
GlobalShortcut(); v8::Local<v8::ObjectTemplate> prototype);
~GlobalShortcut() override;
// mate::Wrappable implementations: protected:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder( explicit GlobalShortcut(v8::Isolate* isolate);
v8::Isolate* isolate) override; ~GlobalShortcut() override;
private: private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap; typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;

View file

@ -19,7 +19,7 @@ namespace atom {
namespace api { namespace api {
Menu::Menu() Menu::Menu(v8::Isolate* isolate)
: model_(new AtomMenuModel(this)), : model_(new AtomMenuModel(this)),
parent_(NULL) { parent_(NULL) {
} }
@ -28,7 +28,7 @@ Menu::~Menu() {
} }
void Menu::AfterInit(v8::Isolate* isolate) { void Menu::AfterInit(v8::Isolate* isolate) {
mate::Dictionary wrappable(isolate, GetWrapper(isolate)); mate::Dictionary wrappable(isolate, GetWrapper());
mate::Dictionary delegate; mate::Dictionary delegate;
if (!wrappable.Get("delegate", &delegate)) if (!wrappable.Get("delegate", &delegate))
return; return;

View file

@ -20,7 +20,7 @@ namespace api {
class Menu : public mate::TrackableObject<Menu>, class Menu : public mate::TrackableObject<Menu>,
public AtomMenuModel::Delegate { public AtomMenuModel::Delegate {
public: public:
static mate::Wrappable* Create(); static mate::WrappableBase* Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
@ -36,7 +36,7 @@ class Menu : public mate::TrackableObject<Menu>,
AtomMenuModel* model() const { return model_.get(); } AtomMenuModel* model() const { return model_.get(); }
protected: protected:
Menu(); explicit Menu(v8::Isolate* isolate);
~Menu() override; ~Menu() override;
// mate::Wrappable: // mate::Wrappable:

View file

@ -17,7 +17,7 @@ namespace api {
class MenuMac : public Menu { class MenuMac : public Menu {
protected: protected:
MenuMac(); explicit MenuMac(v8::Isolate* isolate);
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;

View file

@ -15,7 +15,7 @@ namespace atom {
namespace api { namespace api {
MenuMac::MenuMac() { MenuMac::MenuMac(v8::Isolate* isolate) : Menu(isolate) {
} }
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
@ -68,8 +68,8 @@ void Menu::SendActionToFirstResponder(const std::string& action) {
} }
// static // static
mate::Wrappable* Menu::Create() { mate::WrappableBase* Menu::Create(v8::Isolate* isolate) {
return new MenuMac(); return new MenuMac(isolate);
} }
} // namespace api } // namespace api

View file

@ -13,7 +13,7 @@ namespace atom {
namespace api { namespace api {
MenuViews::MenuViews() { MenuViews::MenuViews(v8::Isolate* isolate) : Menu(isolate) {
} }
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
@ -49,8 +49,8 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
} }
// static // static
mate::Wrappable* Menu::Create() { mate::WrappableBase* Menu::Create(v8::Isolate* isolate) {
return new MenuViews(); return new MenuViews(isolate);
} }
} // namespace api } // namespace api

View file

@ -14,7 +14,7 @@ namespace api {
class MenuViews : public Menu { class MenuViews : public Menu {
public: public:
MenuViews(); explicit MenuViews(v8::Isolate* isolate);
protected: protected:
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;

View file

@ -14,8 +14,9 @@ namespace atom {
namespace api { namespace api {
PowerMonitor::PowerMonitor() { PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
base::PowerMonitor::Get()->AddObserver(this); base::PowerMonitor::Get()->AddObserver(this);
Init(isolate);
} }
PowerMonitor::~PowerMonitor() { PowerMonitor::~PowerMonitor() {
@ -46,7 +47,13 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
return v8::Null(isolate); return v8::Null(isolate);
} }
return CreateHandle(isolate, new PowerMonitor).ToV8(); return mate::CreateHandle(isolate, new PowerMonitor(isolate)).ToV8();
}
// static
void PowerMonitor::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype);
} }
} // namespace api } // namespace api

View file

@ -19,8 +19,11 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
public: public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate); static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
PowerMonitor(); explicit PowerMonitor(v8::Isolate* isolate);
~PowerMonitor() override; ~PowerMonitor() override;
// base::PowerObserver implementations: // base::PowerObserver implementations:

View file

@ -37,9 +37,10 @@ namespace atom {
namespace api { namespace api {
PowerSaveBlocker::PowerSaveBlocker() PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
: current_blocker_type_( : current_blocker_type_(
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) { content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
Init(isolate);
} }
PowerSaveBlocker::~PowerSaveBlocker() { PowerSaveBlocker::~PowerSaveBlocker() {
@ -97,17 +98,18 @@ bool PowerSaveBlocker::IsStarted(int id) {
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end(); return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
} }
mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder( // static
v8::Isolate* isolate) { mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate) return mate::CreateHandle(isolate, new PowerSaveBlocker(isolate));
.SetMethod("start", &PowerSaveBlocker::Start)
.SetMethod("stop", &PowerSaveBlocker::Stop)
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
} }
// static // static
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) { void PowerSaveBlocker::BuildPrototype(
return CreateHandle(isolate, new PowerSaveBlocker); v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("start", &PowerSaveBlocker::Start)
.SetMethod("stop", &PowerSaveBlocker::Stop)
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
} }
} // namespace api } // namespace api

View file

@ -24,13 +24,12 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
public: public:
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate); static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
protected: static void BuildPrototype(v8::Isolate* isolate,
PowerSaveBlocker(); v8::Local<v8::ObjectTemplate> prototype);
~PowerSaveBlocker() override;
// mate::Wrappable implementations: protected:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder( explicit PowerSaveBlocker(v8::Isolate* isolate);
v8::Isolate* isolate) override; ~PowerSaveBlocker() override;
private: private:
void UpdatePowerSaveBlocker(); void UpdatePowerSaveBlocker();

View file

@ -22,37 +22,11 @@ namespace atom {
namespace api { namespace api {
Protocol::Protocol(AtomBrowserContext* browser_context) Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()), : request_context_getter_(browser_context->GetRequestContext()),
job_factory_(browser_context->job_factory()) { job_factory_(browser_context->job_factory()) {
CHECK(job_factory_); CHECK(job_factory_);
} Init(isolate);
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
.SetMethod("registerServiceWorkerSchemes",
&Protocol::RegisterServiceWorkerSchemes)
.SetMethod("registerStringProtocol",
&Protocol::RegisterProtocol<URLRequestStringJob>)
.SetMethod("registerBufferProtocol",
&Protocol::RegisterProtocol<URLRequestBufferJob>)
.SetMethod("registerFileProtocol",
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
.SetMethod("registerHttpProtocol",
&Protocol::RegisterProtocol<URLRequestFetchJob>)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
.SetMethod("interceptStringProtocol",
&Protocol::InterceptProtocol<URLRequestStringJob>)
.SetMethod("interceptBufferProtocol",
&Protocol::InterceptProtocol<URLRequestBufferJob>)
.SetMethod("interceptFileProtocol",
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
.SetMethod("interceptHttpProtocol",
&Protocol::InterceptProtocol<URLRequestFetchJob>)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
} }
void Protocol::RegisterStandardSchemes( void Protocol::RegisterStandardSchemes(
@ -150,7 +124,35 @@ std::string Protocol::ErrorCodeToString(ProtocolError error) {
// static // static
mate::Handle<Protocol> Protocol::Create( mate::Handle<Protocol> Protocol::Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context) { v8::Isolate* isolate, AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Protocol(browser_context)); return mate::CreateHandle(isolate, new Protocol(isolate, browser_context));
}
// static
void Protocol::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
.SetMethod("registerServiceWorkerSchemes",
&Protocol::RegisterServiceWorkerSchemes)
.SetMethod("registerStringProtocol",
&Protocol::RegisterProtocol<URLRequestStringJob>)
.SetMethod("registerBufferProtocol",
&Protocol::RegisterProtocol<URLRequestBufferJob>)
.SetMethod("registerFileProtocol",
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
.SetMethod("registerHttpProtocol",
&Protocol::RegisterProtocol<URLRequestFetchJob>)
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
.SetMethod("interceptStringProtocol",
&Protocol::InterceptProtocol<URLRequestStringJob>)
.SetMethod("interceptBufferProtocol",
&Protocol::InterceptProtocol<URLRequestBufferJob>)
.SetMethod("interceptFileProtocol",
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
.SetMethod("interceptHttpProtocol",
&Protocol::InterceptProtocol<URLRequestFetchJob>)
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
} }
} // namespace api } // namespace api

View file

@ -30,7 +30,7 @@ class AtomURLRequestJobFactory;
namespace api { namespace api {
class Protocol : public mate::Wrappable { class Protocol : public mate::Wrappable<Protocol> {
public: public:
using Handler = using Handler =
base::Callback<void(const net::URLRequest*, v8::Local<v8::Value>)>; base::Callback<void(const net::URLRequest*, v8::Local<v8::Value>)>;
@ -40,12 +40,11 @@ class Protocol : public mate::Wrappable {
static mate::Handle<Protocol> Create( static mate::Handle<Protocol> Create(
v8::Isolate* isolate, AtomBrowserContext* browser_context); v8::Isolate* isolate, AtomBrowserContext* browser_context);
protected: static void BuildPrototype(v8::Isolate* isolate,
explicit Protocol(AtomBrowserContext* browser_context); v8::Local<v8::ObjectTemplate> prototype);
// mate::Wrappable implementations: protected:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
v8::Isolate* isolate);
private: private:
// Possible errors. // Possible errors.

View file

@ -47,9 +47,10 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
} // namespace } // namespace
Screen::Screen(gfx::Screen* screen) : screen_(screen) { Screen::Screen(v8::Isolate* isolate, gfx::Screen* screen)
displays_ = screen_->GetAllDisplays(); : screen_(screen) {
screen_->AddObserver(this); screen_->AddObserver(this);
Init(isolate);
} }
Screen::~Screen() { Screen::~Screen() {
@ -65,7 +66,7 @@ gfx::Display Screen::GetPrimaryDisplay() {
} }
std::vector<gfx::Display> Screen::GetAllDisplays() { std::vector<gfx::Display> Screen::GetAllDisplays() {
return displays_; return screen_->GetAllDisplays();
} }
gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) { gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
@ -77,39 +78,18 @@ gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
} }
void Screen::OnDisplayAdded(const gfx::Display& new_display) { void Screen::OnDisplayAdded(const gfx::Display& new_display) {
displays_.push_back(new_display);
Emit("display-added", new_display); Emit("display-added", new_display);
} }
void Screen::OnDisplayRemoved(const gfx::Display& old_display) { void Screen::OnDisplayRemoved(const gfx::Display& old_display) {
auto iter = FindById(&displays_, old_display.id());
if (iter == displays_.end())
return;
displays_.erase(iter);
Emit("display-removed", old_display); Emit("display-removed", old_display);
} }
void Screen::OnDisplayMetricsChanged(const gfx::Display& display, void Screen::OnDisplayMetricsChanged(const gfx::Display& display,
uint32_t changed_metrics) { uint32_t changed_metrics) {
auto iter = FindById(&displays_, display.id());
if (iter == displays_.end())
return;
*iter = display;
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics)); Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
} }
mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
}
// static // static
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) { v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) { if (!Browser::Get()->is_ready()) {
@ -126,7 +106,18 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
return v8::Null(isolate); return v8::Null(isolate);
} }
return mate::CreateHandle(isolate, new Screen(screen)).ToV8(); return mate::CreateHandle(isolate, new Screen(isolate, screen)).ToV8();
}
// static
void Screen::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
} }
} // namespace api } // namespace api

View file

@ -21,14 +21,17 @@ namespace atom {
namespace api { namespace api {
class Screen : public mate::EventEmitter, class Screen : public mate::EventEmitter<Screen>,
public gfx::DisplayObserver { public gfx::DisplayObserver {
public: public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate); static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Screen(gfx::Screen* screen); Screen(v8::Isolate* isolate, gfx::Screen* screen);
virtual ~Screen(); ~Screen() override;
gfx::Point GetCursorScreenPoint(); gfx::Point GetCursorScreenPoint();
gfx::Display GetPrimaryDisplay(); gfx::Display GetPrimaryDisplay();
@ -42,13 +45,8 @@ class Screen : public mate::EventEmitter,
void OnDisplayMetricsChanged(const gfx::Display& display, void OnDisplayMetricsChanged(const gfx::Display& display,
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private: private:
gfx::Screen* screen_; gfx::Screen* screen_;
std::vector<gfx::Display> displays_;
DISALLOW_COPY_AND_ASSIGN(Screen); DISALLOW_COPY_AND_ASSIGN(Screen);
}; };

View file

@ -9,9 +9,7 @@
#include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/api/atom_api_download_item.h" #include "atom/browser/api/atom_api_download_item.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/atom_api_web_request.h"
#include "atom/browser/api/save_page_handler.h"
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_permission_manager.h" #include "atom/browser/atom_permission_manager.h"
@ -23,12 +21,13 @@
#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/guid.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h" #include "base/thread_task_runner_handle.h"
#include "brightray/browser/net/devtools_network_conditions.h" #include "brightray/browser/net/devtools_network_conditions.h"
#include "brightray/browser/net/devtools_network_controller.h" #include "brightray/browser/net/devtools_network_controller_handle.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
@ -287,13 +286,15 @@ void ClearHostResolverCacheInIO(
} // namespace } // namespace
Session::Session(AtomBrowserContext* browser_context) Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) { : devtools_network_emulation_client_id_(base::GenerateGUID()),
AttachAsUserData(browser_context); browser_context_(browser_context) {
// Observe DownloadManger to get download notifications. // Observe DownloadManger to get download notifications.
content::BrowserContext::GetDownloadManager(browser_context)-> content::BrowserContext::GetDownloadManager(browser_context)->
AddObserver(this); AddObserver(this);
Init(isolate);
AttachAsUserData(browser_context);
} }
Session::~Session() { Session::~Session() {
@ -303,13 +304,15 @@ Session::~Session() {
void Session::OnDownloadCreated(content::DownloadManager* manager, void Session::OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) { content::DownloadItem* item) {
auto web_contents = item->GetWebContents(); if (item->IsSavePackageDownload())
if (SavePageHandler::IsSavePageTypes(item->GetMimeType()))
return; return;
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
bool prevent_default = Emit( bool prevent_default = Emit(
"will-download", "will-download",
DownloadItem::Create(isolate(), item), DownloadItem::Create(isolate(), item),
api::WebContents::CreateFrom(isolate(), web_contents)); item->GetWebContents());
if (prevent_default) { if (prevent_default) {
item->Cancel(true); item->Cancel(true);
item->Remove(); item->Remove();
@ -381,25 +384,19 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
download_throughput, download_throughput,
upload_throughput)); upload_throughput));
} }
auto controller = browser_context_->GetDevToolsNetworkController();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, browser_context_->network_controller_handle()->SetNetworkState(
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState, devtools_network_emulation_client_id_, std::move(conditions));
base::Unretained(controller), browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
std::string(), devtools_network_emulation_client_id_);
base::Passed(&conditions)));
} }
void Session::DisableNetworkEmulation() { void Session::DisableNetworkEmulation() {
scoped_ptr<brightray::DevToolsNetworkConditions> conditions( scoped_ptr<brightray::DevToolsNetworkConditions> conditions;
new brightray::DevToolsNetworkConditions(false)); browser_context_->network_controller_handle()->SetNetworkState(
auto controller = browser_context_->GetDevToolsNetworkController(); devtools_network_emulation_client_id_, std::move(conditions));
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, std::string());
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
base::Unretained(controller),
std::string(),
base::Passed(&conditions)));
} }
void Session::SetCertVerifyProc(v8::Local<v8::Value> val, void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
@ -458,7 +455,8 @@ mate::Handle<Session> Session::CreateFrom(
if (existing) if (existing)
return mate::CreateHandle(isolate, static_cast<Session*>(existing)); return mate::CreateHandle(isolate, static_cast<Session*>(existing));
auto handle = mate::CreateHandle(isolate, new Session(browser_context)); auto handle = mate::CreateHandle(
isolate, new Session(isolate, browser_context));
g_wrap_session.Run(handle.ToV8()); g_wrap_session.Run(handle.ToV8());
return handle; return handle;
} }
@ -493,16 +491,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
.SetProperty("webRequest", &Session::WebRequest); .SetProperty("webRequest", &Session::WebRequest);
} }
void ClearWrapSession() {
g_wrap_session.Reset();
}
void SetWrapSession(const WrapSessionCallback& callback) { void SetWrapSession(const WrapSessionCallback& callback) {
g_wrap_session = callback; g_wrap_session = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapSession));
} }
} // namespace api } // namespace api

View file

@ -58,7 +58,7 @@ class Session: public mate::TrackableObject<Session>,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Session(AtomBrowserContext* browser_context); Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Session(); ~Session();
// content::DownloadManager::Observer: // content::DownloadManager::Observer:
@ -86,6 +86,9 @@ class Session: public mate::TrackableObject<Session>,
v8::Global<v8::Value> cookies_; v8::Global<v8::Value> cookies_;
v8::Global<v8::Value> web_request_; v8::Global<v8::Value> web_request_;
// The X-DevTools-Emulate-Network-Conditions-Client-Id.
std::string devtools_network_emulation_client_id_;
scoped_refptr<AtomBrowserContext> browser_context_; scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(Session); DISALLOW_COPY_AND_ASSIGN(Session);

View file

@ -0,0 +1,75 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_system_preferences.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/node_includes.h"
#include "native_mate/dictionary.h"
#if defined(OS_WIN)
#include "ui/base/win/shell.h"
#endif
namespace atom {
namespace api {
SystemPreferences::SystemPreferences(v8::Isolate* isolate) {
Init(isolate);
}
SystemPreferences::~SystemPreferences() {
}
#if defined(OS_WIN)
bool SystemPreferences::IsAeroGlassEnabled() {
return ui::win::IsAeroGlassEnabled();
}
#endif
#if !defined(OS_MACOSX)
bool SystemPreferences::IsDarkMode() {
return false;
}
#endif
// static
mate::Handle<SystemPreferences> SystemPreferences::Create(
v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new SystemPreferences(isolate));
}
// static
void SystemPreferences::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
#if defined(OS_WIN)
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
#elif defined(OS_MACOSX)
.SetMethod("subscribeNotification",
&SystemPreferences::SubscribeNotification)
.SetMethod("unsubscribeNotification",
&SystemPreferences::UnsubscribeNotification)
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
#endif
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("systemPreferences", atom::api::SystemPreferences::Create(isolate));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_system_preferences, Initialize);

View file

@ -0,0 +1,48 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
#define ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
#include <string>
#include "atom/browser/api/event_emitter.h"
#include "base/callback.h"
#include "native_mate/handle.h"
namespace atom {
namespace api {
class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
public:
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
#if defined(OS_WIN)
bool IsAeroGlassEnabled();
#elif defined(OS_MACOSX)
int SubscribeNotification(const std::string& name,
const base::Closure& callback);
void UnsubscribeNotification(int id);
v8::Local<v8::Value> GetUserDefault(const std::string& name,
const std::string& type);
#endif
bool IsDarkMode();
protected:
explicit SystemPreferences(v8::Isolate* isolate);
~SystemPreferences() override;
private:
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_

View file

@ -0,0 +1,83 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_system_preferences.h"
#include <map>
#import <Cocoa/Cocoa.h>
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/strings/sys_string_conversions.h"
#include "net/base/mac/url_conversions.h"
namespace atom {
namespace api {
namespace {
int g_next_id = 0;
// The map to convert |id| to |int|.
std::map<int, id> g_id_map;
} // namespace
int SystemPreferences::SubscribeNotification(const std::string& name,
const base::Closure& callback) {
int request_id = g_next_id++;
__block base::Closure copied_callback = callback;
g_id_map[request_id] = [[NSDistributedNotificationCenter defaultCenter]
addObserverForName:base::SysUTF8ToNSString(name)
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
copied_callback.Run();
}
];
return request_id;
}
void SystemPreferences::UnsubscribeNotification(int request_id) {
auto iter = g_id_map.find(request_id);
if (iter != g_id_map.end()) {
id observer = iter->second;
[[NSDistributedNotificationCenter defaultCenter] removeObserver:observer];
g_id_map.erase(iter);
}
}
v8::Local<v8::Value> SystemPreferences::GetUserDefault(
const std::string& name, const std::string& type) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString* key = base::SysUTF8ToNSString(name);
if (type == "string") {
return mate::StringToV8(
isolate(), base::SysNSStringToUTF8([defaults stringForKey:key]));
} else if (type == "boolean") {
return v8::Boolean::New(isolate(), [defaults boolForKey:key]);
} else if (type == "float") {
return v8::Number::New(isolate(), [defaults floatForKey:key]);
} else if (type == "integer") {
return v8::Integer::New(isolate(), [defaults integerForKey:key]);
} else if (type == "double") {
return v8::Number::New(isolate(), [defaults doubleForKey:key]);
} else if (type == "url") {
return mate::ConvertToV8(
isolate(), net::GURLWithNSURL([defaults URLForKey:key]));
} else {
return v8::Undefined(isolate());
}
}
bool SystemPreferences::IsDarkMode() {
NSString* mode = [[NSUserDefaults standardUserDefaults]
stringForKey:@"AppleInterfaceStyle"];
return [mode isEqualToString:@"Dark"];
}
} // namespace api
} // namespace atom

View file

@ -22,7 +22,7 @@ namespace atom {
namespace api { namespace api {
Tray::Tray(const gfx::Image& image) Tray::Tray(v8::Isolate* isolate, const gfx::Image& image)
: tray_icon_(TrayIcon::Create()) { : tray_icon_(TrayIcon::Create()) {
tray_icon_->SetImage(image); tray_icon_->SetImage(image);
tray_icon_->AddObserver(this); tray_icon_->AddObserver(this);
@ -32,13 +32,13 @@ Tray::~Tray() {
} }
// static // static
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { mate::WrappableBase* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
if (!Browser::Get()->is_ready()) { if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8( isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create Tray before app is ready"))); isolate, "Cannot create Tray before app is ready")));
return nullptr; return nullptr;
} }
return new Tray(image); return new Tray(isolate, image);
} }
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {

View file

@ -32,13 +32,14 @@ class Menu;
class Tray : public mate::TrackableObject<Tray>, class Tray : public mate::TrackableObject<Tray>,
public TrayIconObserver { public TrayIconObserver {
public: public:
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image); static mate::WrappableBase* New(
v8::Isolate* isolate, const gfx::Image& image);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit Tray(const gfx::Image& image); Tray(v8::Isolate* isolate, const gfx::Image& image);
~Tray() override; ~Tray() override;
// TrayIconObserver: // TrayIconObserver:

View file

@ -215,13 +215,17 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
} // namespace } // namespace
WebContents::WebContents(content::WebContents* web_contents) WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents), : content::WebContentsObserver(web_contents),
embedder_(nullptr),
type_(REMOTE), type_(REMOTE),
request_id_(0), request_id_(0),
background_throttling_(true) { background_throttling_(true) {
AttachAsUserData(web_contents);
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
Init(isolate);
AttachAsUserData(web_contents);
} }
WebContents::WebContents(v8::Isolate* isolate, WebContents::WebContents(v8::Isolate* isolate,
@ -269,7 +273,6 @@ WebContents::WebContents(v8::Isolate* isolate,
} }
Observe(web_contents); Observe(web_contents);
AttachAsUserData(web_contents);
InitWithWebContents(web_contents); InitWithWebContents(web_contents);
managed_web_contents()->GetView()->SetDelegate(this); managed_web_contents()->GetView()->SetDelegate(this);
@ -298,6 +301,9 @@ WebContents::WebContents(v8::Isolate* isolate,
if (owner_window) if (owner_window)
SetOwnerWindow(owner_window); SetOwnerWindow(owner_window);
} }
Init(isolate);
AttachAsUserData(web_contents);
} }
WebContents::~WebContents() { WebContents::~WebContents() {
@ -792,6 +798,14 @@ bool WebContents::IsLoading() const {
return web_contents()->IsLoading(); return web_contents()->IsLoading();
} }
bool WebContents::IsLoadingMainFrame() const {
// Comparing site instances works because Electron always creates a new site
// instance when navigating, regardless of origin. See AtomBrowserClient.
return (web_contents()->GetLastCommittedURL().is_empty() ||
web_contents()->GetSiteInstance() !=
web_contents()->GetPendingSiteInstance()) && IsLoading();
}
bool WebContents::IsWaitingForResponse() const { bool WebContents::IsWaitingForResponse() const {
return web_contents()->IsWaitingForResponse(); return web_contents()->IsWaitingForResponse();
} }
@ -848,14 +862,20 @@ void WebContents::OpenDevTools(mate::Arguments* args) {
if (type_ == REMOTE) if (type_ == REMOTE)
return; return;
bool detach = false; std::string state;
if (type_ == WEB_VIEW) { if (type_ == WEB_VIEW) {
detach = true; state = "detach";
} else if (args && args->Length() == 1) { } else if (args && args->Length() == 1) {
bool detach = false;
mate::Dictionary options; mate::Dictionary options;
args->GetNext(&options) && options.Get("detach", &detach); if (args->GetNext(&options)) {
options.Get("mode", &state);
options.Get("detach", &detach);
if (state.empty() && detach)
state = "detach";
}
} }
managed_web_contents()->SetCanDock(!detach); managed_web_contents()->SetDockState(state);
managed_web_contents()->ShowDevTools(); managed_web_contents()->ShowDevTools();
} }
@ -1188,6 +1208,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("_getURL", &WebContents::GetURL) .SetMethod("_getURL", &WebContents::GetURL)
.SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("getTitle", &WebContents::GetTitle)
.SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isLoading", &WebContents::IsLoading)
.SetMethod("isLoadingMainFrame", &WebContents::IsLoadingMainFrame)
.SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse)
.SetMethod("_stop", &WebContents::Stop) .SetMethod("_stop", &WebContents::Stop)
.SetMethod("_goBack", &WebContents::GoBack) .SetMethod("_goBack", &WebContents::GoBack)
@ -1274,7 +1295,8 @@ mate::Handle<WebContents> WebContents::CreateFrom(
return mate::CreateHandle(isolate, static_cast<WebContents*>(existing)); return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
// Otherwise create a new WebContents wrapper object. // Otherwise create a new WebContents wrapper object.
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents)); auto handle = mate::CreateHandle(
isolate, new WebContents(isolate, web_contents));
g_wrap_web_contents.Run(handle.ToV8()); g_wrap_web_contents.Run(handle.ToV8());
return handle; return handle;
} }
@ -1287,16 +1309,8 @@ mate::Handle<WebContents> WebContents::Create(
return handle; return handle;
} }
void ClearWrapWebContents() {
g_wrap_web_contents.Reset();
}
void SetWrapWebContents(const WrapWebContentsCallback& callback) { void SetWrapWebContents(const WrapWebContentsCallback& callback) {
g_wrap_web_contents = callback; g_wrap_web_contents = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapWebContents));
} }
} // namespace api } // namespace api

View file

@ -55,6 +55,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
static mate::Handle<WebContents> Create( static mate::Handle<WebContents> Create(
v8::Isolate* isolate, const mate::Dictionary& options); v8::Isolate* isolate, const mate::Dictionary& options);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
int GetID() const; int GetID() const;
bool Equal(const WebContents* web_contents) const; bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options); void LoadURL(const GURL& url, const mate::Dictionary& options);
@ -62,6 +65,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
GURL GetURL() const; GURL GetURL() const;
base::string16 GetTitle() const; base::string16 GetTitle() const;
bool IsLoading() const; bool IsLoading() const;
bool IsLoadingMainFrame() const;
bool IsWaitingForResponse() const; bool IsWaitingForResponse() const;
void Stop(); void Stop();
void ReloadIgnoringCache(); void ReloadIgnoringCache();
@ -155,12 +159,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate); v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
v8::Local<v8::Value> Debugger(v8::Isolate* isolate); v8::Local<v8::Value> Debugger(v8::Isolate* isolate);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit WebContents(content::WebContents* web_contents); WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
WebContents(v8::Isolate* isolate, const mate::Dictionary& options); WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
~WebContents(); ~WebContents();

View file

@ -36,8 +36,10 @@ namespace atom {
namespace api { namespace api {
WebRequest::WebRequest(AtomBrowserContext* browser_context) WebRequest::WebRequest(v8::Isolate* isolate,
AtomBrowserContext* browser_context)
: browser_context_(browser_context) { : browser_context_(browser_context) {
Init(isolate);
} }
WebRequest::~WebRequest() { WebRequest::~WebRequest() {
@ -81,7 +83,7 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
mate::Handle<WebRequest> WebRequest::Create( mate::Handle<WebRequest> WebRequest::Create(
v8::Isolate* isolate, v8::Isolate* isolate,
AtomBrowserContext* browser_context) { AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new WebRequest(browser_context)); return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context));
} }
// static // static

View file

@ -21,13 +21,12 @@ class WebRequest : public mate::TrackableObject<WebRequest> {
static mate::Handle<WebRequest> Create(v8::Isolate* isolate, static mate::Handle<WebRequest> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context); AtomBrowserContext* browser_context);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
explicit WebRequest(AtomBrowserContext* browser_context); WebRequest(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~WebRequest(); ~WebRequest() override;
// C++ can not distinguish overloaded member function. // C++ can not distinguish overloaded member function.
template<AtomNetworkDelegate::SimpleEvent type> template<AtomNetworkDelegate::SimpleEvent type>

View file

@ -2,9 +2,9 @@
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h" #include "atom/browser/web_view_manager.h"
#include "atom/common/native_mate_converters/content_converter.h"
#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
@ -12,22 +12,6 @@
using atom::WebContentsPreferences; using atom::WebContentsPreferences;
namespace mate {
template<>
struct Converter<content::WebContents*> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* contents;
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
return false;
*out = contents->web_contents();
return true;
}
};
} // namespace mate
namespace { namespace {
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) { atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {

View file

@ -151,7 +151,7 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
api_web_contents_ = web_contents.get(); api_web_contents_ = web_contents.get();
// Keep a copy of the options for later use. // Keep a copy of the options for later use.
mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set( mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
"browserWindowOptions", options); "browserWindowOptions", options);
// Creates BrowserWindow. // Creates BrowserWindow.
@ -287,7 +287,7 @@ void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
#endif #endif
// static // static
mate::Wrappable* Window::New(v8::Isolate* isolate, mate::Arguments* args) { mate::WrappableBase* Window::New(v8::Isolate* isolate, mate::Arguments* args) {
if (!Browser::Get()->is_ready()) { if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8( isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create BrowserWindow before app is ready"))); isolate, "Cannot create BrowserWindow before app is ready")));
@ -440,6 +440,10 @@ std::vector<int> Window::GetMaximumSize() {
return result; return result;
} }
void Window::SetSheetOffset(double offset) {
window_->SetSheetOffset(offset);
}
void Window::SetResizable(bool resizable) { void Window::SetResizable(bool resizable) {
window_->SetResizable(resizable); window_->SetResizable(resizable);
} }
@ -746,6 +750,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getMinimumSize", &Window::GetMinimumSize) .SetMethod("getMinimumSize", &Window::GetMinimumSize)
.SetMethod("setMaximumSize", &Window::SetMaximumSize) .SetMethod("setMaximumSize", &Window::SetMaximumSize)
.SetMethod("getMaximumSize", &Window::GetMaximumSize) .SetMethod("getMaximumSize", &Window::GetMaximumSize)
.SetMethod("setSheetOffset", &Window::SetSheetOffset)
.SetMethod("setResizable", &Window::SetResizable) .SetMethod("setResizable", &Window::SetResizable)
.SetMethod("isResizable", &Window::IsResizable) .SetMethod("isResizable", &Window::IsResizable)
.SetMethod("setMovable", &Window::SetMovable) .SetMethod("setMovable", &Window::SetMovable)
@ -812,7 +817,7 @@ v8::Local<v8::Value> Window::From(v8::Isolate* isolate,
NativeWindow* native_window) { NativeWindow* native_window) {
auto existing = TrackableObject::FromWrappedClass(isolate, native_window); auto existing = TrackableObject::FromWrappedClass(isolate, native_window);
if (existing) if (existing)
return existing->GetWrapper(isolate); return existing->GetWrapper();
else else
return v8::Null(isolate); return v8::Null(isolate);
} }

View file

@ -38,7 +38,7 @@ class WebContents;
class Window : public mate::TrackableObject<Window>, class Window : public mate::TrackableObject<Window>,
public NativeWindowObserver { public NativeWindowObserver {
public: public:
static mate::Wrappable* New(v8::Isolate* isolate, mate::Arguments* args); static mate::WrappableBase* New(v8::Isolate* isolate, mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
@ -51,7 +51,7 @@ class Window : public mate::TrackableObject<Window>,
protected: protected:
Window(v8::Isolate* isolate, const mate::Dictionary& options); Window(v8::Isolate* isolate, const mate::Dictionary& options);
virtual ~Window(); ~Window() override;
// NativeWindowObserver: // NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override; void WillCloseWindow(bool* prevent_default) override;
@ -110,6 +110,7 @@ class Window : public mate::TrackableObject<Window>,
std::vector<int> GetMinimumSize(); std::vector<int> GetMinimumSize();
void SetMaximumSize(int width, int height); void SetMaximumSize(int width, int height);
std::vector<int> GetMaximumSize(); std::vector<int> GetMaximumSize();
void SetSheetOffset(double offset);
void SetResizable(bool resizable); void SetResizable(bool resizable);
bool IsResizable(); bool IsResizable();
void SetMovable(bool movable); void SetMovable(bool movable);

View file

@ -11,31 +11,15 @@
namespace mate { namespace mate {
namespace { Event::Event(v8::Isolate* isolate)
v8::Persistent<v8::ObjectTemplate> template_;
} // namespace
Event::Event()
: sender_(NULL), : sender_(NULL),
message_(NULL) { message_(NULL) {
Init(isolate);
} }
Event::~Event() { Event::~Event() {
} }
ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, ObjectTemplateBuilder(isolate)
.SetMethod("preventDefault", &Event::PreventDefault)
.SetMethod("sendReply", &Event::SendReply)
.Build());
return ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
void Event::SetSenderAndMessage(content::WebContents* sender, void Event::SetSenderAndMessage(content::WebContents* sender,
IPC::Message* message) { IPC::Message* message) {
DCHECK(!sender_); DCHECK(!sender_);
@ -52,7 +36,7 @@ void Event::WebContentsDestroyed() {
} }
void Event::PreventDefault(v8::Isolate* isolate) { void Event::PreventDefault(v8::Isolate* isolate) {
GetWrapper(isolate)->Set(StringToV8(isolate, "defaultPrevented"), GetWrapper()->Set(StringToV8(isolate, "defaultPrevented"),
v8::True(isolate)); v8::True(isolate));
} }
@ -66,7 +50,15 @@ bool Event::SendReply(const base::string16& json) {
// static // static
Handle<Event> Event::Create(v8::Isolate* isolate) { Handle<Event> Event::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new Event); return mate::CreateHandle(isolate, new Event(isolate));
}
// static
void Event::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("preventDefault", &Event::PreventDefault)
.SetMethod("sendReply", &Event::SendReply);
} }
} // namespace mate } // namespace mate

View file

@ -15,11 +15,14 @@ class Message;
namespace mate { namespace mate {
class Event : public Wrappable, class Event : public Wrappable<Event>,
public content::WebContentsObserver { public content::WebContentsObserver {
public: public:
static Handle<Event> Create(v8::Isolate* isolate); static Handle<Event> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
// Pass the sender and message to be replied. // Pass the sender and message to be replied.
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message); void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
@ -30,11 +33,8 @@ class Event : public Wrappable,
bool SendReply(const base::string16& json); bool SendReply(const base::string16& json);
protected: protected:
Event(); explicit Event(v8::Isolate* isolate);
virtual ~Event(); ~Event() override;
// Wrappable implementations:
ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
// content::WebContentsObserver implementations: // content::WebContentsObserver implementations:
void WebContentsDestroyed() override; void WebContentsDestroyed() override;

View file

@ -34,11 +34,13 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
} // namespace } // namespace
EventEmitter::EventEmitter() { namespace internal {
}
v8::Local<v8::Object> EventEmitter::CreateJSEvent( v8::Local<v8::Object> CreateJSEvent(
v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) { v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::WebContents* sender,
IPC::Message* message) {
v8::Local<v8::Object> event; v8::Local<v8::Object> event;
bool use_native_event = sender && message; bool use_native_event = sender && message;
@ -49,16 +51,20 @@ v8::Local<v8::Object> EventEmitter::CreateJSEvent(
} else { } else {
event = CreateEventObject(isolate); event = CreateEventObject(isolate);
} }
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate)); mate::Dictionary(isolate, event).Set("sender", object);
return event; return event;
} }
v8::Local<v8::Object> EventEmitter::CreateCustomEvent( v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate, v8::Local<v8::Object> custom_event) { v8::Isolate* isolate,
v8::Local<v8::Object> object,
v8::Local<v8::Object> custom_event) {
v8::Local<v8::Object> event = CreateEventObject(isolate); v8::Local<v8::Object> event = CreateEventObject(isolate);
(void)event->SetPrototype(custom_event->CreationContext(), custom_event); (void)event->SetPrototype(custom_event->CreationContext(), custom_event);
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate)); mate::Dictionary(isolate, event).Set("sender", object);
return event; return event;
} }
} // namespace internal
} // namespace mate } // namespace mate

View file

@ -20,17 +20,38 @@ class Message;
namespace mate { namespace mate {
namespace internal {
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::WebContents* sender,
IPC::Message* message);
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> object,
v8::Local<v8::Object> event);
} // namespace internal
// Provide helperers to emit event in JavaScript. // Provide helperers to emit event in JavaScript.
class EventEmitter : public Wrappable { template<typename T>
class EventEmitter : public Wrappable<T> {
public: public:
typedef std::vector<v8::Local<v8::Value>> ValueArray; typedef std::vector<v8::Local<v8::Value>> ValueArray;
// Make the convinient methods visible:
// https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
v8::Local<v8::Object> GetWrapper() { return Wrappable<T>::GetWrapper(); }
v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
// this.emit(name, event, args...); // this.emit(name, event, args...);
template<typename... Args> template<typename... Args>
bool EmitCustomEvent(const base::StringPiece& name, bool EmitCustomEvent(const base::StringPiece& name,
v8::Local<v8::Object> event, v8::Local<v8::Object> event,
const Args&... args) { const Args&... args) {
return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...); return EmitWithEvent(
name,
internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...);
} }
// this.emit(name, new Event(), args...); // this.emit(name, new Event(), args...);
@ -47,12 +68,13 @@ class EventEmitter : public Wrappable {
const Args&... args) { const Args&... args) {
v8::Locker locker(isolate()); v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate()); v8::HandleScope handle_scope(isolate());
v8::Local<v8::Object> event = CreateJSEvent(isolate(), sender, message); v8::Local<v8::Object> event = internal::CreateJSEvent(
isolate(), GetWrapper(), sender, message);
return EmitWithEvent(name, event, args...); return EmitWithEvent(name, event, args...);
} }
protected: protected:
EventEmitter(); EventEmitter() {}
private: private:
// this.emit(name, event, args...); // this.emit(name, event, args...);
@ -62,17 +84,11 @@ class EventEmitter : public Wrappable {
const Args&... args) { const Args&... args) {
v8::Locker locker(isolate()); v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate()); v8::HandleScope handle_scope(isolate());
EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...); EmitEvent(isolate(), GetWrapper(), name, event, args...);
return event->Get( return event->Get(
StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
} }
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message);
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate, v8::Local<v8::Object> event);
DISALLOW_COPY_AND_ASSIGN(EventEmitter); DISALLOW_COPY_AND_ASSIGN(EventEmitter);
}; };

View file

@ -73,11 +73,6 @@ void SavePageHandler::Destroy(content::DownloadItem* item) {
delete this; delete this;
} }
// static
bool SavePageHandler::IsSavePageTypes(const std::string& type) {
return type == "multipart/related" || type == "text/html";
}
} // namespace api } // namespace api
} // namespace atom } // namespace atom

View file

@ -37,8 +37,6 @@ class SavePageHandler : public content::DownloadManager::Observer,
bool Handle(const base::FilePath& full_path, bool Handle(const base::FilePath& full_path,
const content::SavePageType& save_type); const content::SavePageType& save_type);
static bool IsSavePageTypes(const std::string& type);
private: private:
void Destroy(content::DownloadItem* item); void Destroy(content::DownloadItem* item);

View file

@ -37,15 +37,6 @@ TrackableObjectBase::~TrackableObjectBase() {
cleanup_.Run(); cleanup_.Run();
} }
void TrackableObjectBase::AfterInit(v8::Isolate* isolate) {
if (wrapped_)
AttachAsUserData(wrapped_);
}
void TrackableObjectBase::MarkDestroyed() {
GetWrapper(isolate())->SetAlignedPointerInInternalField(0, nullptr);
}
base::Closure TrackableObjectBase::GetDestroyClosure() { base::Closure TrackableObjectBase::GetDestroyClosure() {
return base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr()); return base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr());
} }

View file

@ -21,7 +21,7 @@ class SupportsUserData;
namespace mate { namespace mate {
// Users should use TrackableObject instead. // Users should use TrackableObject instead.
class TrackableObjectBase : public mate::EventEmitter { class TrackableObjectBase {
public: public:
TrackableObjectBase(); TrackableObjectBase();
@ -32,13 +32,7 @@ class TrackableObjectBase : public mate::EventEmitter {
void AttachAsUserData(base::SupportsUserData* wrapped); void AttachAsUserData(base::SupportsUserData* wrapped);
protected: protected:
~TrackableObjectBase() override; virtual ~TrackableObjectBase();
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// Mark the JS object as destroyed.
void MarkDestroyed();
// Returns a closure that can destroy the native class. // Returns a closure that can destroy the native class.
base::Closure GetDestroyClosure(); base::Closure GetDestroyClosure();
@ -65,8 +59,14 @@ class TrackableObjectBase : public mate::EventEmitter {
// All instances of TrackableObject will be kept in a weak map and can be got // All instances of TrackableObject will be kept in a weak map and can be got
// from its ID. // from its ID.
template<typename T> template<typename T>
class TrackableObject : public TrackableObjectBase { class TrackableObject : public TrackableObjectBase,
public mate::EventEmitter<T> {
public: public:
// Mark the JS object as destroyed.
void MarkDestroyed() {
Wrappable<T>::GetWrapper()->SetAlignedPointerInInternalField(0, nullptr);
}
// Finds out the TrackableObject from its ID in weak map. // Finds out the TrackableObject from its ID in weak map.
static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) { static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) {
if (!weak_map_) if (!weak_map_)
@ -106,6 +106,7 @@ class TrackableObject : public TrackableObjectBase {
protected: protected:
TrackableObject() {} TrackableObject() {}
~TrackableObject() override { ~TrackableObject() override {
RemoveFromWeakMap(); RemoveFromWeakMap();
} }
@ -113,41 +114,18 @@ class TrackableObject : public TrackableObjectBase {
void AfterInit(v8::Isolate* isolate) override { void AfterInit(v8::Isolate* isolate) override {
if (!weak_map_) { if (!weak_map_) {
weak_map_.reset(new atom::IDWeakMap); weak_map_.reset(new atom::IDWeakMap);
RegisterDestructionCallback(
base::Bind(&TrackableObject<T>::ReleaseAllWeakReferences));
} }
weak_map_id_ = weak_map_->Add(isolate, GetWrapper(isolate)); weak_map_id_ = weak_map_->Add(isolate, Wrappable<T>::GetWrapper());
TrackableObjectBase::AfterInit(isolate); if (wrapped_)
AttachAsUserData(wrapped_);
} }
private: private:
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override {
if (template_.IsEmpty()) {
auto templ = v8::ObjectTemplate::New(isolate);
T::BuildPrototype(isolate, templ);
template_.Reset(isolate, templ);
}
return ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
// Releases all weak references in weak map, called when app is terminating.
static void ReleaseAllWeakReferences() {
weak_map_.reset();
}
static v8::Persistent<v8::ObjectTemplate> template_;
static scoped_ptr<atom::IDWeakMap> weak_map_; static scoped_ptr<atom::IDWeakMap> weak_map_;
DISALLOW_COPY_AND_ASSIGN(TrackableObject); DISALLOW_COPY_AND_ASSIGN(TrackableObject);
}; };
template<typename T>
v8::Persistent<v8::ObjectTemplate> TrackableObject<T>::template_;
template<typename T> template<typename T>
scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_; scoped_ptr<atom::IDWeakMap> TrackableObject<T>::weak_map_;

View file

@ -37,7 +37,6 @@
#include "content/public/browser/site_instance.h" #include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/web_preferences.h" #include "content/public/common/web_preferences.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h" #include "ppapi/host/ppapi_host.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
@ -55,26 +54,6 @@ std::string g_custom_schemes = "";
// Custom schemes to be registered to handle service worker. // Custom schemes to be registered to handle service worker.
std::string g_custom_service_worker_schemes = ""; std::string g_custom_service_worker_schemes = "";
scoped_refptr<net::X509Certificate> ImportCertFromFile(
const base::FilePath& path) {
if (path.empty())
return nullptr;
std::string cert_data;
if (!base::ReadFileToString(path, &cert_data))
return nullptr;
net::CertificateList certs =
net::X509Certificate::CreateCertificateListFromBytes(
cert_data.data(), cert_data.size(),
net::X509Certificate::FORMAT_AUTO);
if (certs.empty())
return nullptr;
return certs[0];
}
} // namespace } // namespace
// static // static
@ -242,16 +221,6 @@ void AtomBrowserClient::SelectClientCertificate(
content::WebContents* web_contents, content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info, net::SSLCertRequestInfo* cert_request_info,
scoped_ptr<content::ClientCertificateDelegate> delegate) { scoped_ptr<content::ClientCertificateDelegate> delegate) {
// --client-certificate=`path`
auto cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kClientCertificate)) {
auto cert_path = cmd->GetSwitchValuePath(switches::kClientCertificate);
auto certificate = ImportCertFromFile(cert_path);
if (certificate.get())
delegate->ContinueWithCertificate(certificate.get());
return;
}
if (!cert_request_info->client_certs.empty() && delegate_) { if (!cert_request_info->client_certs.empty() && delegate_) {
delegate_->SelectClientCertificate( delegate_->SelectClientCertificate(
web_contents, cert_request_info, std::move(delegate)); web_contents, cert_request_info, std::move(delegate));

View file

@ -70,7 +70,9 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
return; return;
NativeWindow* window = nullptr; NativeWindow* window = nullptr;
auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents()); content::WebContents* web_contents = item->GetWebContents();
auto relay = web_contents ? NativeWindowRelay::FromWebContents(web_contents)
: nullptr;
if (relay) if (relay)
window = relay->window.get(); window = relay->window.get();

View file

@ -5,6 +5,7 @@
#include "atom/browser/atom_resource_dispatcher_host_delegate.h" #include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/login_handler.h" #include "atom/browser/login_handler.h"
#include "atom/browser/web_contents_permission_helper.h"
#include "atom/common/platform_util.h" #include "atom/common/platform_util.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/base/escape.h" #include "net/base/escape.h"
@ -14,20 +15,46 @@ using content::BrowserThread;
namespace atom { namespace atom {
namespace {
void OnOpenExternal(const GURL& escaped_url,
bool allowed) {
if (allowed)
platform_util::OpenExternal(escaped_url, true);
}
void HandleExternalProtocolInUI(
const GURL& url,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
bool has_user_gesture) {
content::WebContents* web_contents = web_contents_getter.Run();
if (!web_contents)
return;
GURL escaped_url(net::EscapeExternalHandlerValue(url.spec()));
auto callback = base::Bind(&OnOpenExternal, escaped_url);
auto permission_helper =
WebContentsPermissionHelper::FromWebContents(web_contents);
permission_helper->RequestOpenExternalPermission(callback, has_user_gesture);
}
} // namespace
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() { AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {
} }
bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
const GURL& url, const GURL& url,
int child_id, int child_id,
const content::ResourceRequestInfo::WebContentsGetter&, const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
bool is_main_frame, bool is_main_frame,
ui::PageTransition transition, ui::PageTransition transition,
bool has_user_gesture) { bool has_user_gesture) {
GURL escaped_url(net::EscapeExternalHandlerValue(url.spec()));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind( base::Bind(&HandleExternalProtocolInUI,
base::IgnoreResult(platform_util::OpenExternal), escaped_url, true)); url,
web_contents_getter,
has_user_gesture));
return true; return true;
} }

View file

@ -22,6 +22,12 @@ SQRLUpdater* g_updater = nil;
} // namespace } // namespace
namespace {
bool g_update_available = false;
}
// static // static
void AutoUpdater::SetFeedURL(const std::string& feed) { void AutoUpdater::SetFeedURL(const std::string& feed) {
if (g_updater == nil) { if (g_updater == nil) {
@ -69,6 +75,7 @@ void AutoUpdater::CheckForUpdates() {
take:1] take:1]
subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) { subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) {
if (downloadedUpdate) { if (downloadedUpdate) {
g_update_available = true;
SQRLUpdate* update = downloadedUpdate.update; SQRLUpdate* update = downloadedUpdate.update;
// There is a new update that has been downloaded. // There is a new update that has been downloaded.
delegate->OnUpdateDownloaded( delegate->OnUpdateDownloaded(
@ -77,6 +84,7 @@ void AutoUpdater::CheckForUpdates() {
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970), base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
base::SysNSStringToUTF8(update.updateURL.absoluteString)); base::SysNSStringToUTF8(update.updateURL.absoluteString));
} else { } else {
g_update_available = false;
// When the completed event is sent with no update, then we know there // When the completed event is sent with no update, then we know there
// is no update available. // is no update available.
delegate->OnUpdateNotAvailable(); delegate->OnUpdateNotAvailable();
@ -89,11 +97,16 @@ void AutoUpdater::CheckForUpdates() {
} }
void AutoUpdater::QuitAndInstall() { void AutoUpdater::QuitAndInstall() {
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) { Delegate* delegate = AutoUpdater::GetDelegate();
Delegate* delegate = AutoUpdater::GetDelegate(); if (g_update_available) {
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
if (delegate)
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
}];
} else {
if (delegate) if (delegate)
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription)); delegate->OnError("No update available, can't quit and install");
}]; }
} }
} // namespace auto_updater } // namespace auto_updater

View file

@ -9,7 +9,10 @@
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/native_window.h" #include "atom/browser/native_window.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "base/files/file_util.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "brightray/browser/brightray_paths.h"
namespace atom { namespace atom {
@ -139,6 +142,11 @@ void Browser::WillFinishLaunching() {
} }
void Browser::DidFinishLaunching() { void Browser::DidFinishLaunching() {
// Make sure the userData directory is created.
base::FilePath user_data;
if (PathService::Get(brightray::DIR_USER_DATA, &user_data))
base::CreateDirectoryAndGetError(user_data, nullptr);
is_ready_ = true; is_ready_ = true;
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching()); FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
} }
@ -187,8 +195,4 @@ void Browser::OnWindowAllClosed() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed()); FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed());
} }
void Browser::PlatformThemeChanged() {
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnPlatformThemeChanged());
}
} // namespace atom } // namespace atom

View file

@ -82,6 +82,9 @@ class Browser : public WindowListObserver {
// Set as default handler for a protocol. // Set as default handler for a protocol.
bool SetAsDefaultProtocolClient(const std::string& protocol); bool SetAsDefaultProtocolClient(const std::string& protocol);
// Query the current state of default handler for a protocol.
bool IsDefaultProtocolClient(const std::string& protocol);
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// Hide the application. // Hide the application.
void Hide(); void Hide();
@ -89,9 +92,6 @@ class Browser : public WindowListObserver {
// Show the application. // Show the application.
void Show(); void Show();
// Check if the system is in Dark Mode.
bool IsDarkMode();
// Bounce the dock icon. // Bounce the dock icon.
enum BounceType { enum BounceType {
BOUNCE_CRITICAL = 0, BOUNCE_CRITICAL = 0,
@ -151,9 +151,6 @@ class Browser : public WindowListObserver {
// Request basic auth login. // Request basic auth login.
void RequestLogin(LoginHandler* login_handler); void RequestLogin(LoginHandler* login_handler);
// Tell the application that plaform's theme changed.
void PlatformThemeChanged();
void AddObserver(BrowserObserver* obs) { void AddObserver(BrowserObserver* obs) {
observers_.AddObserver(obs); observers_.AddObserver(obs);
} }

View file

@ -42,6 +42,10 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
return false; return false;
} }
bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
return false;
}
std::string Browser::GetExecutableFileVersion() const { std::string Browser::GetExecutableFileVersion() const {
return brightray::GetApplicationVersion(); return brightray::GetApplicationVersion();
} }

View file

@ -27,11 +27,6 @@ void Browser::Show() {
[[AtomApplication sharedApplication] unhide:nil]; [[AtomApplication sharedApplication] unhide:nil];
} }
bool Browser::IsDarkMode() {
NSString *mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
return [mode isEqualToString: @"Dark"];
}
void Browser::AddRecentDocument(const base::FilePath& path) { void Browser::AddRecentDocument(const base::FilePath& path) {
NSString* path_string = base::mac::FilePathToNSString(path); NSString* path_string = base::mac::FilePathToNSString(path);
if (!path_string) if (!path_string)
@ -65,6 +60,30 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
return return_code == noErr; return return_code == noErr;
} }
bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
if (protocol.empty())
return false;
NSString* identifier = [base::mac::MainBundle() bundleIdentifier];
if (!identifier)
return false;
NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()];
CFStringRef bundle =
LSCopyDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol_ns));
NSString* bundleId = static_cast<NSString*>(
base::mac::CFTypeRefToNSObjectAutorelease(bundle));
if (!bundleId)
return false;
// Ensure the comparison is case-insensitive
// as LS does not persist the case of the bundle id.
NSComparisonResult result =
[bundleId caseInsensitiveCompare:identifier];
return result == NSOrderedSame;
}
void Browser::SetAppUserModelID(const base::string16& name) { void Browser::SetAppUserModelID(const base::string16& name) {
} }

View file

@ -45,8 +45,6 @@ class BrowserObserver {
// The browser requests HTTP login. // The browser requests HTTP login.
virtual void OnLogin(LoginHandler* login_handler) {} virtual void OnLogin(LoginHandler* login_handler) {}
virtual void OnPlatformThemeChanged() {}
protected: protected:
virtual ~BrowserObserver() {} virtual ~BrowserObserver() {}
}; };

View file

@ -225,6 +225,50 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) {
return true; return true;
} }
bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
if (protocol.empty())
return false;
base::FilePath path;
if (!PathService::Get(base::FILE_EXE, &path)) {
LOG(ERROR) << "Error getting app exe path";
return false;
}
// Main Registry Key
HKEY root = HKEY_CURRENT_USER;
std::string keyPathStr = "Software\\Classes\\" + protocol;
std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end());
// Command Key
std::string cmdPathStr = keyPathStr + "\\shell\\open\\command";
std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end());
base::win::RegKey key;
base::win::RegKey commandKey;
if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS)))
// Key doesn't exist, we can confirm that it is not set
return false;
if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS)))
// Key doesn't exist, we can confirm that it is not set
return false;
std::wstring keyVal;
if (FAILED(commandKey.ReadValue(L"", &keyVal)))
// Default value not set, we can confirm that it is not set
return false;
std::wstring exePath(path.value());
std::wstring exe = L"\"" + exePath + L"\" \"%1\"";
if (keyVal == exe) {
// Default value is the same as current file path
return true;
} else {
return false;
}
}
PCWSTR Browser::GetAppUserModelID() { PCWSTR Browser::GetAppUserModelID() {
if (app_user_model_id_.empty()) { if (app_user_model_id_.empty()) {
SetAppUserModelID(base::ReplaceStringPlaceholders( SetAppUserModelID(base::ReplaceStringPlaceholders(

View file

@ -24,9 +24,6 @@
// Don't add the "Enter Full Screen" menu item automatically. // Don't add the "Enter Full Screen" menu item automatically.
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"]; [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];
// Add observer to monitor the system's Dark Mode theme.
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(platformThemeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil];
atom::Browser::Get()->WillFinishLaunching(); atom::Browser::Get()->WillFinishLaunching();
} }
@ -62,8 +59,4 @@
return flag; return flag;
} }
- (void)platformThemeChanged:(NSNotification *)notify {
atom::Browser::Get()->PlatformThemeChanged();
}
@end @end

View file

@ -54,6 +54,7 @@ NativeWindow::NativeWindow(
enable_larger_than_screen_(false), enable_larger_than_screen_(false),
is_closed_(false), is_closed_(false),
has_dialog_attached_(false), has_dialog_attached_(false),
sheet_offset_(0.0),
aspect_ratio_(0.0), aspect_ratio_(0.0),
inspectable_web_contents_(inspectable_web_contents), inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) { weak_factory_(this) {
@ -254,6 +255,14 @@ gfx::Size NativeWindow::GetMaximumSize() {
return GetSizeConstraints().GetMaximumSize(); return GetSizeConstraints().GetMaximumSize();
} }
void NativeWindow::SetSheetOffset(const double offset) {
sheet_offset_ = offset;
}
double NativeWindow::GetSheetOffset() {
return sheet_offset_;
}
void NativeWindow::SetRepresentedFilename(const std::string& filename) { void NativeWindow::SetRepresentedFilename(const std::string& filename) {
} }

View file

@ -123,6 +123,8 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::Size GetMinimumSize(); virtual gfx::Size GetMinimumSize();
virtual void SetMaximumSize(const gfx::Size& size); virtual void SetMaximumSize(const gfx::Size& size);
virtual gfx::Size GetMaximumSize(); virtual gfx::Size GetMaximumSize();
virtual void SetSheetOffset(const double offset);
virtual double GetSheetOffset();
virtual void SetResizable(bool resizable) = 0; virtual void SetResizable(bool resizable) = 0;
virtual bool IsResizable() = 0; virtual bool IsResizable() = 0;
virtual void SetMovable(bool movable) = 0; virtual void SetMovable(bool movable) = 0;
@ -326,6 +328,9 @@ class NativeWindow : public base::SupportsUserData,
// it should be cancelled when we can prove that the window is responsive. // it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_; base::CancelableClosure window_unresposive_closure_;
// Used to display sheets at the appropriate vertical offset
double sheet_offset_;
// Used to maintain the aspect ratio of a view which is inside of the // Used to maintain the aspect ratio of a view which is inside of the
// content view. // content view.
double aspect_ratio_; double aspect_ratio_;

View file

@ -243,6 +243,13 @@ bool ScopedDisableResize::disable_resize_ = false;
return NO; return NO;
} }
- (NSRect)window:(NSWindow*)window
willPositionSheet:(NSWindow*)sheet usingRect:(NSRect)rect {
NSView* view = window.contentView;
rect.origin.y = view.frame.size.height - shell_->GetSheetOffset();
return rect;
}
@end @end
@interface AtomNSWindow : NSWindow { @interface AtomNSWindow : NSWindow {
@ -595,10 +602,16 @@ bool NativeWindowMac::IsVisible() {
} }
void NativeWindowMac::Maximize() { void NativeWindowMac::Maximize() {
if (IsMaximized())
return;
[window_ zoom:nil]; [window_ zoom:nil];
} }
void NativeWindowMac::Unmaximize() { void NativeWindowMac::Unmaximize() {
if (!IsMaximized())
return;
[window_ zoom:nil]; [window_ zoom:nil];
} }

View file

@ -4,15 +4,16 @@
#include "atom/browser/net/atom_network_delegate.h" #include "atom/browser/net/atom_network_delegate.h"
#include <string>
#include <utility> #include <utility>
#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/net_converter.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "brightray/browser/net/devtools_network_transaction.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
using brightray::DevToolsNetworkTransaction;
using content::BrowserThread; using content::BrowserThread;
namespace atom { namespace atom {
@ -226,6 +227,12 @@ void AtomNetworkDelegate::SetResponseListenerInIO(
response_listeners_[type] = { patterns, callback }; response_listeners_[type] = { patterns, callback };
} }
void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId(
const std::string& client_id) {
base::AutoLock auto_lock(lock_);
client_id_ = client_id;
}
int AtomNetworkDelegate::OnBeforeURLRequest( int AtomNetworkDelegate::OnBeforeURLRequest(
net::URLRequest* request, net::URLRequest* request,
const net::CompletionCallback& callback, const net::CompletionCallback& callback,
@ -241,6 +248,16 @@ int AtomNetworkDelegate::OnBeforeSendHeaders(
net::URLRequest* request, net::URLRequest* request,
const net::CompletionCallback& callback, const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) { net::HttpRequestHeaders* headers) {
std::string client_id;
{
base::AutoLock auto_lock(lock_);
client_id = client_id_;
}
if (!client_id.empty())
headers->SetHeader(
DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId,
client_id);
if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders)) if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders))
return brightray::NetworkDelegate::OnBeforeSendHeaders( return brightray::NetworkDelegate::OnBeforeSendHeaders(
request, callback, headers); request, callback, headers);

View file

@ -7,9 +7,11 @@
#include <map> #include <map>
#include <set> #include <set>
#include <string>
#include "brightray/browser/network_delegate.h" #include "brightray/browser/network_delegate.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/synchronization/lock.h"
#include "base/values.h" #include "base/values.h"
#include "extensions/common/url_pattern.h" #include "extensions/common/url_pattern.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
@ -68,6 +70,8 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
const URLPatterns& patterns, const URLPatterns& patterns,
const ResponseListener& callback); const ResponseListener& callback);
void SetDevToolsNetworkEmulationClientId(const std::string& client_id);
protected: protected:
// net::NetworkDelegate: // net::NetworkDelegate:
int OnBeforeURLRequest(net::URLRequest* request, int OnBeforeURLRequest(net::URLRequest* request,
@ -116,6 +120,11 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
std::map<ResponseEvent, ResponseListenerInfo> response_listeners_; std::map<ResponseEvent, ResponseListenerInfo> response_listeners_;
std::map<uint64_t, net::CompletionCallback> callbacks_; std::map<uint64_t, net::CompletionCallback> callbacks_;
base::Lock lock_;
// Client id for devtools network emulation.
std::string client_id_;
DISALLOW_COPY_AND_ASSIGN(AtomNetworkDelegate); DISALLOW_COPY_AND_ASSIGN(AtomNetworkDelegate);
}; };

View file

@ -17,9 +17,9 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>electron.icns</string> <string>electron.icns</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.37.6</string> <string>0.37.8</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.37.6</string> <string>0.37.8</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string> <string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View file

@ -56,8 +56,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,37,6,0 FILEVERSION 0,37,8,0
PRODUCTVERSION 0,37,6,0 PRODUCTVERSION 0,37,8,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -74,12 +74,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "GitHub, Inc." VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron" VALUE "FileDescription", "Electron"
VALUE "FileVersion", "0.37.6" VALUE "FileVersion", "0.37.8"
VALUE "InternalName", "electron.exe" VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe" VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron" VALUE "ProductName", "Electron"
VALUE "ProductVersion", "0.37.6" VALUE "ProductVersion", "0.37.8"
VALUE "SquirrelAwareVersion", "1" VALUE "SquirrelAwareVersion", "1"
END END
END END

View file

@ -13,12 +13,6 @@ namespace accelerator_util {
void SetPlatformAccelerator(ui::Accelerator* accelerator) { void SetPlatformAccelerator(ui::Accelerator* accelerator) {
unichar character; unichar character;
unichar characterIgnoringModifiers; unichar characterIgnoringModifiers;
ui::MacKeyCodeForWindowsKeyCode(accelerator->key_code(),
0,
&character,
&characterIgnoringModifiers);
NSString* characters =
[[[NSString alloc] initWithCharacters:&character length:1] autorelease];
NSUInteger modifiers = NSUInteger modifiers =
(accelerator->IsCtrlDown() ? NSControlKeyMask : 0) | (accelerator->IsCtrlDown() ? NSControlKeyMask : 0) |
@ -26,6 +20,18 @@ void SetPlatformAccelerator(ui::Accelerator* accelerator) {
(accelerator->IsAltDown() ? NSAlternateKeyMask : 0) | (accelerator->IsAltDown() ? NSAlternateKeyMask : 0) |
(accelerator->IsShiftDown() ? NSShiftKeyMask : 0); (accelerator->IsShiftDown() ? NSShiftKeyMask : 0);
ui::MacKeyCodeForWindowsKeyCode(accelerator->key_code(),
modifiers,
&character,
&characterIgnoringModifiers);
if (character != characterIgnoringModifiers) {
modifiers ^= NSShiftKeyMask;
}
NSString* characters =
[[[NSString alloc] initWithCharacters:&character length:1] autorelease];
scoped_ptr<ui::PlatformAccelerator> platform_accelerator( scoped_ptr<ui::PlatformAccelerator> platform_accelerator(
new ui::PlatformAcceleratorCocoa(characters, modifiers)); new ui::PlatformAcceleratorCocoa(characters, modifiers));
accelerator->set_platform_accelerator(std::move(platform_accelerator)); accelerator->set_platform_accelerator(std::move(platform_accelerator));

View file

@ -91,4 +91,12 @@ void WebContentsPermissionHelper::RequestPointerLockPermission(
user_gesture); user_gesture);
} }
void WebContentsPermissionHelper::RequestOpenExternalPermission(
const base::Callback<void(bool)>& callback,
bool user_gesture) {
RequestPermission((content::PermissionType)(PermissionType::OPEN_EXTERNAL),
callback,
user_gesture);
}
} // namespace atom } // namespace atom

View file

@ -19,7 +19,8 @@ class WebContentsPermissionHelper
enum class PermissionType { enum class PermissionType {
POINTER_LOCK = static_cast<int>(content::PermissionType::NUM) + 1, POINTER_LOCK = static_cast<int>(content::PermissionType::NUM) + 1,
FULLSCREEN FULLSCREEN,
OPEN_EXTERNAL,
}; };
void RequestFullscreenPermission( void RequestFullscreenPermission(
@ -30,6 +31,9 @@ class WebContentsPermissionHelper
void RequestWebNotificationPermission( void RequestWebNotificationPermission(
const base::Callback<void(bool)>& callback); const base::Callback<void(bool)>& callback);
void RequestPointerLockPermission(bool user_gesture); void RequestPointerLockPermission(bool user_gesture);
void RequestOpenExternalPermission(
const base::Callback<void(bool)>& callback,
bool user_gesture);
private: private:
explicit WebContentsPermissionHelper(content::WebContents* web_contents); explicit WebContentsPermissionHelper(content::WebContents* web_contents);

View file

@ -18,21 +18,39 @@
namespace { namespace {
v8::Persistent<v8::ObjectTemplate> template_; class Archive : public mate::Wrappable<Archive> {
class Archive : public mate::Wrappable {
public: public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate, static v8::Local<v8::Value> Create(v8::Isolate* isolate,
const base::FilePath& path) { const base::FilePath& path) {
scoped_ptr<asar::Archive> archive(new asar::Archive(path)); scoped_ptr<asar::Archive> archive(new asar::Archive(path));
if (!archive->Init()) if (!archive->Init())
return v8::False(isolate); return v8::False(isolate);
return (new Archive(std::move(archive)))->GetWrapper(isolate); return (new Archive(isolate, std::move(archive)))->GetWrapper();
}
static void BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetProperty("path", &Archive::GetPath)
.SetMethod("getFileInfo", &Archive::GetFileInfo)
.SetMethod("stat", &Archive::Stat)
.SetMethod("readdir", &Archive::Readdir)
.SetMethod("realpath", &Archive::Realpath)
.SetMethod("copyFileOut", &Archive::CopyFileOut)
.SetMethod("getFd", &Archive::GetFD)
.SetMethod("destroy", &Archive::Destroy);
} }
protected: protected:
explicit Archive(scoped_ptr<asar::Archive> archive) Archive(v8::Isolate* isolate, scoped_ptr<asar::Archive> archive)
: archive_(std::move(archive)) {} : archive_(std::move(archive)) {
Init(isolate);
}
// Returns the path of the file.
base::FilePath GetPath() {
return archive_->path();
}
// Reads the offset and size of file. // Reads the offset and size of file.
v8::Local<v8::Value> GetFileInfo(v8::Isolate* isolate, v8::Local<v8::Value> GetFileInfo(v8::Isolate* isolate,
@ -101,24 +119,6 @@ class Archive : public mate::Wrappable {
archive_.reset(); archive_.reset();
} }
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetValue("path", archive_->path())
.SetMethod("getFileInfo", &Archive::GetFileInfo)
.SetMethod("stat", &Archive::Stat)
.SetMethod("readdir", &Archive::Readdir)
.SetMethod("realpath", &Archive::Realpath)
.SetMethod("copyFileOut", &Archive::CopyFileOut)
.SetMethod("getFd", &Archive::GetFD)
.SetMethod("destroy", &Archive::Destroy)
.Build());
return mate::ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
private: private:
scoped_ptr<asar::Archive> archive_; scoped_ptr<asar::Archive> archive_;

View file

@ -12,7 +12,7 @@ namespace atom {
namespace api { namespace api {
IDWeakMap::IDWeakMap() { IDWeakMap::IDWeakMap(v8::Isolate* isolate) {
} }
IDWeakMap::~IDWeakMap() { IDWeakMap::~IDWeakMap() {
@ -52,8 +52,8 @@ void IDWeakMap::BuildPrototype(v8::Isolate* isolate,
} }
// static // static
mate::Wrappable* IDWeakMap::Create(v8::Isolate* isolate) { mate::WrappableBase* IDWeakMap::Create(v8::Isolate* isolate) {
return new IDWeakMap; return new IDWeakMap(isolate);
} }
} // namespace api } // namespace api

View file

@ -13,15 +13,15 @@ namespace atom {
namespace api { namespace api {
class IDWeakMap : public mate::Wrappable { class IDWeakMap : public mate::Wrappable<IDWeakMap> {
public: public:
static mate::Wrappable* Create(v8::Isolate* isolate); static mate::WrappableBase* Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype); v8::Local<v8::ObjectTemplate> prototype);
protected: protected:
IDWeakMap(); explicit IDWeakMap(v8::Isolate* isolate);
~IDWeakMap(); ~IDWeakMap();
private: private:

View file

@ -168,35 +168,15 @@ bool ReadImageSkiaFromICO(gfx::ImageSkia* image, const base::FilePath& path) {
} }
#endif #endif
v8::Persistent<v8::ObjectTemplate> template_;
} // namespace } // namespace
NativeImage::NativeImage() {} NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image)
: image_(image) {
NativeImage::NativeImage(const gfx::Image& image) : image_(image) {} Init(isolate);
}
NativeImage::~NativeImage() {} NativeImage::~NativeImage() {}
mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
.SetMethod("toPng", &NativeImage::ToPNG)
.SetMethod("toJpeg", &NativeImage::ToJPEG)
.SetMethod("getNativeHandle", &NativeImage::GetNativeHandle)
.SetMethod("toDataURL", &NativeImage::ToDataURL)
.SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated.
.SetMethod("isEmpty", &NativeImage::IsEmpty)
.SetMethod("getSize", &NativeImage::GetSize)
.SetMethod("setTemplateImage", &NativeImage::SetTemplateImage)
.SetMethod("isTemplateImage", &NativeImage::IsTemplateImage)
.Build());
return mate::ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
v8::Local<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) { v8::Local<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) {
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes(); scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
return node::Buffer::Copy(isolate, return node::Buffer::Copy(isolate,
@ -255,13 +235,13 @@ bool NativeImage::IsTemplateImage() {
// static // static
mate::Handle<NativeImage> NativeImage::CreateEmpty(v8::Isolate* isolate) { mate::Handle<NativeImage> NativeImage::CreateEmpty(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new NativeImage); return mate::CreateHandle(isolate, new NativeImage(isolate, gfx::Image()));
} }
// static // static
mate::Handle<NativeImage> NativeImage::Create( mate::Handle<NativeImage> NativeImage::Create(
v8::Isolate* isolate, const gfx::Image& image) { v8::Isolate* isolate, const gfx::Image& image) {
return mate::CreateHandle(isolate, new NativeImage(image)); return mate::CreateHandle(isolate, new NativeImage(isolate, image));
} }
// static // static
@ -330,6 +310,21 @@ mate::Handle<NativeImage> NativeImage::CreateFromDataURL(
return CreateEmpty(isolate); return CreateEmpty(isolate);
} }
// static
void NativeImage::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("toPng", &NativeImage::ToPNG)
.SetMethod("toJpeg", &NativeImage::ToJPEG)
.SetMethod("getNativeHandle", &NativeImage::GetNativeHandle)
.SetMethod("toDataURL", &NativeImage::ToDataURL)
.SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated.
.SetMethod("isEmpty", &NativeImage::IsEmpty)
.SetMethod("getSize", &NativeImage::GetSize)
.SetMethod("setTemplateImage", &NativeImage::SetTemplateImage)
.SetMethod("isTemplateImage", &NativeImage::IsTemplateImage);
}
} // namespace api } // namespace api
} // namespace atom } // namespace atom

View file

@ -29,7 +29,7 @@ namespace atom {
namespace api { namespace api {
class NativeImage : public mate::Wrappable { class NativeImage : public mate::Wrappable<NativeImage> {
public: public:
static mate::Handle<NativeImage> CreateEmpty(v8::Isolate* isolate); static mate::Handle<NativeImage> CreateEmpty(v8::Isolate* isolate);
static mate::Handle<NativeImage> Create( static mate::Handle<NativeImage> Create(
@ -45,18 +45,14 @@ class NativeImage : public mate::Wrappable {
static mate::Handle<NativeImage> CreateFromDataURL( static mate::Handle<NativeImage> CreateFromDataURL(
v8::Isolate* isolate, const GURL& url); v8::Isolate* isolate, const GURL& url);
// The default constructor should only be used by image_converter.cc. static void BuildPrototype(v8::Isolate* isolate,
NativeImage(); v8::Local<v8::ObjectTemplate> prototype);
const gfx::Image& image() const { return image_; } const gfx::Image& image() const { return image_; }
protected: protected:
explicit NativeImage(const gfx::Image& image); NativeImage(v8::Isolate* isolate, const gfx::Image& image);
virtual ~NativeImage(); ~NativeImage() override;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private: private:
v8::Local<v8::Value> ToPNG(v8::Isolate* isolate); v8::Local<v8::Value> ToPNG(v8::Isolate* isolate);

View file

@ -4,7 +4,9 @@
#include <string> #include <string>
#include "atom/common/api/object_life_monitor.h" #include "atom/common/api/remote_callback_freer.h"
#include "atom/common/api/remote_object_freer.h"
#include "atom/common/native_mate_converters/content_converter.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "v8/include/v8-profiler.h" #include "v8/include/v8-profiler.h"
@ -51,12 +53,6 @@ int32_t GetObjectHash(v8::Local<v8::Object> object) {
return object->GetIdentityHash(); return object->GetIdentityHash();
} }
void SetDestructor(v8::Isolate* isolate,
v8::Local<v8::Object> object,
v8::Local<v8::Function> callback) {
atom::ObjectLifeMonitor::BindTo(isolate, object, callback);
}
void TakeHeapSnapshot(v8::Isolate* isolate) { void TakeHeapSnapshot(v8::Isolate* isolate) {
isolate->GetHeapProfiler()->TakeHeapSnapshot(); isolate->GetHeapProfiler()->TakeHeapSnapshot();
} }
@ -68,8 +64,9 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("setHiddenValue", &SetHiddenValue); dict.SetMethod("setHiddenValue", &SetHiddenValue);
dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue); dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue);
dict.SetMethod("getObjectHash", &GetObjectHash); dict.SetMethod("getObjectHash", &GetObjectHash);
dict.SetMethod("setDestructor", &SetDestructor);
dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot); dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot);
dict.SetMethod("setRemoteCallbackFreer", &atom::RemoteCallbackFreer::BindTo);
dict.SetMethod("setRemoteObjectFreer", &atom::RemoteObjectFreer::BindTo);
} }
} // namespace } // namespace

View file

@ -10,30 +10,28 @@
namespace atom { namespace atom {
// static
void ObjectLifeMonitor::BindTo(v8::Isolate* isolate,
v8::Local<v8::Object> target,
v8::Local<v8::Function> destructor) {
new ObjectLifeMonitor(isolate, target, destructor);
}
ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate, ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate,
v8::Local<v8::Object> target, v8::Local<v8::Object> target)
v8::Local<v8::Function> destructor)
: isolate_(isolate), : isolate_(isolate),
context_(isolate, isolate->GetCurrentContext()), context_(isolate, isolate->GetCurrentContext()),
target_(isolate, target), target_(isolate, target),
destructor_(isolate, destructor),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter); target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter);
} }
ObjectLifeMonitor::~ObjectLifeMonitor() {
if (target_.IsEmpty())
return;
target_.ClearWeak();
target_.Reset();
}
// static // static
void ObjectLifeMonitor::OnObjectGC( void ObjectLifeMonitor::OnObjectGC(
const v8::WeakCallbackInfo<ObjectLifeMonitor>& data) { const v8::WeakCallbackInfo<ObjectLifeMonitor>& data) {
ObjectLifeMonitor* self = data.GetParameter(); ObjectLifeMonitor* self = data.GetParameter();
self->target_.Reset(); self->target_.Reset();
self->RunCallback(); self->RunDestructor();
data.SetSecondPassCallback(Free); data.SetSecondPassCallback(Free);
} }
@ -43,13 +41,4 @@ void ObjectLifeMonitor::Free(
delete data.GetParameter(); delete data.GetParameter();
} }
void ObjectLifeMonitor::RunCallback() {
v8::HandleScope handle_scope(isolate_);
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(
isolate_, context_);
v8::Context::Scope context_scope(context);
v8::Local<v8::Function>::New(isolate_, destructor_)->Call(
context->Global(), 0, nullptr);
}
} // namespace atom } // namespace atom

View file

@ -12,25 +12,19 @@
namespace atom { namespace atom {
class ObjectLifeMonitor { class ObjectLifeMonitor {
public: protected:
static void BindTo(v8::Isolate* isolate, ObjectLifeMonitor(v8::Isolate* isolate, v8::Local<v8::Object> target);
v8::Local<v8::Object> target, virtual ~ObjectLifeMonitor();
v8::Local<v8::Function> destructor);
virtual void RunDestructor() = 0;
private: private:
ObjectLifeMonitor(v8::Isolate* isolate,
v8::Local<v8::Object> target,
v8::Local<v8::Function> destructor);
static void OnObjectGC(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data); static void OnObjectGC(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data);
static void Free(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data); static void Free(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data);
void RunCallback();
v8::Isolate* isolate_; v8::Isolate* isolate_;
v8::Global<v8::Context> context_; v8::Global<v8::Context> context_;
v8::Global<v8::Object> target_; v8::Global<v8::Object> target_;
v8::Global<v8::Function> destructor_;
base::WeakPtrFactory<ObjectLifeMonitor> weak_ptr_factory_; base::WeakPtrFactory<ObjectLifeMonitor> weak_ptr_factory_;

View file

@ -0,0 +1,47 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/api/remote_callback_freer.h"
#include "atom/common/api/api_messages.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
namespace atom {
// static
void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_contents) {
new RemoteCallbackFreer(isolate, target, object_id, web_contents);
}
RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_contents)
: ObjectLifeMonitor(isolate, target),
content::WebContentsObserver(web_contents),
object_id_(object_id) {
}
RemoteCallbackFreer::~RemoteCallbackFreer() {
}
void RemoteCallbackFreer::RunDestructor() {
base::string16 channel =
base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK");
base::ListValue args;
args.AppendInteger(object_id_);
Send(new AtomViewMsg_Message(routing_id(), channel, args));
Observe(nullptr);
}
void RemoteCallbackFreer::RenderViewDeleted(content::RenderViewHost*) {
delete this;
}
} // namespace atom

View file

@ -0,0 +1,40 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
#define ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
#include "atom/common/api/object_life_monitor.h"
#include "content/public/browser/web_contents_observer.h"
namespace atom {
class RemoteCallbackFreer : public ObjectLifeMonitor,
public content::WebContentsObserver {
public:
static void BindTo(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_conents);
protected:
RemoteCallbackFreer(v8::Isolate* isolate,
v8::Local<v8::Object> target,
int object_id,
content::WebContents* web_conents);
~RemoteCallbackFreer() override;
void RunDestructor() override;
// content::WebContentsObserver:
void RenderViewDeleted(content::RenderViewHost*) override;
private:
int object_id_;
DISALLOW_COPY_AND_ASSIGN(RemoteCallbackFreer);
};
} // namespace atom
#endif // ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_

View file

@ -0,0 +1,63 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/api/remote_object_freer.h"
#include "atom/common/api/api_messages.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
using blink::WebLocalFrame;
using blink::WebView;
namespace atom {
namespace {
content::RenderView* GetCurrentRenderView() {
WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext();
if (!frame)
return nullptr;
WebView* view = frame->view();
if (!view)
return nullptr; // can happen during closing.
return content::RenderView::FromWebView(view);
}
} // namespace
// static
void RemoteObjectFreer::BindTo(
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id) {
new RemoteObjectFreer(isolate, target, object_id);
}
RemoteObjectFreer::RemoteObjectFreer(
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id)
: ObjectLifeMonitor(isolate, target),
object_id_(object_id) {
}
RemoteObjectFreer::~RemoteObjectFreer() {
}
void RemoteObjectFreer::RunDestructor() {
content::RenderView* render_view = GetCurrentRenderView();
if (!render_view)
return;
base::string16 channel = base::ASCIIToUTF16("ipc-message");
base::ListValue args;
args.AppendString("ELECTRON_BROWSER_DEREFERENCE");
args.AppendInteger(object_id_);
render_view->Send(
new AtomViewHostMsg_Message(render_view->GetRoutingID(), channel, args));
}
} // namespace atom

View file

@ -0,0 +1,32 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_
#define ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_
#include "atom/common/api/object_life_monitor.h"
namespace atom {
class RemoteObjectFreer : public ObjectLifeMonitor {
public:
static void BindTo(
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id);
protected:
RemoteObjectFreer(
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id);
~RemoteObjectFreer() override;
void RunDestructor() override;
private:
int object_id_;
DISALLOW_COPY_AND_ASSIGN(RemoteObjectFreer);
};
} // namespace atom
#endif // ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_

View file

@ -7,7 +7,7 @@
#define ATOM_MAJOR_VERSION 0 #define ATOM_MAJOR_VERSION 0
#define ATOM_MINOR_VERSION 37 #define ATOM_MINOR_VERSION 37
#define ATOM_PATCH_VERSION 6 #define ATOM_PATCH_VERSION 8
#define ATOM_VERSION_IS_RELEASE 1 #define ATOM_VERSION_IS_RELEASE 1

View file

@ -145,6 +145,8 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
return StringToV8(isolate, "pointerLock"); return StringToV8(isolate, "pointerLock");
else if (val == (content::PermissionType)(PermissionType::FULLSCREEN)) else if (val == (content::PermissionType)(PermissionType::FULLSCREEN))
return StringToV8(isolate, "fullscreen"); return StringToV8(isolate, "fullscreen");
else if (val == (content::PermissionType)(PermissionType::OPEN_EXTERNAL))
return StringToV8(isolate, "openExternal");
return StringToV8(isolate, "unknown"); return StringToV8(isolate, "unknown");
} }
@ -178,4 +180,17 @@ v8::Local<v8::Value> Converter<content::WebContents*>::ToV8(
return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); return atom::api::WebContents::CreateFrom(isolate, val).ToV8();
} }
// static
bool Converter<content::WebContents*>::FromV8(
v8::Isolate* isolate,
v8::Local<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* web_contents = nullptr;
if (!ConvertFromV8(isolate, val, &web_contents) || !web_contents)
return false;
*out = web_contents->web_contents();
return true;
}
} // namespace mate } // namespace mate

View file

@ -57,6 +57,8 @@ template<>
struct Converter<content::WebContents*> { struct Converter<content::WebContents*> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
content::WebContents* val); content::WebContents* val);
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
content::WebContents** out);
}; };
} // namespace mate } // namespace mate

View file

@ -44,6 +44,7 @@ REFERENCE_MODULE(atom_browser_power_save_blocker);
REFERENCE_MODULE(atom_browser_protocol); REFERENCE_MODULE(atom_browser_protocol);
REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_session); REFERENCE_MODULE(atom_browser_session);
REFERENCE_MODULE(atom_browser_system_preferences);
REFERENCE_MODULE(atom_browser_tray); REFERENCE_MODULE(atom_browser_tray);
REFERENCE_MODULE(atom_browser_web_contents); REFERENCE_MODULE(atom_browser_web_contents);
REFERENCE_MODULE(atom_browser_web_view_manager); REFERENCE_MODULE(atom_browser_web_view_manager);

View file

@ -119,9 +119,6 @@ const char kPpapiFlashPath[] = "ppapi-flash-path";
// Ppapi Flash version. // Ppapi Flash version.
const char kPpapiFlashVersion[] = "ppapi-flash-version"; const char kPpapiFlashVersion[] = "ppapi-flash-version";
// Path to client certificate.
const char kClientCertificate[] = "client-certificate";
// Disable HTTP cache. // Disable HTTP cache.
const char kDisableHttpCache[] = "disable-http-cache"; const char kDisableHttpCache[] = "disable-http-cache";

View file

@ -68,7 +68,6 @@ namespace switches {
extern const char kEnablePlugins[]; extern const char kEnablePlugins[];
extern const char kPpapiFlashPath[]; extern const char kPpapiFlashPath[];
extern const char kPpapiFlashVersion[]; extern const char kPpapiFlashVersion[];
extern const char kClientCertificate[];
extern const char kDisableHttpCache[]; extern const char kDisableHttpCache[];
extern const char kRegisterStandardSchemes[]; extern const char kRegisterStandardSchemes[];
extern const char kRegisterServiceWorkerSchemes[]; extern const char kRegisterServiceWorkerSchemes[];

View file

@ -54,8 +54,9 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
} // namespace } // namespace
WebFrame::WebFrame() WebFrame::WebFrame(v8::Isolate* isolate)
: web_frame_(blink::WebLocalFrame::frameForCurrentContext()) { : web_frame_(blink::WebLocalFrame::frameForCurrentContext()) {
Init(isolate);
} }
WebFrame::~WebFrame() { WebFrame::~WebFrame() {
@ -67,7 +68,7 @@ void WebFrame::SetName(const std::string& name) {
double WebFrame::SetZoomLevel(double level) { double WebFrame::SetZoomLevel(double level) {
double ret = web_frame_->view()->setZoomLevel(level); double ret = web_frame_->view()->setZoomLevel(level);
mate::EmitEvent(isolate(), GetWrapper(isolate()), "zoom-level-changed", ret); mate::EmitEvent(isolate(), GetWrapper(), "zoom-level-changed", ret);
return ret; return ret;
} }
@ -162,9 +163,15 @@ void WebFrame::ExecuteJavaScript(const base::string16& code,
callback.release()); callback.release());
} }
mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( // static
v8::Isolate* isolate) { mate::Handle<WebFrame> WebFrame::Create(v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate) return mate::CreateHandle(isolate, new WebFrame(isolate));
}
// static
void WebFrame::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("setName", &WebFrame::SetName) .SetMethod("setName", &WebFrame::SetName)
.SetMethod("setZoomLevel", &WebFrame::SetZoomLevel) .SetMethod("setZoomLevel", &WebFrame::SetZoomLevel)
.SetMethod("getZoomLevel", &WebFrame::GetZoomLevel) .SetMethod("getZoomLevel", &WebFrame::GetZoomLevel)
@ -187,11 +194,6 @@ mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder(
.SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript); .SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript);
} }
// static
mate::Handle<WebFrame> WebFrame::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new WebFrame);
}
} // namespace api } // namespace api
} // namespace atom } // namespace atom

View file

@ -26,13 +26,16 @@ namespace api {
class SpellCheckClient; class SpellCheckClient;
class WebFrame : public mate::Wrappable { class WebFrame : public mate::Wrappable<WebFrame> {
public: public:
static mate::Handle<WebFrame> Create(v8::Isolate* isolate); static mate::Handle<WebFrame> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
private: private:
WebFrame(); explicit WebFrame(v8::Isolate* isolate);
virtual ~WebFrame(); ~WebFrame() override;
void SetName(const std::string& name); void SetName(const std::string& name);
@ -66,10 +69,6 @@ class WebFrame : public mate::Wrappable {
// Excecuting scripts. // Excecuting scripts.
void ExecuteJavaScript(const base::string16& code, mate::Arguments* args); void ExecuteJavaScript(const base::string16& code, mate::Arguments* args);
// mate::Wrappable:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate);
scoped_ptr<SpellCheckClient> spell_check_client_; scoped_ptr<SpellCheckClient> spell_check_client_;
blink::WebLocalFrame* web_frame_; blink::WebLocalFrame* web_frame_;

View file

@ -0,0 +1,173 @@
// Copyright (c) 2012 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 "chrome/browser/certificate_manager_model.h"
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/cert/nss_cert_database.h"
#include "net/cert/x509_certificate.h"
using content::BrowserThread;
namespace {
net::NSSCertDatabase* g_nss_cert_database = nullptr;
net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
content::ResourceContext* context,
const base::Callback<void(net::NSSCertDatabase*)>& callback) {
// This initialization is not thread safe. This CHECK ensures that this code
// is only run on a single thread.
CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
if (!g_nss_cert_database) {
// Linux has only a single persistent slot compared to ChromeOS's separate
// public and private slot.
// Redirect any slot usage to this persistent slot on Linux.
g_nss_cert_database = new net::NSSCertDatabase(
crypto::ScopedPK11Slot(
crypto::GetPersistentNSSKeySlot()) /* public slot */,
crypto::ScopedPK11Slot(
crypto::GetPersistentNSSKeySlot()) /* private slot */);
}
return g_nss_cert_database;
}
} // namespace
// CertificateManagerModel is created on the UI thread. It needs a
// NSSCertDatabase handle (and on ChromeOS it needs to get the TPM status) which
// needs to be done on the IO thread.
//
// The initialization flow is roughly:
//
// UI thread IO Thread
//
// CertificateManagerModel::Create
// \--------------------------------------v
// CertificateManagerModel::GetCertDBOnIOThread
// |
// GetNSSCertDatabaseForResourceContext
// |
// CertificateManagerModel::DidGetCertDBOnIOThread
// v--------------------------------------/
// CertificateManagerModel::DidGetCertDBOnUIThread
// |
// new CertificateManagerModel
// |
// callback
// static
void CertificateManagerModel::Create(
content::BrowserContext* browser_context,
const CreationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&CertificateManagerModel::GetCertDBOnIOThread,
browser_context->GetResourceContext(),
callback));
}
CertificateManagerModel::CertificateManagerModel(
net::NSSCertDatabase* nss_cert_database,
bool is_user_db_available)
: cert_db_(nss_cert_database),
is_user_db_available_(is_user_db_available) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
CertificateManagerModel::~CertificateManagerModel() {
}
int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module,
const std::string& data,
const base::string16& password,
bool is_extractable,
net::CertificateList* imported_certs) {
return cert_db_->ImportFromPKCS12(module, data, password,
is_extractable, imported_certs);
}
int CertificateManagerModel::ImportUserCert(const std::string& data) {
return cert_db_->ImportUserCert(data);
}
bool CertificateManagerModel::ImportCACerts(
const net::CertificateList& certificates,
net::NSSCertDatabase::TrustBits trust_bits,
net::NSSCertDatabase::ImportCertFailureList* not_imported) {
return cert_db_->ImportCACerts(certificates, trust_bits, not_imported);
}
bool CertificateManagerModel::ImportServerCert(
const net::CertificateList& certificates,
net::NSSCertDatabase::TrustBits trust_bits,
net::NSSCertDatabase::ImportCertFailureList* not_imported) {
return cert_db_->ImportServerCert(certificates, trust_bits,
not_imported);
}
bool CertificateManagerModel::SetCertTrust(
const net::X509Certificate* cert,
net::CertType type,
net::NSSCertDatabase::TrustBits trust_bits) {
return cert_db_->SetCertTrust(cert, type, trust_bits);
}
bool CertificateManagerModel::Delete(net::X509Certificate* cert) {
return cert_db_->DeleteCertAndKey(cert);
}
// static
void CertificateManagerModel::DidGetCertDBOnUIThread(
net::NSSCertDatabase* cert_db,
bool is_user_db_available,
const CreationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
scoped_ptr<CertificateManagerModel> model(new CertificateManagerModel(
cert_db, is_user_db_available));
callback.Run(std::move(model));
}
// static
void CertificateManagerModel::DidGetCertDBOnIOThread(
const CreationCallback& callback,
net::NSSCertDatabase* cert_db) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool is_user_db_available = !!cert_db->GetPublicSlot();
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&CertificateManagerModel::DidGetCertDBOnUIThread,
cert_db,
is_user_db_available,
callback));
}
// static
void CertificateManagerModel::GetCertDBOnIOThread(
content::ResourceContext* context,
const CreationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext(
context,
base::Bind(&CertificateManagerModel::DidGetCertDBOnIOThread,
callback));
if (cert_db)
DidGetCertDBOnIOThread(callback, cert_db);
}

View file

@ -0,0 +1,119 @@
// Copyright (c) 2012 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.
#ifndef CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_
#define CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_
#include <map>
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "net/cert/nss_cert_database.h"
namespace content {
class BrowserContext;
class ResourceContext;
} // namespace content
// CertificateManagerModel provides the data to be displayed in the certificate
// manager dialog, and processes changes from the view.
class CertificateManagerModel {
public:
typedef base::Callback<void(scoped_ptr<CertificateManagerModel>)>
CreationCallback;
// Creates a CertificateManagerModel. The model will be passed to the callback
// when it is ready. The caller must ensure the model does not outlive the
// |browser_context|.
static void Create(content::BrowserContext* browser_context,
const CreationCallback& callback);
~CertificateManagerModel();
bool is_user_db_available() const { return is_user_db_available_; }
// Accessor for read-only access to the underlying NSSCertDatabase.
const net::NSSCertDatabase* cert_db() const { return cert_db_; }
// Import private keys and certificates from PKCS #12 encoded
// |data|, using the given |password|. If |is_extractable| is false,
// mark the private key as unextractable from the module.
// Returns a net error code on failure.
int ImportFromPKCS12(net::CryptoModule* module,
const std::string& data,
const base::string16& password,
bool is_extractable,
net::CertificateList* imported_certs);
// Import user certificate from DER encoded |data|.
// Returns a net error code on failure.
int ImportUserCert(const std::string& data);
// Import CA certificates.
// Tries to import all the certificates given. The root will be trusted
// according to |trust_bits|. Any certificates that could not be imported
// will be listed in |not_imported|.
// |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase.
// Returns false if there is an internal error, otherwise true is returned and
// |not_imported| should be checked for any certificates that were not
// imported.
bool ImportCACerts(const net::CertificateList& certificates,
net::NSSCertDatabase::TrustBits trust_bits,
net::NSSCertDatabase::ImportCertFailureList* not_imported);
// Import server certificate. The first cert should be the server cert. Any
// additional certs should be intermediate/CA certs and will be imported but
// not given any trust.
// Any certificates that could not be imported will be listed in
// |not_imported|.
// |trust_bits| can be set to explicitly trust or distrust the certificate, or
// use TRUST_DEFAULT to inherit trust as normal.
// Returns false if there is an internal error, otherwise true is returned and
// |not_imported| should be checked for any certificates that were not
// imported.
bool ImportServerCert(
const net::CertificateList& certificates,
net::NSSCertDatabase::TrustBits trust_bits,
net::NSSCertDatabase::ImportCertFailureList* not_imported);
// Set trust values for certificate.
// |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase.
// Returns true on success or false on failure.
bool SetCertTrust(const net::X509Certificate* cert,
net::CertType type,
net::NSSCertDatabase::TrustBits trust_bits);
// Delete the cert. Returns true on success. |cert| is still valid when this
// function returns.
bool Delete(net::X509Certificate* cert);
private:
CertificateManagerModel(net::NSSCertDatabase* nss_cert_database,
bool is_user_db_available);
// Methods used during initialization, see the comment at the top of the .cc
// file for details.
static void DidGetCertDBOnUIThread(
net::NSSCertDatabase* cert_db,
bool is_user_db_available,
const CreationCallback& callback);
static void DidGetCertDBOnIOThread(
const CreationCallback& callback,
net::NSSCertDatabase* cert_db);
static void GetCertDBOnIOThread(content::ResourceContext* context,
const CreationCallback& callback);
net::NSSCertDatabase* cert_db_;
// Whether the certificate database has a public slot associated with the
// profile. If not set, importing certificates is not allowed with this model.
bool is_user_db_available_;
DISALLOW_COPY_AND_ASSIGN(CertificateManagerModel);
};
#endif // CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_

View file

@ -111,7 +111,7 @@ const base::FilePath::CharType kSingletonCookieFilename[] =
const base::FilePath::CharType kSingletonLockFilename[] = FILE_PATH_LITERAL("SingletonLock"); const base::FilePath::CharType kSingletonLockFilename[] = FILE_PATH_LITERAL("SingletonLock");
const base::FilePath::CharType kSingletonSocketFilename[] = const base::FilePath::CharType kSingletonSocketFilename[] =
FILE_PATH_LITERAL("SingletonSocket"); FILE_PATH_LITERAL("SS");
// Set the close-on-exec bit on a file descriptor. // Set the close-on-exec bit on a file descriptor.
// Returns 0 on success, -1 on failure. // Returns 0 on success, -1 on failure.
@ -717,6 +717,9 @@ ProcessSingleton::ProcessSingleton(
const NotificationCallback& notification_callback) const NotificationCallback& notification_callback)
: notification_callback_(notification_callback), : notification_callback_(notification_callback),
current_pid_(base::GetCurrentProcId()) { current_pid_(base::GetCurrentProcId()) {
// The user_data_dir may have not been created yet.
base::CreateDirectoryAndGetError(user_data_dir, nullptr);
socket_path_ = user_data_dir.Append(kSingletonSocketFilename); socket_path_ = user_data_dir.Append(kSingletonSocketFilename);
lock_path_ = user_data_dir.Append(kSingletonLockFilename); lock_path_ = user_data_dir.Append(kSingletonLockFilename);
cookie_path_ = user_data_dir.Append(kSingletonCookieFilename); cookie_path_ = user_data_dir.Append(kSingletonCookieFilename);
@ -943,6 +946,19 @@ bool ProcessSingleton::Create() {
#endif #endif
} }
#if defined(MAS_BUILD)
// For Mac App Store build, the tmp dir could be too long to fit
// addr->sun_path, so we need to make it as short as possible.
base::FilePath tmp_dir;
if (!base::GetTempDir(&tmp_dir)) {
LOG(ERROR) << "Failed to get temporary directory.";
return false;
}
if (!socket_dir_.Set(tmp_dir.Append("S"))) {
LOG(ERROR) << "Failed to set socket directory.";
return false;
}
#else
// Create the socket file somewhere in /tmp which is usually mounted as a // Create the socket file somewhere in /tmp which is usually mounted as a
// normal filesystem. Some network filesystems (notably AFS) are screwy and // normal filesystem. Some network filesystems (notably AFS) are screwy and
// do not support Unix domain sockets. // do not support Unix domain sockets.
@ -950,6 +966,7 @@ bool ProcessSingleton::Create() {
LOG(ERROR) << "Failed to create socket directory."; LOG(ERROR) << "Failed to create socket directory.";
return false; return false;
} }
#endif
// Check that the directory was created with the correct permissions. // Check that the directory was created with the correct permissions.
int dir_mode = 0; int dir_mode = 0;

View file

@ -10,6 +10,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/process/process.h" #include "base/process/process.h"
#include "base/process/process_info.h" #include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
@ -190,6 +191,8 @@ ProcessSingleton::ProcessSingleton(
user_data_dir_(user_data_dir), user_data_dir_(user_data_dir),
should_kill_remote_process_callback_( should_kill_remote_process_callback_(
base::Bind(&TerminateAppWithError)) { base::Bind(&TerminateAppWithError)) {
// The user_data_dir may have not been created yet.
base::CreateDirectoryAndGetError(user_data_dir, nullptr);
} }
ProcessSingleton::~ProcessSingleton() { ProcessSingleton::~ProcessSingleton() {

View file

@ -15,7 +15,7 @@ exports.load = function (appUrl) {
width: 800, width: 800,
height: 600, height: 600,
autoHideMenuBar: true, autoHideMenuBar: true,
backgroundColor: '#A5ECFA', backgroundColor: '#FFFFFF',
useContentSize: true useContentSize: true
}) })
mainWindow.loadURL(appUrl) mainWindow.loadURL(appUrl)

File diff suppressed because one or more lines are too long

View file

@ -35,7 +35,7 @@
* [content-tracing](../../docs/api/content-tracing.md) * [content-tracing](../../docs/api/content-tracing.md)
* [dialog](../../docs/api/dialog.md) * [dialog](../../docs/api/dialog.md)
* [global-shortcut](../../docs/api/global-shortcut.md) * [global-shortcut](../../docs/api/global-shortcut.md)
* [ipc (proceso principal)](../../docs/api/ipc-main-process.md) * [ipc (proceso principal)](../../docs/api/ipc-main.md)
* [menu](../../docs/api/menu.md) * [menu](../../docs/api/menu.md)
* [menu-item](../../docs/api/menu-item.md) * [menu-item](../../docs/api/menu-item.md)
* [power-monitor](../../docs/api/power-monitor.md) * [power-monitor](../../docs/api/power-monitor.md)
@ -66,6 +66,6 @@
* [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) * [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md)
* [Repaso del Sistema de Compilación](development/build-system-overview.md) * [Repaso del Sistema de Compilación](development/build-system-overview.md)
* [Instrucciones de Compilación (Mac)](development/build-instructions-osx.md) * [Instrucciones de Compilación (Mac)](development/build-instructions-osx.md)
* [Instrucciones de Compilación (Windows)](../../development/build-instructions-windows.md) * [Instrucciones de Compilación (Windows)](development/build-instructions-windows.md)
* [Instrucciones de Compilación (Linux)](development/build-instructions-linux.md) * [Instrucciones de Compilación (Linux)](development/build-instructions-linux.md)
* [Configurando un Servidor de Símbolos en el depurador](../../development/setting-up-symbol-server.md) * [Configurando un Servidor de Símbolos en el depurador](development/setting-up-symbol-server.md)

Some files were not shown because too many files have changed in this diff Show more