Browse Source

Merge branch 'master' into native-window-open

Ryohei Ikegami 8 years ago
parent
commit
8dff29185b
100 changed files with 1920 additions and 576 deletions
  1. 2 2
      README.md
  2. 3 5
      atom/browser/api/atom_api_auto_updater.cc
  3. 162 0
      atom/browser/api/atom_api_browser_view.cc
  4. 72 0
      atom/browser/api/atom_api_browser_view.h
  5. 6 0
      atom/browser/api/atom_api_dialog.cc
  6. 8 3
      atom/browser/api/atom_api_web_contents.cc
  7. 5 4
      atom/browser/api/atom_api_web_contents.h
  8. 31 3
      atom/browser/api/atom_api_window.cc
  9. 4 0
      atom/browser/api/atom_api_window.h
  10. 5 8
      atom/browser/browser.cc
  11. 1 3
      atom/browser/browser_linux.cc
  12. 2 3
      atom/browser/browser_mac.mm
  13. 3 4
      atom/browser/browser_win.cc
  14. 7 2
      atom/browser/common_web_contents_delegate.cc
  15. 18 0
      atom/browser/native_browser_view.cc
  16. 57 0
      atom/browser/native_browser_view.h
  17. 30 0
      atom/browser/native_browser_view_mac.h
  18. 60 0
      atom/browser/native_browser_view_mac.mm
  19. 36 0
      atom/browser/native_browser_view_views.cc
  20. 33 0
      atom/browser/native_browser_view_views.h
  21. 5 2
      atom/browser/native_window.cc
  22. 4 0
      atom/browser/native_window.h
  23. 4 0
      atom/browser/native_window_mac.h
  24. 33 1
      atom/browser/native_window_mac.mm
  25. 57 4
      atom/browser/native_window_views.cc
  26. 4 0
      atom/browser/native_window_views.h
  27. 2 2
      atom/browser/resources/mac/Info.plist
  28. 1 1
      atom/browser/resources/win/atom.manifest
  29. 4 4
      atom/browser/resources/win/atom.rc
  30. 29 0
      atom/browser/ui/certificate_trust.h
  31. 112 0
      atom/browser/ui/certificate_trust_mac.mm
  32. 2 0
      atom/browser/ui/cocoa/atom_touch_bar.h
  33. 52 12
      atom/browser/ui/cocoa/atom_touch_bar.mm
  34. 1 0
      atom/browser/ui/cocoa/touch_bar_forward_declarations.h
  35. 7 3
      atom/browser/ui/message_box_mac.mm
  36. 0 91
      atom/browser/ui/views/menu_layout.cc
  37. 0 36
      atom/browser/ui/views/menu_layout.h
  38. 3 3
      atom/browser/ui/views/submenu_button.cc
  39. 0 1
      atom/browser/ui/views/win_frame_view.cc
  40. 0 8
      atom/browser/ui/win/atom_desktop_window_tree_host_win.cc
  41. 0 1
      atom/browser/ui/win/atom_desktop_window_tree_host_win.h
  42. 17 0
      atom/browser/window_list.cc
  43. 7 16
      atom/browser/window_list.h
  44. 1 1
      atom/common/atom_version.h
  45. 52 0
      atom/common/native_mate_converters/net_converter.cc
  46. 4 0
      atom/common/native_mate_converters/net_converter.h
  47. 3 2
      atom/common/node_bindings.cc
  48. 84 0
      atom/renderer/atom_render_frame_observer.cc
  49. 53 0
      atom/renderer/atom_render_frame_observer.h
  50. 35 130
      atom/renderer/atom_renderer_client.cc
  51. 10 7
      atom/renderer/atom_renderer_client.h
  52. 0 46
      atom/renderer/atom_sandboxed_renderer_client.cc
  53. 9 4
      atom/renderer/atom_sandboxed_renderer_client.h
  54. 16 9
      atom/renderer/renderer_client_base.cc
  55. 8 0
      atom/renderer/renderer_client_base.h
  56. 12 0
      atom/utility/atom_content_utility_client.cc
  57. 2 0
      atom/utility/atom_content_utility_client.h
  58. 1 0
      chromium_src/chrome/browser/printing/print_view_manager_base.cc
  59. 1 2
      docs-translations/ko-KR/tutorial/windows-store-guide.md
  60. 3 3
      docs-translations/tr-TR/README.md
  61. 85 0
      docs-translations/tr-TR/project/README.md
  62. 178 0
      docs-translations/tr-TR/tutorial/application-distribution.md
  63. 29 0
      docs-translations/tr-TR/tutorial/supported-platforms.md
  64. 4 0
      docs-translations/zh-CN/README.md
  65. 22 3
      docs-translations/zh-CN/api/accelerator.md
  66. 9 9
      docs-translations/zh-CN/api/menu-item.md
  67. 58 127
      docs-translations/zh-CN/api/menu.md
  68. 4 0
      docs-translations/zh-CN/api/structures/bluetooth-device.md
  69. 8 0
      docs-translations/zh-CN/api/structures/certificate-principal.md
  70. 12 0
      docs-translations/zh-CN/api/structures/certificate.md
  71. 12 0
      docs-translations/zh-CN/api/structures/cookie.md
  72. 4 0
      docs-translations/zh-CN/api/structures/crash-report.md
  73. 7 0
      docs-translations/zh-CN/api/structures/desktop-capturer-source.md
  74. 15 0
      docs-translations/zh-CN/api/structures/display.md
  75. 4 0
      docs-translations/zh-CN/api/structures/file-filter.md
  76. 21 0
      docs-translations/zh-CN/api/structures/jump-list-category.md
  77. 28 0
      docs-translations/zh-CN/api/structures/jump-list-item.md
  78. 5 0
      docs-translations/zh-CN/api/structures/memory-usage-details.md
  79. 4 0
      docs-translations/zh-CN/api/structures/mime-typed-buffer.md
  80. 4 0
      docs-translations/zh-CN/api/structures/point.md
  81. 6 0
      docs-translations/zh-CN/api/structures/rectangle.md
  82. 5 0
      docs-translations/zh-CN/api/structures/remove-client-certificate.md
  83. 15 0
      docs-translations/zh-CN/api/structures/remove-password.md
  84. 4 0
      docs-translations/zh-CN/api/structures/scrubber-item.md
  85. 5 0
      docs-translations/zh-CN/api/structures/segmented-control-segment.md
  86. 15 0
      docs-translations/zh-CN/api/structures/shortcut-details.md
  87. 4 0
      docs-translations/zh-CN/api/structures/size.md
  88. 14 0
      docs-translations/zh-CN/api/structures/task.md
  89. 21 0
      docs-translations/zh-CN/api/structures/thumbar-button.md
  90. 4 0
      docs-translations/zh-CN/api/structures/upload-blob.md
  91. 6 0
      docs-translations/zh-CN/api/structures/upload-data.md
  92. 9 0
      docs-translations/zh-CN/api/structures/upload-file-system.md
  93. 9 0
      docs-translations/zh-CN/api/structures/upload-file.md
  94. 4 0
      docs-translations/zh-CN/api/structures/upload-raw-data.md
  95. 1 2
      docs-translations/zh-CN/tutorial/windows-store-guide.md
  96. 1 1
      docs/README.md
  97. 74 0
      docs/api/browser-view.md
  98. 8 3
      docs/api/browser-window.md
  99. 2 3
      docs/api/desktop-capturer.md
  100. 17 2
      docs/api/dialog.md

