Merge branch 'master' into felix-notification-docs

This commit is contained in:
Zeke "Offline in April" Sikelianos 2017-05-01 15:56:14 -07:00 committed by GitHub
commit 9fd1e2c8c4
243 changed files with 6040 additions and 1835 deletions

View file

@ -5,7 +5,7 @@
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev) [![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) [![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/)
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) :memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) | [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR/project/README.md)
The Electron framework lets you write cross-platform desktop applications The Electron framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
@ -75,7 +75,7 @@ forums
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)* - [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)* - [`electron-tr`](https://electron-tr.slack.com) *(Turkish)*
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)* - [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)

View file

@ -44,7 +44,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
std::vector<std::string> flash_version_numbers = base::SplitString( std::vector<std::string> flash_version_numbers = base::SplitString(
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
if (flash_version_numbers.size() < 1) if (flash_version_numbers.empty())
flash_version_numbers.push_back("11"); flash_version_numbers.push_back("11");
// |SplitString()| puts in an empty string given an empty string. :( // |SplitString()| puts in an empty string given an empty string. :(
else if (flash_version_numbers[0].empty()) else if (flash_version_numbers[0].empty())

View file

@ -427,7 +427,7 @@ void OnClientCertificateSelected(
auto certs = net::X509Certificate::CreateCertificateListFromBytes( auto certs = net::X509Certificate::CreateCertificateListFromBytes(
data.c_str(), data.length(), net::X509Certificate::FORMAT_AUTO); data.c_str(), data.length(), net::X509Certificate::FORMAT_AUTO);
if (certs.size() > 0) if (!certs.empty())
delegate->ContinueWithCertificate(certs[0].get()); delegate->ContinueWithCertificate(certs[0].get());
} }
@ -520,7 +520,7 @@ void App::OnQuit() {
int exitCode = AtomBrowserMainParts::Get()->GetExitCode(); int exitCode = AtomBrowserMainParts::Get()->GetExitCode();
Emit("quit", exitCode); Emit("quit", exitCode);
if (process_singleton_.get()) { if (process_singleton_) {
process_singleton_->Cleanup(); process_singleton_->Cleanup();
process_singleton_.reset(); process_singleton_.reset();
} }
@ -655,6 +655,14 @@ void App::OnGpuProcessCrashed(base::TerminationStatus status) {
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED); status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
} }
base::FilePath App::GetAppPath() const {
return app_path_;
}
void App::SetAppPath(const base::FilePath& app_path) {
app_path_ = app_path;
}
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;
@ -695,7 +703,7 @@ std::string App::GetLocale() {
bool App::MakeSingleInstance( bool App::MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback) { const ProcessSingleton::NotificationCallback& callback) {
if (process_singleton_.get()) if (process_singleton_)
return false; return false;
base::FilePath user_dir; base::FilePath user_dir;
@ -716,7 +724,7 @@ bool App::MakeSingleInstance(
} }
void App::ReleaseSingleInstance() { void App::ReleaseSingleInstance() {
if (process_singleton_.get()) { if (process_singleton_) {
process_singleton_->Cleanup(); process_singleton_->Cleanup();
process_singleton_.reset(); process_singleton_.reset();
} }
@ -959,6 +967,8 @@ void App::BuildPrototype(
.SetMethod("isUnityRunning", .SetMethod("isUnityRunning",
base::Bind(&Browser::IsUnityRunning, browser)) base::Bind(&Browser::IsUnityRunning, browser))
#endif #endif
.SetMethod("setAppPath", &App::SetAppPath)
.SetMethod("getAppPath", &App::GetAppPath)
.SetMethod("setPath", &App::SetPath) .SetMethod("setPath", &App::SetPath)
.SetMethod("getPath", &App::GetPath) .SetMethod("getPath", &App::GetPath)
.SetMethod("setDesktopName", &App::SetDesktopName) .SetMethod("setDesktopName", &App::SetDesktopName)

View file

@ -70,6 +70,8 @@ class App : public AtomBrowserClient::Delegate,
std::unique_ptr<CertificateManagerModel> model); std::unique_ptr<CertificateManagerModel> model);
#endif #endif
base::FilePath GetAppPath() const;
protected: protected:
explicit App(v8::Isolate* isolate); explicit App(v8::Isolate* isolate);
~App() override; ~App() override;
@ -115,6 +117,8 @@ class App : public AtomBrowserClient::Delegate,
void OnGpuProcessCrashed(base::TerminationStatus status) override; void OnGpuProcessCrashed(base::TerminationStatus status) override;
private: private:
void SetAppPath(const base::FilePath& app_path);
// 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);
void SetPath(mate::Arguments* args, void SetPath(mate::Arguments* args,
@ -154,6 +158,8 @@ class App : public AtomBrowserClient::Delegate,
// Tracks tasks requesting file icons. // Tracks tasks requesting file icons.
base::CancelableTaskTracker cancelable_task_tracker_; base::CancelableTaskTracker cancelable_task_tracker_;
base::FilePath app_path_;
DISALLOW_COPY_AND_ASSIGN(App); DISALLOW_COPY_AND_ASSIGN(App);
}; };

View file

@ -7,6 +7,7 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.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 "atom/common/api/event_emitter_caller.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
#include "base/time/time.h" #include "base/time/time.h"
@ -47,7 +48,9 @@ void AutoUpdater::OnError(const std::string& message) {
v8::Locker locker(isolate()); v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate()); v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message)); auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
EmitCustomEvent( mate::EmitEvent(
isolate(),
GetWrapper(),
"error", "error",
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(), error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
// Message is also emitted to keep compatibility with old code. // Message is also emitted to keep compatibility with old code.
@ -87,16 +90,14 @@ void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
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(); if (WindowList::IsEmpty()) {
if (window_list->size() == 0) {
auto_updater::AutoUpdater::QuitAndInstall(); auto_updater::AutoUpdater::QuitAndInstall();
return; return;
} }
// Otherwise do the restart after all windows have been closed. // Otherwise do the restart after all windows have been closed.
window_list->AddObserver(this); WindowList::AddObserver(this);
for (NativeWindow* window : *window_list) WindowList::CloseAllWindows();
window->Close();
} }
// static // static

View file

@ -0,0 +1,162 @@
// Copyright (c) 2017 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_browser_view.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_browser_view.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/geometry/rect.h"
namespace mate {
template <>
struct Converter<atom::AutoResizeFlags> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::AutoResizeFlags* auto_resize_flags) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params)) {
return false;
}
uint8_t flags = 0;
bool width = false;
if (params.Get("width", &width) && width) {
flags |= atom::kAutoResizeWidth;
}
bool height = false;
if (params.Get("height", &height) && height) {
flags |= atom::kAutoResizeHeight;
}
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
BrowserView::BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options)
: api_web_contents_(nullptr) {
Init(isolate, wrapper, options);
}
void BrowserView::Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
web_preferences.Set("isBrowserView", true);
mate::Handle<class WebContents> web_contents =
WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
view_.reset(NativeBrowserView::Create(
api_web_contents_->managed_web_contents()->GetView()));
InitWith(isolate, wrapper);
}
BrowserView::~BrowserView() {
api_web_contents_->DestroyWebContents(true /* async */);
}
// static
mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create BrowserView before app is ready");
return nullptr;
}
if (args->Length() > 1) {
args->ThrowError("Too many arguments");
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserView(args->isolate(), args->GetThis(), options);
}
int32_t BrowserView::ID() const {
return weak_map_id();
}
void BrowserView::SetAutoResize(AutoResizeFlags flags) {
view_->SetAutoResizeFlags(flags);
}
void BrowserView::SetBounds(const gfx::Rect& bounds) {
view_->SetBounds(bounds);
}
void BrowserView::SetBackgroundColor(const std::string& color_name) {
view_->SetBackgroundColor(ParseHexColor(color_name));
}
v8::Local<v8::Value> BrowserView::WebContents() {
if (web_contents_.IsEmpty()) {
return v8::Null(isolate());
}
return v8::Local<v8::Value>::New(isolate(), web_contents_);
}
// static
void BrowserView::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
.SetMethod("setBounds", &BrowserView::SetBounds)
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
.SetProperty("webContents", &BrowserView::WebContents)
.SetProperty("id", &BrowserView::ID);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::BrowserView;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New));
mate::Dictionary browser_view(
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserView", browser_view);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize)

View file

@ -0,0 +1,72 @@
// Copyright (c) 2017 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_BROWSER_VIEW_H_
#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#include <memory>
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_browser_view.h"
#include "native_mate/handle.h"
namespace gfx {
class Rect;
}
namespace mate {
class Arguments;
class Dictionary;
} // namespace mate
namespace atom {
class NativeBrowserView;
namespace api {
class WebContents;
class BrowserView : public mate::TrackableObject<BrowserView> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
NativeBrowserView* view() const { return view_.get(); }
int32_t ID() const;
protected:
BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~BrowserView() override;
private:
void Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);
void SetBackgroundColor(const std::string& color_name);
v8::Local<v8::Value> WebContents();
v8::Global<v8::Value> web_contents_;
class WebContents* api_web_contents_;
std::unique_ptr<NativeBrowserView> view_;
DISALLOW_COPY_AND_ASSIGN(BrowserView);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_

View file

@ -179,6 +179,13 @@ void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED)); base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
} }
// Flushes cookie store in IO thread.
void FlushCookieStoreOnIOThread(
scoped_refptr<net::URLRequestContextGetter> getter,
const base::Closure& callback) {
GetCookieStore(getter)->FlushStore(base::Bind(RunCallbackInUI, callback));
}
// Sets cookie with |details| in IO thread. // Sets cookie with |details| in IO thread.
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter, void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> details, std::unique_ptr<base::DictionaryValue> details,
@ -265,6 +272,13 @@ void Cookies::Set(const base::DictionaryValue& details,
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback)); base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
} }
void Cookies::FlushStore(const base::Closure& callback) {
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(FlushCookieStoreOnIOThread, getter, callback));
}
void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie, void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie,
bool removed, bool removed,
net::CookieStore::ChangeCause cause) { net::CookieStore::ChangeCause cause) {
@ -286,7 +300,8 @@ void Cookies::BuildPrototype(v8::Isolate* isolate,
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("get", &Cookies::Get) .SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove) .SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set); .SetMethod("set", &Cookies::Set)
.SetMethod("flushStore", &Cookies::FlushStore);
} }
} // namespace api } // namespace api

View file

@ -53,6 +53,7 @@ class Cookies : public mate::TrackableObject<Cookies>,
void Remove(const GURL& url, const std::string& name, void Remove(const GURL& url, const std::string& name,
const base::Closure& callback); const base::Closure& callback);
void Set(const base::DictionaryValue& details, const SetCallback& callback); void Set(const base::DictionaryValue& details, const SetCallback& callback);
void FlushStore(const base::Closure& callback);
// AtomCookieDelegate::Observer: // AtomCookieDelegate::Observer:
void OnCookieChanged(const net::CanonicalCookie& cookie, void OnCookieChanged(const net::CanonicalCookie& cookie,

View file

@ -9,7 +9,6 @@
#include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
@ -45,12 +44,23 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) { const std::string& message) {
DCHECK(agent_host == agent_host_.get()); DCHECK(agent_host == agent_host_.get());
std::unique_ptr<base::Value> parsed_message(base::JSONReader::Read(message)); v8::Locker locker(isolate());
if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY)) v8::HandleScope handle_scope(isolate());
return;
v8::Local<v8::String> local_message =
v8::String::NewFromUtf8(isolate(), message.data());
v8::MaybeLocal<v8::Value> parsed_message = v8::JSON::Parse(
isolate()->GetCurrentContext(), local_message);
if (parsed_message.IsEmpty()) {
return;
}
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
if (!mate::ConvertFromV8(isolate(), parsed_message.ToLocalChecked(),
dict.get())) {
return;
}
base::DictionaryValue* dict =
static_cast<base::DictionaryValue*>(parsed_message.get());
int id; int id;
if (!dict->GetInteger("id", &id)) { if (!dict->GetInteger("id", &id)) {
std::string method; std::string method;

View file

@ -8,11 +8,13 @@
#include "atom/browser/api/atom_api_window.h" #include "atom/browser/api/atom_api_window.h"
#include "atom/browser/native_window.h" #include "atom/browser/native_window.h"
#include "atom/browser/ui/certificate_trust.h"
#include "atom/browser/ui/file_dialog.h" #include "atom/browser/ui/file_dialog.h"
#include "atom/browser/ui/message_box.h" #include "atom/browser/ui/message_box.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.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/image_converter.h" #include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
@ -78,13 +80,14 @@ void ShowMessageBox(int type,
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
peek, peek,
&callback)) { &callback)) {
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
default_id, cancel_id, options, title, message, detail, buttons, default_id, cancel_id, options, title,
checkbox_label, checkbox_checked, icon, callback); message, detail, checkbox_label, checkbox_checked,
icon, callback);
} else { } else {
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type, int chosen = atom::ShowMessageBox(
buttons, default_id, cancel_id, window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
options, title, message, detail, icon); cancel_id, options, title, message, detail, icon);
args->Return(chosen); args->Return(chosen);
} }
} }
@ -126,6 +129,10 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("showErrorBox", &atom::ShowErrorBox); dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
dict.SetMethod("showOpenDialog", &ShowOpenDialog); dict.SetMethod("showOpenDialog", &ShowOpenDialog);
dict.SetMethod("showSaveDialog", &ShowSaveDialog); dict.SetMethod("showSaveDialog", &ShowSaveDialog);
#if defined(OS_MACOSX)
dict.SetMethod("showCertificateTrustDialog",
&certificate_trust::ShowCertificateTrust);
#endif
} }
} // namespace } // namespace

View file

