Merge branch 'master' into native-window-open

This commit is contained in:
Ryohei Ikegami 2017-04-18 21:59:22 +09:00
commit 8dff29185b
141 changed files with 2393 additions and 748 deletions

View file

@ -87,16 +87,14 @@ void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
void AutoUpdater::QuitAndInstall() {
// If we don't have any window then quitAndInstall immediately.
WindowList* window_list = WindowList::GetInstance();
if (window_list->empty()) {
if (WindowList::IsEmpty()) {
auto_updater::AutoUpdater::QuitAndInstall();
return;
}
// Otherwise do the restart after all windows have been closed.
window_list->AddObserver(this);
for (NativeWindow* window : *window_list)
window->Close();
WindowList::AddObserver(this);
WindowList::CloseAllWindows();
}
// 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();
}
// 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

@ -8,11 +8,13 @@
#include "atom/browser/api/atom_api_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/message_box.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/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
@ -127,6 +129,10 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
#if defined(OS_MACOSX)
dict.SetMethod("showCertificateTrustDialog",
&certificate_trust::ShowCertificateTrust);
#endif
}
} // namespace

View file

@ -189,6 +189,7 @@ struct Converter<atom::api::WebContents::Type> {
switch (val) {
case Type::BACKGROUND_PAGE: type = "backgroundPage"; break;
case Type::BROWSER_WINDOW: type = "window"; break;
case Type::BROWSER_VIEW: type = "browserView"; break;
case Type::REMOTE: type = "remote"; break;
case Type::WEB_VIEW: type = "webview"; break;
case Type::OFF_SCREEN: type = "offscreen"; break;
@ -203,10 +204,12 @@ struct Converter<atom::api::WebContents::Type> {
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
if (type == "webview") {
*out = Type::WEB_VIEW;
} else if (type == "backgroundPage") {
if (type == "backgroundPage") {
*out = Type::BACKGROUND_PAGE;
} else if (type == "browserView") {
*out = Type::BROWSER_VIEW;
} else if (type == "webview") {
*out = Type::WEB_VIEW;
} else if (type == "offscreen") {
*out = Type::OFF_SCREEN;
} else {
@ -307,6 +310,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
type_ = WEB_VIEW;
else if (options.Get("isBackgroundPage", &b) && b)
type_ = BACKGROUND_PAGE;
else if (options.Get("isBrowserView", &b) && b)
type_ = BROWSER_VIEW;
else if (options.Get("offscreen", &b) && b)
type_ = OFF_SCREEN;

View file

@ -53,10 +53,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
public:
enum Type {
BACKGROUND_PAGE, // A DevTools extension background page.
BROWSER_WINDOW, // Used by BrowserWindow.
REMOTE, // Thin wrap around an existing WebContents.
WEB_VIEW, // Used by <webview>.
OFF_SCREEN, // Used for offscreen rendering
BROWSER_WINDOW, // Used by BrowserWindow.
BROWSER_VIEW, // Used by BrowserView.
REMOTE, // Thin wrap around an existing WebContents.
WEB_VIEW, // Used by <webview>.
OFF_SCREEN, // Used for offscreen rendering
};
// For node.js callback function type: function(error, buffer)

View file

@ -5,6 +5,7 @@
#include "atom/browser/api/atom_api_window.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_web_contents.h"
#include "atom/browser/browser.h"
@ -816,6 +817,25 @@ std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
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 {
return window_->is_modal();
}
@ -853,15 +873,20 @@ void Window::RefreshTouchBarItem(const std::string& item_id) {
window_->RefreshTouchBarItem(item_id);
}
void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
window_->SetEscapeTouchBarItem(item);
}
int32_t Window::ID() const {
return weak_map_id();
}
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty())
if (web_contents_.IsEmpty()) {
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() {
@ -906,6 +931,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
#endif
.SetMethod("getParentWindow", &Window::GetParentWindow)
.SetMethod("getChildWindows", &Window::GetChildWindows)
.SetMethod("getBrowserView", &Window::GetBrowserView)
.SetMethod("setBrowserView", &Window::SetBrowserView)
.SetMethod("isModal", &Window::IsModal)
.SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
.SetMethod("getBounds", &Window::GetBounds)
@ -975,6 +1002,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setVibrancy", &Window::SetVibrancy)
.SetMethod("_setTouchBarItems", &Window::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem", &Window::SetEscapeTouchBarItem)
#if defined(OS_WIN)
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)

View file

@ -180,6 +180,8 @@ class Window : public mate::TrackableObject<Window>,
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
v8::Local<v8::Value> GetParentWindow() 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;
v8::Local<v8::Value> GetNativeWindowHandle();
@ -208,6 +210,7 @@ class Window : public mate::TrackableObject<Window>,
void SetVibrancy(mate::Arguments* args);
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
void RefreshTouchBarItem(const std::string& item_id);
void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
@ -219,6 +222,7 @@ class Window : public mate::TrackableObject<Window>,
MessageCallbackMap messages_callback_map_;
#endif
v8::Global<v8::Value> browser_view_;
v8::Global<v8::Value> web_contents_;
v8::Global<v8::Value> menu_;
v8::Global<v8::Value> parent_window_;

View file

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

View file

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

View file

@ -204,9 +204,8 @@ std::string Browser::DockGetBadgeText() {
}
void Browser::DockHide() {
WindowList* list = WindowList::GetInstance();
for (WindowList::iterator it = list->begin(); it != list->end(); ++it)
[(*it)->GetNativeWindow() setCanHide:NO];
for (const auto& window : WindowList::GetWindows())
[window->GetNativeWindow() setCanHide:NO];
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToUIElementApplication);

View file

@ -61,11 +61,11 @@ bool GetProtocolLaunchPath(mate::Arguments* args, base::string16* exe) {
// Read in optional args arg
std::vector<base::string16> launch_args;
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(),
base::JoinString(launch_args, L" ").c_str());
else
*exe = base::StringPrintf(L"\"%s\" \"%%1\"", exe->c_str());
*exe = base::StringPrintf(L"\"%ls\" \"%%1\"", exe->c_str());
return true;
}
@ -76,8 +76,7 @@ bool FormatCommandLineString(base::string16* exe,
}
if (!launch_args.empty()) {
base::string16 formatString = L"%s %s";
*exe = base::StringPrintf(formatString.c_str(),
*exe = base::StringPrintf(L"%ls %ls",
exe->c_str(),
base::JoinString(launch_args, L" ").c_str());
}

View file

@ -178,9 +178,14 @@ void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) {
void CommonWebContentsDelegate::SetOwnerWindow(
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_);
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::ResetManagedWebContents() {

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
NativeWindow* NativeWindow::FromWebContents(
content::WebContents* web_contents) {
WindowList& window_list = *WindowList::GetInstance();
for (NativeWindow* window : window_list) {
for (const auto& window : WindowList::GetWindows()) {
if (window->web_contents() == web_contents)
return window;
}
@ -347,6 +346,10 @@ void NativeWindow::SetTouchBar(
void NativeWindow::RefreshTouchBarItem(const std::string& item_id) {
}
void NativeWindow::SetEscapeTouchBarItem(
const mate::PersistentDictionary& item) {
}
void NativeWindow::FocusOnWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
}

View file

@ -47,6 +47,8 @@ class Dictionary;
namespace atom {
class NativeBrowserView;
struct DraggableRegion;
class NativeWindow : public base::SupportsUserData,
@ -144,6 +146,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetFocusable(bool focusable);
virtual void SetMenu(AtomMenuModel* menu);
virtual void SetParentWindow(NativeWindow* parent);
virtual void SetBrowserView(NativeBrowserView* browser_view) = 0;
virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
@ -174,6 +177,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetTouchBar(
const std::vector<mate::PersistentDictionary>& items);
virtual void RefreshTouchBarItem(const std::string& item_id);
virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
// Webview APIs.
virtual void FocusOnWebView();

View file

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

View file

@ -7,6 +7,7 @@
#include <Quartz/Quartz.h>
#include <string>
#include "atom/browser/native_browser_view_mac.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.h"
#include "atom/browser/window_list.h"
#include "atom/common/color_util.h"
@ -19,9 +20,9 @@
#include "brightray/browser/inspectable_web_contents_view.h"
#include "brightray/browser/mac/event_dispatching_window.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_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkRegion.h"
@ -368,6 +369,7 @@ enum {
- (void)enableWindowButtonsOffset;
- (void)resetTouchBar:(const std::vector<mate::PersistentDictionary>&)settings;
- (void)refreshTouchBarItem:(const std::string&)item_id;
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item;
@end
@ -410,6 +412,11 @@ enum {
return nil;
}
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item {
if (atom_touch_bar_ && self.touchBar)
[atom_touch_bar_ setEscapeTouchBarItem:item forTouchBar:self.touchBar];
}
// NSWindow overrides.
- (void)swipeWithEvent:(NSEvent *)event {
@ -665,6 +672,7 @@ NativeWindowMac::NativeWindowMac(
const mate::Dictionary& options,
NativeWindow* parent)
: NativeWindow(web_contents, options, parent),
browser_view_(nullptr),
is_kiosk_(false),
was_fullscreen_(false),
zoom_to_page_width_(false),
@ -1263,6 +1271,26 @@ void NativeWindowMac::SetContentProtection(bool enable) {
: 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) {
if (is_modal())
return;
@ -1417,6 +1445,10 @@ void NativeWindowMac::RefreshTouchBarItem(const std::string& item_id) {
[window_ refreshTouchBarItem:item_id];
}
void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
[window_ setEscapeTouchBarItem:item];
}
void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
switch (event.type) {
case blink::WebInputEvent::GestureScrollBegin:

View file

@ -7,8 +7,8 @@
#include <string>
#include <vector>
#include "atom/browser/native_browser_view_views.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/common/color_util.h"
#include "atom/common/draggable_region.h"
@ -135,6 +135,7 @@ NativeWindowViews::NativeWindowViews(
: NativeWindow(web_contents, options, parent),
window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()),
browser_view_(nullptr),
menu_bar_autohide_(false),
menu_bar_visible_(false),
menu_bar_alt_pressed_(false),
@ -274,9 +275,6 @@ NativeWindowViews::NativeWindowViews(
SetWindowType(GetAcceleratedWidget(), window_type);
#endif
// Add web view.
SetLayoutManager(new MenuLayout(this, kMenuBarHeight));
AddChildView(web_view_);
#if defined(OS_WIN)
@ -881,6 +879,24 @@ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
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) {
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() {
return NativeWindow::GetMinimumSize();
}

View file

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

View file

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

View file

@ -32,7 +32,7 @@
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<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>
</asmv3:windowsSettings>
</asmv3:application>

View file

@ -56,8 +56,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,6,5,0
PRODUCTVERSION 1,6,5,0
FILEVERSION 1,6,6,0
PRODUCTVERSION 1,6,6,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -74,12 +74,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "1.6.5"
VALUE "FileVersion", "1.6.6"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "1.6.5"
VALUE "ProductVersion", "1.6.6"
VALUE "SquirrelAwareVersion", "1"
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

@ -31,6 +31,8 @@
- (NSTouchBar*)touchBarFromItemIdentifiers:(NSMutableArray*)items;
- (NSMutableArray*)identifiersFromSettings:(const std::vector<mate::PersistentDictionary>&)settings;
- (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;

View file

@ -113,19 +113,10 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
return 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);
NSTouchBarItemIdentifier identifier = [self identifierFromID:item_id
type:item_type];
if (!identifier) return;
id:(NSTouchBarItemIdentifier)identifier
withType:(const std::string&)item_type
withSettings:(const mate::PersistentDictionary&)settings {
NSTouchBarItem* item = [touchBar itemForIdentifier:identifier];
if (!item) return;
@ -145,7 +136,56 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
} else if (item_type == "scrubber") {
[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 {

View file

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

View file

@ -71,10 +71,14 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
switch (type) {
case MESSAGE_BOX_TYPE_INFORMATION:
[alert setAlertStyle:NSInformationalAlertStyle];
alert.alertStyle = NSInformationalAlertStyle;
break;
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;
default:
break;
@ -192,7 +196,7 @@ void ShowErrorBox(const base::string16& title, const base::string16& content) {
NSAlert* alert = [[NSAlert alloc] init];
[alert setMessageText:base::SysUTF16ToNSString(title)];
[alert setInformativeText:base::SysUTF16ToNSString(content)];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
[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

@ -23,8 +23,8 @@ SubmenuButton::SubmenuButton(const base::string16& title,
menu_button_listener, false),
accelerator_(0),
show_underline_(false),
underline_start_(-1),
underline_end_(-1),
underline_start_(0),
underline_end_(0),
text_width_(0),
text_height_(0),
underline_color_(SK_ColorBLACK),
@ -106,7 +106,7 @@ bool SubmenuButton::GetUnderlinePosition(const base::string16& text,
void SubmenuButton::GetCharacterPosition(
const base::string16& text, int index, int* pos) {
int height;
int height = 0;
gfx::Canvas::SizeStringInt(text.substr(0, index), GetFontList(), pos, &height,
0, 0);
}

View file

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

View file

@ -25,12 +25,4 @@ bool AtomDesktopWindowTreeHostWin::PreHandleMSG(
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

View file

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

View file

@ -26,6 +26,16 @@ WindowList* WindowList::GetInstance() {
return instance_;
}
// static
WindowList::WindowVector WindowList::GetWindows() {
return GetInstance()->windows_;
}
// static
bool WindowList::IsEmpty() {
return GetInstance()->windows_.empty();
}
// static
void WindowList::AddWindow(NativeWindow* window) {
DCHECK(window);
@ -76,6 +86,13 @@ void WindowList::CloseAllWindows() {
window->Close();
}
// static
void WindowList::DestroyAllWindows() {
WindowVector windows = GetInstance()->windows_;
for (const auto& window : windows)
window->CloseContents(nullptr); // e.g. Destroy()
}
WindowList::WindowList() {
}

View file

@ -19,23 +19,9 @@ class WindowListObserver;
class WindowList {
public:
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,
// so the |window()| member function may return NULL.
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();
static WindowVector GetWindows();
static bool IsEmpty();
// Adds or removes |window| from the list it is associated with.
static void AddWindow(NativeWindow* window);
@ -51,7 +37,12 @@ class WindowList {
// Closes all windows.
static void CloseAllWindows();
// Destroy all windows.
static void DestroyAllWindows();
private:
static WindowList* GetInstance();
WindowList();
~WindowList();

View file

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

View file

@ -26,6 +26,27 @@
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
v8::Local<v8::Value> Converter<const net::AuthChallengeInfo*>::ToV8(
v8::Isolate* isolate, const net::AuthChallengeInfo* val) {
@ -73,6 +94,37 @@ v8::Local<v8::Value> Converter<scoped_refptr<net::X509Certificate>>::ToV8(
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
v8::Local<v8::Value> Converter<net::CertPrincipal>::ToV8(
v8::Isolate* isolate, const net::CertPrincipal& val) {

View file

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

View file

@ -33,17 +33,18 @@
// Electron's builtin modules.
REFERENCE_MODULE(atom_browser_app);
REFERENCE_MODULE(atom_browser_auto_updater);
REFERENCE_MODULE(atom_browser_browser_view);
REFERENCE_MODULE(atom_browser_content_tracing);
REFERENCE_MODULE(atom_browser_dialog);
REFERENCE_MODULE(atom_browser_debugger);
REFERENCE_MODULE(atom_browser_desktop_capturer);
REFERENCE_MODULE(atom_browser_dialog);
REFERENCE_MODULE(atom_browser_download_item);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_menu);
REFERENCE_MODULE(atom_browser_net);
REFERENCE_MODULE(atom_browser_power_monitor);
REFERENCE_MODULE(atom_browser_power_save_blocker);
REFERENCE_MODULE(atom_browser_protocol);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_render_process_preferences);
REFERENCE_MODULE(atom_browser_session);
REFERENCE_MODULE(atom_browser_system_preferences);

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

@ -16,16 +16,15 @@
#include "atom/common/node_bindings.h"
#include "atom/common/options_switches.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/node_array_buffer_bridge.h"
#include "atom/renderer/web_worker_observer.h"
#include "base/command_line.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "native_mate/dictionary.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"
#include "atom/common/node_includes.h"
@ -33,127 +32,6 @@ namespace atom {
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, 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));
}
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);
};
bool IsDevToolsExtension(content::RenderFrame* render_frame) {
return static_cast<GURL>(render_frame->GetWebFrame()->document().url())
.SchemeIs("chrome-extension");
@ -180,7 +58,6 @@ void AtomRendererClient::RenderThreadStarted() {
void AtomRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new AtomRenderFrameObserver(render_frame, this);
RendererClientBase::RenderFrameCreated(render_frame);
}
@ -189,12 +66,6 @@ void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
RendererClientBase::RenderViewCreated(render_view);
}
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(
content::RenderFrame* render_frame) {
// Inform the document start pharse.
@ -307,4 +178,38 @@ v8::Local<v8::Context> AtomRendererClient::GetContext(
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

View file

@ -20,16 +20,19 @@ class AtomRendererClient : public RendererClientBase {
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.
v8::Local<v8::Context> GetContext(
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:
enum NodeIntegration {

View file

@ -20,7 +20,6 @@
#include "base/command_line.h"
#include "chrome/renderer/printing/print_web_view_helper.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_observer.h"
#include "ipc/ipc_message_macros.h"
@ -89,50 +88,6 @@ void InitializeBindings(v8::Local<v8::Object> binding,
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 {
public:
AtomSandboxedRenderViewObserver(content::RenderView* render_view,
@ -181,7 +136,6 @@ AtomSandboxedRendererClient::~AtomSandboxedRendererClient() {
void AtomSandboxedRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new AtomSandboxedRenderFrameObserver(render_frame, this);
RendererClientBase::RenderFrameCreated(render_frame);
}

View file

@ -16,13 +16,18 @@ class AtomSandboxedRendererClient : public RendererClientBase {
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,
const std::string& callback_name,
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:
void RenderFrameCreated(content::RenderFrame*) override;
void RenderViewCreated(content::RenderView*) override;

View file

@ -11,6 +11,7 @@
#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"
@ -27,6 +28,7 @@
#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)
@ -96,21 +98,20 @@ void RendererClientBase::RenderThreadStarted() {
#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);
}
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);
@ -151,6 +152,12 @@ void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
}
}
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);

View file

@ -19,6 +19,14 @@ class RendererClientBase : public content::ContentRendererClient {
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);

View file

@ -19,4 +19,16 @@ 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

View file

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