+ 2 - 2
README.md

@@ -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)

+ 3 - 5
atom/browser/api/atom_api_auto_updater.cc

@@ -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

+ 162 - 0
atom/browser/api/atom_api_browser_view.cc

@@ -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)

+ 72 - 0
atom/browser/api/atom_api_browser_view.h

@@ -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_

+ 6 - 0
atom/browser/api/atom_api_dialog.cc

@@ -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

+ 8 - 3
atom/browser/api/atom_api_web_contents.cc

@@ -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;
 

+ 5 - 4
atom/browser/api/atom_api_web_contents.h

@@ -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)

+ 31 - 3
atom/browser/api/atom_api_window.cc

@@ -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)

+ 4 - 0
atom/browser/api/atom_api_window.h

@@ -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_;

+ 5 - 8
atom/browser/browser.cc

@@ -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();
     }
   }
 }

+ 1 - 3
atom/browser/browser_linux.cc

@@ -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;

+ 2 - 3
atom/browser/browser_mac.mm

@@ -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);

+ 3 - 4
atom/browser/browser_win.cc

@@ -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());
   }

+ 7 - 2
atom/browser/common_web_contents_delegate.cc

@@ -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() {

+ 18 - 0
atom/browser/native_browser_view.cc

@@ -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

+ 57 - 0
atom/browser/native_browser_view.h

@@ -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_

+ 30 - 0
atom/browser/native_browser_view_mac.h

@@ -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_

+ 60 - 0
atom/browser/native_browser_view_mac.mm

@@ -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

+ 36 - 0
atom/browser/native_browser_view_views.cc

@@ -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

+ 33 - 0
atom/browser/native_browser_view_views.h

@@ -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_

+ 5 - 2
atom/browser/native_window.cc

@@ -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();
 }