@ -233,7 +233,7 @@ class ResolveProxyHelper {
public: public:
ResolveProxyHelper(AtomBrowserContext* browser_context, ResolveProxyHelper(AtomBrowserContext* browser_context,
const GURL& url, const GURL& url,
Session::ResolveProxyCallback callback) const Session::ResolveProxyCallback& callback)
: callback_(callback), : callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) { original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter = scoped_refptr<net::URLRequestContextGetter> context_getter =

View file

@ -8,6 +8,7 @@
#include "atom/browser/net/atom_url_request.h" #include "atom/browser/net/atom_url_request.h"
#include "atom/common/api/event_emitter_caller.h" #include "atom/common/api/event_emitter_caller.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
@ -145,6 +146,8 @@ mate::WrappableBase* URLRequest::New(mate::Arguments* args) {
dict.Get("method", &method); dict.Get("method", &method);
std::string url; std::string url;
dict.Get("url", &url); dict.Get("url", &url);
std::string redirect_policy;
dict.Get("redirect", &redirect_policy);
std::string partition; std::string partition;
mate::Handle<api::Session> session; mate::Handle<api::Session> session;
if (dict.Get("session", &session)) { if (dict.Get("session", &session)) {
@ -156,8 +159,8 @@ mate::WrappableBase* URLRequest::New(mate::Arguments* args) {
} }
auto browser_context = session->browser_context(); auto browser_context = session->browser_context();
auto api_url_request = new URLRequest(args->isolate(), args->GetThis()); auto api_url_request = new URLRequest(args->isolate(), args->GetThis());
auto atom_url_request = auto atom_url_request = AtomURLRequest::Create(
AtomURLRequest::Create(browser_context, method, url, api_url_request); browser_context, method, url, redirect_policy, api_url_request);
api_url_request->atom_request_ = atom_url_request; api_url_request->atom_request_ = atom_url_request;
@ -176,6 +179,7 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setExtraHeader", &URLRequest::SetExtraHeader) .SetMethod("setExtraHeader", &URLRequest::SetExtraHeader)
.SetMethod("removeExtraHeader", &URLRequest::RemoveExtraHeader) .SetMethod("removeExtraHeader", &URLRequest::RemoveExtraHeader)
.SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload) .SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload)
.SetMethod("followRedirect", &URLRequest::FollowRedirect)
.SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags) .SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags)
.SetProperty("notStarted", &URLRequest::NotStarted) .SetProperty("notStarted", &URLRequest::NotStarted)
.SetProperty("finished", &URLRequest::Finished) .SetProperty("finished", &URLRequest::Finished)
@ -246,6 +250,17 @@ void URLRequest::Cancel() {
Close(); Close();
} }
void URLRequest::FollowRedirect() {
if (request_state_.Canceled() || request_state_.Closed()) {
return;
}
DCHECK(atom_request_);
if (atom_request_) {
atom_request_->FollowRedirect();
}
}
bool URLRequest::SetExtraHeader(const std::string& name, bool URLRequest::SetExtraHeader(const std::string& name,
const std::string& value) { const std::string& value) {
// Request state must be in the initial non started state. // Request state must be in the initial non started state.
@ -305,6 +320,24 @@ void URLRequest::SetLoadFlags(int flags) {
} }
} }
void URLRequest::OnReceivedRedirect(
int status_code,
const std::string& method,
const GURL& url,
scoped_refptr<net::HttpResponseHeaders> response_headers) {
if (request_state_.Canceled() || request_state_.Closed()) {
return;
}
DCHECK(atom_request_);
if (!atom_request_) {
return;
}
EmitRequestEvent(false, "redirect", status_code, method, url,
response_headers.get());
}
void URLRequest::OnAuthenticationRequired( void URLRequest::OnAuthenticationRequired(
scoped_refptr<const net::AuthChallengeInfo> auth_info) { scoped_refptr<const net::AuthChallengeInfo> auth_info) {
if (request_state_.Canceled() || request_state_.Closed()) { if (request_state_.Canceled() || request_state_.Closed()) {

View file

@ -99,6 +99,11 @@ class URLRequest : public mate::EventEmitter<URLRequest> {
v8::Local<v8::FunctionTemplate> prototype); v8::Local<v8::FunctionTemplate> prototype);
// Methods for reporting events into JavaScript. // Methods for reporting events into JavaScript.
void OnReceivedRedirect(
int status_code,
const std::string& method,
const GURL& url,
scoped_refptr<net::HttpResponseHeaders> response_headers);
void OnAuthenticationRequired( void OnAuthenticationRequired(
scoped_refptr<const net::AuthChallengeInfo> auth_info); scoped_refptr<const net::AuthChallengeInfo> auth_info);
void OnResponseStarted( void OnResponseStarted(
@ -170,6 +175,7 @@ class URLRequest : public mate::EventEmitter<URLRequest> {
bool Failed() const; bool Failed() const;
bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last); bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last);
void Cancel(); void Cancel();
void FollowRedirect();
bool SetExtraHeader(const std::string& name, const std::string& value); bool SetExtraHeader(const std::string& name, const std::string& value);
void RemoveExtraHeader(const std::string& name); void RemoveExtraHeader(const std::string& name);
void SetChunkedUpload(bool is_chunked_upload); void SetChunkedUpload(bool is_chunked_upload);

View file

@ -188,6 +188,7 @@ struct Converter<atom::api::WebContents::Type> {
switch (val) { switch (val) {
case Type::BACKGROUND_PAGE: type = "backgroundPage"; break; case Type::BACKGROUND_PAGE: type = "backgroundPage"; break;
case Type::BROWSER_WINDOW: type = "window"; break; case Type::BROWSER_WINDOW: type = "window"; break;
case Type::BROWSER_VIEW: type = "browserView"; break;
case Type::REMOTE: type = "remote"; break; case Type::REMOTE: type = "remote"; break;
case Type::WEB_VIEW: type = "webview"; break; case Type::WEB_VIEW: type = "webview"; break;
case Type::OFF_SCREEN: type = "offscreen"; break; case Type::OFF_SCREEN: type = "offscreen"; break;
@ -202,10 +203,12 @@ struct Converter<atom::api::WebContents::Type> {
std::string type; std::string type;
if (!ConvertFromV8(isolate, val, &type)) if (!ConvertFromV8(isolate, val, &type))
return false; return false;
if (type == "webview") { if (type == "backgroundPage") {
*out = Type::WEB_VIEW;
} else if (type == "backgroundPage") {
*out = Type::BACKGROUND_PAGE; *out = Type::BACKGROUND_PAGE;
} else if (type == "browserView") {
*out = Type::BROWSER_VIEW;
} else if (type == "webview") {
*out = Type::WEB_VIEW;
} else if (type == "offscreen") { } else if (type == "offscreen") {
*out = Type::OFF_SCREEN; *out = Type::OFF_SCREEN;
} else { } else {
@ -240,7 +243,7 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
} }
// Called when CapturePage is done. // Called when CapturePage is done.
void OnCapturePageDone(base::Callback<void(const gfx::Image&)> callback, void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap, const SkBitmap& bitmap,
content::ReadbackResponse response) { content::ReadbackResponse response) {
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
@ -306,6 +309,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
type_ = WEB_VIEW; type_ = WEB_VIEW;
else if (options.Get("isBackgroundPage", &b) && b) else if (options.Get("isBackgroundPage", &b) && b)
type_ = BACKGROUND_PAGE; type_ = BACKGROUND_PAGE;
else if (options.Get("isBrowserView", &b) && b)
type_ = BROWSER_VIEW;
else if (options.Get("offscreen", &b) && b) else if (options.Get("offscreen", &b) && b)
type_ = OFF_SCREEN; type_ = OFF_SCREEN;
@ -411,14 +416,31 @@ WebContents::~WebContents() {
if (type_ == WEB_VIEW) if (type_ == WEB_VIEW)
guest_delegate_->Destroy(); guest_delegate_->Destroy();
// The WebContentsDestroyed will not be called automatically because we
// unsubscribe from webContents before destroying it. So we have to manually
// call it here to make sure "destroyed" event is emitted.
RenderViewDeleted(web_contents()->GetRenderViewHost()); RenderViewDeleted(web_contents()->GetRenderViewHost());
WebContentsDestroyed();
if (type_ == WEB_VIEW) {
DestroyWebContents(false /* async */);
} else {
if (type_ == BROWSER_WINDOW && owner_window()) {
owner_window()->CloseContents(nullptr);
} else {
DestroyWebContents(true /* async */);
}
// The WebContentsDestroyed will not be called automatically because we
// destroy the webContents in the next tick. So we have to manually
// call it here to make sure "destroyed" event is emitted.
WebContentsDestroyed();
}
} }
} }
void WebContents::DestroyWebContents(bool async) {
// This event is only for internal use, which is emitted when WebContents is
// being destroyed.
Emit("will-destroy");
ResetManagedWebContents(async);
}
bool WebContents::DidAddMessageToConsole(content::WebContents* source, bool WebContents::DidAddMessageToConsole(content::WebContents* source,
int32_t level, int32_t level,
const base::string16& message, const base::string16& message,
@ -468,7 +490,7 @@ void WebContents::AddNewContents(content::WebContents* source,
if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture, if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture,
initial_rect.x(), initial_rect.y(), initial_rect.width(), initial_rect.x(), initial_rect.y(), initial_rect.width(),
initial_rect.height())) { initial_rect.height())) {
api_web_contents->DestroyWebContents(); api_web_contents->DestroyWebContents(true /* async */);
} }
} }
@ -807,10 +829,8 @@ void WebContents::DidFinishNavigation(
void WebContents::TitleWasSet(content::NavigationEntry* entry, void WebContents::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) { bool explicit_set) {
if (entry) auto title = entry ? entry->GetTitle() : base::string16();
Emit("-page-title-updated", entry->GetTitle(), explicit_set); Emit("page-title-updated", title, explicit_set);
else
Emit("-page-title-updated", "", explicit_set);
} }
void WebContents::DidUpdateFaviconURL( void WebContents::DidUpdateFaviconURL(
@ -919,10 +939,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
// be destroyed on close, and WebContentsDestroyed would be called for it, so // be destroyed on close, and WebContentsDestroyed would be called for it, so
// we need to make sure the api::WebContents is also deleted. // we need to make sure the api::WebContents is also deleted.
void WebContents::WebContentsDestroyed() { void WebContents::WebContentsDestroyed() {
// This event is only for internal use, which is emitted when WebContents is
// being destroyed.
Emit("will-destroy");
// Cleanup relationships with other parts. // Cleanup relationships with other parts.
RemoveFromWeakMap(); RemoveFromWeakMap();

View file

@ -53,10 +53,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
public: public:
enum Type { enum Type {
BACKGROUND_PAGE, // A DevTools extension background page. BACKGROUND_PAGE, // A DevTools extension background page.
BROWSER_WINDOW, // Used by BrowserWindow. BROWSER_WINDOW, // Used by BrowserWindow.
REMOTE, // Thin wrap around an existing WebContents. BROWSER_VIEW, // Used by BrowserView.
WEB_VIEW, // Used by <webview>. REMOTE, // Thin wrap around an existing WebContents.
OFF_SCREEN, // Used for offscreen rendering WEB_VIEW, // Used by <webview>.
OFF_SCREEN, // Used for offscreen rendering
}; };
// For node.js callback function type: function(error, buffer) // For node.js callback function type: function(error, buffer)
@ -76,6 +77,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
static void BuildPrototype(v8::Isolate* isolate, static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype); v8::Local<v8::FunctionTemplate> prototype);
// Notifies to destroy any guest web contents before destroying self.
void DestroyWebContents(bool async);
int64_t GetID() const; int64_t GetID() const;
int GetProcessID() const; int GetProcessID() const;
Type GetType() const; Type GetType() const;

View file

@ -5,6 +5,7 @@
#include "atom/browser/api/atom_api_window.h" #include "atom/browser/api/atom_api_window.h"
#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
#include "atom/browser/api/atom_api_browser_view.h"
#include "atom/browser/api/atom_api_menu.h" #include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
@ -172,7 +173,7 @@ void Window::WillDestroyNativeObject() {
} }
void Window::OnWindowClosed() { void Window::OnWindowClosed() {
api_web_contents_->DestroyWebContents(); api_web_contents_->DestroyWebContents(true /* async */);
RemoveFromWeakMap(); RemoveFromWeakMap();
window_->RemoveObserver(this); window_->RemoveObserver(this);
@ -190,6 +191,10 @@ void Window::OnWindowClosed() {
FROM_HERE, GetDestroyClosure()); FROM_HERE, GetDestroyClosure());
} }
void Window::OnWindowEndSession() {
Emit("session-end");
}
void Window::OnWindowBlur() { void Window::OnWindowBlur() {
Emit("blur"); Emit("blur");
} }
@ -262,6 +267,14 @@ void Window::OnWindowSwipe(const std::string& direction) {
Emit("swipe", direction); Emit("swipe", direction);
} }
void Window::OnWindowSheetBegin() {
Emit("sheet-begin");
}
void Window::OnWindowSheetEnd() {
Emit("sheet-end");
}
void Window::OnWindowEnterHtmlFullScreen() { void Window::OnWindowEnterHtmlFullScreen() {
Emit("enter-html-full-screen"); Emit("enter-html-full-screen");
} }
@ -816,6 +829,25 @@ std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
return child_windows_.Values(isolate()); return child_windows_.Values(isolate());
} }
v8::Local<v8::Value> Window::GetBrowserView() const {
if (browser_view_.IsEmpty()) {
return v8::Null(isolate());
}
return v8::Local<v8::Value>::New(isolate(), browser_view_);
}
void Window::SetBrowserView(v8::Local<v8::Value> value) {
mate::Handle<BrowserView> browser_view;
if (value->IsNull()) {
window_->SetBrowserView(nullptr);
browser_view_.Reset();
} else if (mate::ConvertFromV8(isolate(), value, &browser_view)) {
window_->SetBrowserView(browser_view->view());
browser_view_.Reset(isolate(), value);
}
}
bool Window::IsModal() const { bool Window::IsModal() const {
return window_->is_modal(); return window_->is_modal();
} }
@ -853,15 +885,20 @@ void Window::RefreshTouchBarItem(const std::string& item_id) {
window_->RefreshTouchBarItem(item_id); window_->RefreshTouchBarItem(item_id);
} }
void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
window_->SetEscapeTouchBarItem(item);
}
int32_t Window::ID() const { int32_t Window::ID() const {
return weak_map_id(); return weak_map_id();
} }
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) { v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty()) if (web_contents_.IsEmpty()) {
return v8::Null(isolate); return v8::Null(isolate);
else }
return v8::Local<v8::Value>::New(isolate, web_contents_);
return v8::Local<v8::Value>::New(isolate, web_contents_);
} }
void Window::RemoveFromParentChildWindows() { void Window::RemoveFromParentChildWindows() {
@ -906,6 +943,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
#endif #endif
.SetMethod("getParentWindow", &Window::GetParentWindow) .SetMethod("getParentWindow", &Window::GetParentWindow)
.SetMethod("getChildWindows", &Window::GetChildWindows) .SetMethod("getChildWindows", &Window::GetChildWindows)
.SetMethod("getBrowserView", &Window::GetBrowserView)
.SetMethod("setBrowserView", &Window::SetBrowserView)
.SetMethod("isModal", &Window::IsModal) .SetMethod("isModal", &Window::IsModal)
.SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle) .SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
.SetMethod("getBounds", &Window::GetBounds) .SetMethod("getBounds", &Window::GetBounds)
@ -975,6 +1014,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setVibrancy", &Window::SetVibrancy) .SetMethod("setVibrancy", &Window::SetVibrancy)
.SetMethod("_setTouchBarItems", &Window::SetTouchBar) .SetMethod("_setTouchBarItems", &Window::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem) .SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem", &Window::SetEscapeTouchBarItem)
#if defined(OS_WIN) #if defined(OS_WIN)
.SetMethod("hookWindowMessage", &Window::HookWindowMessage) .SetMethod("hookWindowMessage", &Window::HookWindowMessage)
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked) .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)

View file

@ -63,6 +63,7 @@ class Window : public mate::TrackableObject<Window>,
void WillCloseWindow(bool* prevent_default) override; void WillCloseWindow(bool* prevent_default) override;
void WillDestroyNativeObject() override; void WillDestroyNativeObject() override;
void OnWindowClosed() override; void OnWindowClosed() override;
void OnWindowEndSession() override;
void OnWindowBlur() override; void OnWindowBlur() override;
void OnWindowFocus() override; void OnWindowFocus() override;
void OnWindowShow() override; void OnWindowShow() override;
@ -79,6 +80,8 @@ class Window : public mate::TrackableObject<Window>,
void OnWindowScrollTouchEnd() override; void OnWindowScrollTouchEnd() override;
void OnWindowScrollTouchEdge() override; void OnWindowScrollTouchEdge() override;
void OnWindowSwipe(const std::string& direction) override; void OnWindowSwipe(const std::string& direction) override;
void OnWindowSheetBegin() override;
void OnWindowSheetEnd() override;
void OnWindowEnterFullScreen() override; void OnWindowEnterFullScreen() override;
void OnWindowLeaveFullScreen() override; void OnWindowLeaveFullScreen() override;
void OnWindowEnterHtmlFullScreen() override; void OnWindowEnterHtmlFullScreen() override;
@ -180,6 +183,8 @@ class Window : public mate::TrackableObject<Window>,
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args); void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
v8::Local<v8::Value> GetParentWindow() const; v8::Local<v8::Value> GetParentWindow() const;
std::vector<v8::Local<v8::Object>> GetChildWindows() const; std::vector<v8::Local<v8::Object>> GetChildWindows() const;
v8::Local<v8::Value> GetBrowserView() const;
void SetBrowserView(v8::Local<v8::Value> value);
bool IsModal() const; bool IsModal() const;
v8::Local<v8::Value> GetNativeWindowHandle(); v8::Local<v8::Value> GetNativeWindowHandle();
@ -208,6 +213,7 @@ class Window : public mate::TrackableObject<Window>,
void SetVibrancy(mate::Arguments* args); void SetVibrancy(mate::Arguments* args);
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items); void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
void RefreshTouchBarItem(const std::string& item_id); void RefreshTouchBarItem(const std::string& item_id);
void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
v8::Local<v8::Value> WebContents(v8::Isolate* isolate); v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
@ -219,6 +225,7 @@ class Window : public mate::TrackableObject<Window>,
MessageCallbackMap messages_callback_map_; MessageCallbackMap messages_callback_map_;
#endif #endif
v8::Global<v8::Value> browser_view_;
v8::Global<v8::Value> web_contents_; v8::Global<v8::Value> web_contents_;
v8::Global<v8::Value> menu_; v8::Global<v8::Value> menu_;
v8::Global<v8::Value> parent_window_; v8::Global<v8::Value> parent_window_;

View file

@ -7,11 +7,13 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/common/google_api_key.h" #include "atom/common/google_api_key.h"
#include "base/environment.h" #include "base/environment.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "device/geolocation/geolocation_provider.h" #include "device/geolocation/geolocation_provider.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread; using content::BrowserThread;
@ -19,51 +21,40 @@ namespace atom {
namespace internal { namespace internal {
// Loads access tokens and other necessary data on the UI thread, and class GeoURLRequestContextGetter : public net::URLRequestContextGetter {
// calls back to the originator on the originating thread.
class TokenLoadingJob : public base::RefCountedThreadSafe<TokenLoadingJob> {
public: public:
explicit TokenLoadingJob( net::URLRequestContext* GetURLRequestContext() override {
const device::AccessTokenStore::LoadAccessTokensCallback& callback) DCHECK_CURRENTLY_ON(BrowserThread::IO);
: callback_(callback), request_context_getter_(nullptr) {} if (!url_request_context_.get()) {
net::URLRequestContextBuilder builder;
builder.set_proxy_config_service(
net::ProxyService::CreateSystemProxyConfigService(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
url_request_context_ = builder.Build();
}
return url_request_context_.get();
}
void Run(AtomBrowserContext* browser_context) { scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
DCHECK_CURRENTLY_ON(BrowserThread::UI); const override {
request_context_getter_ = browser_context->GetRequestContext(); return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
std::unique_ptr<base::Environment> env(base::Environment::Create());
if (!env->GetVar("GOOGLE_API_KEY", &api_key_))
api_key_ = GOOGLEAPIS_API_KEY;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&TokenLoadingJob::RespondOnIOThread, this));
} }
private: private:
friend class base::RefCountedThreadSafe<TokenLoadingJob>; friend class atom::AtomAccessTokenStore;
~TokenLoadingJob() {} GeoURLRequestContextGetter() {}
~GeoURLRequestContextGetter() override {}
void RespondOnIOThread() { std::unique_ptr<net::URLRequestContext> url_request_context_;
// Equivalent to access_token_map[kGeolocationProviderURL]. DISALLOW_COPY_AND_ASSIGN(GeoURLRequestContextGetter);
// Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
device::AccessTokenStore::AccessTokenMap access_token_map;
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(GOOGLEAPIS_ENDPOINT + api_key_);
access_token_map.insert(token_pair);
callback_.Run(access_token_map, request_context_getter_);
}
device::AccessTokenStore::LoadAccessTokensCallback callback_;
net::URLRequestContextGetter* request_context_getter_;
std::string api_key_;
}; };
} // namespace internal } // namespace internal
AtomAccessTokenStore::AtomAccessTokenStore() { AtomAccessTokenStore::AtomAccessTokenStore()
browser_context_ = AtomBrowserContext::From("", false); : request_context_getter_(new internal::GeoURLRequestContextGetter) {
device::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices(); device::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
} }
@ -72,16 +63,19 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
void AtomAccessTokenStore::LoadAccessTokens( void AtomAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallback& callback) { const LoadAccessTokensCallback& callback) {
scoped_refptr<internal::TokenLoadingJob> job( std::unique_ptr<base::Environment> env(base::Environment::Create());
new internal::TokenLoadingJob(callback)); std::string api_key;
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, if (!env->GetVar("GOOGLE_API_KEY", &api_key))
base::Bind(&AtomAccessTokenStore::RunTokenLoadingJob, api_key = GOOGLEAPIS_API_KEY;
this, base::RetainedRef(job))); // Equivalent to access_token_map[kGeolocationProviderURL].
} // Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
device::AccessTokenStore::AccessTokenMap access_token_map;
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(GOOGLEAPIS_ENDPOINT + api_key);
access_token_map.insert(token_pair);
void AtomAccessTokenStore::RunTokenLoadingJob( callback.Run(access_token_map, request_context_getter_.get());
scoped_refptr<internal::TokenLoadingJob> job) {
job->Run(browser_context_.get());
} }
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url, void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,

View file

@ -9,10 +9,8 @@
namespace atom { namespace atom {
class AtomBrowserContext;
namespace internal { namespace internal {
class TokenLoadingJob; class GeoURLRequestContextGetter;
} }
class AtomAccessTokenStore : public device::AccessTokenStore { class AtomAccessTokenStore : public device::AccessTokenStore {
@ -27,9 +25,7 @@ class AtomAccessTokenStore : public device::AccessTokenStore {
const base::string16& access_token) override; const base::string16& access_token) override;
private: private:
void RunTokenLoadingJob(scoped_refptr<internal::TokenLoadingJob> job); scoped_refptr<internal::GeoURLRequestContextGetter> request_context_getter_;
scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore); DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
}; };

View file

@ -172,6 +172,7 @@ std::string AtomBrowserClient::GetApplicationLocale() {
} }
void AtomBrowserClient::OverrideSiteInstanceForNavigation( void AtomBrowserClient::OverrideSiteInstanceForNavigation(
content::RenderFrameHost* render_frame_host,
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
content::SiteInstance* current_instance, content::SiteInstance* current_instance,
const GURL& url, const GURL& url,
@ -234,6 +235,11 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
} }
#endif #endif
if (delegate_) {
auto app_path = static_cast<api::App*>(delegate_)->GetAppPath();
command_line->AppendSwitchPath(switches::kAppPath, app_path);
}
content::WebContents* web_contents = GetWebContentsFromProcessID(process_id); content::WebContents* web_contents = GetWebContentsFromProcessID(process_id);
if (!web_contents) if (!web_contents)
return; return;

View file

@ -54,6 +54,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
content::WebPreferences* prefs) override; content::WebPreferences* prefs) override;
std::string GetApplicationLocale() override; std::string GetApplicationLocale() override;
void OverrideSiteInstanceForNavigation( void OverrideSiteInstanceForNavigation(
content::RenderFrameHost* render_frame_host,
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
content::SiteInstance* current_instance, content::SiteInstance* current_instance,
const GURL& dest_url, const GURL& dest_url,

View file

@ -27,7 +27,7 @@ namespace {
bool g_update_available = false; bool g_update_available = false;
std::string update_url_ = ""; std::string update_url_ = "";
} } // namespace
std::string AutoUpdater::GetFeedURL() { std::string AutoUpdater::GetFeedURL() {
return update_url_; return update_url_;

View file

@ -43,11 +43,10 @@ void Browser::Quit() {
if (!is_quiting_) if (!is_quiting_)
return; return;
atom::WindowList* window_list = atom::WindowList::GetInstance(); if (atom::WindowList::IsEmpty())
if (window_list->size() == 0)
NotifyAndShutdown(); NotifyAndShutdown();
else
window_list->CloseAllWindows(); atom::WindowList::CloseAllWindows();
} }
void Browser::Exit(mate::Arguments* args) { void Browser::Exit(mate::Arguments* args) {
@ -65,14 +64,12 @@ void Browser::Exit(mate::Arguments* args) {
is_exiting_ = true; is_exiting_ = true;
// Must destroy windows before quitting, otherwise bad things can happen. // Must destroy windows before quitting, otherwise bad things can happen.
atom::WindowList* window_list = atom::WindowList::GetInstance(); if (atom::WindowList::IsEmpty()) {
if (window_list->size() == 0) {
Shutdown(); Shutdown();
} else { } else {
// Unlike Quit(), we do not ask to close window, but destroy the window // Unlike Quit(), we do not ask to close window, but destroy the window
// without asking. // without asking.
for (NativeWindow* window : *window_list) atom::WindowList::DestroyAllWindows();
window->CloseContents(nullptr); // e.g. Destroy()
} }
} }
} }

View file

@ -102,7 +102,7 @@ class Browser : public WindowListObserver {
std::vector<base::string16> args; std::vector<base::string16> args;
}; };
void SetLoginItemSettings(LoginItemSettings settings); void SetLoginItemSettings(LoginItemSettings settings);
LoginItemSettings GetLoginItemSettings(LoginItemSettings options); LoginItemSettings GetLoginItemSettings(const LoginItemSettings& options);
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// Hide the application. // Hide the application.

View file

