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

@ -5,7 +5,7 @@
[![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/)
: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
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-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`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)*
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)

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;

View file

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

View file

@ -67,8 +67,7 @@ npm install -g electron-windows-store
│ └── atom.asar
├── snapshot_blob.bin
├── squirrel.exe
├── ui_resources_200_percent.pak
└── xinput1_3.dll
└── ui_resources_200_percent.pak
```
## `electron-windows-store` 실행하기

View file

@ -5,12 +5,12 @@ Eğer öyleyse, atom.io üzerinden [mevcut sürümler](https://electron.atom.io/
## SSS(Sıkça Sorulan Sorular)
Bir problem(issue) bildirmeden önce sıkça sorulan sorulara göz atın:
* [Electron SSS](https://github.com/electron/electron/tree/master/docs/faq/electron-faq.md)
* [Electron SSS](https://github.com/electron/electron/blob/master/docs/faq.md)
## Klavuzlar
* [Desteklenen Platformlar ](https://github.com/electron/electron/tree/master/docs/tutorial/supported-platforms.md)
* [Uygulama Dağıtımı](https://github.com/electron/electron/tree/master/docs/tutorial/application-distribution.md)
* [Desteklenen Platformlar ](tutorial/supported-platforms.md)
* [Uygulama Dağıtımı](tutorial/application-distribution.md)
* [Mac Uygulama Mağazası Başvuru Klavuzu](https://github.com/electron/electron/tree/master/docs/tutorial/mac-app-store-submission-guide.md)
* [Uygulama Paketleme](https://github.com/electron/electron/tree/master/docs/tutorial/application-packaging.md)
* [Native Node Modüllerini Kullanma](https://github.com/electron/electron/tree/master/docs/tutorial/using-native-node-modules.md)

View file

@ -0,0 +1,85 @@
[![Electron Logo](https://electron.atom.io/images/electron-logo.svg)](https://electron.atom.io/)
[![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bc56v83355fi3369/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron/branch/master)
[![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/)
:memo: Mevcut çeviriler: [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)
Electron framework JavaScript, HTML ve CSS kullanarak çapraz platform
masaüstü uygulamaları yazmanıza yarar. Electron [Node.js](https://nodejs.org/) ile geliştirilmiş;
[Atom editor](https://github.com/atom/atom) ve birçok uygulama [apps](https://electron.atom.io/apps) tarafından kullanılmaktadir.
Önemli duyurular için Twitter da [@ElectronJS](https://twitter.com/electronjs) adresini takip edin.
Bu proje katılımcı sözleşmesine bağlıdır. Katılarak,
bu kodun sürdürülebilir olduğunu üstlenmeniz beklenmekte.
Lütfen uygun olmayan davranışları electron@github.com'a rapor edin.
## Downloads
Electron prebuilt mimarisini yüklemek için,
[`npm`](https://docs.npmjs.com/):
```sh
# Development dependency olarak yükleyin
npm install electron --save-dev
# `electron` komutunu global olarak $PATH'a yükleyin
npm install electron -g
```
Prebuilt mimarileri, debug sembolleri, ve fazlası için
[releases page](https://github.com/electron/electron/releases) sayfasını ziyaret edin.
### Mirrors
- [China](https://npm.taobao.org/mirrors/electron)
## Dokümantasyon
Klavuz ve API referansları [docs](https://github.com/electron/electron/tree/master/docs) klasöründe bulunabilir.
Aynı zamanda nasıl kurulum gerçekleştirileceği ve Electron'un gelişimine nasıl katılacağınızı
ıklayan dosyalar içermektedir.
## Dökümantasyon Çevirileri
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp)
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
- [Thai](https://github.com/electron/electron/tree/master/docs-Translations/th-TH)
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
## Hızlı Başlangıç
Minimal Electron uygulamasını calışırken görmek için [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
repository'ni klonla ve çalıştır.
## Topluluk
Asağıdaki sayfalardan sorular sorabilir ve topluluk ile etkileşime geçebilirsiniz:
- [`electron`](http://discuss.atom.io/c/electron) Atom forumundaki kategoriler
- `#atom-shell` Freenode kanal'ı
- [`Atom`](http://atom-slack.herokuapp.com/) Slack kanal'ı
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)*
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
Topluluk tarafından sağlanan örnek uygulamaları, aracları ve kaynaklara ulaşmak için
[awesome-electron](https://github.com/sindresorhus/awesome-electron) sayfasını ziyaret et.
## Lisans
[MIT](https://github.com/electron/electron/blob/master/LICENSE)
Electron veya Github logolarını kullandığınızda, [GitHub logo guidelines](https://github.com/logos) sayfasını okuduğunuzdan emin olun.

View file

@ -0,0 +1,178 @@
# Application Distribution
Electron uygulamanızı dağıtmak için önce Electron nun [prebuilt mimarilerini]
(https://github.com/electron/electron/releases) indirmeniz gerekmektedir.
Sonrasında, uygulamanızın bulundugu klasör `app` şeklinde isimlendirilmeli ve
Electron kaynaklar klasörüne aşagıda gösterildiği gibi yerleştirilmelidir.
Unutmayın, Electronun prebuilt mimarileri aşağıdaki örneklerde `electron/`
şeklinde belirtilmiştir.
MacOS da:
```text
electron/Electron.app/Contents/Resources/app/
├── package.json
├── main.js
└── index.html
```
Windows ve Linux da:
```text
electron/resources/app
├── package.json
├── main.js
└── index.html
```
Ardından `Electron.app` (veya `electron` Linux'da, `electron.exe` Windows'da) şeklinde çalıstırın,
ve Electron uygulama şeklinde çalışacaktır.
`electron` klasörü son kullanıcıya aktaracağınız dağıtımınız olacaktır.
## Uygulamanın bir dosya şeklinde paketlenmesi
Tüm kaynak kodlarını kopyalama yoluyla uygulamanızı dağıtmak haricinde,
uygulamanızı [asar](https://github.com/electron/asar) ile arşiv haline getirerek,
kaynak kodlarınızın kullanıcılar tarafından görülmesini engelliye bilirsiniz.
`app` klasörü yerine `asar` arşiv dosyası kullanmak için, arşiv dosyanızı `app.asar`
şeklinde isimlendirmeniz gerekiyor, ve bu dosyayı Electron'nun kaynak klasörüne aşağıdaki
gibi yerleştirmelisiniz. Böylelikle Electron arşivi okuyup ondan başlayacaktır.
MacOS'da:
```text
electron/Electron.app/Contents/Resources/
└── app.asar
```
Windows ve Linux'da:
```text
electron/resources/
└── app.asar
```
Daha fazla bilgi için [Application packaging](application-packaging.md).
## İndirilen mimarileri yeniden adlandırma
Uygulamanızı Electron ile paketledikten sonra ve kullanıcılara uygulamanızı dağıtmadan önce
adını değiştirmek isteye bilirsiniz.
### Windows
`electron.exe` istediğiniz şekilde yeniden adlandırabilirsiniz. Icon ve diğer
bilgileri bu gibi araçlar [rcedit](https://github.com/atom/rcedit) ile düzenleye bilirsiniz.
### macOS
`Electron.app`'i istediğiniz şekilde yeniden adlandırabilirsiniz, ve aşağıdaki dosyalarda
`CFBundleDisplayName`, `CFBundleIdentifier` ve `CFBundleName` kısımlarınıda düzenlemelisiniz.
* `Electron.app/Contents/Info.plist`
* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist`
Görev yöneticisinde `Electron Helper` şeklinde göstermek yerine,
isterseniz helper uygulamasınında adını değiştire bilirsiniz,
ancak dosyanın adınıılabilir olduğundan emin olun.
Yeniden adlandırılmış uygulamanın klasör yapısı bu şekilde görünecektir:
```
MyApp.app/Contents
├── Info.plist
├── MacOS/
│   └── MyApp
└── Frameworks/
├── MyApp Helper EH.app
| ├── Info.plist
| └── MacOS/
|    └── MyApp Helper EH
├── MyApp Helper NP.app
| ├── Info.plist
| └── MacOS/
|    └── MyApp Helper NP
└── MyApp Helper.app
├── Info.plist
└── MacOS/
   └── MyApp Helper
```
### Linux
`electron` dosyasını istediğiniz şekilde yeniden adlandırabilirsiniz.
## Paketleme Araçları
Uygulamanızı manuel şekilde paketlemek dışında, üçüncü parti
paketleme araçlarıylada otomatik olarak ayni şekilde paketliye bilirsiniz:
* [electron-builder](https://github.com/electron-userland/electron-builder)
* [electron-packager](https://github.com/electron-userland/electron-packager)
## Kaynaktan yeniden kurulum yoluyla isim değişikliği
Ürün adını değiştirip, kaynaktan kurulum yoluylada Electron'nun adını değiştirmek mümkün.
Bunun için `atom.gyp` dosyasını yeniden modifiye edip, tekrardan temiz bir kurulum yapmalısınız.
### grunt-build-atom-shell
Manuel olarak Electron kodlarını kontrol edip tekrar kurulum yapmak biraz zor olabilir,
bu yüzden tüm bu işlemleri otomatik olarak gerçekleştirecek bir Grunt görevi oluşturuldu:
[grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell).
Bu görev otomatik olarak `.gyp` dosyasını düzenleyecek, kaynaktan kurulumu gerçekleştirecek,
sonrasında ise uygulamanızın doğal Node modüllerini, yeni yürütülebilen isim ile eşleştirmek icin
tekrardan kuracaktır.
### Özel bir Electron kopyası oluşturma
Electron'un size ait bir kopyasını oluşturmak, neredeyse uygulamanızı kurmak için hiç ihtiyacınız
olmayacak bir işlemdir, "Production Level" uygulamalarda buna dahildir.
`electron-packager` veya `electron-builder` gibi araçlar kullanarak yukarıda ki işlemleri
gerçekleştirmeksizin, "Rebrand" Electron işlemini uygulaya bilirsiniz.
Eğer kendinize ait yüklenemiyen veya resmi versiyondan red edilmiş,
direk olarak Electron a paketlediğiniz C++ kodunuz var ise,
öncelikle Electron'un bir kopyasını oluşturmalısınız.
Electron'nun destekleyicileri olarak, senaryonuzun çalışmasını çok isteriz,
bu yüzden lütfen yapacağınız değişiklikleri Electron'nun resmi versiyonuna
entegre etmeye calışın, bu sizin için daha kolay olacaktır, ve yardimlarınız
için cok minnettar olacağız.
#### surf-build İle Özel Dağıtım oluşturulması
1. Npm yoluyla [Surf](https://github.com/surf-build/surf) yükleyin:
`npm install -g surf-build@latest`
2. Yeni bir S3 bucket ve aşağıdakı boş klasör yapısını oluşturun:
```
- atom-shell/
- symbols/
- dist/
```
3. Aşağıdaki Ortam Değişkenlerini ayarlayın:
* `ELECTRON_GITHUB_TOKEN` - GitHub üzerinden dağıtım oluşturan token
* `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` -
node.js bağlantılarını ve sembollerini yükleyeceğiniz yer
* `ELECTRON_RELEASE` - `true` şeklinde ayarlayın ve yükleme işlemi çalışacaktır,
yapmamanız halinde, `surf-build` sadece CI-type kontrolü yapacak,
tüm pull isteklerine uygun hale getirecektir.
* `CI` - `true` olarak ayarlayın yoksa çalışmayacaktır.
* `GITHUB_TOKEN` - bununla aynı şekilde ayarlayın `ELECTRON_GITHUB_TOKEN`
* `SURF_TEMP` - Windowsda ki 'path too long' sorunundan kaçınmak için `C:\Temp` şeklinde ayarlayın
* `TARGET_ARCH` - `ia32` veya `x64` şeklinde ayarlayın
4. `script/upload.py` dosyasında ki `ELECTRON_REPO` kısmını, kendi kopyanız ile değiştirmek _zorundasınız_,
özellikle eğer bir Electron proper destekleyicisi iseniz.
5. `surf-build -r https://github.com/MYORG/electron -s YOUR_COMMIT -n 'surf-PLATFORM-ARCH'`
6. Kurulum bitene kadar uzunca bekleyin.

View file

@ -0,0 +1,29 @@
# Desteklenen platformlar
Aşağıdaki platformlar Electron tarafından desteklenmektedir:
### macOS
MacOS için sadece 64bit mimariler sağlanmakta olup, desteklenen minimum macOS versiyonu 10.9 dur.
### Windows
Windows 7 ve gelişmiş versiyonlar desteklenmektedir, eski işletim sistemleri desteklenmemektedir
(ve çalışmayacaktır).
Windows `ia32` (`x86`) ve `x64` (`amd64`) mimarileri desteklenmektedir.
Unutmayın, `ARM` mimarisi al₺tında çalışan Windows işletim sistemleri şuan için desteklenmemektedir.
### Linux
Electron `ia32` (`i686`) ve `x64` (`amd64`) Prebuilt mimarileri Ubuntu 12.04 üzerinde kurulmuştur,
`arm` mimarisi ARM v7 ye karşılık olarak, hard-float ABI ve NEON Debian Wheezy ile kurulmuştur.
Prebuilt
Prebuilt mimarisi ancak Electron'nun yapı platformu ile bağlantılı olan kütüphaneleri içeren dağıtımlar ile çalışır.
Bu yüzden sadece Ubuntu 12.04 üzerinde çalışması garanti ediliyor, fakat aşagidaki platformlarında
Electron Prebuilt mimarisini çalıştıra bileceği doğrulanmıştır.
* Ubuntu 12.04 ve sonrası
* Fedora 21
* Debian 8

View file

@ -26,6 +26,7 @@
* [使用 Widevine CDM 插件](tutorial/using-widevine-cdm-plugin.md)
* [通过自动化持续集成系统CI进行测试 (Travis, Jenkins)](tutorial/testing-on-headless-ci.md)
* [离屏渲染](tutorial/offscreen-rendering.md)
* [快捷键](tutorial/keyboard-shortcuts.md)
## 教程
@ -96,3 +97,6 @@
* [调试步骤 (Windows)](development/debug-instructions-windows.md)
* [在调试中使用 Symbol Server](development/setting-up-symbol-server.md)
* [文档风格指南](styleguide.md)
* [升级 Chrome](development/upgrading-chrome.md)
* [Chromium 开发](development/chromium-development.md)
* [V8 开发](development/v8-development.md)

View file

@ -4,15 +4,30 @@
例如:
* `Command+A`
* `Ctrl+Shift+Z`
* `CommandOrControl+A`
* `CommandOrControl+Shift+Z`
快捷键使用 [`globalShortcut`](global-shortcut.md)里的 [`register`](global-shortcut.md#globalshortcutregisteraccelerator-callback) 方法注册
```javascript
const {app, globalShortcut} = require('electron')
app.on('ready', () => {
// Register a 'CommandOrControl+Y' shortcut listener.
globalShortcut.register('CommandOrControl+Y', () => {
// Do stuff when Y and either Command/Control is pressed.
})
})
```
## 运行平台相关的提示
在 Linux 和 Windows 上,`Command` 键并不存在,因此我们通常用 `CommandOrControl` 来表示“在 macOS 下为 `Command` 键,但在
Linux 和 Windows 下为 `Control` 键。
`Super` 键是指 Linux 和 Windows 上的 `Windows` 键,但是在 macOS 下为 `Command` 键。
使用 `Alt` 键 代替 `Option`。`Option` 键只在 macOS 系统上存在,而 `Alt` 键在任何系统上都有效。
`Super` 键是指 Linux 和 Windows 上的 `Windows` 键,但是在 macOS 下为 `Cmd` 键。
## 可用的功能按键
@ -20,6 +35,8 @@ Linux 和 Windows 下为 `Control` 键。
* `Control`(缩写为 `Ctrl`
* `CommandOrControl`(缩写为 `CmdOrCtrl`
* `Alt`
* `Option`
* `AltGr`
* `Shift`
* `Super`
@ -31,6 +48,7 @@ Linux 和 Windows 下为 `Control` 键。
* 类似与 `~`、`!`、`@`、`#`、`$` 的标点符号。
* `Plus`
* `Space`
* `Tab`
* `Backspace`
* `Delete`
* `Insert`
@ -41,3 +59,4 @@ Linux 和 Windows 下为 `Control` 键。
* `Escape`(缩写为 `Esc`
* `VolumeUp`、`VolumeDown` 和 `VolumeMute`
* `MediaNextTrack`、`MediaPreviousTrack`、`MediaStop` 和 `MediaPlayPause`
* `PrintScreen`

View file

@ -15,26 +15,24 @@
* `menuItem` MenuItem
* `browserWindow` BrowserWindow
* `event` Event
* `role` String (可选) - 定义菜单项的行为,在指定 `click` 属性时将会被忽略。
* `type` String (可选) - 取值 `normal`, `separator`, `submenu`, `checkbox` or `radio`
* `role` String (可选) - 定义菜单项的行为,在指定 `click` 属性时将会被忽略。参见 [roles](#roles).
* `type` String (可选) - 取值 `normal`, `separator`, `submenu`, `checkbox` `radio`
* `label` String - (可选)
* `sublabel` String - (可选)
* `accelerator` [Accelerator](accelerator.md) (可选)
* `icon` ([NativeImage](native-image.md) | String) (可选)
* `enabled` Boolean (可选) - 如果为 false菜单项将显示为灰色不可点击。
unclickable.
* `visible` Boolean (可选) - 如果为 false菜单项将完全隐藏。
* `checked` Boolean (可选) - 只为 `checkbox``radio` 类型的菜单项。
* `submenu` (MenuItemConstructorOptions[] | Menu) (可选) - 应当作为 `submenu` 菜单项的特定类型,当它作为 `type: 'submenu'` 菜单项的特定类型时可以忽略。如果它的值不是 `Menu`,将自动转为 `Menu.buildFromTemplate`
* `id` String (可选) - 标志一个菜单的唯一性。如果被定义使用,它将被用作这个菜单项的参考位置属性。
* `id` String (可选) - 菜单的唯一标识。如果被定义使用,它将被用作这个菜单项的参考位置属性。
* `position` String (可选) - 定义菜单的具体指定位置信息。
在创建菜单项时,如果有匹配的方法,建议指定 `role` 属性,
而不是试图手动实现在一个 `click` 函数中的行为。
内置的 `role` 行为将提供最好的原生体验。
### Roles
Roles 允许菜单项有预定义的行为。最好为每个菜单项指定一个行为,而不是自己实现一个 `click` 函数中的行为。内置的 `role` 行为将提供最好的原生体验。
当使用 `role` 时,`label` 和 `accelerator` 的值是可选的,会针对每个平台设置默认值。
当使用 `role' 时,`label' 和 `accelerator` 是可选的,默认为
到每个平台的适当值。
`role`属性值可以为:
@ -56,6 +54,8 @@
* `resetzoom` - 将对焦页面的缩放级别重置为原始大小
* `zoomin` - 将聚焦页面缩小10
* `zoomout` - 将聚焦页面放大10
* `editMenu` - 完整的默认 "Edit" 编辑菜单(拷贝,黏贴,等)
* `windowMenu` - 完整的默认 "Window" 窗口菜单(最小化,关闭,等)
在 macOS 上,`role` 还可以有以下值:

View file

@ -19,6 +19,8 @@
在 macOS 上设置应用菜单 `menu`
在 windows 和 linux是为每个窗口都在其顶部设置菜单 `menu`
设置为 `null` 时,将在 Windows 和 Linux 上删除菜单条,但在 macOS 系统中无效。
**注意:** 这个API必须在 `app` 模块的 `ready` 事件后调用。
#### `Menu.getApplicationMenu()`
@ -29,7 +31,7 @@
* `action` String
发送 `action` 给应用的第一个响应器.这个用来模仿 Cocoa 菜单的默认行为,通常你只需要使用 `MenuItem` 的属性 `role`.
发送 `action` 给应用的第一个响应器.这个用来模仿 Cocoa 菜单的默认行为,通常你只需要使用 [`MenuItem`](menu-item.md) 的属性 [`role`](menu-item.md#roles).
查看更多 macOS 的原生 action [macOS Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) .
@ -47,15 +49,23 @@
`menu` 对象有如下实例方法
#### `menu.popup([browserWindow, x, y, positioningItem])`
#### `menu.popup([browserWindow, options])`
* `browserWindow` BrowserWindow (可选) - 默认为 `null`.
* `x` Number (可选) - 默认为 -1.
* `y` Number (**必须** 如果x设置了) - 默认为 -1.
* `positioningItem` Number (可选) _macOS_ - 在指定坐标鼠标位置下面的菜单项的索引. 默认为
* `browserWindow` BrowserWindow (可选) - 默认为当前激活的窗口.
* `options` Object (可选)
* `x` Number (可选) - 默认为当前光标所在的位置.
* `y` Number (**必须** 如果x设置了) - 默认为当前光标所在的位置.
* `async` Boolean (可选) - 设置为 `true` 时,调用这个方法会立即返回。设置为 `false` 时,当菜单被选择或者被关闭时才会返回。默认为 `false`
* `positioningItem` Number (可选) _macOS_ - 指定坐标鼠标位置下面的菜单项的索引. 默认为
-1.
`browserWindow` 中弹出 context menu .你可以选择性地提供指定的 `x, y` 来设置菜单应该放在哪里,否则它将默认地放在当前鼠标的位置.
`browserWindow` 中弹出菜单.
#### `menu.closePopup([browserWindow])`
* `browserWindow` BrowserWindow (可选) - 默认为当前激活的窗口.
`browserWindow` 关闭菜单.
#### `menu.append(menuItem)`
@ -95,76 +105,36 @@ const template = [
{
label: 'Edit',
submenu: [
{
role: 'undo'
},
{
role: 'redo'
},
{
type: 'separator'
},
{
role: 'cut'
},
{
role: 'copy'
},
{
role: 'paste'
},
{
role: 'pasteandmatchstyle'
},
{
role: 'delete'
},
{
role: 'selectall'
}
{role: 'undo'},
{role: 'redo'},
{type: 'separator'},
{role: 'cut'},
{role: 'copy'},
{role: 'paste'},
{role: 'pasteandmatchstyle'},
{role: 'delete'},
{role: 'selectall'}
]
},
{
label: 'View',
submenu: [
{
role: 'reload'
},
{
role: 'forcereload'
},
{
role: 'toggledevtools'
},
{
type: 'separator'
},
{
role: 'resetzoom'
},
{
role: 'zoomin'
},
{
role: 'zoomout'
},
{
type: 'separator'
},
{
role: 'togglefullscreen'
}
{role: 'reload'},
{role: 'forcereload'},
{role: 'toggledevtools'},
{type: 'separator'},
{role: 'resetzoom'},
{role: 'zoomin'},
{role: 'zoomout'},
{type: 'separator'},
{role: 'togglefullscreen'}
]
},
{
role: 'window',
submenu: [
{
role: 'minimize'
},
{
role: 'close'
}
{role: 'minimize'},
{role: 'close'}
]
},
{
@ -182,76 +152,37 @@ if (process.platform === 'darwin') {
template.unshift({
label: app.getName(),
submenu: [
{
role: 'about'
},
{
type: 'separator'
},
{
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
role: 'hide'
},
{
role: 'hideothers'
},
{
role: 'unhide'
},
{
type: 'separator'
},
{
role: 'quit'
}
{role: 'about'},
{type: 'separator'},
{role: 'services', submenu: []},
{type: 'separator'},
{role: 'hide'},
{role: 'hideothers'},
{role: 'unhide'},
{type: 'separator'},
{role: 'quit'}
]
})
// Edit menu.
// Edit menu
template[1].submenu.push(
{
type: 'separator'
},
{type: 'separator'},
{
label: 'Speech',
submenu: [
{
role: 'startspeaking'
},
{
role: 'stopspeaking'
}
{role: 'startspeaking'},
{role: 'stopspeaking'}
]
}
)
// Window menu.
// Window menu
template[3].submenu = [
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Zoom',
role: 'zoom'
},
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
}
{role: 'close'},
{role: 'minimize'},
{role: 'zoom'},
{type: 'separator'},
{role: 'front'}
]
}

View file

@ -0,0 +1,4 @@
# 蓝牙设备 Object
* `deviceName` String
* `deviceId` String

View file

@ -0,0 +1,8 @@
# CertificatePrincipal Object
* `commonName` String - 通用名
* `organizations` String[] - 组织名
* `organizationUnits` String[] - 组织单位名称
* `locality` String - 地区
* `state` String - 州或省
* `country` String - 国家或地区

View file

@ -0,0 +1,12 @@
# Certificate Object 证书对象
* `data` String - PEM encoded data
* `issuer` [CertificatePrincipal](certificate-principal.md) - Issuer principal
* `issuerName` String - Issuer's Common Name
* `issuerCert` Certificate - Issuer certificate (if not self-signed)
* `subject` [CertificatePrincipal](certificate-principal.md) - Subject principal
* `subjectName` String - Subject's Common Name
* `serialNumber` String - Hex value represented string
* `validStart` Number - Start date of the certificate being valid in seconds
* `validExpiry` Number - End date of the certificate being valid in seconds
* `fingerprint` String - Fingerprint of the certificate

View file

@ -0,0 +1,12 @@
# Cookie Object
* `name` String - cookie 的名称.
* `value` String - cookie 的值.
* `domain` String (optional) - cookie 的域名.
* `hostOnly` Boolean (optional) - cookie 的类型是否为 host-only.
* `path` String (optional) - cookie 的路径.
* `secure` Boolean (optional) - cookie 是否标记为安全.
* `httpOnly` Boolean (optional) - cookie 是否只标记为 HTTP.
* `session` Boolean (optional) - cookie 是否是一个 session cookie, 还是一个带有过期时间的持续 cookie.
* `expirationDate` Double (optional) - cookie 距离 UNIX 时间戳的过期时间,数值为秒。不需要提供给 session
cookies.

View file

@ -0,0 +1,4 @@
# 崩溃报告的对象
* `date` String
* `ID` Integer

View file

@ -0,0 +1,7 @@
# DesktopCapturerSource Object
* `id` String - 窗口或者屏幕的标识符,当调用 [`navigator.webkitGetUserMedia`] 时可以被当成 `chromeMediaSourceId` 使用。
标识符的格式为`window:XX` 或 `screen:XX``XX` 是一个随机生成的数字.
* `name` String - 窗口的来源将被命名为 `Entire Screen``Screen <index>`,而窗口来源的名字将会和窗口的标题匹配.
* `thumbnail` [NativeImage](../native-image.md) - 缩略图. **注:** 通过 `desktopCapturer.getSources` 方法,
不能保证缩略图的大小与 `options` 中指定的 `thumbnailSize` 相同。实际大小取决于窗口或者屏幕的比例。

View file

@ -0,0 +1,15 @@
# Display Object
* `id` Number - Unique identifier associated with the display.
* `rotation` Number - Can be 0, 90, 180, 270, represents screen rotation in
clock-wise degrees.
* `scaleFactor` Number - Output device's pixel scale factor.
* `touchSupport` String - Can be `available`, `unavailable`, `unknown`.
* `bounds` [Rectangle](rectangle.md)
* `size` [Size](size.md)
* `workArea` [Rectangle](rectangle.md)
* `workAreaSize` [Size](size.md)
The `Display` object represents a physical display connected to the system. A
fake `Display` may exist on a headless system, or a `Display` may correspond to
a remote, virtual display.

View file

@ -0,0 +1,4 @@
# FileFilter Object
* `name` String
* `extensions` String[]

View file

@ -0,0 +1,21 @@
# JumpListCategory Object
* `type` String (optional) - One of the following:
* `tasks` - Items in this category will be placed into the standard `Tasks`
category. There can be only one such category, and it will always be
displayed at the bottom of the Jump List.
* `frequent` - Displays a list of files frequently opened by the app, the
name of the category and its items are set by Windows.
* `recent` - Displays a list of files recently opened by the app, the name
of the category and its items are set by Windows. Items may be added to
this category indirectly using `app.addRecentDocument(path)`.
* `custom` - Displays tasks or file links, `name` must be set by the app.
* `name` String (optional) - Must be set if `type` is `custom`, otherwise it should be
omitted.
* `items` JumpListItem[] (optional) - Array of [`JumpListItem`](jump-list-item.md) objects if `type` is `tasks` or
`custom`, otherwise it should be omitted.
**Note:** If a `JumpListCategory` object has neither the `type` nor the `name`
property set then its `type` is assumed to be `tasks`. If the `name` property
is set but the `type` property is omitted then the `type` is assumed to be
`custom`.

View file

@ -0,0 +1,28 @@
# JumpListItem Object
* `type` String (optional) - One of the following:
* `task` - A task will launch an app with specific arguments.
* `separator` - Can be used to separate items in the standard `Tasks`
category.
* `file` - A file link will open a file using the app that created the
Jump List, for this to work the app must be registered as a handler for
the file type (though it doesn't have to be the default handler).
* `path` String (optional) - Path of the file to open, should only be set if `type` is
`file`.
* `program` String (optional) - Path of the program to execute, usually you should
specify `process.execPath` which opens the current program. Should only be
set if `type` is `task`.
* `args` String (optional) - The command line arguments when `program` is executed. Should
only be set if `type` is `task`.
* `title` String (optional) - The text to be displayed for the item in the Jump List.
Should only be set if `type` is `task`.
* `description` String (optional) - Description of the task (displayed in a tooltip).
Should only be set if `type` is `task`.
* `iconPath` String (optional) - The absolute path to an icon to be displayed in a
Jump List, which can be an arbitrary resource file that contains an icon
(e.g. `.ico`, `.exe`, `.dll`). You can usually specify `process.execPath` to
show the program icon.
* `iconIndex` Number (optional) - The index of the icon in the resource file. If a
resource file contains multiple icons this value can be used to specify the
zero-based index of the icon that should be displayed for this task. If a
resource file contains only one icon, this property should be set to zero.

View file

@ -0,0 +1,5 @@
# MemoryUsageDetails Object
* `count` Number
* `size` Number
* `liveSize` Number

View file

@ -0,0 +1,4 @@
# MimeTypedBuffer Object
* `mimeType` String - The mimeType of the Buffer that you are sending
* `data` Buffer - The actual Buffer content

View file

@ -0,0 +1,4 @@
# Point Object
* `x` Number
* `y` Number

View file

@ -0,0 +1,6 @@
# Rectangle Object
* `x` Number - The x coordinate of the origin of the rectangle
* `y` Number - The y coordinate of the origin of the rectangle
* `width` Number
* `height` Number

View file

@ -0,0 +1,5 @@
# RemoveClientCertificate Object
* `type` String - `clientCertificate`.
* `origin` String - Origin of the server whose associated client certificate
must be removed from the cache.

View file

@ -0,0 +1,15 @@
# RemovePassword Object
* `type` String - `password`.
* `origin` String (optional) - When provided, the authentication info
related to the origin will only be removed otherwise the entire cache
will be cleared.
* `scheme` String (optional) - Scheme of the authentication.
Can be `basic`, `digest`, `ntlm`, `negotiate`. Must be provided if
removing by `origin`.
* `realm` String (optional) - Realm of the authentication. Must be provided if
removing by `origin`.
* `username` String (optional) - Credentials of the authentication. Must be
provided if removing by `origin`.
* `password` String (optional) - Credentials of the authentication. Must be
provided if removing by `origin`.

View file

@ -0,0 +1,4 @@
# ScrubberItem Object
* `label` String - (Optional) The text to appear in this item
* `icon` NativeImage - (Optional) The image to appear in this item

View file

@ -0,0 +1,5 @@
# SegmentedControlSegment Object
* `label` String - (Optional) The text to appear in this segment
* `icon` NativeImage - (Optional) The image to appear in this segment
* `enabled` Boolean - (Optional) Whether this segment is selectable. Default: true

View file

@ -0,0 +1,15 @@
# ShortcutDetails Object
* `target` String - The target to launch from this shortcut.
* `cwd` String (optional) - The working directory. Default is empty.
* `args` String (optional) - The arguments to be applied to `target` when
launching from this shortcut. Default is empty.
* `description` String (optional) - The description of the shortcut. Default
is empty.
* `icon` String (optional) - The path to the icon, can be a DLL or EXE. `icon`
and `iconIndex` have to be set together. Default is empty, which uses the
target's icon.
* `iconIndex` Number (optional) - The resource ID of icon when `icon` is a
DLL or EXE. Default is 0.
* `appUserModelId` String (optional) - The Application User Model ID. Default
is empty.

View file

@ -0,0 +1,4 @@
# Size Object
* `width` Number
* `height` Number

View file

@ -0,0 +1,14 @@
# Task Object
* `program` String - Path of the program to execute, usually you should
specify `process.execPath` which opens the current program.
* `arguments` String - The command line arguments when `program` is
executed.
* `title` String - The string to be displayed in a JumpList.
* `description` String - Description of this task.
* `iconPath` String - The absolute path to an icon to be displayed in a
JumpList, which can be an arbitrary resource file that contains an icon. You
can usually specify `process.execPath` to show the icon of the program.
* `iconIndex` Number - The icon index in the icon file. If an icon file
consists of two or more icons, set this value to identify the icon. If an
icon file consists of one icon, this value is 0.

View file

@ -0,0 +1,21 @@
# ThumbarButton Object
* `icon` [NativeImage](../native-image.md) - The icon showing in thumbnail
toolbar.
* `click` Function
* `tooltip` String (optional) - The text of the button's tooltip.
* `flags` String[] (optional) - Control specific states and behaviors of the
button. By default, it is `['enabled']`.
The `flags` is an array that can include following `String`s:
* `enabled` - The button is active and available to the user.
* `disabled` - The button is disabled. It is present, but has a visual state
indicating it will not respond to user action.
* `dismissonclick` - When the button is clicked, the thumbnail window closes
immediately.
* `nobackground` - Do not draw a button border, use only the image.
* `hidden` - The button is not shown to the user.
* `noninteractive` - The button is enabled but not interactive; no pressed
button state is drawn. This value is intended for instances where the button
is used in a notification.

View file

@ -0,0 +1,4 @@
# UploadBlob Object
* `type` String - `blob`.
* `blobUUID` String - UUID of blob data to upload.

View file

@ -0,0 +1,6 @@
# UploadData Object
* `bytes` Buffer - Content being sent.
* `file` String - Path of file being uploaded.
* `blobUUID` String - UUID of blob data. Use [ses.getBlobData](../session.md#sesgetblobdataidentifier-callback) method
to retrieve the data.

View file

@ -0,0 +1,9 @@
# UploadFileSystem Object
* `type` String - `fileSystem`.
* `filsSystemURL` String - FileSystem url to read data for upload.
* `offset` Integer - Defaults to `0`.
* `length` Integer - Number of bytes to read from `offset`.
Defaults to `0`.
* `modificationTime` Double - Last Modification time in
number of seconds sine the UNIX epoch.

View file

@ -0,0 +1,9 @@
# UploadFile Object
* `type` String - `file`.
* `filePath` String - Path of file to be uploaded.
* `offset` Integer - Defaults to `0`.
* `length` Integer - Number of bytes to read from `offset`.
Defaults to `0`.
* `modificationTime` Double - Last Modification time in
number of seconds sine the UNIX epoch.

View file

@ -0,0 +1,4 @@
# UploadRawData Object
* `type` String - `rawData`.
* `bytes` Buffer - Data to be uploaded.

View file

@ -49,8 +49,7 @@ npm install -g electron-windows-store
│   └── atom.asar
├── snapshot_blob.bin
├── squirrel.exe
├── ui_resources_200_percent.pak
└── xinput1_3.dll
└── ui_resources_200_percent.pak
```
## 步骤 2: 运行 electron-windows-store

View file

@ -103,6 +103,6 @@ an issue:
* [Debug Instructions (Windows)](development/debug-instructions-windows.md)
* [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md)
* [Documentation Styleguide](styleguide.md)
* [Updating Chrome](development/updating-chrome.md)
* [Upgrading Chrome](development/upgrading-chrome.md)
* [Chromium Development](development/chromium-development.md)
* [V8 Development](development/v8-development.md)

74
docs/api/browser-view.md Normal file
View file

@ -0,0 +1,74 @@
## Class: BrowserView
> Create and control views.
**Note:** The BrowserView API is currently experimental and may change or be
removed in future Electron releases.
Process: [Main](../glossary.md#main-process)
A `BrowserView` can be used to embed additional web content into a
`BrowserWindow`. It is like a child window, except that it is positioned
relative to its owning window. It is meant to be an alternative to the
`webview` tag.
## Example
```javascript
// In the main process.
const {BrowserView, BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 800, height: 600})
win.on('closed', () => {
win = null
})
let view = new BrowserView({
webPreferences: {
nodeIntegration: false
}
})
win.addChildView(view)
view.setBounds(0, 0, 300, 300)
view.webContents.loadURL('https://electron.atom.io')
```
### `new BrowserView([options])` _Experimental_
* `options` Object (optional)
* `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md).
### Instance Properties
Objects created with `new BrowserView` have the following properties:
#### `view.webContents` _Experimental_
A [`webContents`](web-contents.md) object owned by this view.
#### `win.id` _Experimental_
A `Integer` representing the unique ID of the view.
### Instance Methods
Objects created with `new BrowserWindow` have the following instance methods:
#### `win.setAutoResize(options)` _Experimental_
* `options` Object
* `width`: If `true`, the view's width will grow and shrink together with
the window. `false` by default.
* `height`: If `true`, the view's height will grow and shrink together with
the window. `false` by default.
#### `win.setBounds(bounds)` _Experimental_
* `bounds` [Rectangle](structures/rectangle.md)
Resizes and moves the view to the supplied bounds relative to the window.
#### `win.setBackgroundColor(color)` _Experimental_
* `color` String - Color in `#aarrggbb` or `#argb` form. The alpha channel is
optional.

View file

@ -683,10 +683,8 @@ Returns `Boolean` - Whether the window is in fullscreen mode.
* `aspectRatio` Float - The aspect ratio to maintain for some portion of the
content view.
* `extraSize` Object (optional) - The extra size not to be included while
* `extraSize` [Size](structures/size.md) - The extra size not to be included while
maintaining the aspect ratio.
* `width` Integer
* `height` Integer
This will make a window maintain an aspect ratio. The extra size allows a
developer to have space, specified in pixels, not included within the aspect
@ -1292,6 +1290,13 @@ machine has a touch bar and is running on macOS 10.12.1+.
**Note:** The TouchBar API is currently experimental and may change or be
removed in future Electron releases.
#### `win.setBrowserView(browserView)` _Experimental_
* `browserView` [BrowserView](browser-view.md)
**Note:** The BrowserView API is currently experimental and may change or be
removed in future Electron releases.
[blink-feature-string]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5?l=62
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look
[vibrancy-docs]: https://developer.apple.com/reference/appkit/nsvisualeffectview?language=objc

View file

@ -60,9 +60,8 @@ The `desktopCapturer` module has the following methods:
* `options` Object
* `types` String[] - An array of Strings that lists the types of desktop sources
to be captured, available types are `screen` and `window`.
* `thumbnailSize` Object (optional) - The size that the media source thumbnail should be scaled to.
* `width` Integer - Default is `150`
* `height` Integer - Default is `150`
* `thumbnailSize` [Size](structures/size.md) (optional) - The size that the media source thumbnail
should be scaled to. Default is `150` x `150`.
* `callback` Function
* `error` Error
* `sources` [DesktopCapturerSource[]](structures/desktop-capturer-source.md)

View file

@ -115,8 +115,9 @@ will be passed via `callback(filename)`
* `browserWindow` BrowserWindow (optional)
* `options` Object
* `type` String (optional) - Can be `"none"`, `"info"`, `"error"`, `"question"` or
`"warning"`. On Windows, "question" displays the same icon as "info", unless
you set an icon using the "icon" option.
`"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
you set an icon using the `"icon"` option. On macOS, both `"warning"` and
`"error"` display the same warning icon.
* `buttons` String[] (optional) - Array of texts for buttons. On Windows, an empty array
will result in one button labeled "OK".
* `defaultId` Integer (optional) - Index of the button in the buttons array which will
@ -175,6 +176,20 @@ it is usually used to report errors in early stage of startup. If called
before the app `ready`event on Linux, the message will be emitted to stderr,
and no GUI dialog will appear.
### `dialog.showCertificateTrustDialog([browserWindow, ]options, callback)` _macOS_
* `browserWindow` BrowserWindow (optional)
* `options` Object
* `certificate` [Certificate](structures/certificate.md) - The certificate to trust/import.
* `message` String - The message to display to the user.
* `callback` Function
Displays a modal dialog that shows a message and certificate information, and
gives the user the option of trusting/importing the certificate.
The `browserWindow` argument allows the dialog to attach itself to a parent
window, making it modal.
## Sheets
On macOS, dialogs are presented as sheets attached to a window if you provide

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