+ 4 - 0
atom/browser/native_window.h

@@ -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();

+ 4 - 0
atom/browser/native_window_mac.h

@@ -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_;

+ 33 - 1
atom/browser/native_window_mac.mm

@@ -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:

+ 57 - 4
atom/browser/native_window_views.cc

@@ -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();
 }

+ 4 - 0
atom/browser/native_window_views.h

@@ -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_;

+ 2 - 2
atom/browser/resources/mac/Info.plist

@@ -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>

+ 1 - 1
atom/browser/resources/win/atom.manifest

@@ -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>

+ 4 - 4
atom/browser/resources/win/atom.rc

@@ -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

+ 29 - 0
atom/browser/ui/certificate_trust.h

@@ -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_

+ 112 - 0
atom/browser/ui/certificate_trust_mac.mm

@@ -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

+ 2 - 0
atom/browser/ui/cocoa/atom_touch_bar.h

@@ -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;

+ 52 - 12
atom/browser/ui/cocoa/atom_touch_bar.mm

@@ -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 {

+ 1 - 0
atom/browser/ui/cocoa/touch_bar_forward_declarations.h

@@ -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;
 

+ 7 - 3
atom/browser/ui/message_box_mac.mm

@@ -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];
 }

+ 0 - 91
atom/browser/ui/views/menu_layout.cc

@@ -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

+ 0 - 36
atom/browser/ui/views/menu_layout.h

@@ -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_

+ 3 - 3
atom/browser/ui/views/submenu_button.cc

@@ -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);
 }

+ 0 - 1
atom/browser/ui/views/win_frame_view.cc

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

+ 0 - 8
atom/browser/ui/win/atom_desktop_window_tree_host_win.cc

@@ -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

+ 0 - 1
atom/browser/ui/win/atom_desktop_window_tree_host_win.h

@@ -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

+ 17 - 0
atom/browser/window_list.cc

@@ -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() {
 }
 

+ 7 - 16
atom/browser/window_list.h

@@ -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();
 

+ 1 - 1
atom/common/atom_version.h

@@ -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
 

+ 52 - 0
atom/common/native_mate_converters/net_converter.cc

@@ -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) {

+ 4 - 0
atom/common/native_mate_converters/net_converter.h

@@ -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<>

+ 3 - 2
atom/common/node_bindings.cc

@@ -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);

+ 84 - 0
atom/renderer/atom_render_frame_observer.cc

@@ -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

+ 53 - 0
atom/renderer/atom_render_frame_observer.h

@@ -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_

+ 35 - 130
atom/renderer/atom_renderer_client.cc

@@ -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

+ 10 - 7
atom/renderer/atom_renderer_client.h

@@ -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 {

+ 0 - 46
atom/renderer/atom_sandboxed_renderer_client.cc

@@ -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);
 }
 

+ 9 - 4
atom/renderer/atom_sandboxed_renderer_client.h

@@ -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;

+ 16 - 9
atom/renderer/renderer_client_base.cc

@@ -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);

+ 8 - 0
atom/renderer/renderer_client_base.h

@@ -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);

+ 12 - 0
atom/utility/atom_content_utility_client.cc

@@ -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

+ 2 - 0
atom/utility/atom_content_utility_client.h

@@ -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;