@ -16,9 +16,7 @@ namespace atom {
void Browser::Focus() { void Browser::Focus() {
// Focus on the first visible window. // Focus on the first visible window.
WindowList* list = WindowList::GetInstance(); for (const auto& window : WindowList::GetWindows()) {
for (WindowList::iterator iter = list->begin(); iter != list->end(); ++iter) {
NativeWindow* window = *iter;
if (window->IsVisible()) { if (window->IsVisible()) {
window->Focus(true); window->Focus(true);
break; break;
@ -64,7 +62,7 @@ void Browser::SetLoginItemSettings(LoginItemSettings settings) {
} }
Browser::LoginItemSettings Browser::GetLoginItemSettings( Browser::LoginItemSettings Browser::GetLoginItemSettings(
LoginItemSettings options) { const LoginItemSettings& options) {
return LoginItemSettings(); return LoginItemSettings();
} }

View file

@ -64,8 +64,9 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
// On macOS, we can't query the default, but the handlers list seems to put // On macOS, we can't query the default, but the handlers list seems to put
// Apple's defaults first, so we'll use the first option that isn't our bundle // Apple's defaults first, so we'll use the first option that isn't our bundle
CFStringRef other = nil; CFStringRef other = nil;
for (CFIndex i = 0; i < CFArrayGetCount(bundleList); i++) { for (CFIndex i = 0; i < CFArrayGetCount(bundleList); ++i) {
other = (CFStringRef)CFArrayGetValueAtIndex(bundleList, i); other = base::mac::CFCast<CFStringRef>(CFArrayGetValueAtIndex(bundleList,
i));
if (![identifier isEqualToString: (__bridge NSString *)other]) { if (![identifier isEqualToString: (__bridge NSString *)other]) {
break; break;
} }
@ -152,7 +153,7 @@ bool Browser::ContinueUserActivity(const std::string& type,
} }
Browser::LoginItemSettings Browser::GetLoginItemSettings( Browser::LoginItemSettings Browser::GetLoginItemSettings(
LoginItemSettings options) { const LoginItemSettings& options) {
LoginItemSettings settings; LoginItemSettings settings;
settings.open_at_login = base::mac::CheckLoginItemStatus( settings.open_at_login = base::mac::CheckLoginItemStatus(
&settings.open_as_hidden); &settings.open_as_hidden);
@ -179,7 +180,7 @@ std::string Browser::GetExecutableFileProductName() const {
int Browser::DockBounce(BounceType type) { int Browser::DockBounce(BounceType type) {
return [[AtomApplication sharedApplication] return [[AtomApplication sharedApplication]
requestUserAttention:(NSRequestUserAttentionType)type]; requestUserAttention:static_cast<NSRequestUserAttentionType>(type)];
} }
void Browser::DockCancelBounce(int request_id) { void Browser::DockCancelBounce(int request_id) {
@ -203,9 +204,8 @@ std::string Browser::DockGetBadgeText() {
} }
void Browser::DockHide() { void Browser::DockHide() {
WindowList* list = WindowList::GetInstance(); for (const auto& window : WindowList::GetWindows())
for (WindowList::iterator it = list->begin(); it != list->end(); ++it) [window->GetNativeWindow() setCanHide:NO];
[(*it)->GetNativeWindow() setCanHide:NO];
ProcessSerialNumber psn = { 0, kCurrentProcess }; ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToUIElementApplication); TransformProcessType(&psn, kProcessTransformToUIElementApplication);

View file

@ -61,11 +61,11 @@ bool GetProtocolLaunchPath(mate::Arguments* args, base::string16* exe) {
// Read in optional args arg // Read in optional args arg
std::vector<base::string16> launch_args; std::vector<base::string16> launch_args;
if (args->GetNext(&launch_args) && !launch_args.empty()) if (args->GetNext(&launch_args) && !launch_args.empty())
*exe = base::StringPrintf(L"\"%s\" %s \"%%1\"", *exe = base::StringPrintf(L"\"%ls\" %ls \"%%1\"",
exe->c_str(), exe->c_str(),
base::JoinString(launch_args, L" ").c_str()); base::JoinString(launch_args, L" ").c_str());
else else
*exe = base::StringPrintf(L"\"%s\" \"%%1\"", exe->c_str()); *exe = base::StringPrintf(L"\"%ls\" \"%%1\"", exe->c_str());
return true; return true;
} }
@ -76,8 +76,7 @@ bool FormatCommandLineString(base::string16* exe,
} }
if (!launch_args.empty()) { if (!launch_args.empty()) {
base::string16 formatString = L"%s %s"; *exe = base::StringPrintf(L"%ls %ls",
*exe = base::StringPrintf(formatString.c_str(),
exe->c_str(), exe->c_str(),
base::JoinString(launch_args, L" ").c_str()); base::JoinString(launch_args, L" ").c_str());
} }
@ -287,7 +286,7 @@ void Browser::SetLoginItemSettings(LoginItemSettings settings) {
} }
Browser::LoginItemSettings Browser::GetLoginItemSettings( Browser::LoginItemSettings Browser::GetLoginItemSettings(
LoginItemSettings options) { const LoginItemSettings& options) {
LoginItemSettings settings; LoginItemSettings settings;
base::string16 keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; base::string16 keyPath = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS); base::win::RegKey key(HKEY_CURRENT_USER, keyPath.c_str(), KEY_ALL_ACCESS);

View file

@ -178,13 +178,23 @@ void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) {
void CommonWebContentsDelegate::SetOwnerWindow( void CommonWebContentsDelegate::SetOwnerWindow(
content::WebContents* web_contents, NativeWindow* owner_window) { content::WebContents* web_contents, NativeWindow* owner_window) {
owner_window_ = owner_window->GetWeakPtr(); owner_window_ = owner_window ? owner_window->GetWeakPtr() : nullptr;
NativeWindowRelay* relay = new NativeWindowRelay(owner_window_); NativeWindowRelay* relay = new NativeWindowRelay(owner_window_);
web_contents->SetUserData(relay->key, relay); if (owner_window) {
web_contents->SetUserData(relay->key, relay);
} else {
web_contents->RemoveUserData(relay->key);
delete relay;
}
} }
void CommonWebContentsDelegate::DestroyWebContents() { void CommonWebContentsDelegate::ResetManagedWebContents(bool async) {
web_contents_.reset(); if (async) {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
web_contents_.release());
} else {
web_contents_.reset();
}
} }
content::WebContents* CommonWebContentsDelegate::GetWebContents() const { content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
@ -338,7 +348,7 @@ void CommonWebContentsDelegate::DevToolsRequestFileSystems() {
} }
std::vector<FileSystem> file_systems; std::vector<FileSystem> file_systems;
for (auto file_system_path : file_system_paths) { for (const auto& file_system_path : file_system_paths) {
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path); base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(), std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
path); path);

View file

@ -42,9 +42,6 @@ class CommonWebContentsDelegate
void SetOwnerWindow(content::WebContents* web_contents, void SetOwnerWindow(content::WebContents* web_contents,
NativeWindow* owner_window); NativeWindow* owner_window);
// Destroy the managed InspectableWebContents object.
void DestroyWebContents();
// Returns the WebContents managed by this delegate. // Returns the WebContents managed by this delegate.
content::WebContents* GetWebContents() const; content::WebContents* GetWebContents() const;
@ -114,6 +111,9 @@ class CommonWebContentsDelegate
std::string* name, std::string* class_name) override; std::string* name, std::string* class_name) override;
#endif #endif
// Destroy the managed InspectableWebContents object.
void ResetManagedWebContents(bool async);
private: private:
// Callback for when DevToolsSaveToFile has completed. // Callback for when DevToolsSaveToFile has completed.
void OnDevToolsSaveToFile(const std::string& url); void OnDevToolsSaveToFile(const std::string& url);

View file

@ -10,10 +10,6 @@
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/values.h" #include "base/values.h"
@interface NSWindow (SierraSDK)
@property(class) BOOL allowsAutomaticWindowTabbing;
@end
@implementation AtomApplicationDelegate @implementation AtomApplicationDelegate
- (void)setApplicationDockMenu:(atom::AtomMenuModel*)model { - (void)setApplicationDockMenu:(atom::AtomMenuModel*)model {
@ -25,10 +21,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"];
// Don't add the "Show Tab Bar" menu item.
if ([NSWindow respondsToSelector:@selector(allowsAutomaticWindowTabbing)])
NSWindow.allowsAutomaticWindowTabbing = NO;
atom::Browser::Get()->WillFinishLaunching(); atom::Browser::Get()->WillFinishLaunching();
} }

View file

@ -0,0 +1,18 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/native_browser_view.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
namespace atom {
NativeBrowserView::NativeBrowserView(
brightray::InspectableWebContentsView* web_contents_view)
: web_contents_view_(web_contents_view) {}
NativeBrowserView::~NativeBrowserView() {}
} // namespace atom

View file

@ -0,0 +1,57 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_
#include "base/macros.h"
#include "third_party/skia/include/core/SkColor.h"
namespace brightray {
class InspectableWebContentsView;
}
namespace gfx {
class Rect;
}
namespace atom {
namespace api {
class WebContents;
}
enum AutoResizeFlags {
kAutoResizeWidth = 0x1,
kAutoResizeHeight = 0x2,
};
class NativeBrowserView {
public:
virtual ~NativeBrowserView();
static NativeBrowserView* Create(
brightray::InspectableWebContentsView* web_contents_view);
brightray::InspectableWebContentsView* GetInspectableWebContentsView() {
return web_contents_view_;
}
virtual void SetAutoResizeFlags(uint8_t flags) = 0;
virtual void SetBounds(const gfx::Rect& bounds) = 0;
virtual void SetBackgroundColor(SkColor color) = 0;
protected:
explicit NativeBrowserView(
brightray::InspectableWebContentsView* web_contents_view);
brightray::InspectableWebContentsView* web_contents_view_;
private:
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_

View file

@ -0,0 +1,30 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_
#import <Cocoa/Cocoa.h>
#include "atom/browser/native_browser_view.h"
namespace atom {
class NativeBrowserViewMac : public NativeBrowserView {
public:
explicit NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view);
~NativeBrowserViewMac() override;
void SetAutoResizeFlags(uint8_t flags) override;
void SetBounds(const gfx::Rect& bounds) override;
void SetBackgroundColor(SkColor color) override;
private:
DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewMac);
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_

View file

@ -0,0 +1,60 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/native_browser_view_mac.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "skia/ext/skia_utils_mac.h"
#include "ui/gfx/geometry/rect.h"
// Match view::Views behavior where the view sticks to the top-left origin.
const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
NSViewMaxXMargin | NSViewMinYMargin;
namespace atom {
NativeBrowserViewMac::NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view)
: NativeBrowserView(web_contents_view) {
auto* view = GetInspectableWebContentsView()->GetNativeView();
view.autoresizingMask = kDefaultAutoResizingMask;
}
NativeBrowserViewMac::~NativeBrowserViewMac() {}
void NativeBrowserViewMac::SetAutoResizeFlags(uint8_t flags) {
NSAutoresizingMaskOptions autoresizing_mask = kDefaultAutoResizingMask;
if (flags & kAutoResizeWidth) {
autoresizing_mask |= NSViewWidthSizable;
}
if (flags & kAutoResizeHeight) {
autoresizing_mask |= NSViewHeightSizable;
}
auto* view = GetInspectableWebContentsView()->GetNativeView();
view.autoresizingMask = autoresizing_mask;
}
void NativeBrowserViewMac::SetBounds(const gfx::Rect& bounds) {
auto* view = GetInspectableWebContentsView()->GetNativeView();
auto* superview = view.superview;
const auto superview_height = superview ? superview.frame.size.height : 0;
view.frame =
NSMakeRect(bounds.x(), superview_height - bounds.y() - bounds.height(),
bounds.width(), bounds.height());
}
void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
auto* view = GetInspectableWebContentsView()->GetNativeView();
view.wantsLayer = YES;
view.layer.backgroundColor = skia::CGColorCreateFromSkColor(color);
}
// static
NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) {
return new NativeBrowserViewMac(web_contents_view);
}
} // namespace atom

View file

@ -0,0 +1,36 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/native_browser_view_views.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/background.h"
#include "ui/views/view.h"
namespace atom {
NativeBrowserViewViews::NativeBrowserViewViews(
brightray::InspectableWebContentsView* web_contents_view)
: NativeBrowserView(web_contents_view) {}
NativeBrowserViewViews::~NativeBrowserViewViews() {}
void NativeBrowserViewViews::SetBounds(const gfx::Rect& bounds) {
auto* view = GetInspectableWebContentsView()->GetView();
view->SetBoundsRect(bounds);
}
void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
auto* view = GetInspectableWebContentsView()->GetView();
view->set_background(views::Background::CreateSolidBackground(color));
}
// static
NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) {
return new NativeBrowserViewViews(web_contents_view);
}
} // namespace atom

View file

@ -0,0 +1,33 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_
#include "atom/browser/native_browser_view.h"
namespace atom {
class NativeBrowserViewViews : public NativeBrowserView {
public:
explicit NativeBrowserViewViews(
brightray::InspectableWebContentsView* web_contents_view);
~NativeBrowserViewViews() override;
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }
void SetAutoResizeFlags(uint8_t flags) override {
auto_resize_flags_ = flags;
}
void SetBounds(const gfx::Rect& bounds) override;
void SetBackgroundColor(SkColor color) override;
private:
uint8_t auto_resize_flags_;
DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewViews);
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_

View file

@ -104,8 +104,7 @@ NativeWindow::~NativeWindow() {
// static // static
NativeWindow* NativeWindow::FromWebContents( NativeWindow* NativeWindow::FromWebContents(
content::WebContents* web_contents) { content::WebContents* web_contents) {
WindowList& window_list = *WindowList::GetInstance(); for (const auto& window : WindowList::GetWindows()) {
for (NativeWindow* window : window_list) {
if (window->web_contents() == web_contents) if (window->web_contents() == web_contents)
return window; return window;
} }
@ -347,6 +346,10 @@ void NativeWindow::SetTouchBar(
void NativeWindow::RefreshTouchBarItem(const std::string& item_id) { void NativeWindow::RefreshTouchBarItem(const std::string& item_id) {
} }
void NativeWindow::SetEscapeTouchBarItem(
const mate::PersistentDictionary& item) {
}
void NativeWindow::FocusOnWebView() { void NativeWindow::FocusOnWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Focus(); web_contents()->GetRenderViewHost()->GetWidget()->Focus();
} }
@ -471,6 +474,11 @@ void NativeWindow::NotifyWindowClosed() {
observer.OnWindowClosed(); observer.OnWindowClosed();
} }
void NativeWindow::NotifyWindowEndSession() {
for (NativeWindowObserver& observer : observers_)
observer.OnWindowEndSession();
}
void NativeWindow::NotifyWindowBlur() { void NativeWindow::NotifyWindowBlur() {
for (NativeWindowObserver& observer : observers_) for (NativeWindowObserver& observer : observers_)
observer.OnWindowBlur(); observer.OnWindowBlur();
@ -551,6 +559,16 @@ void NativeWindow::NotifyWindowSwipe(const std::string& direction) {
observer.OnWindowSwipe(direction); observer.OnWindowSwipe(direction);
} }
void NativeWindow::NotifyWindowSheetBegin() {
for (NativeWindowObserver& observer : observers_)
observer.OnWindowSheetBegin();
}
void NativeWindow::NotifyWindowSheetEnd() {
for (NativeWindowObserver& observer : observers_)
observer.OnWindowSheetEnd();
}
void NativeWindow::NotifyWindowLeaveFullScreen() { void NativeWindow::NotifyWindowLeaveFullScreen() {
for (NativeWindowObserver& observer : observers_) for (NativeWindowObserver& observer : observers_)
observer.OnWindowLeaveFullScreen(); observer.OnWindowLeaveFullScreen();

View file

@ -47,6 +47,8 @@ class Dictionary;
namespace atom { namespace atom {
class NativeBrowserView;
struct DraggableRegion; struct DraggableRegion;
class NativeWindow : public base::SupportsUserData, class NativeWindow : public base::SupportsUserData,
@ -144,6 +146,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetFocusable(bool focusable); virtual void SetFocusable(bool focusable);
virtual void SetMenu(AtomMenuModel* menu); virtual void SetMenu(AtomMenuModel* menu);
virtual void SetParentWindow(NativeWindow* parent); virtual void SetParentWindow(NativeWindow* parent);
virtual void SetBrowserView(NativeBrowserView* browser_view) = 0;
virtual gfx::NativeWindow GetNativeWindow() = 0; virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
@ -174,6 +177,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetTouchBar( virtual void SetTouchBar(
const std::vector<mate::PersistentDictionary>& items); const std::vector<mate::PersistentDictionary>& items);
virtual void RefreshTouchBarItem(const std::string& item_id); virtual void RefreshTouchBarItem(const std::string& item_id);
virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
// Webview APIs. // Webview APIs.
virtual void FocusOnWebView(); virtual void FocusOnWebView();
@ -214,6 +218,7 @@ class NativeWindow : public base::SupportsUserData,
// Public API used by platform-dependent delegates and observers to send UI // Public API used by platform-dependent delegates and observers to send UI
// related notifications. // related notifications.
void NotifyWindowClosed(); void NotifyWindowClosed();
void NotifyWindowEndSession();
void NotifyWindowBlur(); void NotifyWindowBlur();
void NotifyWindowFocus(); void NotifyWindowFocus();
void NotifyWindowShow(); void NotifyWindowShow();
@ -229,6 +234,8 @@ class NativeWindow : public base::SupportsUserData,
void NotifyWindowScrollTouchEnd(); void NotifyWindowScrollTouchEnd();
void NotifyWindowScrollTouchEdge(); void NotifyWindowScrollTouchEdge();
void NotifyWindowSwipe(const std::string& direction); void NotifyWindowSwipe(const std::string& direction);
void NotifyWindowSheetBegin();
void NotifyWindowSheetEnd();
void NotifyWindowEnterFullScreen(); void NotifyWindowEnterFullScreen();
void NotifyWindowLeaveFullScreen(); void NotifyWindowLeaveFullScreen();
void NotifyWindowEnterHtmlFullScreen(); void NotifyWindowEnterHtmlFullScreen();

View file

@ -87,6 +87,7 @@ class NativeWindowMac : public NativeWindow,
bool IsDocumentEdited() override; bool IsDocumentEdited() override;
void SetIgnoreMouseEvents(bool ignore) override; void SetIgnoreMouseEvents(bool ignore) override;
void SetContentProtection(bool enable) override; void SetContentProtection(bool enable) override;
void SetBrowserView(NativeBrowserView* browser_view) override;
void SetParentWindow(NativeWindow* parent) override; void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override; gfx::NativeWindow GetNativeWindow() override;
gfx::AcceleratedWidget GetAcceleratedWidget() override; gfx::AcceleratedWidget GetAcceleratedWidget() override;
@ -103,6 +104,7 @@ class NativeWindowMac : public NativeWindow,
void SetTouchBar( void SetTouchBar(
const std::vector<mate::PersistentDictionary>& items) override; const std::vector<mate::PersistentDictionary>& items) override;
void RefreshTouchBarItem(const std::string& item_id) override; void RefreshTouchBarItem(const std::string& item_id) override;
void SetEscapeTouchBarItem(const mate::PersistentDictionary& item) override;
// content::RenderWidgetHost::InputEventObserver: // content::RenderWidgetHost::InputEventObserver:
void OnInputEvent(const blink::WebInputEvent& event) override; void OnInputEvent(const blink::WebInputEvent& event) override;
@ -163,6 +165,8 @@ class NativeWindowMac : public NativeWindow,
// The view that will fill the whole frameless window. // The view that will fill the whole frameless window.
base::scoped_nsobject<FullSizeContentView> content_view_; base::scoped_nsobject<FullSizeContentView> content_view_;
NativeBrowserView* browser_view_;
std::vector<DraggableRegion> draggable_regions_; std::vector<DraggableRegion> draggable_regions_;
bool is_kiosk_; bool is_kiosk_;

View file

@ -7,6 +7,7 @@
#include <Quartz/Quartz.h> #include <Quartz/Quartz.h>
#include <string> #include <string>
#include "atom/browser/native_browser_view_mac.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.h" #include "atom/browser/ui/cocoa/atom_touch_bar.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/color_util.h" #include "atom/common/color_util.h"
@ -19,9 +20,9 @@
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents_view.h"
#include "brightray/browser/mac/event_dispatching_window.h" #include "brightray/browser/mac/event_dispatching_window.h"
#include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "skia/ext/skia_utils_mac.h" #include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkRegion.h"
@ -312,6 +313,14 @@ bool ScopedDisableResize::disable_resize_ = false;
return rect; return rect;
} }
- (void)windowWillBeginSheet:(NSNotification *)notification {
shell_->NotifyWindowSheetBegin();
}
- (void)windowDidEndSheet:(NSNotification *)notification {
shell_->NotifyWindowSheetEnd();
}
@end @end
@interface AtomPreviewItem : NSObject <QLPreviewItem> @interface AtomPreviewItem : NSObject <QLPreviewItem>
@ -336,6 +345,19 @@ bool ScopedDisableResize::disable_resize_ = false;
@end @end
#if !defined(MAC_OS_X_VERSION_10_12)
enum {
NSWindowTabbingModeDisallowed = 2
};
@interface NSWindow (SierraSDK)
- (void)setTabbingMode:(NSInteger)mode;
- (void)setTabbingIdentifier:(NSString*)identifier;
@end
#endif // MAC_OS_X_VERSION_10_12
@interface AtomNSWindow : EventDispatchingWindow<QLPreviewPanelDataSource, QLPreviewPanelDelegate, NSTouchBarDelegate> { @interface AtomNSWindow : EventDispatchingWindow<QLPreviewPanelDataSource, QLPreviewPanelDelegate, NSTouchBarDelegate> {
@private @private
atom::NativeWindowMac* shell_; atom::NativeWindowMac* shell_;
@ -355,6 +377,7 @@ bool ScopedDisableResize::disable_resize_ = false;
- (void)enableWindowButtonsOffset; - (void)enableWindowButtonsOffset;
- (void)resetTouchBar:(const std::vector<mate::PersistentDictionary>&)settings; - (void)resetTouchBar:(const std::vector<mate::PersistentDictionary>&)settings;
- (void)refreshTouchBarItem:(const std::string&)item_id; - (void)refreshTouchBarItem:(const std::string&)item_id;
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item;
@end @end
@ -397,6 +420,11 @@ bool ScopedDisableResize::disable_resize_ = false;
return nil; return nil;
} }
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item {
if (atom_touch_bar_ && self.touchBar)
[atom_touch_bar_ setEscapeTouchBarItem:item forTouchBar:self.touchBar];
}
// NSWindow overrides. // NSWindow overrides.
- (void)swipeWithEvent:(NSEvent *)event { - (void)swipeWithEvent:(NSEvent *)event {
@ -652,6 +680,7 @@ NativeWindowMac::NativeWindowMac(
const mate::Dictionary& options, const mate::Dictionary& options,
NativeWindow* parent) NativeWindow* parent)
: NativeWindow(web_contents, options, parent), : NativeWindow(web_contents, options, parent),
browser_view_(nullptr),
is_kiosk_(false), is_kiosk_(false),
was_fullscreen_(false), was_fullscreen_(false),
zoom_to_page_width_(false), zoom_to_page_width_(false),
@ -682,6 +711,9 @@ NativeWindowMac::NativeWindowMac(
options.Get(options::kTitleBarStyle, &title_bar_style_); options.Get(options::kTitleBarStyle, &title_bar_style_);
std::string tabbingIdentifier;
options.Get(options::kTabbingIdentifier, &tabbingIdentifier);
std::string windowType; std::string windowType;
options.Get(options::kType, &windowType); options.Get(options::kType, &windowType);
@ -754,6 +786,18 @@ NativeWindowMac::NativeWindowMac(
[window_ setOpaque:NO]; [window_ setOpaque:NO];
} }
// Create a tab only if tabbing identifier is specified and window has
// a native title bar.
if (tabbingIdentifier.empty() || transparent() || !has_frame()) {
if ([window_ respondsToSelector:@selector(tabbingMode)]) {
[window_ setTabbingMode:NSWindowTabbingModeDisallowed];
}
} else {
if ([window_ respondsToSelector:@selector(tabbingIdentifier)]) {
[window_ setTabbingIdentifier:base::SysUTF8ToNSString(tabbingIdentifier)];
}
}
// We will manage window's lifetime ourselves. // We will manage window's lifetime ourselves.
[window_ setReleasedWhenClosed:NO]; [window_ setReleasedWhenClosed:NO];
@ -1235,6 +1279,26 @@ void NativeWindowMac::SetContentProtection(bool enable) {
: NSWindowSharingReadOnly]; : NSWindowSharingReadOnly];
} }
void NativeWindowMac::SetBrowserView(NativeBrowserView* browser_view) {
if (browser_view_) {
[browser_view_->GetInspectableWebContentsView()->GetNativeView()
removeFromSuperview];
browser_view_ = nullptr;
}
if (!browser_view) {
return;
}
browser_view_ = browser_view;
auto* native_view =
browser_view->GetInspectableWebContentsView()->GetNativeView();
[[window_ contentView] addSubview:native_view
positioned:NSWindowAbove
relativeTo:nil];
native_view.hidden = NO;
}
void NativeWindowMac::SetParentWindow(NativeWindow* parent) { void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
if (is_modal()) if (is_modal())
return; return;
@ -1262,7 +1326,7 @@ void NativeWindowMac::SetProgressBar(double progress, const NativeWindow::Progre
NSDockTile* dock_tile = [NSApp dockTile]; NSDockTile* dock_tile = [NSApp dockTile];
// For the first time API invoked, we need to create a ContentView in DockTile. // For the first time API invoked, we need to create a ContentView in DockTile.
if (dock_tile.contentView == NULL) { if (dock_tile.contentView == nullptr) {
NSImageView* image_view = [[NSImageView alloc] init]; NSImageView* image_view = [[NSImageView alloc] init];
[image_view setImage:[NSApp applicationIconImage]]; [image_view setImage:[NSApp applicationIconImage]];
[dock_tile setContentView:image_view]; [dock_tile setContentView:image_view];
@ -1358,22 +1422,22 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
// they are available in the minimum SDK version // they are available in the minimum SDK version
if (type == "selection") { if (type == "selection") {
// NSVisualEffectMaterialSelection // NSVisualEffectMaterialSelection
vibrancyType = (NSVisualEffectMaterial) 4; vibrancyType = static_cast<NSVisualEffectMaterial>(4);
} else if (type == "menu") { } else if (type == "menu") {
// NSVisualEffectMaterialMenu // NSVisualEffectMaterialMenu
vibrancyType = (NSVisualEffectMaterial) 5; vibrancyType = static_cast<NSVisualEffectMaterial>(5);
} else if (type == "popover") { } else if (type == "popover") {
// NSVisualEffectMaterialPopover // NSVisualEffectMaterialPopover
vibrancyType = (NSVisualEffectMaterial) 6; vibrancyType = static_cast<NSVisualEffectMaterial>(6);
} else if (type == "sidebar") { } else if (type == "sidebar") {
// NSVisualEffectMaterialSidebar // NSVisualEffectMaterialSidebar
vibrancyType = (NSVisualEffectMaterial) 7; vibrancyType = static_cast<NSVisualEffectMaterial>(7);
} else if (type == "medium-light") { } else if (type == "medium-light") {
// NSVisualEffectMaterialMediumLight // NSVisualEffectMaterialMediumLight
vibrancyType = (NSVisualEffectMaterial) 8; vibrancyType = static_cast<NSVisualEffectMaterial>(8);
} else if (type == "ultra-dark") { } else if (type == "ultra-dark") {
// NSVisualEffectMaterialUltraDark // NSVisualEffectMaterialUltraDark
vibrancyType = (NSVisualEffectMaterial) 9; vibrancyType = static_cast<NSVisualEffectMaterial>(9);
} }
} }
@ -1389,6 +1453,10 @@ void NativeWindowMac::RefreshTouchBarItem(const std::string& item_id) {
[window_ refreshTouchBarItem:item_id]; [window_ refreshTouchBarItem:item_id];
} }
void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
[window_ setEscapeTouchBarItem:item];
}
void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) { void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
switch (event.type) { switch (event.type) {
case blink::WebInputEvent::GestureScrollBegin: case blink::WebInputEvent::GestureScrollBegin:

View file

@ -40,6 +40,9 @@ class NativeWindowObserver {
// Called when the window is closed. // Called when the window is closed.
virtual void OnWindowClosed() {} virtual void OnWindowClosed() {}
// Called when Windows sends WM_ENDSESSION message
virtual void OnWindowEndSession() {}
// Called when window loses focus. // Called when window loses focus.
virtual void OnWindowBlur() {} virtual void OnWindowBlur() {}
@ -67,6 +70,8 @@ class NativeWindowObserver {
virtual void OnWindowScrollTouchEnd() {} virtual void OnWindowScrollTouchEnd() {}
virtual void OnWindowScrollTouchEdge() {} virtual void OnWindowScrollTouchEdge() {}
virtual void OnWindowSwipe(const std::string& direction) {} virtual void OnWindowSwipe(const std::string& direction) {}
virtual void OnWindowSheetBegin() {}
virtual void OnWindowSheetEnd() {}
virtual void OnWindowEnterFullScreen() {} virtual void OnWindowEnterFullScreen() {}
virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowLeaveFullScreen() {}
virtual void OnWindowEnterHtmlFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {}

View file

@ -7,8 +7,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "atom/browser/native_browser_view_views.h"
#include "atom/browser/ui/views/menu_bar.h" #include "atom/browser/ui/views/menu_bar.h"
#include "atom/browser/ui/views/menu_layout.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/color_util.h" #include "atom/common/color_util.h"
#include "atom/common/draggable_region.h" #include "atom/common/draggable_region.h"
@ -135,6 +135,7 @@ NativeWindowViews::NativeWindowViews(
: NativeWindow(web_contents, options, parent), : NativeWindow(web_contents, options, parent),
window_(new views::Widget), window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()), web_view_(inspectable_web_contents()->GetView()->GetView()),
browser_view_(nullptr),
menu_bar_autohide_(false), menu_bar_autohide_(false),
menu_bar_visible_(false), menu_bar_visible_(false),
menu_bar_alt_pressed_(false), menu_bar_alt_pressed_(false),
@ -274,9 +275,6 @@ NativeWindowViews::NativeWindowViews(
SetWindowType(GetAcceleratedWidget(), window_type); SetWindowType(GetAcceleratedWidget(), window_type);
#endif #endif
// Add web view.
SetLayoutManager(new MenuLayout(this, kMenuBarHeight));
AddChildView(web_view_); AddChildView(web_view_);
#if defined(OS_WIN) #if defined(OS_WIN)
@ -881,6 +879,24 @@ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
Layout(); Layout();
} }
void NativeWindowViews::SetBrowserView(NativeBrowserView* browser_view) {
if (browser_view_) {
web_view_->RemoveChildView(
browser_view_->GetInspectableWebContentsView()->GetView());
browser_view_ = nullptr;
}
if (!browser_view) {
return;
}
// Add as child of the main web view to avoid (0, 0) origin from overlapping
// with menu bar.
browser_view_ = browser_view;
web_view_->AddChildView(
browser_view->GetInspectableWebContentsView()->GetView());
}
void NativeWindowViews::SetParentWindow(NativeWindow* parent) { void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
NativeWindow::SetParentWindow(parent); NativeWindow::SetParentWindow(parent);
@ -1248,6 +1264,43 @@ void NativeWindowViews::HandleKeyboardEvent(
} }
} }
void NativeWindowViews::Layout() {
const auto size = GetContentsBounds().size();
const auto menu_bar_bounds =
menu_bar_visible_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight)
: gfx::Rect();
if (menu_bar_) {
menu_bar_->SetBoundsRect(menu_bar_bounds);
}
const auto old_web_view_size = web_view_ ? web_view_->size() : gfx::Size();
if (web_view_) {
web_view_->SetBoundsRect(
gfx::Rect(0, menu_bar_bounds.height(), size.width(),
size.height() - menu_bar_bounds.height()));
}
const auto new_web_view_size = web_view_ ? web_view_->size() : gfx::Size();
if (browser_view_) {
const auto flags = static_cast<NativeBrowserViewViews*>(browser_view_)
->GetAutoResizeFlags();
int width_delta = 0;
int height_delta = 0;
if (flags & kAutoResizeWidth) {
width_delta = new_web_view_size.width() - old_web_view_size.width();
}
if (flags & kAutoResizeHeight) {
height_delta = new_web_view_size.height() - old_web_view_size.height();
}
auto* view = browser_view_->GetInspectableWebContentsView()->GetView();
auto new_view_size = view->size();
new_view_size.set_width(new_view_size.width() + width_delta);
new_view_size.set_height(new_view_size.height() + height_delta);
view->SetSize(new_view_size);
}
}
gfx::Size NativeWindowViews::GetMinimumSize() { gfx::Size NativeWindowViews::GetMinimumSize() {
return NativeWindow::GetMinimumSize(); return NativeWindow::GetMinimumSize();
} }

View file

@ -104,6 +104,7 @@ class NativeWindowViews : public NativeWindow,
void SetContentProtection(bool enable) override; void SetContentProtection(bool enable) override;
void SetFocusable(bool focusable) override; void SetFocusable(bool focusable) override;
void SetMenu(AtomMenuModel* menu_model) override; void SetMenu(AtomMenuModel* menu_model) override;
void SetBrowserView(NativeBrowserView* browser_view) override;
void SetParentWindow(NativeWindow* parent) override; void SetParentWindow(NativeWindow* parent) override;
gfx::NativeWindow GetNativeWindow() override; gfx::NativeWindow GetNativeWindow() override;
void SetOverlayIcon(const gfx::Image& overlay, void SetOverlayIcon(const gfx::Image& overlay,
@ -176,6 +177,7 @@ class NativeWindowViews : public NativeWindow,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;
// views::View: // views::View:
void Layout() override;
gfx::Size GetMinimumSize() override; gfx::Size GetMinimumSize() override;
gfx::Size GetMaximumSize() override; gfx::Size GetMaximumSize() override;
bool AcceleratorPressed(const ui::Accelerator& accelerator) override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
@ -189,6 +191,8 @@ class NativeWindowViews : public NativeWindow,
std::unique_ptr<views::Widget> window_; std::unique_ptr<views::Widget> window_;
views::View* web_view_; // Managed by inspectable_web_contents_. views::View* web_view_; // Managed by inspectable_web_contents_.
NativeBrowserView* browser_view_;
std::unique_ptr<MenuBar> menu_bar_; std::unique_ptr<MenuBar> menu_bar_;
bool menu_bar_autohide_; bool menu_bar_autohide_;
bool menu_bar_visible_; bool menu_bar_visible_;

View file

@ -147,6 +147,11 @@ bool NativeWindowViews::PreHandleMSG(
} }
return false; return false;
} }
case WM_ENDSESSION: {
if (w_param) {
NotifyWindowEndSession();
}
}
default: default:
return false; return false;
} }

View file

@ -50,7 +50,7 @@ class CertVerifierRequest : public AtomCertVerifier::Request {
first_response_(true), first_response_(true),
weak_ptr_factory_(this) {} weak_ptr_factory_(this) {}
~CertVerifierRequest() { ~CertVerifierRequest() override {
cert_verifier_->RemoveRequest(params_); cert_verifier_->RemoveRequest(params_);
default_verifier_request_.reset(); default_verifier_request_.reset();
while (!response_list_.empty() && !first_response_) { while (!response_list_.empty() && !first_response_) {

View file

@ -402,7 +402,7 @@ void AtomNetworkDelegate::OnListenerResultInIO(
if (!base::ContainsKey(callbacks_, id)) if (!base::ContainsKey(callbacks_, id))
return; return;
ReadFromResponseObject(*response.get(), out); ReadFromResponseObject(*response, out);
bool cancel = false; bool cancel = false;
response->GetBoolean("cancel", &cancel); response->GetBoolean("cancel", &cancel);

View file

@ -13,6 +13,7 @@
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_bytes_element_reader.h"
#include "net/url_request/redirect_info.h"
namespace { namespace {
const int kBufferSize = 4096; const int kBufferSize = 4096;
@ -58,6 +59,7 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
AtomBrowserContext* browser_context, AtomBrowserContext* browser_context,
const std::string& method, const std::string& method,
const std::string& url, const std::string& url,
const std::string& redirect_policy,
api::URLRequest* delegate) { api::URLRequest* delegate) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@ -76,7 +78,7 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
if (content::BrowserThread::PostTask( if (content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE, content::BrowserThread::IO, FROM_HERE,
base::Bind(&AtomURLRequest::DoInitialize, atom_url_request, base::Bind(&AtomURLRequest::DoInitialize, atom_url_request,
request_context_getter, method, url))) { request_context_getter, method, url, redirect_policy))) {
return atom_url_request; return atom_url_request;
} }
return nullptr; return nullptr;
@ -93,10 +95,12 @@ void AtomURLRequest::Terminate() {
void AtomURLRequest::DoInitialize( void AtomURLRequest::DoInitialize(
scoped_refptr<net::URLRequestContextGetter> request_context_getter, scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const std::string& method, const std::string& method,
const std::string& url) { const std::string& url,
const std::string& redirect_policy) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
DCHECK(request_context_getter); DCHECK(request_context_getter);
redirect_policy_ = redirect_policy;
request_context_getter_ = request_context_getter; request_context_getter_ = request_context_getter;
request_context_getter_->AddObserver(this); request_context_getter_->AddObserver(this);
auto context = request_context_getter_->GetURLRequestContext(); auto context = request_context_getter_->GetURLRequestContext();
@ -150,6 +154,13 @@ void AtomURLRequest::Cancel() {
base::Bind(&AtomURLRequest::DoCancel, this)); base::Bind(&AtomURLRequest::DoCancel, this));
} }
void AtomURLRequest::FollowRedirect() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&AtomURLRequest::DoFollowRedirect, this));
}
void AtomURLRequest::SetExtraHeader(const std::string& name, void AtomURLRequest::SetExtraHeader(const std::string& name,
const std::string& value) const { const std::string& value) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@ -246,6 +257,13 @@ void AtomURLRequest::DoCancel() {
DoTerminate(); DoTerminate();
} }
void AtomURLRequest::DoFollowRedirect() {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (request_ && request_->is_redirecting() && redirect_policy_ == "manual") {
request_->FollowDeferredRedirect();
}
}
void AtomURLRequest::DoSetExtraHeader(const std::string& name, void AtomURLRequest::DoSetExtraHeader(const std::string& name,
const std::string& value) const { const std::string& value) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@ -297,6 +315,29 @@ void AtomURLRequest::DoSetLoadFlags(int flags) const {
request_->SetLoadFlags(request_->load_flags() | flags); request_->SetLoadFlags(request_->load_flags() | flags);
} }
void AtomURLRequest::OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& info,
bool* defer_redirect) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (!request_ || redirect_policy_ == "follow")
return;
if (redirect_policy_ == "error") {
request->Cancel();
DoCancelWithError(
"Request cannot follow redirect with the current redirect mode", true);
} else if (redirect_policy_ == "manual") {
*defer_redirect = true;
scoped_refptr<net::HttpResponseHeaders> response_headers =
request->response_headers();
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&AtomURLRequest::InformDelegateReceivedRedirect, this,
info.status_code, info.new_method, info.new_url,
response_headers));
}
}
void AtomURLRequest::OnAuthRequired(net::URLRequest* request, void AtomURLRequest::OnAuthRequired(net::URLRequest* request,
net::AuthChallengeInfo* auth_info) { net::AuthChallengeInfo* auth_info) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@ -348,6 +389,14 @@ void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) {
DCHECK_EQ(request, request_.get()); DCHECK_EQ(request, request_.get());
const auto status = request_->status(); const auto status = request_->status();
if (status.error() == bytes_read &&
bytes_read == net::ERR_CONTENT_DECODING_INIT_FAILED) {
// When the request job is unable to create a source stream for the
// content encoding, we fail the request.
DoCancelWithError(net::ErrorToString(net::ERR_CONTENT_DECODING_INIT_FAILED),
true);
return;
}
bool response_error = false; bool response_error = false;
bool data_ended = false; bool data_ended = false;
@ -399,6 +448,16 @@ bool AtomURLRequest::CopyAndPostBuffer(int bytes_read) {
buffer_copy)); buffer_copy));
} }
void AtomURLRequest::InformDelegateReceivedRedirect(
int status_code,
const std::string& method,
const GURL& url,
scoped_refptr<net::HttpResponseHeaders> response_headers) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (delegate_)
delegate_->OnReceivedRedirect(status_code, method, url, response_headers);
}
void AtomURLRequest::InformDelegateAuthenticationRequired( void AtomURLRequest::InformDelegateAuthenticationRequired(
scoped_refptr<net::AuthChallengeInfo> auth_info) const { scoped_refptr<net::AuthChallengeInfo> auth_info) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

View file

@ -30,12 +30,14 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
AtomBrowserContext* browser_context, AtomBrowserContext* browser_context,
const std::string& method, const std::string& method,
const std::string& url, const std::string& url,
const std::string& redirect_policy,
api::URLRequest* delegate); api::URLRequest* delegate);
void Terminate(); void Terminate();
bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last); bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last);
void SetChunkedUpload(bool is_chunked_upload); void SetChunkedUpload(bool is_chunked_upload);
void Cancel(); void Cancel();
void FollowRedirect();
void SetExtraHeader(const std::string& name, const std::string& value) const; void SetExtraHeader(const std::string& name, const std::string& value) const;
void RemoveExtraHeader(const std::string& name) const; void RemoveExtraHeader(const std::string& name) const;
void PassLoginInformation(const base::string16& username, void PassLoginInformation(const base::string16& username,
@ -44,6 +46,9 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
protected: protected:
// Overrides of net::URLRequest::Delegate // Overrides of net::URLRequest::Delegate
void OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& info,
bool* defer_redirect) override;
void OnAuthRequired(net::URLRequest* request, void OnAuthRequired(net::URLRequest* request,
net::AuthChallengeInfo* auth_info) override; net::AuthChallengeInfo* auth_info) override;
void OnResponseStarted(net::URLRequest* request) override; void OnResponseStarted(net::URLRequest* request) override;
@ -60,11 +65,13 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
void DoInitialize(scoped_refptr<net::URLRequestContextGetter>, void DoInitialize(scoped_refptr<net::URLRequestContextGetter>,
const std::string& method, const std::string& method,
const std::string& url); const std::string& url,
const std::string& redirect_policy);
void DoTerminate(); void DoTerminate();
void DoWriteBuffer(scoped_refptr<const net::IOBufferWithSize> buffer, void DoWriteBuffer(scoped_refptr<const net::IOBufferWithSize> buffer,
bool is_last); bool is_last);
void DoCancel(); void DoCancel();
void DoFollowRedirect();
void DoSetExtraHeader(const std::string& name, void DoSetExtraHeader(const std::string& name,
const std::string& value) const; const std::string& value) const;
void DoRemoveExtraHeader(const std::string& name) const; void DoRemoveExtraHeader(const std::string& name) const;
@ -77,6 +84,11 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
void ReadResponse(); void ReadResponse();
bool CopyAndPostBuffer(int bytes_read); bool CopyAndPostBuffer(int bytes_read);
void InformDelegateReceivedRedirect(
int status_code,
const std::string& method,
const GURL& url,
scoped_refptr<net::HttpResponseHeaders> response_headers) const;
void InformDelegateAuthenticationRequired( void InformDelegateAuthenticationRequired(
scoped_refptr<net::AuthChallengeInfo> auth_info) const; scoped_refptr<net::AuthChallengeInfo> auth_info) const;
void InformDelegateResponseStarted( void InformDelegateResponseStarted(
@ -92,6 +104,7 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
scoped_refptr<net::URLRequestContextGetter> request_context_getter_; scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
bool is_chunked_upload_; bool is_chunked_upload_;
std::string redirect_policy_;
std::unique_ptr<net::ChunkedUploadDataStream> chunked_stream_; std::unique_ptr<net::ChunkedUploadDataStream> chunked_stream_;
std::unique_ptr<net::ChunkedUploadDataStream::Writer> chunked_stream_writer_; std::unique_ptr<net::ChunkedUploadDataStream::Writer> chunked_stream_writer_;
std::vector<std::unique_ptr<net::UploadElementReader>> std::vector<std::unique_ptr<net::UploadElementReader>>

View file

@ -164,7 +164,7 @@ void NodeDebugger::DidRead(net::test_server::StreamListenSocket* socket,
buffer_.append(data, len); buffer_.append(data, len);
do { do {
if (buffer_.size() == 0) if (buffer_.empty())
return; return;
// Read the "Content-Length" header. // Read the "Content-Length" header.

View file

@ -851,12 +851,12 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval( GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_)); base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_));
if (copy_frame_generator_.get()) { if (copy_frame_generator_) {
copy_frame_generator_->set_frame_rate_threshold_ms( copy_frame_generator_->set_frame_rate_threshold_ms(
frame_rate_threshold_ms_); frame_rate_threshold_ms_);
} }
if (begin_frame_timer_.get()) { if (begin_frame_timer_) {
begin_frame_timer_->SetFrameRateThresholdMs(frame_rate_threshold_ms_); begin_frame_timer_->SetFrameRateThresholdMs(frame_rate_threshold_ms_);
} else { } else {
begin_frame_timer_.reset(new AtomBeginFrameTimer( begin_frame_timer_.reset(new AtomBeginFrameTimer(
@ -871,7 +871,7 @@ void OffScreenRenderWidgetHostView::Invalidate() {
if (software_output_device_) { if (software_output_device_) {
software_output_device_->OnPaint(bounds_in_pixels); software_output_device_->OnPaint(bounds_in_pixels);
} else if (copy_frame_generator_.get()) { } else if (copy_frame_generator_) {
copy_frame_generator_->GenerateCopyFrame(true, bounds_in_pixels); copy_frame_generator_->GenerateCopyFrame(true, bounds_in_pixels);
} }
} }

View file

@ -145,4 +145,4 @@ OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
return browser_compositor_->GetDelegatedFrameHost(); return browser_compositor_->GetDelegatedFrameHost();
} }
} // namespace } // namespace atom

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>1.6.4</string> <string>1.6.7</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.6.4</string> <string>1.6.7</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

@ -32,7 +32,7 @@
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware> <dpiAware>true/pm</dpiAware>
<disableWindowFiltering xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings">true</disableWindowFiltering> <disableWindowFiltering xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings">true</disableWindowFiltering>
</asmv3:windowsSettings> </asmv3:windowsSettings>
</asmv3:application> </asmv3:application>

View file

@ -56,8 +56,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,6,4,0 FILEVERSION 1,6,7,0
PRODUCTVERSION 1,6,4,0 PRODUCTVERSION 1,6,7,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", "1.6.4" VALUE "FileVersion", "1.6.7"
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", "1.6.4" VALUE "ProductVersion", "1.6.7"
VALUE "SquirrelAwareVersion", "1" VALUE "SquirrelAwareVersion", "1"
END END
END END

View file

@ -0,0 +1,29 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_CERTIFICATE_TRUST_H_
#define ATOM_BROWSER_UI_CERTIFICATE_TRUST_H_
#include <string>
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "net/cert/x509_certificate.h"
namespace atom {
class NativeWindow;
} // namespace atom
namespace certificate_trust {
typedef base::Callback<void(void)> ShowTrustCallback;
void ShowCertificateTrust(atom::NativeWindow* parent_window,
const scoped_refptr<net::X509Certificate>& cert,
const std::string& message,
const ShowTrustCallback& callback);
} // namespace certificate_trust
#endif // ATOM_BROWSER_UI_CERTIFICATE_TRUST_H_

View file

@ -0,0 +1,112 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/ui/certificate_trust.h"
#import <Cocoa/Cocoa.h>
#import <SecurityInterface/SFCertificateTrustPanel.h>
#include "atom/browser/native_window.h"
#include "base/strings/sys_string_conversions.h"
#include "net/cert/cert_database.h"
@interface TrustDelegate : NSObject {
@private
certificate_trust::ShowTrustCallback callback_;
SFCertificateTrustPanel* panel_;
scoped_refptr<net::X509Certificate> cert_;
SecTrustRef trust_;
CFArrayRef cert_chain_;
SecPolicyRef sec_policy_;
}
- (id)initWithCallback:(const certificate_trust::ShowTrustCallback&)callback
panel:(SFCertificateTrustPanel*)panel
cert:(const scoped_refptr<net::X509Certificate>&)cert
trust:(SecTrustRef)trust
certChain:(CFArrayRef)certChain
secPolicy:(SecPolicyRef)secPolicy;
- (void)panelDidEnd:(NSWindow*)sheet
returnCode:(int)returnCode
contextInfo:(void*)contextInfo;
@end
@implementation TrustDelegate
- (void)dealloc {
[panel_ release];
CFRelease(trust_);
CFRelease(cert_chain_);
CFRelease(sec_policy_);
[super dealloc];
}
- (id)initWithCallback:(const certificate_trust::ShowTrustCallback&)callback
panel:(SFCertificateTrustPanel*)panel
cert:(const scoped_refptr<net::X509Certificate>&)cert
trust:(SecTrustRef)trust
certChain:(CFArrayRef)certChain
secPolicy:(SecPolicyRef)secPolicy {
if ((self = [super init])) {
callback_ = callback;
panel_ = panel;
cert_ = cert;
trust_ = trust;
cert_chain_ = certChain;
sec_policy_ = secPolicy;
}
return self;
}
- (void)panelDidEnd:(NSWindow*)sheet
returnCode:(int)returnCode
contextInfo:(void*)contextInfo {
auto cert_db = net::CertDatabase::GetInstance();
// This forces Chromium to reload the certificate since it might be trusted
// now.
cert_db->NotifyObserversCertDBChanged(cert_.get());
callback_.Run();
[self autorelease];
}
@end
namespace certificate_trust {
void ShowCertificateTrust(atom::NativeWindow* parent_window,
const scoped_refptr<net::X509Certificate>& cert,
const std::string& message,
const ShowTrustCallback& callback) {
auto sec_policy = SecPolicyCreateBasicX509();
auto cert_chain = cert->CreateOSCertChainForCert();
SecTrustRef trust = nullptr;
SecTrustCreateWithCertificates(cert_chain, sec_policy, &trust);
NSWindow* window = parent_window ?
parent_window->GetNativeWindow() :
nil;
auto msg = base::SysUTF8ToNSString(message);
auto panel = [[SFCertificateTrustPanel alloc] init];
auto delegate = [[TrustDelegate alloc] initWithCallback:callback
panel:panel
cert:cert
trust:trust
certChain:cert_chain
secPolicy:sec_policy];
[panel beginSheetForWindow:window
modalDelegate:delegate
didEndSelector:@selector(panelDidEnd:returnCode:contextInfo:)
contextInfo:nil
trust:trust
message:msg];
}
} // namespace certificate_trust

View file

@ -70,7 +70,7 @@ Role kRolesMap[] = {
// while its context menu is still open. // while its context menu is still open.
[self cancel]; [self cancel];
model_ = NULL; model_ = nullptr;
[super dealloc]; [super dealloc];
} }

View file

@ -31,6 +31,8 @@
- (NSTouchBar*)touchBarFromItemIdentifiers:(NSMutableArray*)items; - (NSTouchBar*)touchBarFromItemIdentifiers:(NSMutableArray*)items;
- (NSMutableArray*)identifiersFromSettings:(const std::vector<mate::PersistentDictionary>&)settings; - (NSMutableArray*)identifiersFromSettings:(const std::vector<mate::PersistentDictionary>&)settings;
- (void)refreshTouchBarItem:(NSTouchBar*)touchBar id:(const std::string&)item_id; - (void)refreshTouchBarItem:(NSTouchBar*)touchBar id:(const std::string&)item_id;
- (void)addNonDefaultTouchBarItems:(const std::vector<mate::PersistentDictionary>&)items;
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item forTouchBar:(NSTouchBar*)touchBar;
- (NSString*)idFromIdentifier:(NSString*)identifier withPrefix:(NSString*)prefix; - (NSString*)idFromIdentifier:(NSString*)identifier withPrefix:(NSString*)prefix;

View file

@ -113,19 +113,10 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
return nil; return nil;
} }
- (void)refreshTouchBarItem:(NSTouchBar*)touchBar - (void)refreshTouchBarItem:(NSTouchBar*)touchBar
id:(const std::string&)item_id { id:(NSTouchBarItemIdentifier)identifier
if (![self hasItemWithID:item_id]) return; withType:(const std::string&)item_type
withSettings:(const mate::PersistentDictionary&)settings {
mate::PersistentDictionary settings = settings_[item_id];
std::string item_type;
settings.Get("type", &item_type);
NSTouchBarItemIdentifier identifier = [self identifierFromID:item_id
type:item_type];
if (!identifier) return;
NSTouchBarItem* item = [touchBar itemForIdentifier:identifier]; NSTouchBarItem* item = [touchBar itemForIdentifier:identifier];
if (!item) return; if (!item) return;
@ -145,7 +136,56 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
} else if (item_type == "scrubber") { } else if (item_type == "scrubber") {
[self updateScrubber:(NSCustomTouchBarItem*)item withSettings:settings]; [self updateScrubber:(NSCustomTouchBarItem*)item withSettings:settings];
} }
}
- (void)addNonDefaultTouchBarItems:(const std::vector<mate::PersistentDictionary>&)items {
[self identifiersFromSettings:items];
}
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item forTouchBar:(NSTouchBar*)touchBar {
std::string type;
std::string item_id;
NSTouchBarItemIdentifier identifier = nil;
if (item.Get("type", &type) && item.Get("id", &item_id)) {
identifier = [self identifierFromID:item_id type:type];
}
if (identifier) {
[self addNonDefaultTouchBarItems:{ item }];
touchBar.escapeKeyReplacementItemIdentifier = identifier;
} else {
touchBar.escapeKeyReplacementItemIdentifier = nil;
}
}
- (void)refreshTouchBarItem:(NSTouchBar*)touchBar
id:(const std::string&)item_id {
if (![self hasItemWithID:item_id]) return;
mate::PersistentDictionary settings = settings_[item_id];
std::string item_type;
settings.Get("type", &item_type);
auto identifier = [self identifierFromID:item_id type:item_type];
if (!identifier) return;
std::vector<std::string> popover_ids;
settings.Get("_popover", &popover_ids);
for (auto& popover_id : popover_ids) {
auto popoverIdentifier = [self identifierFromID:popover_id type:"popover"];
if (!popoverIdentifier) continue;
NSPopoverTouchBarItem* popoverItem =
[touchBar itemForIdentifier:popoverIdentifier];
[self refreshTouchBarItem:popoverItem.popoverTouchBar
id:identifier
withType:item_type
withSettings:settings];
}
[self refreshTouchBarItem:touchBar
id:identifier
withType:item_type
withSettings:settings];
} }
- (void)buttonAction:(id)sender { - (void)buttonAction:(id)sender {
@ -270,6 +310,16 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
gfx::Image image; gfx::Image image;
if (settings.Get("icon", &image)) { if (settings.Get("icon", &image)) {
button.image = image.AsNSImage(); button.image = image.AsNSImage();
std::string iconPosition;
settings.Get("iconPosition", &iconPosition);
if (iconPosition == "left") {
button.imagePosition = NSImageLeft;
} else if (iconPosition == "right") {
button.imagePosition = NSImageRight;
} else {
button.imagePosition = NSImageOverlaps;
}
} }
} }
@ -319,7 +369,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
- (void)updateColorPicker:(NSColorPickerTouchBarItem*)item - (void)updateColorPicker:(NSColorPickerTouchBarItem*)item
withSettings:(const mate::PersistentDictionary&)settings { withSettings:(const mate::PersistentDictionary&)settings {
std::vector<std::string> colors; std::vector<std::string> colors;
if (settings.Get("availableColors", &colors) && colors.size() > 0) { if (settings.Get("availableColors", &colors) && !colors.empty()) {
NSColorList* color_list = [[[NSColorList alloc] initWithName:@""] autorelease]; NSColorList* color_list = [[[NSColorList alloc] initWithName:@""] autorelease];
for (size_t i = 0; i < colors.size(); ++i) { for (size_t i = 0; i < colors.size(); ++i) {
[color_list insertColor:[self colorFromHexColorString:colors[i]] [color_list insertColor:[self colorFromHexColorString:colors[i]]
@ -414,7 +464,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
NSMutableArray* generatedItems = [NSMutableArray array]; NSMutableArray* generatedItems = [NSMutableArray array];
NSMutableArray* identifiers = [self identifiersFromSettings:items]; NSMutableArray* identifiers = [self identifiersFromSettings:items];
for (NSUInteger i = 0; i < [identifiers count]; i++) { for (NSUInteger i = 0; i < [identifiers count]; ++i) {
if ([identifiers objectAtIndex:i] != NSTouchBarItemIdentifierOtherItemsProxy) { if ([identifiers objectAtIndex:i] != NSTouchBarItemIdentifierOtherItemsProxy) {
NSTouchBarItem* generatedItem = [self makeItemForIdentifier:[identifiers objectAtIndex:i]]; NSTouchBarItem* generatedItem = [self makeItemForIdentifier:[identifiers objectAtIndex:i]];
if (generatedItem) { if (generatedItem) {
@ -474,7 +524,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
settings.Get("segments", &segments); settings.Get("segments", &segments);
control.segmentCount = segments.size(); control.segmentCount = segments.size();
for (int i = 0; i < (int)segments.size(); i++) { for (size_t i = 0; i < segments.size(); ++i) {
std::string label; std::string label;
gfx::Image image; gfx::Image image;
bool enabled = true; bool enabled = true;
@ -581,7 +631,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
std::vector<mate::PersistentDictionary> items; std::vector<mate::PersistentDictionary> items;
if (!settings.Get("items", &items)) return nil; if (!settings.Get("items", &items)) return nil;
if (index >= (long)items.size()) return nil; if (index >= static_cast<NSInteger>(items.size())) return nil;
mate::PersistentDictionary item = items[index]; mate::PersistentDictionary item = items[index];

View file

@ -55,6 +55,7 @@ static const NSTouchBarItemIdentifier NSTouchBarItemIdentifierOtherItemsProxy =
@property(copy) NSArray* defaultItemIdentifiers; @property(copy) NSArray* defaultItemIdentifiers;
@property(copy, readonly) NSArray* itemIdentifiers; @property(copy, readonly) NSArray* itemIdentifiers;
@property(copy, nullable) NSTouchBarItemIdentifier principalItemIdentifier; @property(copy, nullable) NSTouchBarItemIdentifier principalItemIdentifier;
@property(copy, nullable) NSTouchBarItemIdentifier escapeKeyReplacementItemIdentifier;
@property(copy) NSSet* templateItems; @property(copy) NSSet* templateItems;
@property(nullable, weak) id<NSTouchBarDelegate> delegate; @property(nullable, weak) id<NSTouchBarDelegate> delegate;

View file

@ -154,7 +154,7 @@ void ShowOpenDialog(const DialogSettings& settings,
NSWindow* window = settings.parent_window ? NSWindow* window = settings.parent_window ?
settings.parent_window->GetNativeWindow() : settings.parent_window->GetNativeWindow() :
NULL; nullptr;
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) { completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { if (chosen == NSFileHandlingPanelCancelButton) {
@ -193,7 +193,7 @@ void ShowSaveDialog(const DialogSettings& settings,
NSWindow* window = settings.parent_window ? NSWindow* window = settings.parent_window ?
settings.parent_window->GetNativeWindow() : settings.parent_window->GetNativeWindow() :
NULL; nullptr;
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) { completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { if (chosen == NSFileHandlingPanelCancelButton) {

View file

@ -71,10 +71,14 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
switch (type) { switch (type) {
case MESSAGE_BOX_TYPE_INFORMATION: case MESSAGE_BOX_TYPE_INFORMATION:
[alert setAlertStyle:NSInformationalAlertStyle]; alert.alertStyle = NSInformationalAlertStyle;
break; break;
case MESSAGE_BOX_TYPE_WARNING: case MESSAGE_BOX_TYPE_WARNING:
[alert setAlertStyle:NSWarningAlertStyle]; case MESSAGE_BOX_TYPE_ERROR:
// NSWarningAlertStyle shows the app icon while NSCriticalAlertStyle
// shows a warning icon with an app icon badge. Since there is no
// error variant, lets just use NSCriticalAlertStyle.
alert.alertStyle = NSCriticalAlertStyle;
break; break;
default: default:
break; break;
@ -192,7 +196,7 @@ void ShowErrorBox(const base::string16& title, const base::string16& content) {
NSAlert* alert = [[NSAlert alloc] init]; NSAlert* alert = [[NSAlert alloc] init];
[alert setMessageText:base::SysUTF16ToNSString(title)]; [alert setMessageText:base::SysUTF16ToNSString(title)];
[alert setInformativeText:base::SysUTF16ToNSString(content)]; [alert setInformativeText:base::SysUTF16ToNSString(content)];
[alert setAlertStyle:NSWarningAlertStyle]; [alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal]; [alert runModal];
[alert release]; [alert release];
} }

View file

@ -1,91 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/ui/views/menu_layout.h"
#if defined(OS_WIN)
#include "atom/browser/native_window_views.h"
#include "ui/display/win/screen_win.h"
#endif
namespace atom {
namespace {
#if defined(OS_WIN)
gfx::Rect SubtractBorderSize(gfx::Rect bounds) {
gfx::Point borderSize = gfx::Point(
GetSystemMetrics(SM_CXSIZEFRAME) - 1, // width
GetSystemMetrics(SM_CYSIZEFRAME) - 1); // height
gfx::Point dpiAdjustedSize =
display::win::ScreenWin::ScreenToDIPPoint(borderSize);
bounds.set_x(bounds.x() + dpiAdjustedSize.x());
bounds.set_y(bounds.y() + dpiAdjustedSize.y());
bounds.set_width(bounds.width() - 2 * dpiAdjustedSize.x());
bounds.set_height(bounds.height() - 2 * dpiAdjustedSize.y());
return bounds;
}
#endif
} // namespace
MenuLayout::MenuLayout(NativeWindowViews* window, int menu_height)
: window_(window),
menu_height_(menu_height) {
}
MenuLayout::~MenuLayout() {
}
void MenuLayout::Layout(views::View* host) {
#if defined(OS_WIN)
// Reserve border space for maximized frameless window so we won't have the
// content go outside of screen.
if (!window_->has_frame() && window_->IsMaximized()) {
gfx::Rect bounds = SubtractBorderSize(host->GetContentsBounds());
host->child_at(0)->SetBoundsRect(bounds);
return;
}
#endif
if (!HasMenu(host)) {
views::FillLayout::Layout(host);
return;
}
gfx::Size size = host->GetContentsBounds().size();
gfx::Rect menu_Bar_bounds = gfx::Rect(0, 0, size.width(), menu_height_);
gfx::Rect web_view_bounds = gfx::Rect(
0, menu_height_, size.width(), size.height() - menu_height_);
views::View* web_view = host->child_at(0);
views::View* menu_bar = host->child_at(1);
web_view->SetBoundsRect(web_view_bounds);
menu_bar->SetBoundsRect(menu_Bar_bounds);
}
gfx::Size MenuLayout::GetPreferredSize(const views::View* host) const {
gfx::Size size = views::FillLayout::GetPreferredSize(host);
if (!HasMenu(host))
return size;
size.set_height(size.height() + menu_height_);
return size;
}
int MenuLayout::GetPreferredHeightForWidth(
const views::View* host, int width) const {
int height = views::FillLayout::GetPreferredHeightForWidth(host, width);
if (!HasMenu(host))
return height;
return height + menu_height_;
}
bool MenuLayout::HasMenu(const views::View* host) const {
return host->child_count() == 2;
}
} // namespace atom

View file

@ -1,36 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_VIEWS_MENU_LAYOUT_H_
#define ATOM_BROWSER_UI_VIEWS_MENU_LAYOUT_H_
#include "ui/views/layout/fill_layout.h"
namespace atom {
class NativeWindowViews;
class MenuLayout : public views::FillLayout {
public:
MenuLayout(NativeWindowViews* window, int menu_height);
virtual ~MenuLayout();
// views::LayoutManager:
void Layout(views::View* host) override;
gfx::Size GetPreferredSize(const views::View* host) const override;
int GetPreferredHeightForWidth(
const views::View* host, int width) const override;
private:
bool HasMenu(const views::View* host) const;
NativeWindowViews* window_;
int menu_height_;
DISALLOW_COPY_AND_ASSIGN(MenuLayout);
};
} // namespace atom
#endif // ATOM_BROWSER_UI_VIEWS_MENU_LAYOUT_H_

View file

@ -16,26 +16,15 @@
namespace atom { namespace atom {
namespace {
// Filter out the "&" in menu label.
base::string16 FilterAccelerator(const base::string16& label) {
base::string16 out;
base::RemoveChars(label, base::ASCIIToUTF16("&").c_str(), &out);
return out;
}
} // namespace
SubmenuButton::SubmenuButton(const base::string16& title, SubmenuButton::SubmenuButton(const base::string16& title,
views::MenuButtonListener* menu_button_listener, views::MenuButtonListener* menu_button_listener,
const SkColor& background_color) const SkColor& background_color)
: views::MenuButton(FilterAccelerator(title), : views::MenuButton(gfx::RemoveAcceleratorChar(title, '&', NULL, NULL),
menu_button_listener, false), menu_button_listener, false),
accelerator_(0), accelerator_(0),
show_underline_(false), show_underline_(false),
underline_start_(-1), underline_start_(0),
underline_end_(-1), underline_end_(0),
text_width_(0), text_width_(0),
text_height_(0), text_height_(0),
underline_color_(SK_ColorBLACK), underline_color_(SK_ColorBLACK),
@ -117,7 +106,7 @@ bool SubmenuButton::GetUnderlinePosition(const base::string16& text,
void SubmenuButton::GetCharacterPosition( void SubmenuButton::GetCharacterPosition(
const base::string16& text, int index, int* pos) { const base::string16& text, int index, int* pos) {
int height; int height = 0;
gfx::Canvas::SizeStringInt(text.substr(0, index), GetFontList(), pos, &height, gfx::Canvas::SizeStringInt(text.substr(0, index), GetFontList(), pos, &height,
0, 0); 0, 0);
} }

View file

@ -23,7 +23,6 @@ WinFrameView::WinFrameView() {
WinFrameView::~WinFrameView() { WinFrameView::~WinFrameView() {
} }
gfx::Rect WinFrameView::GetWindowBoundsForClientBounds( gfx::Rect WinFrameView::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const { const gfx::Rect& client_bounds) const {
return views::GetWindowBoundsForClientBounds( return views::GetWindowBoundsForClientBounds(

View file

@ -25,12 +25,4 @@ bool AtomDesktopWindowTreeHostWin::PreHandleMSG(
return delegate_->PreHandleMSG(message, w_param, l_param, result); return delegate_->PreHandleMSG(message, w_param, l_param, result);
} }
/** Override the client area inset
* Returning true forces a border of 0 for frameless windows
*/
bool AtomDesktopWindowTreeHostWin::GetClientAreaInsets(
gfx::Insets* insets) const {
return !HasFrame();
}
} // namespace atom } // namespace atom

View file

@ -27,7 +27,6 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin {
protected: protected:
bool PreHandleMSG( bool PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
bool GetClientAreaInsets(gfx::Insets* insets) const override;
private: private:
MessageHandlerDelegate* delegate_; // weak ref MessageHandlerDelegate* delegate_; // weak ref

View file

@ -66,8 +66,9 @@ void WebContentsPermissionHelper::RequestPermission(
void WebContentsPermissionHelper::RequestFullscreenPermission( void WebContentsPermissionHelper::RequestFullscreenPermission(
const base::Callback<void(bool)>& callback) { const base::Callback<void(bool)>& callback) {
RequestPermission((content::PermissionType)(PermissionType::FULLSCREEN), RequestPermission(
callback); static_cast<content::PermissionType>(PermissionType::FULLSCREEN),
callback);
} }
void WebContentsPermissionHelper::RequestMediaAccessPermission( void WebContentsPermissionHelper::RequestMediaAccessPermission(
@ -86,17 +87,17 @@ void WebContentsPermissionHelper::RequestWebNotificationPermission(
void WebContentsPermissionHelper::RequestPointerLockPermission( void WebContentsPermissionHelper::RequestPointerLockPermission(
bool user_gesture) { bool user_gesture) {
RequestPermission((content::PermissionType)(PermissionType::POINTER_LOCK), RequestPermission(
base::Bind(&OnPointerLockResponse, web_contents_), static_cast<content::PermissionType>(PermissionType::POINTER_LOCK),
user_gesture); base::Bind(&OnPointerLockResponse, web_contents_), user_gesture);
} }
void WebContentsPermissionHelper::RequestOpenExternalPermission( void WebContentsPermissionHelper::RequestOpenExternalPermission(
const base::Callback<void(bool)>& callback, const base::Callback<void(bool)>& callback,
bool user_gesture) { bool user_gesture) {
RequestPermission((content::PermissionType)(PermissionType::OPEN_EXTERNAL), RequestPermission(
callback, static_cast<content::PermissionType>(PermissionType::OPEN_EXTERNAL),
user_gesture); callback, user_gesture);
} }
} // namespace atom } // namespace atom

View file

@ -51,7 +51,7 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
private: private:
friend class base::RefCounted<FileSelectHelper>; friend class base::RefCounted<FileSelectHelper>;
~FileSelectHelper() {} ~FileSelectHelper() override {}
void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) { void OnOpenDialogDone(bool result, const std::vector<base::FilePath>& paths) {
std::vector<content::FileChooserFileInfo> file_info; std::vector<content::FileChooserFileInfo> file_info;

View file

@ -26,6 +26,16 @@ WindowList* WindowList::GetInstance() {
return instance_; return instance_;
} }
// static
WindowList::WindowVector WindowList::GetWindows() {
return GetInstance()->windows_;
}
// static
bool WindowList::IsEmpty() {
return GetInstance()->windows_.empty();
}
// static // static
void WindowList::AddWindow(NativeWindow* window) { void WindowList::AddWindow(NativeWindow* window) {
DCHECK(window); DCHECK(window);
@ -46,7 +56,7 @@ void WindowList::RemoveWindow(NativeWindow* window) {
for (WindowListObserver& observer : observers_.Get()) for (WindowListObserver& observer : observers_.Get())
observer.OnWindowRemoved(window); observer.OnWindowRemoved(window);
if (windows.size() == 0) { if (windows.empty()) {
for (WindowListObserver& observer : observers_.Get()) for (WindowListObserver& observer : observers_.Get())
observer.OnWindowAllClosed(); observer.OnWindowAllClosed();
} }
@ -76,6 +86,13 @@ void WindowList::CloseAllWindows() {
window->Close(); window->Close();
} }
// static
void WindowList::DestroyAllWindows() {
WindowVector windows = GetInstance()->windows_;
for (const auto& window : windows)
window->CloseContents(nullptr); // e.g. Destroy()
}
WindowList::WindowList() { WindowList::WindowList() {
} }

View file

@ -19,23 +19,9 @@ class WindowListObserver;
class WindowList { class WindowList {
public: public:
typedef std::vector<NativeWindow*> WindowVector; typedef std::vector<NativeWindow*> WindowVector;
typedef WindowVector::iterator iterator;
typedef WindowVector::const_iterator const_iterator;
// Windows are added to the list before they have constructed windows, static WindowVector GetWindows();
// so the |window()| member function may return NULL. static bool IsEmpty();
const_iterator begin() const { return windows_.begin(); }
const_iterator end() const { return windows_.end(); }
iterator begin() { return windows_.begin(); }
iterator end() { return windows_.end(); }
bool empty() const { return windows_.empty(); }
size_t size() const { return windows_.size(); }
NativeWindow* get(size_t index) const { return windows_[index]; }
static WindowList* GetInstance();
// Adds or removes |window| from the list it is associated with. // Adds or removes |window| from the list it is associated with.
static void AddWindow(NativeWindow* window); static void AddWindow(NativeWindow* window);
@ -51,7 +37,12 @@ class WindowList {
// Closes all windows. // Closes all windows.
static void CloseAllWindows(); static void CloseAllWindows();
// Destroy all windows.
static void DestroyAllWindows();
private: private:
static WindowList* GetInstance();
WindowList(); WindowList();
~WindowList(); ~WindowList();

View file

@ -12,8 +12,7 @@ namespace atom {
ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate, ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate,
v8::Local<v8::Object> target) v8::Local<v8::Object> target)
: context_(isolate, isolate->GetCurrentContext()), : target_(isolate, target),
target_(isolate, target),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter); target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter);
} }

View file

@ -22,7 +22,6 @@ class ObjectLifeMonitor {
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);
v8::Global<v8::Context> context_;
v8::Global<v8::Object> target_; v8::Global<v8::Object> target_;
base::WeakPtrFactory<ObjectLifeMonitor> weak_ptr_factory_; base::WeakPtrFactory<ObjectLifeMonitor> weak_ptr_factory_;

View file

@ -7,7 +7,7 @@
#define ATOM_MAJOR_VERSION 1 #define ATOM_MAJOR_VERSION 1
#define ATOM_MINOR_VERSION 6 #define ATOM_MINOR_VERSION 6
#define ATOM_PATCH_VERSION 4 #define ATOM_PATCH_VERSION 7
#define ATOM_VERSION_IS_RELEASE 1 #define ATOM_VERSION_IS_RELEASE 1

View file

@ -179,7 +179,7 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name,
google_breakpad::ExceptionHandler::HANDLER_ALL, google_breakpad::ExceptionHandler::HANDLER_ALL,
kSmallDumpType, kSmallDumpType,
pipe_name.c_str(), pipe_name.c_str(),
GetCustomInfo(product_name, version, company_name))); GetCustomInfo(product_name, version, company_name, upload_to_server)));
if (!breakpad_->IsOutOfProcess()) if (!breakpad_->IsOutOfProcess())
LOG(ERROR) << "Cannot initialize out-of-process crash handler"; LOG(ERROR) << "Cannot initialize out-of-process crash handler";
@ -238,14 +238,19 @@ bool CrashReporterWin::MinidumpCallback(const wchar_t* dump_path,
google_breakpad::CustomClientInfo* CrashReporterWin::GetCustomInfo( google_breakpad::CustomClientInfo* CrashReporterWin::GetCustomInfo(
const std::string& product_name, const std::string& product_name,
const std::string& version, const std::string& version,
const std::string& company_name) { const std::string& company_name,
bool upload_to_server) {
custom_info_entries_.clear(); custom_info_entries_.clear();
custom_info_entries_.reserve(2 + upload_parameters_.size()); custom_info_entries_.reserve(3 + upload_parameters_.size());
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry( custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
L"prod", L"Electron")); L"prod", L"Electron"));
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry( custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
L"ver", base::UTF8ToWide(version).c_str())); L"ver", base::UTF8ToWide(version).c_str()));
if (!upload_to_server) {
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
L"skip_upload", L"1"));
}
for (StringMap::const_iterator iter = upload_parameters_.begin(); for (StringMap::const_iterator iter = upload_parameters_.begin();
iter != upload_parameters_.end(); ++iter) { iter != upload_parameters_.end(); ++iter) {

View file

@ -56,7 +56,8 @@ class CrashReporterWin : public CrashReporter {
google_breakpad::CustomClientInfo* GetCustomInfo( google_breakpad::CustomClientInfo* GetCustomInfo(
const std::string& product_name, const std::string& product_name,
const std::string& version, const std::string& version,
const std::string& company_name); const std::string& company_name,
bool upload_to_server);
// Custom information to be passed to crash handler. // Custom information to be passed to crash handler.
std::vector<google_breakpad::CustomInfoEntry> custom_info_entries_; std::vector<google_breakpad::CustomInfoEntry> custom_info_entries_;

View file

@ -391,7 +391,7 @@ void CrashService::OnClientDumpRequest(void* context,
LOG(ERROR) << "could not write custom info file"; LOG(ERROR) << "could not write custom info file";
} }
if (!self->sender_) if (!self->sender_ || map.find(L"skip_upload") != map.end())
return; return;
// Send the crash dump using a worker thread. This operation has retry // Send the crash dump using a worker thread. This operation has retry

View file

@ -168,11 +168,13 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
break; break;
} }
if (val == (content::PermissionType)(PermissionType::POINTER_LOCK)) if (val == static_cast<content::PermissionType>(PermissionType::POINTER_LOCK))
return StringToV8(isolate, "pointerLock"); return StringToV8(isolate, "pointerLock");
else if (val == (content::PermissionType)(PermissionType::FULLSCREEN)) else if (val ==
static_cast<content::PermissionType>(PermissionType::FULLSCREEN))
return StringToV8(isolate, "fullscreen"); return StringToV8(isolate, "fullscreen");
else if (val == (content::PermissionType)(PermissionType::OPEN_EXTERNAL)) else if (val ==
static_cast<content::PermissionType>(PermissionType::OPEN_EXTERNAL))
return StringToV8(isolate, "openExternal"); return StringToV8(isolate, "openExternal");
return StringToV8(isolate, "unknown"); return StringToV8(isolate, "unknown");

View file

@ -26,6 +26,27 @@
namespace mate { namespace mate {
namespace {
bool CertFromData(const std::string& data,
scoped_refptr<net::X509Certificate>* out) {
auto cert_list = net::X509Certificate::CreateCertificateListFromBytes(
data.c_str(), data.length(),
net::X509Certificate::FORMAT_SINGLE_CERTIFICATE);
if (cert_list.empty())
return false;
auto leaf_cert = cert_list.front();
if (!leaf_cert)
return false;
*out = leaf_cert;
return true;
}
} // namespace
// static // static
v8::Local<v8::Value> Converter<const net::AuthChallengeInfo*>::ToV8( v8::Local<v8::Value> Converter<const net::AuthChallengeInfo*>::ToV8(
v8::Isolate* isolate, const net::AuthChallengeInfo* val) { v8::Isolate* isolate, const net::AuthChallengeInfo* val) {
@ -73,6 +94,37 @@ v8::Local<v8::Value> Converter<scoped_refptr<net::X509Certificate>>::ToV8(
return dict.GetHandle(); return dict.GetHandle();
} }
bool Converter<scoped_refptr<net::X509Certificate>>::FromV8(
v8::Isolate* isolate, v8::Local<v8::Value> val,
scoped_refptr<net::X509Certificate>* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
std::string data;
dict.Get("data", &data);
scoped_refptr<net::X509Certificate> leaf_cert;
if (!CertFromData(data, &leaf_cert))
return false;
scoped_refptr<net::X509Certificate> parent;
if (dict.Get("issuerCert", &parent)) {
auto parents = std::vector<net::X509Certificate::OSCertHandle>(
parent->GetIntermediateCertificates());
parents.insert(parents.begin(), parent->os_cert_handle());
auto cert = net::X509Certificate::CreateFromHandle(
leaf_cert->os_cert_handle(), parents);
if (!cert)
return false;
*out = cert;
} else {
*out = leaf_cert;
}
return true;
}
// static // static
v8::Local<v8::Value> Converter<net::CertPrincipal>::ToV8( v8::Local<v8::Value> Converter<net::CertPrincipal>::ToV8(
v8::Isolate* isolate, const net::CertPrincipal& val) { v8::Isolate* isolate, const net::CertPrincipal& val) {

View file

@ -33,6 +33,10 @@ template<>
struct Converter<scoped_refptr<net::X509Certificate>> { struct Converter<scoped_refptr<net::X509Certificate>> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const scoped_refptr<net::X509Certificate>& val); const scoped_refptr<net::X509Certificate>& val);
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
scoped_refptr<net::X509Certificate>* out);
}; };
template<> template<>

View file

@ -33,17 +33,18 @@
// Electron's builtin modules. // Electron's builtin modules.
REFERENCE_MODULE(atom_browser_app); REFERENCE_MODULE(atom_browser_app);
REFERENCE_MODULE(atom_browser_auto_updater); REFERENCE_MODULE(atom_browser_auto_updater);
REFERENCE_MODULE(atom_browser_browser_view);
REFERENCE_MODULE(atom_browser_content_tracing); REFERENCE_MODULE(atom_browser_content_tracing);
REFERENCE_MODULE(atom_browser_dialog);
REFERENCE_MODULE(atom_browser_debugger); REFERENCE_MODULE(atom_browser_debugger);
REFERENCE_MODULE(atom_browser_desktop_capturer); REFERENCE_MODULE(atom_browser_desktop_capturer);
REFERENCE_MODULE(atom_browser_dialog);
REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_download_item);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_menu); REFERENCE_MODULE(atom_browser_menu);
REFERENCE_MODULE(atom_browser_net); REFERENCE_MODULE(atom_browser_net);
REFERENCE_MODULE(atom_browser_power_monitor); REFERENCE_MODULE(atom_browser_power_monitor);
REFERENCE_MODULE(atom_browser_power_save_blocker); 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_render_process_preferences); REFERENCE_MODULE(atom_browser_render_process_preferences);
REFERENCE_MODULE(atom_browser_session); REFERENCE_MODULE(atom_browser_session);
REFERENCE_MODULE(atom_browser_system_preferences); REFERENCE_MODULE(atom_browser_system_preferences);
@ -232,6 +233,12 @@ void NodeBindings::RunMessageLoop() {
void NodeBindings::UvRunOnce() { void NodeBindings::UvRunOnce() {
node::Environment* env = uv_env(); node::Environment* env = uv_env();
// When doing navigation without restarting renderer process, it may happen
// that the node environment is destroyed but the message loop is still there.
// In this case we should not run uv loop.
if (!env)
return;
// Use Locker in browser process. // Use Locker in browser process.
mate::Locker locker(env->isolate()); mate::Locker locker(env->isolate());
v8::HandleScope handle_scope(env->isolate()); v8::HandleScope handle_scope(env->isolate());

View file

@ -51,6 +51,9 @@ const char kZoomToPageWidth[] = "zoomToPageWidth";
// The requested title bar style for the window // The requested title bar style for the window
const char kTitleBarStyle[] = "titleBarStyle"; const char kTitleBarStyle[] = "titleBarStyle";
// Tabbing identifier for the window if native tabs are enabled on macOS.
const char kTabbingIdentifier[] = "tabbingIdentifier";
// The menu bar is hidden unless "Alt" is pressed. // The menu bar is hidden unless "Alt" is pressed.
const char kAutoHideMenuBar[] = "autoHideMenuBar"; const char kAutoHideMenuBar[] = "autoHideMenuBar";
@ -156,6 +159,9 @@ const char kSecureSchemes[] = "secure-schemes";
// The browser process app model ID // The browser process app model ID
const char kAppUserModelId[] = "app-user-model-id"; const char kAppUserModelId[] = "app-user-model-id";
// The application path
const char kAppPath[] = "app-path";
// The command line switch versions of the options. // The command line switch versions of the options.
const char kBackgroundColor[] = "background-color"; const char kBackgroundColor[] = "background-color";
const char kPreloadScript[] = "preload"; const char kPreloadScript[] = "preload";

View file

@ -36,6 +36,7 @@ extern const char kAcceptFirstMouse[];
extern const char kUseContentSize[]; extern const char kUseContentSize[];
extern const char kZoomToPageWidth[]; extern const char kZoomToPageWidth[];
extern const char kTitleBarStyle[]; extern const char kTitleBarStyle[];
extern const char kTabbingIdentifier[];
extern const char kAutoHideMenuBar[]; extern const char kAutoHideMenuBar[];
extern const char kEnableLargerThanScreen[]; extern const char kEnableLargerThanScreen[];
extern const char kDarkTheme[]; extern const char kDarkTheme[];
@ -80,6 +81,7 @@ extern const char kStandardSchemes[];
extern const char kRegisterServiceWorkerSchemes[]; extern const char kRegisterServiceWorkerSchemes[];
extern const char kSecureSchemes[]; extern const char kSecureSchemes[];
extern const char kAppUserModelId[]; extern const char kAppUserModelId[];
extern const char kAppPath[];
extern const char kBackgroundColor[]; extern const char kBackgroundColor[];
extern const char kPreloadScript[]; extern const char kPreloadScript[];

View file

@ -7,7 +7,9 @@
#include <stdio.h> #include <stdio.h>
#include "base/cancelable_callback.h" #include "base/cancelable_callback.h"
#include "base/environment.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/nix/xdg_util.h"
#include "base/process/kill.h" #include "base/process/kill.h"
#include "base/process/launch.h" #include "base/process/launch.h"
#include "url/gurl.h" #include "url/gurl.h"
@ -100,7 +102,18 @@ bool MoveItemToTrash(const base::FilePath& full_path) {
if (getenv(ELECTRON_TRASH) != NULL) { if (getenv(ELECTRON_TRASH) != NULL) {
trash = getenv(ELECTRON_TRASH); trash = getenv(ELECTRON_TRASH);
} else { } else {
trash = ELECTRON_DEFAULT_TRASH; // Determine desktop environment and set accordingly.
std::unique_ptr<base::Environment> env(base::Environment::Create());
base::nix::DesktopEnvironment desktop_env(
base::nix::GetDesktopEnvironment(env.get()));
if (desktop_env == base::nix::DESKTOP_ENVIRONMENT_KDE4 ||
desktop_env == base::nix::DESKTOP_ENVIRONMENT_KDE5) {
trash = "kioclient5";
} else if (desktop_env == base::nix::DESKTOP_ENVIRONMENT_KDE3) {
trash = "kioclient";
} else {
trash = ELECTRON_DEFAULT_TRASH;
}
} }
std::vector<std::string> argv; std::vector<std::string> argv;

View file

@ -11,6 +11,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_logging.h" #include "base/mac/mac_logging.h"
#include "base/mac/scoped_aedesc.h" #include "base/mac/scoped_aedesc.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
@ -71,10 +72,10 @@ std::string MessageForOSStatus(OSStatus status, const char* default_message) {
// thread safe, including LSGetApplicationForURL (> 10.2) and // thread safe, including LSGetApplicationForURL (> 10.2) and
// NSWorkspace#openURLs. // NSWorkspace#openURLs.
std::string OpenURL(NSURL* ns_url, bool activate) { std::string OpenURL(NSURL* ns_url, bool activate) {
CFURLRef openingApp = NULL; CFURLRef openingApp = nullptr;
OSStatus status = LSGetApplicationForURL((CFURLRef)ns_url, OSStatus status = LSGetApplicationForURL(base::mac::NSToCFCast(ns_url),
kLSRolesAll, kLSRolesAll,
NULL, nullptr,
&openingApp); &openingApp);
if (status != noErr) if (status != noErr)
return MessageForOSStatus(status, "Failed to open"); return MessageForOSStatus(status, "Failed to open");
@ -156,7 +157,7 @@ bool OpenItem(const base::FilePath& full_path) {
// Create the list of files (only ever one) to open. // Create the list of files (only ever one) to open.
base::mac::ScopedAEDesc<AEDescList> fileList; base::mac::ScopedAEDesc<AEDescList> fileList;
status = AECreateList(NULL, // factoringPtr status = AECreateList(nullptr, // factoringPtr
0, // factoredSize 0, // factoredSize
false, // isRecord false, // isRecord
fileList.OutPointer()); // resultList fileList.OutPointer()); // resultList
@ -167,7 +168,8 @@ bool OpenItem(const base::FilePath& full_path) {
// Add the single path to the file list. C-style cast to avoid both a // Add the single path to the file list. C-style cast to avoid both a
// static_cast and a const_cast to get across the toll-free bridge. // static_cast and a const_cast to get across the toll-free bridge.
CFURLRef pathURLRef = (CFURLRef)[NSURL fileURLWithPath:path_string]; CFURLRef pathURLRef = base::mac::NSToCFCast(
[NSURL fileURLWithPath:path_string]);
FSRef pathRef; FSRef pathRef;
if (CFURLGetFSRef(pathURLRef, &pathRef)) { if (CFURLGetFSRef(pathURLRef, &pathRef)) {
status = AEPutPtr(fileList.OutPointer(), // theAEDescList status = AEPutPtr(fileList.OutPointer(), // theAEDescList
@ -202,8 +204,8 @@ bool OpenItem(const base::FilePath& full_path) {
kAENoReply + kAEAlwaysInteract, // sendMode kAENoReply + kAEAlwaysInteract, // sendMode
kAENormalPriority, // sendPriority kAENormalPriority, // sendPriority
kAEDefaultTimeout, // timeOutInTicks kAEDefaultTimeout, // timeOutInTicks
NULL, // idleProc nullptr, // idleProc
NULL); // filterProc nullptr); // filterProc
if (status != noErr) { if (status != noErr) {
OSSTATUS_LOG(WARNING, status) OSSTATUS_LOG(WARNING, status)
<< "Could not send AE to Finder in OpenItem()"; << "Could not send AE to Finder in OpenItem()";

View file

@ -0,0 +1,84 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/renderer/atom_render_frame_observer.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
namespace atom {
AtomRenderFrameObserver::AtomRenderFrameObserver(
content::RenderFrame* frame,
RendererClientBase* renderer_client)
: content::RenderFrameObserver(frame),
render_frame_(frame),
renderer_client_(renderer_client) {}
void AtomRenderFrameObserver::DidClearWindowObject() {
renderer_client_->DidClearWindowObject(render_frame_);
}
void AtomRenderFrameObserver::DidCreateScriptContext(
v8::Handle<v8::Context> context,
int extension_group,
int world_id) {
if (ShouldNotifyClient(world_id))
renderer_client_->DidCreateScriptContext(context, render_frame_);
if (renderer_client_->isolated_world() && IsMainWorld(world_id)
&& render_frame_->IsMainFrame()) {
CreateIsolatedWorldContext();
renderer_client_->SetupMainWorldOverrides(context);
}
}
void AtomRenderFrameObserver::WillReleaseScriptContext(
v8::Local<v8::Context> context,
int world_id) {
if (ShouldNotifyClient(world_id))
renderer_client_->WillReleaseScriptContext(context, render_frame_);
}
void AtomRenderFrameObserver::OnDestruct() {
delete this;
}
void AtomRenderFrameObserver::CreateIsolatedWorldContext() {
auto frame = render_frame_->GetWebFrame();
// This maps to the name shown in the context combo box in the Console tab
// of the dev tools.
frame->setIsolatedWorldHumanReadableName(
World::ISOLATED_WORLD,
blink::WebString::fromUTF8("Electron Isolated Context"));
// Setup document's origin policy in isolated world
frame->setIsolatedWorldSecurityOrigin(
World::ISOLATED_WORLD, frame->document().getSecurityOrigin());
// Create initial script context in isolated world
blink::WebScriptSource source("void 0");
frame->executeScriptInIsolatedWorld(
World::ISOLATED_WORLD, &source, 1, ExtensionGroup::MAIN_GROUP);
}
bool AtomRenderFrameObserver::IsMainWorld(int world_id) {
return world_id == World::MAIN_WORLD;
}
bool AtomRenderFrameObserver::IsIsolatedWorld(int world_id) {
return world_id == World::ISOLATED_WORLD;
}
bool AtomRenderFrameObserver::ShouldNotifyClient(int world_id) {
if (renderer_client_->isolated_world() && render_frame_->IsMainFrame())
return IsIsolatedWorld(world_id);
else
return IsMainWorld(world_id);
}
} // namespace atom

View file

@ -0,0 +1,53 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_
#define ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_
#include "atom/renderer/renderer_client_base.h"
#include "content/public/renderer/render_frame_observer.h"
namespace atom {
enum World {
MAIN_WORLD = 0,
// Use a high number far away from 0 to not collide with any other world
// IDs created internally by Chrome.
ISOLATED_WORLD = 999
};
enum ExtensionGroup {
MAIN_GROUP = 1
};
// Helper class to forward the messages to the client.
class AtomRenderFrameObserver : public content::RenderFrameObserver {
public:
AtomRenderFrameObserver(content::RenderFrame* frame,
RendererClientBase* renderer_client);
// content::RenderFrameObserver:
void DidClearWindowObject() override;
void DidCreateScriptContext(v8::Handle<v8::Context> context,
int extension_group,
int world_id) override;
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void OnDestruct() override;
private:
bool ShouldNotifyClient(int world_id);
void CreateIsolatedWorldContext();
bool IsMainWorld(int world_id);
bool IsIsolatedWorld(int world_id);
content::RenderFrame* render_frame_;
RendererClientBase* renderer_client_;
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
};
} // namespace atom
#endif // ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_

View file

@ -9,53 +9,22 @@
#include "atom_natives.h" // NOLINT: This file is generated with js2c #include "atom_natives.h" // NOLINT: This file is generated with js2c
#include "atom/common/api/api_messages.h"
#include "atom/common/api/atom_bindings.h" #include "atom/common/api/atom_bindings.h"
#include "atom/common/api/event_emitter_caller.h" #include "atom/common/api/event_emitter_caller.h"
#include "atom/common/asar/asar_util.h" #include "atom/common/asar/asar_util.h"
#include "atom/common/atom_constants.h" #include "atom/common/atom_constants.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_bindings.h" #include "atom/common/node_bindings.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
#include "atom/renderer/api/atom_api_renderer_ipc.h" #include "atom/renderer/api/atom_api_renderer_ipc.h"
#include "atom/renderer/atom_render_frame_observer.h"
#include "atom/renderer/atom_render_view_observer.h" #include "atom/renderer/atom_render_view_observer.h"
#include "atom/renderer/content_settings_observer.h"
#include "atom/renderer/guest_view_container.h"
#include "atom/renderer/node_array_buffer_bridge.h" #include "atom/renderer/node_array_buffer_bridge.h"
#include "atom/renderer/preferences_manager.h"
#include "atom/renderer/web_worker_observer.h" #include "atom/renderer/web_worker_observer.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/renderer/media/chrome_key_systems.h"
#include "chrome/renderer/pepper/pepper_helper.h"
#include "chrome/renderer/printing/print_web_view_helper.h"
#include "chrome/renderer/tts_dispatcher.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "ipc/ipc_message_macros.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "third_party/WebKit/public/web/WebCustomElement.h"
#include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrameWidget.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
#include "third_party/WebKit/public/web/WebView.h"
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "base/strings/sys_string_conversions.h"
#endif
#if defined(OS_WIN)
#include <shlobj.h>
#endif
#include "atom/common/node_includes.h" #include "atom/common/node_includes.h"
@ -63,156 +32,11 @@ namespace atom {
namespace { namespace {
enum World {
MAIN_WORLD = 0,
// Use a high number far away from 0 to not collide with any other world
// IDs created internally by Chrome.
ISOLATED_WORLD = 999
};
enum ExtensionGroup {
MAIN_GROUP = 1
};
// Helper class to forward the messages to the client.
class AtomRenderFrameObserver : public content::RenderFrameObserver {
public:
AtomRenderFrameObserver(content::RenderFrame* frame,
AtomRendererClient* renderer_client)
: content::RenderFrameObserver(frame),
render_frame_(frame),
renderer_client_(renderer_client) {}
// content::RenderFrameObserver:
void DidClearWindowObject() override {
renderer_client_->DidClearWindowObject(render_frame_);
}
void CreateIsolatedWorldContext() {
auto frame = render_frame_->GetWebFrame();
// This maps to the name shown in the context combo box in the Console tab
// of the dev tools.
frame->setIsolatedWorldHumanReadableName(
World::ISOLATED_WORLD,
blink::WebString::fromUTF8("Electron Isolated Context"));
// Setup document's origin policy in isolated world
frame->setIsolatedWorldSecurityOrigin(
World::ISOLATED_WORLD, frame->document().getSecurityOrigin());
// Create initial script context in isolated world
blink::WebScriptSource source("void 0");
frame->executeScriptInIsolatedWorld(
World::ISOLATED_WORLD, &source, 1, ExtensionGroup::MAIN_GROUP);
}
void SetupMainWorldOverrides(v8::Handle<v8::Context> context) {
// Setup window overrides in the main world context
v8::Isolate* isolate = context->GetIsolate();
// Wrap the bundle into a function that receives the binding object as
// an argument.
std::string bundle(node::isolated_bundle_data,
node::isolated_bundle_data + sizeof(node::isolated_bundle_data));
std::string wrapper = "(function (binding) {\n" + bundle + "\n})";
auto script = v8::Script::Compile(
mate::ConvertToV8(isolate, wrapper)->ToString());
auto func = v8::Handle<v8::Function>::Cast(
script->Run(context).ToLocalChecked());
auto binding = v8::Object::New(isolate);
api::Initialize(binding, v8::Null(isolate), context, nullptr);
// Pass in CLI flags needed to setup window
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
mate::Dictionary dict(isolate, binding);
if (command_line->HasSwitch(switches::kGuestInstanceID))
dict.Set(options::kGuestInstanceID,
command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
if (command_line->HasSwitch(switches::kOpenerID))
dict.Set(options::kOpenerID,
command_line->GetSwitchValueASCII(switches::kOpenerID));
dict.Set("hiddenPage", command_line->HasSwitch(switches::kHiddenPage));
v8::Local<v8::Value> args[] = { binding };
ignore_result(func->Call(context, v8::Null(isolate), 1, args));
}
bool IsMainWorld(int world_id) {
return world_id == World::MAIN_WORLD;
}
bool IsIsolatedWorld(int world_id) {
return world_id == World::ISOLATED_WORLD;
}
bool ShouldNotifyClient(int world_id) {
if (renderer_client_->isolated_world() && render_frame_->IsMainFrame())
return IsIsolatedWorld(world_id);
else
return IsMainWorld(world_id);
}
void DidCreateScriptContext(v8::Handle<v8::Context> context,
int extension_group,
int world_id) override {
if (ShouldNotifyClient(world_id))
renderer_client_->DidCreateScriptContext(context, render_frame_);
if (renderer_client_->isolated_world() && IsMainWorld(world_id)
&& render_frame_->IsMainFrame()) {
CreateIsolatedWorldContext();
SetupMainWorldOverrides(context);
}
}
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override {
if (ShouldNotifyClient(world_id))
renderer_client_->WillReleaseScriptContext(context, render_frame_);
}
void OnDestruct() override {
delete this;
}
private:
content::RenderFrame* render_frame_;
AtomRendererClient* renderer_client_;
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
};
v8::Local<v8::Value> GetRenderProcessPreferences(
const PreferencesManager* preferences_manager, v8::Isolate* isolate) {
if (preferences_manager->preferences())
return mate::ConvertToV8(isolate, *preferences_manager->preferences());
else
return v8::Null(isolate);
}
void AddRenderBindings(v8::Isolate* isolate,
v8::Local<v8::Object> process,
const PreferencesManager* preferences_manager) {
mate::Dictionary dict(isolate, process);
dict.SetMethod(
"getRenderProcessPreferences",
base::Bind(GetRenderProcessPreferences, preferences_manager));
}
bool IsDevToolsExtension(content::RenderFrame* render_frame) { bool IsDevToolsExtension(content::RenderFrame* render_frame) {
return static_cast<GURL>(render_frame->GetWebFrame()->document().url()) return static_cast<GURL>(render_frame->GetWebFrame()->document().url())
.SchemeIs("chrome-extension"); .SchemeIs("chrome-extension");
} }
std::vector<std::string> ParseSchemesCLISwitch(const char* switch_name) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::string custom_schemes = command_line->GetSwitchValueASCII(switch_name);
return base::SplitString(
custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
} // namespace } // namespace
AtomRendererClient::AtomRendererClient() AtomRendererClient::AtomRendererClient()
@ -221,11 +45,6 @@ AtomRendererClient::AtomRendererClient()
atom_bindings_(new AtomBindings(uv_default_loop())) { atom_bindings_(new AtomBindings(uv_default_loop())) {
isolated_world_ = base::CommandLine::ForCurrentProcess()->HasSwitch( isolated_world_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kContextIsolation); switches::kContextIsolation);
// Parse --standard-schemes=scheme1,scheme2
std::vector<std::string> standard_schemes_list =
ParseSchemesCLISwitch(switches::kStandardSchemes);
for (const std::string& scheme : standard_schemes_list)
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
} }
AtomRendererClient::~AtomRendererClient() { AtomRendererClient::~AtomRendererClient() {
@ -233,86 +52,18 @@ AtomRendererClient::~AtomRendererClient() {
} }
void AtomRendererClient::RenderThreadStarted() { void AtomRendererClient::RenderThreadStarted() {
blink::WebCustomElement::addEmbedderCustomElementName("webview");
blink::WebCustomElement::addEmbedderCustomElementName("browserplugin");
OverrideNodeArrayBuffer(); OverrideNodeArrayBuffer();
RendererClientBase::RenderThreadStarted();
preferences_manager_.reset(new PreferencesManager);
#if defined(OS_WIN)
// Set ApplicationUserModelID in renderer process.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
base::string16 app_id =
command_line->GetSwitchValueNative(switches::kAppUserModelId);
if (!app_id.empty()) {
SetCurrentProcessExplicitAppUserModelID(app_id.c_str());
}
#endif
#if defined(OS_MACOSX)
// Disable rubber banding by default.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kScrollBounce)) {
base::ScopedCFTypeRef<CFStringRef> key(
base::SysUTF8ToCFStringRef("NSScrollViewRubberbanding"));
base::ScopedCFTypeRef<CFStringRef> value(
base::SysUTF8ToCFStringRef("false"));
CFPreferencesSetAppValue(key, value, kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
}
#endif
} }
void AtomRendererClient::RenderFrameCreated( void AtomRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) { content::RenderFrame* render_frame) {
new PepperHelper(render_frame); RendererClientBase::RenderFrameCreated(render_frame);
new AtomRenderFrameObserver(render_frame, this);
new ContentSettingsObserver(render_frame);
new printing::PrintWebViewHelper(render_frame);
// Allow file scheme to handle service worker by default.
// FIXME(zcbenz): Can this be moved elsewhere?
blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file");
// This is required for widevine plugin detection provided during runtime.
blink::resetPluginCache();
// Allow access to file scheme from pdf viewer.
blink::WebSecurityPolicy::addOriginAccessWhitelistEntry(
GURL(kPdfViewerUIOrigin), "file", "", true);
// Parse --secure-schemes=scheme1,scheme2
std::vector<std::string> secure_schemes_list =
ParseSchemesCLISwitch(switches::kSecureSchemes);
for (const std::string& secure_scheme : secure_schemes_list)
blink::WebSecurityPolicy::registerURLSchemeAsSecure(
blink::WebString::fromUTF8(secure_scheme));
} }
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
new AtomRenderViewObserver(render_view, this); new AtomRenderViewObserver(render_view, this);
RendererClientBase::RenderViewCreated(render_view);
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
if (!web_frame_widget)
return;
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kGuestInstanceID)) { // webview.
web_frame_widget->setBaseBackgroundColor(SK_ColorTRANSPARENT);
} else { // normal window.
// If backgroundColor is specified then use it.
std::string name = cmd->GetSwitchValueASCII(switches::kBackgroundColor);
// Otherwise use white background.
SkColor color = name.empty() ? SK_ColorWHITE : ParseHexColor(name);
web_frame_widget->setBaseBackgroundColor(color);
}
}
void AtomRendererClient::DidClearWindowObject(
content::RenderFrame* render_frame) {
// Make sure every page will get a script context created.
render_frame->GetWebFrame()->executeScript(blink::WebScriptSource("void 0"));
} }
void AtomRendererClient::RunScriptsAtDocumentStart( void AtomRendererClient::RunScriptsAtDocumentStart(
@ -335,26 +86,6 @@ void AtomRendererClient::RunScriptsAtDocumentEnd(
} }
} }
blink::WebSpeechSynthesizer* AtomRendererClient::OverrideSpeechSynthesizer(
blink::WebSpeechSynthesizerClient* client) {
return new TtsDispatcher(client);
}
bool AtomRendererClient::OverrideCreatePlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (params.mimeType.utf8() == content::kBrowserPluginMimeType ||
params.mimeType.utf8() == kPdfPluginMimeType ||
command_line->HasSwitch(switches::kEnablePlugins))
return false;
*plugin = nullptr;
return true;
}
void AtomRendererClient::DidCreateScriptContext( void AtomRendererClient::DidCreateScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) { v8::Handle<v8::Context> context, content::RenderFrame* render_frame) {
// Only allow node integration for the main frame, unless it is a devtools // Only allow node integration for the main frame, unless it is a devtools
@ -374,8 +105,7 @@ void AtomRendererClient::DidCreateScriptContext(
// Add Electron extended APIs. // Add Electron extended APIs.
atom_bindings_->BindTo(env->isolate(), env->process_object()); atom_bindings_->BindTo(env->isolate(), env->process_object());
AddRenderBindings(env->isolate(), env->process_object(), AddRenderBindings(env->isolate(), env->process_object());
preferences_manager_.get());
// Load everything. // Load everything.
node_bindings_->LoadEnvironment(env); node_bindings_->LoadEnvironment(env);
@ -423,22 +153,6 @@ bool AtomRendererClient::ShouldFork(blink::WebLocalFrame* frame,
return http_method == "GET"; return http_method == "GET";
} }
content::BrowserPluginDelegate* AtomRendererClient::CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) {
if (mime_type == content::kBrowserPluginMimeType) {
return new GuestViewContainer(render_frame);
} else {
return nullptr;
}
}
void AtomRendererClient::AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
AddChromeKeySystems(key_systems);
}
void AtomRendererClient::DidInitializeWorkerContextOnWorkerThread( void AtomRendererClient::DidInitializeWorkerContextOnWorkerThread(
v8::Local<v8::Context> context) { v8::Local<v8::Context> context) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch( if (base::CommandLine::ForCurrentProcess()->HasSwitch(
@ -464,4 +178,38 @@ v8::Local<v8::Context> AtomRendererClient::GetContext(
return frame->mainWorldScriptContext(); return frame->mainWorldScriptContext();
} }
void AtomRendererClient::SetupMainWorldOverrides(
v8::Handle<v8::Context> context) {
// Setup window overrides in the main world context
v8::Isolate* isolate = context->GetIsolate();
// Wrap the bundle into a function that receives the binding object as
// an argument.
std::string bundle(node::isolated_bundle_data,
node::isolated_bundle_data + sizeof(node::isolated_bundle_data));
std::string wrapper = "(function (binding, require) {\n" + bundle + "\n})";
auto script = v8::Script::Compile(
mate::ConvertToV8(isolate, wrapper)->ToString());
auto func = v8::Handle<v8::Function>::Cast(
script->Run(context).ToLocalChecked());
auto binding = v8::Object::New(isolate);
api::Initialize(binding, v8::Null(isolate), context, nullptr);
// Pass in CLI flags needed to setup window
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
mate::Dictionary dict(isolate, binding);
if (command_line->HasSwitch(switches::kGuestInstanceID))
dict.Set(options::kGuestInstanceID,
command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
if (command_line->HasSwitch(switches::kOpenerID))
dict.Set(options::kOpenerID,
command_line->GetSwitchValueASCII(switches::kOpenerID));
dict.Set("hiddenPage", command_line->HasSwitch(switches::kHiddenPage));
v8::Local<v8::Value> args[] = { binding };
ignore_result(func->Call(context, v8::Null(isolate), 1, args));
}
} // namespace atom } // namespace atom

View file

@ -8,29 +8,31 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "content/public/renderer/content_renderer_client.h" #include "atom/renderer/renderer_client_base.h"
namespace atom { namespace atom {
class AtomBindings; class AtomBindings;
class PreferencesManager;
class NodeBindings; class NodeBindings;
class AtomRendererClient : public content::ContentRendererClient { class AtomRendererClient : public RendererClientBase {
public: public:
AtomRendererClient(); AtomRendererClient();
virtual ~AtomRendererClient(); virtual ~AtomRendererClient();
void DidClearWindowObject(content::RenderFrame* render_frame);
void DidCreateScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame);
void WillReleaseScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame);
// Get the context that the Electron API is running in. // Get the context that the Electron API is running in.
v8::Local<v8::Context> GetContext( v8::Local<v8::Context> GetContext(
blink::WebFrame* frame, v8::Isolate* isolate); blink::WebFrame* frame, v8::Isolate* isolate);
bool isolated_world() { return isolated_world_; }
// atom::RendererClientBase:
void DidCreateScriptContext(
v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) override;
void WillReleaseScriptContext(
v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) override;
void SetupMainWorldOverrides(v8::Handle<v8::Context> context) override;
bool isolated_world() override { return isolated_world_; }
private: private:
enum NodeIntegration { enum NodeIntegration {
@ -46,25 +48,12 @@ class AtomRendererClient : public content::ContentRendererClient {
void RenderViewCreated(content::RenderView*) override; void RenderViewCreated(content::RenderView*) override;
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override;
void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
blink::WebSpeechSynthesizer* OverrideSpeechSynthesizer(
blink::WebSpeechSynthesizerClient* client) override;
bool OverrideCreatePlugin(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) override;
bool ShouldFork(blink::WebLocalFrame* frame, bool ShouldFork(blink::WebLocalFrame* frame,
const GURL& url, const GURL& url,
const std::string& http_method, const std::string& http_method,
bool is_initial_navigation, bool is_initial_navigation,
bool is_server_redirect, bool is_server_redirect,
bool* send_referrer) override; bool* send_referrer) override;
content::BrowserPluginDelegate* CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) override;
void AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
override;
void DidInitializeWorkerContextOnWorkerThread( void DidInitializeWorkerContextOnWorkerThread(
v8::Local<v8::Context> context) override; v8::Local<v8::Context> context) override;
void WillDestroyWorkerContextOnWorkerThread( void WillDestroyWorkerContextOnWorkerThread(
@ -75,7 +64,6 @@ class AtomRendererClient : public content::ContentRendererClient {
std::unique_ptr<NodeBindings> node_bindings_; std::unique_ptr<NodeBindings> node_bindings_;
std::unique_ptr<AtomBindings> atom_bindings_; std::unique_ptr<AtomBindings> atom_bindings_;
std::unique_ptr<PreferencesManager> preferences_manager_;
bool isolated_world_; bool isolated_world_;
DISALLOW_COPY_AND_ASSIGN(AtomRendererClient); DISALLOW_COPY_AND_ASSIGN(AtomRendererClient);

View file

@ -9,6 +9,7 @@
#include "atom_natives.h" // NOLINT: This file is generated with js2c #include "atom_natives.h" // NOLINT: This file is generated with js2c
#include "atom/common/api/api_messages.h" #include "atom/common/api/api_messages.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/v8_value_converter.h" #include "atom/common/native_mate_converters/v8_value_converter.h"
#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
@ -19,7 +20,6 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/renderer/printing/print_web_view_helper.h" #include "chrome/renderer/printing/print_web_view_helper.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_observer.h" #include "content/public/renderer/render_view_observer.h"
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
@ -85,52 +85,9 @@ void InitializeBindings(v8::Local<v8::Object> binding,
auto isolate = context->GetIsolate(); auto isolate = context->GetIsolate();
mate::Dictionary b(isolate, binding); mate::Dictionary b(isolate, binding);
b.SetMethod("get", GetBinding); b.SetMethod("get", GetBinding);
b.SetMethod("crash", AtomBindings::Crash);
} }
class AtomSandboxedRenderFrameObserver : public content::RenderFrameObserver {
public:
AtomSandboxedRenderFrameObserver(content::RenderFrame* frame,
AtomSandboxedRendererClient* renderer_client)
: content::RenderFrameObserver(frame),
render_frame_(frame),
world_id_(-1),
renderer_client_(renderer_client) {}
// content::RenderFrameObserver:
void DidClearWindowObject() override {
// Make sure every page will get a script context created.
render_frame_->GetWebFrame()->executeScript(
blink::WebScriptSource("void 0"));
}
void DidCreateScriptContext(v8::Handle<v8::Context> context,
int extension_group,
int world_id) override {
if (world_id_ != -1 && world_id_ != world_id)
return;
world_id_ = world_id;
renderer_client_->DidCreateScriptContext(context, render_frame_);
}
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override {
if (world_id_ != world_id)
return;
renderer_client_->WillReleaseScriptContext(context, render_frame_);
}
void OnDestruct() override {
delete this;
}
private:
content::RenderFrame* render_frame_;
int world_id_;
AtomSandboxedRendererClient* renderer_client_;
DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRenderFrameObserver);
};
class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver { class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver {
public: public:
AtomSandboxedRenderViewObserver(content::RenderView* render_view, AtomSandboxedRenderViewObserver(content::RenderView* render_view,
@ -179,13 +136,13 @@ AtomSandboxedRendererClient::~AtomSandboxedRendererClient() {
void AtomSandboxedRendererClient::RenderFrameCreated( void AtomSandboxedRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) { content::RenderFrame* render_frame) {
new AtomSandboxedRenderFrameObserver(render_frame, this); RendererClientBase::RenderFrameCreated(render_frame);
new printing::PrintWebViewHelper(render_frame);
} }
void AtomSandboxedRendererClient::RenderViewCreated( void AtomSandboxedRendererClient::RenderViewCreated(
content::RenderView* render_view) { content::RenderView* render_view) {
new AtomSandboxedRenderViewObserver(render_view, this); new AtomSandboxedRenderViewObserver(render_view, this);
RendererClientBase::RenderViewCreated(render_view);
} }
void AtomSandboxedRendererClient::DidCreateScriptContext( void AtomSandboxedRendererClient::DidCreateScriptContext(
@ -204,7 +161,7 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
std::string preload_bundle_native(node::preload_bundle_data, std::string preload_bundle_native(node::preload_bundle_data,
node::preload_bundle_data + sizeof(node::preload_bundle_data)); node::preload_bundle_data + sizeof(node::preload_bundle_data));
std::stringstream ss; std::stringstream ss;
ss << "(function(binding, preloadPath) {\n"; ss << "(function(binding, preloadPath, require) {\n";
ss << preload_bundle_native << "\n"; ss << preload_bundle_native << "\n";
ss << "})"; ss << "})";
std::string preload_wrapper = ss.str(); std::string preload_wrapper = ss.str();
@ -216,6 +173,7 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
// Create and initialize the binding object // Create and initialize the binding object
auto binding = v8::Object::New(isolate); auto binding = v8::Object::New(isolate);
InitializeBindings(binding, context); InitializeBindings(binding, context);
AddRenderBindings(isolate, binding);
v8::Local<v8::Value> args[] = { v8::Local<v8::Value> args[] = {
binding, binding,
mate::ConvertToV8(isolate, preload_script) mate::ConvertToV8(isolate, preload_script)
@ -234,7 +192,7 @@ void AtomSandboxedRendererClient::WillReleaseScriptContext(
void AtomSandboxedRendererClient::InvokeIpcCallback( void AtomSandboxedRendererClient::InvokeIpcCallback(
v8::Handle<v8::Context> context, v8::Handle<v8::Context> context,
std::string callback_name, const std::string& callback_name,
std::vector<v8::Handle<v8::Value>> args) { std::vector<v8::Handle<v8::Value>> args) {
auto isolate = context->GetIsolate(); auto isolate = context->GetIsolate();
auto binding_key = mate::ConvertToV8(isolate, kIpcKey)->ToString(); auto binding_key = mate::ConvertToV8(isolate, kIpcKey)->ToString();

View file

@ -7,23 +7,27 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "content/public/renderer/content_renderer_client.h" #include "atom/renderer/renderer_client_base.h"
#include "content/public/renderer/render_frame.h"
namespace atom { namespace atom {
class AtomSandboxedRendererClient : public content::ContentRendererClient { class AtomSandboxedRendererClient : public RendererClientBase {
public: public:
AtomSandboxedRendererClient(); AtomSandboxedRendererClient();
virtual ~AtomSandboxedRendererClient(); virtual ~AtomSandboxedRendererClient();
void DidCreateScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame);
void WillReleaseScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame);
void InvokeIpcCallback(v8::Handle<v8::Context> context, void InvokeIpcCallback(v8::Handle<v8::Context> context,
std::string callback_name, const std::string& callback_name,
std::vector<v8::Handle<v8::Value>> args); std::vector<v8::Handle<v8::Value>> args);
// atom::RendererClientBase:
void DidCreateScriptContext(
v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) override;
void WillReleaseScriptContext(
v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) override;
void SetupMainWorldOverrides(v8::Handle<v8::Context> context) override { }
bool isolated_world() override { return false; }
// content::ContentRendererClient: // content::ContentRendererClient:
void RenderFrameCreated(content::RenderFrame*) override; void RenderFrameCreated(content::RenderFrame*) override;
void RenderViewCreated(content::RenderView*) override; void RenderViewCreated(content::RenderView*) override;

View file

@ -0,0 +1,197 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/renderer/renderer_client_base.h"
#include <string>
#include <vector>
#include "atom/common/atom_constants.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/options_switches.h"
#include "atom/renderer/atom_render_frame_observer.h"
#include "atom/renderer/content_settings_observer.h"
#include "atom/renderer/guest_view_container.h"
#include "atom/renderer/preferences_manager.h"
#include "base/command_line.h"
#include "base/strings/string_split.h"
#include "chrome/renderer/media/chrome_key_systems.h"
#include "chrome/renderer/pepper/pepper_helper.h"
#include "chrome/renderer/printing/print_web_view_helper.h"
#include "chrome/renderer/tts_dispatcher.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/render_view.h"
#include "native_mate/dictionary.h"
#include "third_party/WebKit/public/web/WebCustomElement.h"
#include "third_party/WebKit/public/web/WebFrameWidget.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "base/strings/sys_string_conversions.h"
#endif
#if defined(OS_WIN)
#include <shlobj.h>
#endif
namespace atom {
namespace {
v8::Local<v8::Value> GetRenderProcessPreferences(
const PreferencesManager* preferences_manager, v8::Isolate* isolate) {
if (preferences_manager->preferences())
return mate::ConvertToV8(isolate, *preferences_manager->preferences());
else
return v8::Null(isolate);
}
std::vector<std::string> ParseSchemesCLISwitch(const char* switch_name) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::string custom_schemes = command_line->GetSwitchValueASCII(switch_name);
return base::SplitString(
custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
} // namespace
RendererClientBase::RendererClientBase() {
// Parse --standard-schemes=scheme1,scheme2
std::vector<std::string> standard_schemes_list =
ParseSchemesCLISwitch(switches::kStandardSchemes);
for (const std::string& scheme : standard_schemes_list)
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
}
RendererClientBase::~RendererClientBase() {
}
void RendererClientBase::AddRenderBindings(
v8::Isolate* isolate,
v8::Local<v8::Object> binding_object) {
mate::Dictionary dict(isolate, binding_object);
dict.SetMethod(
"getRenderProcessPreferences",
base::Bind(GetRenderProcessPreferences, preferences_manager_.get()));
}
void RendererClientBase::RenderThreadStarted() {
blink::WebCustomElement::addEmbedderCustomElementName("webview");
blink::WebCustomElement::addEmbedderCustomElementName("browserplugin");
preferences_manager_.reset(new PreferencesManager);
#if defined(OS_WIN)
// Set ApplicationUserModelID in renderer process.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
base::string16 app_id =
command_line->GetSwitchValueNative(switches::kAppUserModelId);
if (!app_id.empty()) {
SetCurrentProcessExplicitAppUserModelID(app_id.c_str());
}
#endif
#if defined(OS_MACOSX)
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
bool scroll_bounce = command_line->HasSwitch(switches::kScrollBounce);
base::ScopedCFTypeRef<CFStringRef> rubber_banding_key(
base::SysUTF8ToCFStringRef("NSScrollViewRubberbanding"));
CFPreferencesSetAppValue(rubber_banding_key,
scroll_bounce ? kCFBooleanTrue : kCFBooleanFalse,
kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
#endif
}
void RendererClientBase::RenderFrameCreated(
content::RenderFrame* render_frame) {
new AtomRenderFrameObserver(render_frame, this);
new PepperHelper(render_frame);
new ContentSettingsObserver(render_frame);
new printing::PrintWebViewHelper(render_frame);
// Allow file scheme to handle service worker by default.
// FIXME(zcbenz): Can this be moved elsewhere?
blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file");
// This is required for widevine plugin detection provided during runtime.
blink::resetPluginCache();
// Allow access to file scheme from pdf viewer.
blink::WebSecurityPolicy::addOriginAccessWhitelistEntry(
GURL(kPdfViewerUIOrigin), "file", "", true);
// Parse --secure-schemes=scheme1,scheme2
std::vector<std::string> secure_schemes_list =
ParseSchemesCLISwitch(switches::kSecureSchemes);
for (const std::string& secure_scheme : secure_schemes_list)
blink::WebSecurityPolicy::registerURLSchemeAsSecure(
blink::WebString::fromUTF8(secure_scheme));
}
void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
if (!web_frame_widget)
return;
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch(switches::kGuestInstanceID)) { // webview.
web_frame_widget->setBaseBackgroundColor(SK_ColorTRANSPARENT);
} else { // normal window.
// If backgroundColor is specified then use it.
std::string name = cmd->GetSwitchValueASCII(switches::kBackgroundColor);
// Otherwise use white background.
SkColor color = name.empty() ? SK_ColorWHITE : ParseHexColor(name);
web_frame_widget->setBaseBackgroundColor(color);
}
}
void RendererClientBase::DidClearWindowObject(
content::RenderFrame* render_frame) {
// Make sure every page will get a script context created.
render_frame->GetWebFrame()->executeScript(blink::WebScriptSource("void 0"));
}
blink::WebSpeechSynthesizer* RendererClientBase::OverrideSpeechSynthesizer(
blink::WebSpeechSynthesizerClient* client) {
return new TtsDispatcher(client);
}
bool RendererClientBase::OverrideCreatePlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (params.mimeType.utf8() == content::kBrowserPluginMimeType ||
params.mimeType.utf8() == kPdfPluginMimeType ||
command_line->HasSwitch(switches::kEnablePlugins))
return false;
*plugin = nullptr;
return true;
}
content::BrowserPluginDelegate* RendererClientBase::CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) {
if (mime_type == content::kBrowserPluginMimeType) {
return new GuestViewContainer(render_frame);
} else {
return nullptr;
}
}
void RendererClientBase::AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
AddChromeKeySystems(key_systems);
}
} // namespace atom

View file

@ -0,0 +1,58 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_RENDERER_RENDERER_CLIENT_BASE_H_
#define ATOM_RENDERER_RENDERER_CLIENT_BASE_H_
#include <string>
#include <vector>
#include "content/public/renderer/content_renderer_client.h"
namespace atom {
class PreferencesManager;
class RendererClientBase : public content::ContentRendererClient {
public:
RendererClientBase();
virtual ~RendererClientBase();
virtual void DidCreateScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) = 0;
virtual void WillReleaseScriptContext(
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) = 0;
virtual void DidClearWindowObject(content::RenderFrame* render_frame);
virtual void SetupMainWorldOverrides(v8::Handle<v8::Context> context) = 0;
virtual bool isolated_world() = 0;
protected:
void AddRenderBindings(v8::Isolate* isolate,
v8::Local<v8::Object> binding_object);
// content::ContentRendererClient:
void RenderThreadStarted() override;
void RenderFrameCreated(content::RenderFrame*) override;
void RenderViewCreated(content::RenderView*) override;
blink::WebSpeechSynthesizer* OverrideSpeechSynthesizer(
blink::WebSpeechSynthesizerClient* client) override;
bool OverrideCreatePlugin(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) override;
content::BrowserPluginDelegate* CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) override;
void AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
override;
private:
std::unique_ptr<PreferencesManager> preferences_manager_;
};
} // namespace atom
#endif // ATOM_RENDERER_RENDERER_CLIENT_BASE_H_

View file

@ -19,4 +19,16 @@ AtomContentUtilityClient::AtomContentUtilityClient() {
AtomContentUtilityClient::~AtomContentUtilityClient() { AtomContentUtilityClient::~AtomContentUtilityClient() {
} }
bool AtomContentUtilityClient::OnMessageReceived(
const IPC::Message& message) {
#if defined(OS_WIN)
for (auto* handler : handlers_) {
if (handler->OnMessageReceived(message))
return true;
}
#endif
return false;
}
} // namespace atom } // namespace atom

View file

@ -20,6 +20,8 @@ class AtomContentUtilityClient : public content::ContentUtilityClient {
AtomContentUtilityClient(); AtomContentUtilityClient();
~AtomContentUtilityClient() override; ~AtomContentUtilityClient() override;
bool OnMessageReceived(const IPC::Message& message) override;
private: private:
#if defined(OS_WIN) #if defined(OS_WIN)
typedef ScopedVector<UtilityMessageHandler> Handlers; typedef ScopedVector<UtilityMessageHandler> Handlers;

View file

@ -159,6 +159,7 @@ void PrintViewManagerBase::OnDidPrintPage(
ShouldQuitFromInnerMessageLoop(); ShouldQuitFromInnerMessageLoop();
#else #else
print_job_->AppendPrintedPage(params.page_number);
if (metafile_must_be_valid) { if (metafile_must_be_valid) {
bool print_text_with_gdi = bool print_text_with_gdi =
document->settings().print_text_with_gdi() && document->settings().print_text_with_gdi() &&

File diff suppressed because one or more lines are too long

45
default_app/renderer.js Normal file
View file

@ -0,0 +1,45 @@
const {remote, shell} = require('electron')
const {execFile} = require('child_process')
const {execPath} = remote.process
document.onclick = function (e) {
e.preventDefault()
if (e.target.tagName === 'A') {
shell.openExternal(e.target.href)
}
return false
}
document.ondragover = document.ondrop = function (e) {
e.preventDefault()
return false
}
const holder = document.getElementById('holder')
holder.ondragover = function () {
this.className = 'hover'
return false
}
holder.ondragleave = holder.ondragend = function () {
this.className = ''
return false
}
holder.ondrop = function (e) {
this.className = ''
e.preventDefault()
const file = e.dataTransfer.files[0]
execFile(execPath, [file.path], {
detached: true, stdio: 'ignore'
}).unref()
return false
}
const version = process.versions.electron
document.querySelector('.header-version').innerText = version
document.querySelector('.command-example').innerText = `${execPath} path-to-your-app`
document.querySelector('.quick-start-link').href = `https://github.com/electron/electron/blob/v${version}/docs/tutorial/quick-start.md`
document.querySelector('.docs-link').href = `https://github.com/electron/electron/tree/v${version}/docs#readme`

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