+ 1 - 0
chromium_src/chrome/browser/printing/print_view_manager_base.cc

@@ -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() &&

+ 1 - 2
docs-translations/ko-KR/tutorial/windows-store-guide.md

@@ -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` 실행하기

+ 3 - 3
docs-translations/tr-TR/README.md

@@ -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)

+ 85 - 0
docs-translations/tr-TR/project/README.md

@@ -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ı [email protected]'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ı
+açı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.

+ 178 - 0
docs-translations/tr-TR/tutorial/application-distribution.md

@@ -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ı açı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.

+ 29 - 0
docs-translations/tr-TR/tutorial/supported-platforms.md

@@ -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

+ 4 - 0
docs-translations/zh-CN/README.md

@@ -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)

+ 22 - 3
docs-translations/zh-CN/api/accelerator.md

@@ -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`

+ 9 - 9
docs-translations/zh-CN/api/menu-item.md

@@ -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` 还可以有以下值:
 

+ 58 - 127
docs-translations/zh-CN/api/menu.md

@@ -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'}
   ]
 }
 

+ 4 - 0
docs-translations/zh-CN/api/structures/bluetooth-device.md

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

+ 8 - 0
docs-translations/zh-CN/api/structures/certificate-principal.md

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

+ 12 - 0
docs-translations/zh-CN/api/structures/certificate.md

@@ -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

+ 12 - 0
docs-translations/zh-CN/api/structures/cookie.md

@@ -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.

+ 4 - 0
docs-translations/zh-CN/api/structures/crash-report.md

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

+ 7 - 0
docs-translations/zh-CN/api/structures/desktop-capturer-source.md

@@ -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` 相同。实际大小取决于窗口或者屏幕的比例。

+ 15 - 0
docs-translations/zh-CN/api/structures/display.md

@@ -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.

+ 4 - 0
docs-translations/zh-CN/api/structures/file-filter.md

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

+ 21 - 0
docs-translations/zh-CN/api/structures/jump-list-category.md

@@ -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`.

+ 28 - 0
docs-translations/zh-CN/api/structures/jump-list-item.md

@@ -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.

+ 5 - 0
docs-translations/zh-CN/api/structures/memory-usage-details.md

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

+ 4 - 0
docs-translations/zh-CN/api/structures/mime-typed-buffer.md

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

+ 4 - 0
docs-translations/zh-CN/api/structures/point.md

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

+ 6 - 0
docs-translations/zh-CN/api/structures/rectangle.md

@@ -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

+ 5 - 0
docs-translations/zh-CN/api/structures/remove-client-certificate.md

@@ -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.

+ 15 - 0
docs-translations/zh-CN/api/structures/remove-password.md

@@ -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`.

+ 4 - 0
docs-translations/zh-CN/api/structures/scrubber-item.md

@@ -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

+ 5 - 0
docs-translations/zh-CN/api/structures/segmented-control-segment.md

@@ -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

+ 15 - 0
docs-translations/zh-CN/api/structures/shortcut-details.md

@@ -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.

+ 4 - 0
docs-translations/zh-CN/api/structures/size.md

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

+ 14 - 0
docs-translations/zh-CN/api/structures/task.md

@@ -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.

+ 21 - 0
docs-translations/zh-CN/api/structures/thumbar-button.md

@@ -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.

+ 4 - 0
docs-translations/zh-CN/api/structures/upload-blob.md

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

+ 6 - 0
docs-translations/zh-CN/api/structures/upload-data.md

@@ -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.

+ 9 - 0
docs-translations/zh-CN/api/structures/upload-file-system.md

@@ -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.

+ 9 - 0
docs-translations/zh-CN/api/structures/upload-file.md

@@ -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.

+ 4 - 0
docs-translations/zh-CN/api/structures/upload-raw-data.md

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

+ 1 - 2
docs-translations/zh-CN/tutorial/windows-store-guide.md

@@ -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

+ 1 - 1
docs/README.md

@@ -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 - 0
docs/api/browser-view.md

@@ -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.

+ 8 - 3
docs/api/browser-window.md

@@ -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

+ 2 - 3
docs/api/desktop-capturer.md

@@ -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)

+ 17 - 2
docs/api/dialog.md

@@ -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 changed in this diff